Example #1
0
        private void TestSHA512AndAssert(Key key, int digits, DateTime time, string expected)
        {
            var otp    = new TimeBasedOtpGenerator(key, digits, new SHA512HMACAlgorithm());
            var result = otp.GenerateOtp(time);

            Assert.AreEqual(expected, result);
        }
Example #2
0
        public string GenerateOtpCodeForServerAccount(AccountModel model)
        {
            var serverAccount = model.ServerAccountSettings.Query().First();
            var otpAccount    = model.OtpAccounts.Query().First(r => r.Id == serverAccount.OtpAccountId);

            var totpcode = new TimeBasedOtpGenerator(
                new Key(otpAccount.Secret),
                otpAccount.Digits,
                new SHA1HMACAlgorithm());

            return(totpcode.GenerateOtp(DateTime.UtcNow));
        }
Example #3
0
        public void ValidateOtp_test_validates_with_an_empty_validity_period()
        {
            var key         = Sha1ReferenceKey;
            var generator   = new TimeBasedOtpGenerator(key, 8);
            var currentTime = new DateTime(2033, 5, 18, 3, 33, 20, DateTimeKind.Utc);
            var zeroSeconds = TimeSpan.FromSeconds(0);

            Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(-30), zeroSeconds), "30 seconds prior should be invalid");
            Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(-01), zeroSeconds), "1 second prior should be valid (due to a 30-second precision)");
            Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+00), zeroSeconds), "The exact time should be valid");
            Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+01), zeroSeconds), "1 seconds after should be valid (due to a 30-second precision)");
            Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(+30), zeroSeconds), "30 seconds after should be invalid");
        }
Example #4
0
        public void ValidateOtp_test_validates_within_50_second_validity_period()
        {
            var key          = Sha1ReferenceKey;
            var generator    = new TimeBasedOtpGenerator(key, 8);
            var currentTime  = new DateTime(2033, 5, 18, 3, 33, 20, DateTimeKind.Utc);
            var fiftySeconds = TimeSpan.FromSeconds(50);

            Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(-90), fiftySeconds), "90 seconds prior should be invalid");
            Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(-60), fiftySeconds), "60 seconds prior should be invalid");
            Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(-30), fiftySeconds), "30 seconds prior should be valid");
            Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+00), fiftySeconds), "The exact time should be valid");
            Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+30), fiftySeconds), "30 seconds after should be valid");
            Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(+60), fiftySeconds), "60 seconds after should be invalid");
            Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(+90), fiftySeconds), "90 seconds after should be invalid");
        }
Example #5
0
        public void ValidateOtp_test_validates_within_60_second_validity_period()
        {
            var key          = Sha1ReferenceKey;
            var generator    = new TimeBasedOtpGenerator(key, 8);
            var currentTime  = new DateTime(2009, 2, 13, 23, 31, 30, DateTimeKind.Utc);
            var sixtySeconds = TimeSpan.FromSeconds(60);

            Assert.IsFalse(generator.ValidateOtp("89005924", currentTime.AddSeconds(-90), sixtySeconds), "90 seconds prior should be invalid");
            Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(-60), sixtySeconds), "60 seconds prior should be valid");
            Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(-15), sixtySeconds), "15 seconds prior should be valid");
            Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(+00), sixtySeconds), "The exact time should be valid");
            Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(+15), sixtySeconds), "15 seconds after should be valid");
            Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(+60), sixtySeconds), "60 seconds after should be valid");
            Assert.IsFalse(generator.ValidateOtp("89005924", currentTime.AddSeconds(+90), sixtySeconds), "90 seconds after should be invalid");
        }
Example #6
0
        public string GenerateOtpCode(int serverAccountId, string accountName)
        {
            var model = AccountModel.GetModel(serverAccountId);

            var otpAccount = model.OtpAccounts.Query().FirstOrDefault(r => r.Label == accountName);

            if (otpAccount == null)
            {
                throw new Exception("Could not find OTP account for given name");
            }

            var totpcode = new TimeBasedOtpGenerator(
                new Key(otpAccount.Secret),
                otpAccount.Digits,
                new SHA1HMACAlgorithm());

            return(totpcode.GenerateOtp(DateTime.UtcNow));
        }
