public Authenticator Convert(IIconResolver iconResolver)
            {
                Authenticator ConvertFromInfo(AuthenticatorType type, string secret)
                {
                    return(new()
                    {
                        Issuer = Name,
                        Username = Login.Username,
                        Type = type,
                        Algorithm = Authenticator.DefaultAlgorithm,
                        Digits = type.GetDefaultDigits(),
                        Period = type.GetDefaultPeriod(),
                        Icon = iconResolver.FindServiceKeyByName(Name),
                        Secret = Authenticator.CleanSecret(secret, type)
                    });
                }

                if (Login.Totp.StartsWith("otpauth"))
                {
                    return(Authenticator.FromOtpAuthUri(Login.Totp, iconResolver));
                }

                if (Login.Totp.StartsWith("steam"))
                {
                    var secret = Login.Totp.Substring("steam://".Length);
                    return(ConvertFromInfo(AuthenticatorType.SteamOtp, secret));
                }

                return(ConvertFromInfo(AuthenticatorType.Totp, Login.Totp));
            }
Пример #2
0
            public Authenticator Convert(IIconResolver iconResolver)
            {
                var type = Type switch
                {
                    Type.Totp => AuthenticatorType.Totp,
                    Type.Hotp => AuthenticatorType.Hotp,
                    _ => throw new ArgumentOutOfRangeException()
                };

                string issuer;
                string username = null;
                string icon     = null;

                if (Issuer == "")
                {
                    issuer = Email;
                }
                else
                {
                    issuer   = Issuer;
                    username = Email;
                    icon     = iconResolver.FindServiceKeyByName(Issuer);
                }

                return(new Authenticator
                {
                    Issuer = issuer,
                    Username = username,
                    Type = type,
                    Secret = Authenticator.CleanSecret(Secret, type),
                    Counter = Counter,
                    Icon = icon
                });
            }
        }
            public Authenticator Convert(IIconResolver iconResolver)
            {
                var type = Type switch
                {
                    Type.Totp => AuthenticatorType.Totp,
                    Type.Hotp => AuthenticatorType.Hotp,
                    _ => throw new ArgumentOutOfRangeException()
                };

                string issuer;
                string username = null;

                if (!String.IsNullOrEmpty(Issuer))
                {
                    issuer = Issuer;

                    if (!String.IsNullOrEmpty(Email))
                    {
                        username = Email;
                    }
                }
                else
                {
                    var originalNameParts = OriginalName.Split(new[] { ':' }, 2);

                    if (originalNameParts.Length == 2)
                    {
                        issuer = originalNameParts[0];

                        if (issuer == "")
                        {
                            issuer = Email;
                        }
                        else
                        {
                            username = Email;
                        }
                    }
                    else
                    {
                        issuer = Email;
                    }
                }

                return(new Authenticator
                {
                    Issuer = issuer,
                    Username = username,
                    Type = type,
                    Secret = Authenticator.CleanSecret(Secret, type),
                    Counter = Counter,
                    Icon = iconResolver.FindServiceKeyByName(issuer)
                });
            }
        }
        public async Task RenameAsync(Authenticator auth, string issuer, string username)
        {
            if (String.IsNullOrEmpty(issuer))
            {
                throw new ArgumentException("Issuer cannot be null or empty");
            }

            auth.Issuer   = issuer;
            auth.Username = username;
            auth.Icon ??= _iconResolver.FindServiceKeyByName(issuer);

            await _authenticatorRepository.UpdateAsync(auth);
        }
            public Authenticator Convert(IIconResolver iconResolver)
            {
                var type = Type switch
                {
                    "TOTP" => AuthenticatorType.Totp,
                    "HOTP" => AuthenticatorType.Hotp,
                    "STEAM" => AuthenticatorType.SteamOtp,
                    _ => throw new ArgumentException("Unknown type")
                };

                var algorithm = Algorithm switch
                {
                    "SHA1" => OtpHashMode.Sha1,
                    "SHA256" => OtpHashMode.Sha256,
                    "SHA512" => OtpHashMode.Sha512,
                    _ => throw new ArgumentException("Unknown algorithm")
                };

                string issuer;
                string username;

                if (String.IsNullOrEmpty(Issuer))
                {
                    issuer   = Label;
                    username = null;
                }
                else
                {
                    issuer   = Issuer;
                    username = Label;
                }

                return(new Authenticator
                {
                    Secret = Authenticator.CleanSecret(Secret, type),
                    Issuer = issuer,
                    Username = username,
                    Digits = Digits,
                    Period = Period ?? type.GetDefaultPeriod(),
                    Counter = Counter,
                    Type = type,
                    Algorithm = algorithm,
                    Icon = iconResolver.FindServiceKeyByName(Thumbnail)
                });
            }
        }
    }
            public Authenticator Convert(IIconResolver iconResolver)
            {
                var type = Type switch
                {
                    "totp" => AuthenticatorType.Totp,
                    "hotp" => AuthenticatorType.Hotp,
                    "steam" => AuthenticatorType.SteamOtp,
                    _ => throw new ArgumentOutOfRangeException(nameof(Type))
                };

                var algorithm = Info.Algorithm switch
                {
                    "SHA1" => HashAlgorithm.Sha1,
                    "SHA256" => HashAlgorithm.Sha256,
                    "SHA512" => HashAlgorithm.Sha512,
                    _ => throw new ArgumentOutOfRangeException(nameof(Info.Algorithm))
                };

                string issuer;
                string username;

                if (String.IsNullOrEmpty(Issuer))
                {
                    issuer   = Name;
                    username = null;
                }
                else
                {
                    issuer   = Issuer;
                    username = Name;
                }

                return(new Authenticator
                {
                    Type = type,
                    Algorithm = algorithm,
                    Secret = Authenticator.CleanSecret(Info.Secret, type),
                    Digits = Info.Digits,
                    Period = Info.Period,
                    Issuer = issuer,
                    Username = username,
                    Counter = Info.Counter,
                    Icon = iconResolver.FindServiceKeyByName(issuer)
                });
            }
        }
            public Authenticator Convert(IIconResolver iconResolver)
            {
                var type = Type switch
                {
                    "TOTP" => AuthenticatorType.Totp,
                    "HOTP" => AuthenticatorType.Hotp,
                    _ => throw new ArgumentOutOfRangeException(nameof(Type))
                };

                var algorithm = Algorithm switch
                {
                    "SHA1" => HashAlgorithm.Sha1,
                    "SHA256" => HashAlgorithm.Sha256,
                    "SHA512" => HashAlgorithm.Sha512,
                    _ => throw new ArgumentOutOfRangeException(nameof(Algorithm))
                };

                string issuer;
                string username;

                if (String.IsNullOrEmpty(Issuer))
                {
                    issuer   = Label;
                    username = null;
                }
                else
                {
                    issuer   = Issuer;
                    username = Label;
                }

                return(new Authenticator
                {
                    Issuer = issuer,
                    Username = username,
                    Algorithm = algorithm,
                    Type = type,
                    Counter = Counter,
                    Digits = Digits,
                    Icon = iconResolver.FindServiceKeyByName(issuer),
                    Period = Period,
                    Secret = Base32.Rfc4648.Encode((ReadOnlySpan <byte>)(Array) Secret)
                });
            }
        }
    }
            public Authenticator Convert(IIconResolver iconResolver)
            {
                var type = Type switch
                {
                    "TOTP" => AuthenticatorType.Totp,
                    "HOTP" => AuthenticatorType.Hotp,
                    _ => throw new ArgumentException("Unknown type")
                };

                var algorithm = Algorithm switch
                {
                    "SHA1" => OtpHashMode.Sha1,
                    "SHA256" => OtpHashMode.Sha256,
                    "SHA512" => OtpHashMode.Sha512,
                    _ => throw new ArgumentException("Unknown algorithm")
                };

                string issuer;
                string username;

                if (String.IsNullOrEmpty(Issuer))
                {
                    issuer   = Label;
                    username = null;
                }
                else
                {
                    issuer   = Issuer;
                    username = Label;
                }

                return(new Authenticator
                {
                    Issuer = issuer,
                    Username = username,
                    Algorithm = algorithm,
                    Type = type,
                    Counter = Counter,
                    Digits = Digits,
                    Icon = iconResolver.FindServiceKeyByName(issuer),
                    Period = Period,
                    Secret = Base32Encoding.ToString((byte[])(Array)Secret)
                });
            }
        }
    }
            public Authenticator Convert(IIconResolver iconResolver)
            {
                string issuer;
                string username;

                if (Issuer == "Unknown")
                {
                    issuer   = Name;
                    username = null;
                }
                else
                {
                    issuer   = Issuer;
                    username = Name;
                }

                var period = Period == ""
                    ? Type.GetDefaultPeriod()
                    : Int32.Parse(Period);

                var digits = Digits == ""
                    ? Type.GetDefaultDigits()
                    : Int32.Parse(Digits);

                // TODO: figure out if this value ever changes
                if (Base != 16)
                {
                    throw new ArgumentOutOfRangeException(nameof(Base), "Cannot parse base other than 16");
                }

                var secretBytes = Base16.Decode(Key);
                var secret      = Base32.Rfc4648.Encode(secretBytes);

                return(new Authenticator
                {
                    Issuer = issuer,
                    Username = username,
                    Type = Type,
                    Period = period,
                    Digits = digits,
                    Algorithm = Authenticator.DefaultAlgorithm,
                    Secret = Authenticator.CleanSecret(secret, Type),
                    Icon = iconResolver.FindServiceKeyByName(issuer)
                });
            }
            public Authenticator Convert(IIconResolver iconResolver)
            {
                var type = Type switch
                {
                    Type.Totp => AuthenticatorType.Totp,
                    Type.Hotp => AuthenticatorType.Hotp,
                    Type.Blizzard => AuthenticatorType.Totp,
                    _ => throw new ArgumentOutOfRangeException()
                };

                string issuer;
                string username = null;

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

                    if (!String.IsNullOrEmpty(Email))
                    {
                        username = Email;
                    }
                }
                else
                {
                    var originalNameParts = OriginalName.Split(new[] { ':' }, 2);

                    if (originalNameParts.Length == 2)
                    {
                        issuer = originalNameParts[0];

                        if (issuer == "")
                        {
                            issuer = Email;
                        }
                        else
                        {
                            username = Email;
                        }
                    }
                    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 = secret,
                    Counter = Counter,
                    Digits = digits,
                    Icon = iconResolver.FindServiceKeyByName(issuer)
                });
            }
        }
