Пример #1
0
        public static Authenticator FromOtpAuthMigrationAuthenticator(OtpAuthMigration.Authenticator input)
        {
            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(32);
                username = null;
            }
            else
            {
                issuer = input.Issuer.Trim().Truncate(32);
                // For some odd reason the username field always follows a '[issuer]: [username]' format
                username = input.Username.Replace($"{input.Issuer}: ", "").Trim().Truncate(40);
            }

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

            var algorithm = input.Algorithm switch
            {
                OtpAuthMigration.Algorithm.Sha1 => OtpHashMode.Sha1,
                _ => throw new InvalidAuthenticatorException()
            };

            string secret;

            try
            {
                secret = Base32Encoding.ToString(input.Secret);
                secret = CleanSecret(secret);
            }
            catch
            {
                throw new InvalidAuthenticatorException();
            }

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

            auth.Validate();
            return(auth);
        }
Пример #2
0
        public static Authenticator FromOtpAuthUri(string uri)
        {
            var uriMatch = Regex.Match(Uri.UnescapeDataString(uri), @"^otpauth:\/\/([a-z]+)\/(.*)\?(.*)$");

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

            var type = uriMatch.Groups[1].Value switch {
                "totp" => AuthenticatorType.Totp,
                "hotp" => AuthenticatorType.Hotp,
                _ => throw new InvalidAuthenticatorException()
            };

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

            string issuer;
            string username;

            if (issuerName.Success)
            {
                issuer   = issuerName.Groups[1].Value;
                username = issuerName.Groups[2].Value;
            }
            else
            {
                issuer   = uriMatch.Groups[2].Value;
                username = "";
            }

            var queryString = uriMatch.Groups[3].Value;
            var args        = Regex.Matches(queryString, "([^?=&]+)(=([^&]*))?")
                              .ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value);

            var algorithm = OtpHashMode.Sha1;

            if (args.ContainsKey("algorithm"))
            {
                switch (args["algorithm"].ToUpper())
                {
                case "SHA1":
                    algorithm = OtpHashMode.Sha1;
                    break;

                case "SHA256":
                    algorithm = OtpHashMode.Sha256;
                    break;

                case "SHA512":
                    algorithm = OtpHashMode.Sha512;
                    break;

                default:
                    throw new InvalidAuthenticatorException();
                }
            }

            var digits = args.ContainsKey("digits") ? Int32.Parse(args["digits"]) : DefaultDigits;
            var period = args.ContainsKey("period") ? Int32.Parse(args["period"]) : DefaultPeriod;

            var secret = CleanSecret(args["secret"]);

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

            auth.Validate();
            return(auth);
        }
Пример #3
0
        public static Authenticator FromKeyUri(string uri)
        {
            const string uriExpr  = @"^otpauth:\/\/([a-z]+)\/(.*?)\?(.*?)$";
            var          raw      = Uri.UnescapeDataString(uri);
            var          uriMatch = Regex.Match(raw, uriExpr);

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

            var type = uriMatch.Groups[1].Value == "totp" ? AuthenticatorType.Totp : AuthenticatorType.Hotp;

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

            string issuer;
            string username;

            if (issuerName.Success)
            {
                issuer   = issuerName.Groups[1].Value;
                username = issuerName.Groups[2].Value;
            }
            else
            {
                issuer   = uriMatch.Groups[2].Value;
                username = "";
            }

            var queryString = uriMatch.Groups[3].Value;
            var args        = Regex.Matches(queryString, "([^?=&]+)(=([^&]*))?")
                              .ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value);

            var algorithm = OtpHashMode.Sha1;

            if (args.ContainsKey("algorithm"))
            {
                switch (args["algorithm"].ToUpper())
                {
                case "SHA1":
                    algorithm = OtpHashMode.Sha1;
                    break;

                case "SHA256":
                    algorithm = OtpHashMode.Sha256;
                    break;

                case "SHA512":
                    algorithm = OtpHashMode.Sha512;
                    break;

                default:
                    throw new InvalidAuthenticatorException();
                }
            }

            var digits = args.ContainsKey("digits") ? Int32.Parse(args["digits"]) : 6;
            var period = args.ContainsKey("period") ? Int32.Parse(args["period"]) : 30;

            var code = "";

            for (var i = 0; i < digits; code += "-", i++)
            {
                ;
            }

            var secret = CleanSecret(args["secret"]);

            var auth = new Authenticator {
                Secret    = secret,
                Issuer    = issuer.Trim().Truncate(32),
                Username  = username.Trim().Truncate(32),
                Icon      = Icons.FindServiceKeyByName(issuer),
                Type      = type,
                Algorithm = algorithm,
                Digits    = digits,
                Period    = period,
                Counter   = 0,
                Code      = code
            };

            auth.Validate();
            return(auth);
        }