Skip to content

Commit

Permalink
implement auth plus blizzard support
Browse files Browse the repository at this point in the history
  • Loading branch information
jamie-mh committed Mar 10, 2021
1 parent b441501 commit 77ddea6
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using AuthenticatorPro.Shared.Source.Util;
using OtpNet;
using SQLite;

namespace AuthenticatorPro.Shared.Source.Data.Backup.Converter
Expand All @@ -11,6 +13,10 @@ public class AuthenticatorPlusBackupConverter : BackupConverter
{
public override BackupPasswordPolicy PasswordPolicy => BackupPasswordPolicy.Always;

private const string TempFileName = "authplus.db";
private const string BlizzardIssuer = "Blizzard";
private const int BlizzardDigits = 8;

public AuthenticatorPlusBackupConverter(IIconResolver iconResolver) : base(iconResolver)
{

Expand All @@ -20,7 +26,7 @@ public override async Task<Backup> Convert(byte[] data, string password = null)
{
var path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
"authplus.db"
TempFileName
);

await Task.Run(delegate { File.WriteAllBytes(path, data); });
Expand Down Expand Up @@ -81,7 +87,7 @@ public override async Task<Backup> Convert(byte[] data, string password = null)

private enum Type
{
Totp = 0, Hotp = 1
Totp = 0, Hotp = 1, Blizzard = 2
}

private class Account
Expand Down Expand Up @@ -113,6 +119,7 @@ public Authenticator Convert(IIconResolver iconResolver)
{
Type.Totp => AuthenticatorType.Totp,
Type.Hotp => AuthenticatorType.Hotp,
Type.Blizzard => AuthenticatorType.Totp,
_ => throw new ArgumentOutOfRangeException()
};

Expand All @@ -121,7 +128,7 @@ public Authenticator Convert(IIconResolver iconResolver)

if(!String.IsNullOrEmpty(Issuer))
{
issuer = Issuer;
issuer = Type == Type.Blizzard ? BlizzardIssuer : Issuer;

if(!String.IsNullOrEmpty(Email))
username = Email;
Expand All @@ -142,14 +149,27 @@ public Authenticator Convert(IIconResolver iconResolver)
else
issuer = Email;
}

var digits = Type == Type.Blizzard ? BlizzardDigits : type.GetDefaultDigits();

string secret;

if(Type == Type.Blizzard)
{
var base32Secret = Base32Encoding.ToString(Secret.ToHexBytes());
secret = Authenticator.CleanSecret(base32Secret, type);
}
else
secret = Authenticator.CleanSecret(Secret, type);

return new Authenticator
{
Issuer = issuer,
Username = username,
Type = type,
Secret = Authenticator.CleanSecret(Secret, type),
Secret = secret,
Counter = Counter,
Digits = digits,
Icon = iconResolver.FindServiceKeyByName(issuer)
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using AuthenticatorPro.Shared.Source.Util;
using Newtonsoft.Json;
using OtpNet;
using PCLCrypto;
Expand Down Expand Up @@ -67,18 +68,6 @@ private class Account
[JsonProperty(PropertyName = "base")]
public int Base { get; set; }


private static byte[] HexToBytes(string data)
{
var len = data.Length;
var output = new byte[len / 2];

for(var i = 0; i < len; i += 2)
output[i / 2] = System.Convert.ToByte(data.Substring(i, 2), 16);

return output;
}

public Authenticator Convert(IIconResolver iconResolver)
{
string issuer;
Expand Down Expand Up @@ -107,7 +96,7 @@ public Authenticator Convert(IIconResolver iconResolver)
if(Base != 16)
throw new ArgumentException("Cannot parse base other than 16");

var secret = Base32Encoding.ToString(HexToBytes(Key));
var secret = Base32Encoding.ToString(Key.ToHexBytes());

return new Authenticator
{
Expand Down
11 changes: 11 additions & 0 deletions AuthenticatorPro.Shared/Source/Util/StringExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,16 @@ public static string Truncate(this string value, int maxLength)

return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}

public static byte[] ToHexBytes(this string data)
{
var len = data.Length;
var output = new byte[len / 2];

for(var i = 0; i < len; i += 2)
output[i / 2] = Convert.ToByte(data.Substring(i, 2), 16);

return output;
}
}
}

0 comments on commit 77ddea6

Please sign in to comment.