Пример #11
0
        public static Authenticator FromOtpAuthUri(string uri, IIconResolver iconResolver)
        {
            var uriMatch = Regex.Match(Uri.UnescapeDataString(uri), @"^otpauth:\/\/([a-z]+)\/([^?]*)(.*)$");

            if (!uriMatch.Success)
            {
                throw new ArgumentException("URI is not valid");
            }

            // Get the issuer and username if possible
            var issuerUsername      = uriMatch.Groups[2].Value;
            var issuerUsernameMatch = Regex.Match(issuerUsername, @"^(.*?):(.*)$");

            var queryString = uriMatch.Groups[3].Value;

            var argMatches = Regex.Matches(queryString, "([^?=&]+)(=([^&]*))?");
            var args       = new Dictionary <string, string>();

            foreach (Match match in argMatches)
            {
                if (!args.ContainsKey(match.Groups[1].Value))
                {
                    args.Add(match.Groups[1].Value, match.Groups[3].Value);
                }
            }

            string issuer;
            string username;

            if (issuerUsernameMatch.Success)
            {
                var issuerValue   = issuerUsernameMatch.Groups[1].Value;
                var usernameValue = issuerUsernameMatch.Groups[2].Value;

                if (issuerValue == "")
                {
                    issuer   = usernameValue;
                    username = null;
                }
                else
                {
                    issuer   = issuerValue;
                    username = usernameValue;
                }
            }
            else
            {
                if (args.ContainsKey("issuer"))
                {
                    issuer   = args["issuer"];
                    username = issuerUsername;
                }
                else
                {
                    issuer   = uriMatch.Groups[2].Value;
                    username = null;
                }
            }

            var type = uriMatch.Groups[1].Value switch
            {
                "totp" when issuer == "Steam" || args.ContainsKey("steam") => AuthenticatorType.SteamOtp,
                "totp" => AuthenticatorType.Totp,
                "hotp" => AuthenticatorType.Hotp,
                _ => throw new ArgumentException("Unknown type")
            };

            var algorithm = DefaultAlgorithm;

            if (args.ContainsKey("algorithm") && type != AuthenticatorType.SteamOtp)
            {
                algorithm = args["algorithm"].ToUpper() switch
                {
                    "SHA1" => HashAlgorithm.Sha1,
                    "SHA256" => HashAlgorithm.Sha256,
                    "SHA512" => HashAlgorithm.Sha512,
                    _ => throw new ArgumentException("Unknown algorithm")
                };
            }

            var digits = type.GetDefaultDigits();

            if (args.ContainsKey("digits") && !Int32.TryParse(args["digits"], out digits))
            {
                throw new ArgumentException("Digits parameter cannot be parsed.");
            }

            var period = type.GetDefaultPeriod();

            if (args.ContainsKey("period") && !Int32.TryParse(args["period"], out period))
            {
                throw new ArgumentException("Period parameter cannot be parsed.");
            }

            var counter = 0;

            if (type == AuthenticatorType.Hotp && args.ContainsKey("counter") &&
                !Int32.TryParse(args["counter"], out counter))
            {
                throw new ArgumentException("Counter parameter cannot be parsed.");
            }

            if (counter < 0)
            {
                throw new ArgumentException("Counter cannot be negative.");
            }

            if (!args.ContainsKey("secret"))
            {
                throw new ArgumentException("Secret parameter is required.");
            }

            var icon   = iconResolver.FindServiceKeyByName(args.ContainsKey("icon") ? args["icon"] : issuer);
            var secret = CleanSecret(args["secret"], type);

            var auth = new Authenticator
            {
                Secret    = secret,
                Issuer    = issuer.Trim().Truncate(IssuerMaxLength),
                Username  = username?.Trim().Truncate(UsernameMaxLength),
                Icon      = icon,
                Type      = type,
                Algorithm = algorithm,
                Digits    = digits,
                Period    = period,
                Counter   = counter
            };

            if (!auth.IsValid())
            {
                throw new ArgumentException("Authenticator is invalid");
            }

            return(auth);
        }
