diff --git a/AuthenticatorPro.Shared/Source/Data/Backup/Converter/AuthenticatorPlusBackupConverter.cs b/AuthenticatorPro.Shared/Source/Data/Backup/Converter/AuthenticatorPlusBackupConverter.cs index 1322b2b4d9..b614973c72 100644 --- a/AuthenticatorPro.Shared/Source/Data/Backup/Converter/AuthenticatorPlusBackupConverter.cs +++ b/AuthenticatorPro.Shared/Source/Data/Backup/Converter/AuthenticatorPlusBackupConverter.cs @@ -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 @@ -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) { @@ -20,7 +26,7 @@ public override async Task 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); }); @@ -81,7 +87,7 @@ public override async Task Convert(byte[] data, string password = null) private enum Type { - Totp = 0, Hotp = 1 + Totp = 0, Hotp = 1, Blizzard = 2 } private class Account @@ -113,6 +119,7 @@ public Authenticator Convert(IIconResolver iconResolver) { Type.Totp => AuthenticatorType.Totp, Type.Hotp => AuthenticatorType.Hotp, + Type.Blizzard => AuthenticatorType.Totp, _ => throw new ArgumentOutOfRangeException() }; @@ -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; @@ -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) }; } diff --git a/AuthenticatorPro.Shared/Source/Data/Backup/Converter/TotpAuthenticatorBackupConverter.cs b/AuthenticatorPro.Shared/Source/Data/Backup/Converter/TotpAuthenticatorBackupConverter.cs index ae1db522ac..af1d386dbd 100644 --- a/AuthenticatorPro.Shared/Source/Data/Backup/Converter/TotpAuthenticatorBackupConverter.cs +++ b/AuthenticatorPro.Shared/Source/Data/Backup/Converter/TotpAuthenticatorBackupConverter.cs @@ -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; @@ -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; @@ -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 { diff --git a/AuthenticatorPro.Shared/Source/Util/StringExt.cs b/AuthenticatorPro.Shared/Source/Util/StringExt.cs index edb09d1d2c..bb9a7fc3d9 100644 --- a/AuthenticatorPro.Shared/Source/Util/StringExt.cs +++ b/AuthenticatorPro.Shared/Source/Util/StringExt.cs @@ -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; + } } } \ No newline at end of file