Example #7
0
        public bool RegisterInitialOtpDevice(string linkCodeString)
        {
            var linkCode   = new LinkCodeRegisterInitialOtpDevice(linkCodeString);
            var newKeyPair = AsymmetricCryptoUtil.GenerateKeyPair();

            var apiClient = new ApiClient(
                linkCode.ServerHttps,
                linkCode.ServerHost,
                linkCode.ServerPort,
                linkCode.ServerApiVersion);
            var request = new ServerAPIRequestsUnauthenticated.RegisterSecondDevice
            {
                LoginRequestIdentifier = linkCode.LoginIdentifier,
                PublicKeyPem           = newKeyPair.PublicPem,
                DeviceLabel            = "My Test Device",
                DeviceType             = "phone",
                DeviceSubtype          = "testdevice"
            };
            var response = request.GetResponse(apiClient);

            var apiClientAuthenticated = new ApiClient(
                linkCode.ServerHttps,
                linkCode.ServerHost,
                linkCode.ServerPort,
                linkCode.ServerApiVersion,
                response.ApiKey,
                newKeyPair.PrivatePem);

            var totpcode = new TimeBasedOtpGenerator(new Key(response.Secret), response.Digits, new SHA1HMACAlgorithm())
                           .GenerateOtp(DateTime.UtcNow);

            try
            {
                var confirmRequest = new ServerAPIRequests.ConfirmSecondDevice
                {
                    OtpCode = totpcode
                };
                confirmRequest.GetResponse(apiClientAuthenticated);
            }
            catch (RequestException)
            {
                MessageBox.Show(@"Unable to validate the device. Please try again.");
                return(false);
            }

            var serverInfo = apiClientAuthenticated.GetServerInfo(new GetServerInfoRequest());

            var newServerId = AppModel.ServerAccounts.Create(new AppModels.ServerAccount
            {
                ServerIdentifier = serverInfo.ServerIdentifier
            });

            var model = AccountModel.GetModel(newServerId);

            var newOtpAccountId = model.OtpAccounts.Create(new OtpAccount
            {
                Type      = response.Type,
                Label     = response.Label,
                Issuer    = response.Issuer,
                Secret    = response.Secret,
                Algorithm = response.Algorithm,
                Digits    = response.Digits,
                Counter   = response.Counter,
                Period    = response.Period
            });

            var cryptoKeyId = model.CryptoKeys.Create(new CryptoKey
            {
                OwnKey           = true,
                Trust            = true,
                PrivateKeyPem    = newKeyPair.PrivatePem,
                PublicKeyPem     = newKeyPair.PublicPem,
                PublicKeyPemHash = HashUtil.Sha256(newKeyPair.PublicPem)
            });

            var serverAccountSettingsId = model.ServerAccountSettings.Create(new ServerAccountSetting
            {
                Identifier       = serverInfo.ServerIdentifier,
                Label            = serverInfo.ServerLabel,
                HttpsEnabled     = linkCode.ServerHttps,
                Host             = linkCode.ServerHost,
                Port             = linkCode.ServerPort,
                ApiVersion       = linkCode.ServerApiVersion,
                UserIdentifier   = response.UserIdentifier,
                DeviceIdentifier = response.DeviceIdentifier,
                OtpAccountId     = newOtpAccountId,
                ApiKey           = response.ApiKey,
                EmailAddress     = linkCode.EmailAddress,
                ApiCryptoKeyId   = cryptoKeyId
            });

            var linkedDeviceRequest = new ServerAPIRequests.GetLinkedDevice();

            ServerAPIRequests.GetLinkedDevice.ResponseParams linkedDeviceResponse;
            linkedDeviceResponse = linkedDeviceRequest.GetResponse(apiClientAuthenticated);

            if (linkCode.InitiatingDevicePublicKeyPem != HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem))
            {
                MessageBox.Show(@"Unable to verify device keys. You will need to do this manually from the desktop app.");
            }
            else
            {
                var linkedDeviceCryptoKeyId = model.CryptoKeys.Create(new CryptoKey
                {
                    Trust            = true,
                    PublicKeyPem     = linkedDeviceResponse.PublicKeyPem,
                    PublicKeyPemHash = HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem)
                });
                model.ServerAccountSettings.Update(serverAccountSettingsId, new ServerAccountSetting
                {
                    LinkedDeviceCryptoKeyId = linkedDeviceCryptoKeyId
                });
            }

            _syncAccounts.Add(newServerId, new SyncAccounts(this, model));
            _syncAccounts[newServerId].Start();

            _mainForm.UpdateForm();

            return(true);
        }
Example #8
0
        private string GetOtpWithImplicitHMAC(Key key, int digits, DateTime time)
        {
            var otp = new TimeBasedOtpGenerator(key, digits);

            return(otp.GenerateOtp(time));
        }
        public async Task <bool> CheckOneTimePassword([FromBody] OtpCodeDto otpCodeDto)
        {
            var secretkey = string.Empty;
            var email     = string.Empty;
            var userId    = string.Empty;


            if (otpCodeDto.ChannelId == "sms")
            {
                var smsUser = this._context.SmsUser.Where(smsuser => smsuser.UserName == otpCodeDto.UserName).FirstOrDefault();

                if (smsUser == null)
                {
                    return(false);
                }

                secretkey = smsUser.SecretKey;
                email     = smsUser.EMail;
                userId    = smsUser.UserId;
            }

            if (otpCodeDto.ChannelId == "directline")
            {
                var directLineUser = this._context.DirectLineUser.Where(smsuser => smsuser.UserName == otpCodeDto.UserName).FirstOrDefault();

                if (directLineUser == null)
                {
                    return(false);
                }

                secretkey = directLineUser.SecretKey;
                email     = directLineUser.EMail;
                userId    = directLineUser.UserId;
            }

            int otpDigits = 6;

            var secretKey = secretkey;

            Key key    = new Key(secretKey);
            var secret = key.Base32;

            TimeBasedOtpGenerator otp = new TimeBasedOtpGenerator(key, otpDigits);
            var time      = GetNistTime();
            var tst       = otp.GenerateOtp(time);
            Key keySecret = new Key(secretKey);

            time = GetNistTime();

            TimeBasedOtpGenerator otp3 = new TimeBasedOtpGenerator(keySecret, otpDigits);

            var valid = otp.ValidateOtp(otpCodeDto.OneTimePasswordCode, time);

            if (valid)
            {
                var jwtoken        = new JwtManager();
                var expirationTime = DateTime.UtcNow.AddMinutes(59);
                var jwt            = jwtoken.GenerateJwtToken(email, userId, 60);

                if (otpCodeDto.ChannelId == "sms")
                {
                    _context.SmsLogin.Add(new Data.Entities.SmsLogin {
                        UserName = otpCodeDto.UserName, ExpirationTime = expirationTime, Jwt = jwt
                    });
                    _context.SaveChanges();
                }

                if (otpCodeDto.ChannelId == "directline")
                {
                    _context.DirectLineLogins.Add(new Data.Entities.DirectLineLogins {
                        UserName = otpCodeDto.UserName, ExpirationTime = expirationTime, Jwt = jwt.ToString()
                    });
                    _context.SaveChanges();
                }
            }

            return(valid);
        }