private async void AddDialogPositive(object sender, EventArgs e)
        {
            var error = false;

            if (_addDialog.Issuer.Trim() == "")
            {
                _addDialog.IssuerError = GetString(Resource.String.noIssuer);
                error = true;
            }

            if (_addDialog.Secret.Trim() == "")
            {
                _addDialog.SecretError = GetString(Resource.String.noSecret);
                error = true;
            }

            var secret = _addDialog.Secret.Trim().ToUpper();

            if (secret.Length < 16)
            {
                _addDialog.SecretError = GetString(Resource.String.secretTooShort);
                error = true;
            }

            if (!Authenticator.IsValidSecret(secret))
            {
                _addDialog.SecretError = GetString(Resource.String.secretInvalidChars);
                error = true;
            }

            if (_addDialog.Digits < 6)
            {
                _addDialog.DigitsError = GetString(Resource.String.digitsToSmall);
                error = true;
            }

            if (_addDialog.Period < 10)
            {
                _addDialog.PeriodError = GetString(Resource.String.periodToShort);
                error = true;
            }

            if (error)
            {
                return;
            }

            var issuer   = _addDialog.Issuer.Trim().Truncate(32);
            var username = _addDialog.Username.Trim().Truncate(32);

            var algorithm = OtpHashMode.Sha1;

            switch (_addDialog.Algorithm)
            {
            case 1:
                algorithm = OtpHashMode.Sha256;
                break;

            case 2:
                algorithm = OtpHashMode.Sha512;
                break;
            }

            var type = _addDialog.Type == 0 ? OtpType.Totp : OtpType.Hotp;

            var code = "";

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

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

            if (_authSource.IsDuplicate(auth))
            {
                Toast.MakeText(this, Resource.String.duplicateAuthenticator, ToastLength.Short).Show();
                return;
            }

            await _connection.InsertAsync(auth);

            await _authSource.UpdateSource();

            CheckEmptyState();
            _authAdapter.NotifyDataSetChanged();

            _addDialog.Dismiss();
        }
Exemple #2
0
        private async void AddDialogPositive(object sender, EventArgs e)
        {
            var error = false;

            if (_addDialog.Issuer.Trim() == "")
            {
                _addDialog.IssuerError = GetString(Resource.String.noIssuer);
                error = true;
            }

            var secret = Authenticator.CleanSecret(_addDialog.Secret);

            if (secret == "")
            {
                _addDialog.SecretError = GetString(Resource.String.noSecret);
                error = true;
            }
            else if (!Authenticator.IsValidSecret(secret))
            {
                _addDialog.SecretError = GetString(Resource.String.secretInvalid);
                error = true;
            }

            if (_addDialog.Digits < 6 || _addDialog.Digits > 10)
            {
                _addDialog.DigitsError = GetString(Resource.String.digitsInvalid);
                error = true;
            }

            if (_addDialog.Period <= 0)
            {
                _addDialog.PeriodError = GetString(Resource.String.periodToShort);
                error = true;
            }

            if (error)
            {
                return;
            }

            var issuer   = _addDialog.Issuer.Trim().Truncate(32);
            var username = _addDialog.Username.Trim().Truncate(32);

            var algorithm = _addDialog.Algorithm switch {
                1 => OtpHashMode.Sha256,
                2 => OtpHashMode.Sha512,
                _ => OtpHashMode.Sha1
            };

            var type = _addDialog.Type == 0 ? AuthenticatorType.Totp : AuthenticatorType.Hotp;

            var code = "";

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

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

            if (_authSource.IsDuplicate(auth))
            {
                _addDialog.SecretError = GetString(Resource.String.duplicateAuthenticator);
                return;
            }

            await _connection.InsertAsync(auth);

            await _authSource.UpdateSource();

            CheckEmptyState();
            _authAdapter.NotifyItemInserted(_authSource.GetPosition(auth.Secret));

            _addDialog.Dismiss();
        }
        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 InvalidFormatException();
            }

            var type = uriMatch.Groups[1].Value == "totp" ? OtpType.Totp : OtpType.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 InvalidFormatException();
                }
            }

            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 = args["secret"].ToUpper();

            if (!IsValidSecret(secret))
            {
                throw new InvalidFormatException();
            }

            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
            };

            return(auth);
        }