Пример #12
0
        public static Authenticator FromOtpAuthMigrationAuthenticator(OtpAuthMigration.Authenticator input,
                                                                      IIconResolver iconResolver)
        {
            string issuer;
            string username;

            // Google Auth may not have an issuer, just use the username instead
            if (String.IsNullOrEmpty(input.Issuer))
            {
                issuer   = input.Username.Trim().Truncate(IssuerMaxLength);
                username = null;
            }
            else
            {
                issuer = input.Issuer.Trim().Truncate(IssuerMaxLength);
                // For some odd reason the username field always follows a '[issuer]: [username]' format
                username = input.Username.Replace($"{input.Issuer}: ", "").Trim().Truncate(UsernameMaxLength);
            }

            var type = input.Type switch
            {
                OtpAuthMigration.Type.Totp => AuthenticatorType.Totp,
                OtpAuthMigration.Type.Hotp => AuthenticatorType.Hotp,
                _ => throw new ArgumentOutOfRangeException(nameof(input.Type), "Unknown type")
            };

            var algorithm = input.Algorithm switch
            {
                OtpAuthMigration.Algorithm.Sha1 => HashAlgorithm.Sha1,
                _ => throw new ArgumentOutOfRangeException(nameof(input.Algorithm), "Unknown algorithm")
            };

            string secret;

            try
            {
                secret = Base32.Rfc4648.Encode(input.Secret);
                secret = CleanSecret(secret, type);
            }
            catch (Exception e)
            {
                throw new ArgumentException("Failed to parse secret", e);
            }

            var auth = new Authenticator
            {
                Issuer    = issuer,
                Username  = username,
                Algorithm = algorithm,
                Type      = type,
                Secret    = secret,
                Counter   = input.Counter,
                Digits    = type.GetDefaultDigits(),
                Period    = type.GetDefaultPeriod(),
                Icon      = iconResolver.FindServiceKeyByName(issuer)
            };

            if (!auth.IsValid())
            {
                throw new ArgumentException("Authenticator is invalid");
            }

            return(auth);
        }