public void FinishAuthentication_InvalidSignatureData()
        {
            var mockGenerateChallenge = new Mock <IGenerateFidoChallenge>();

            mockGenerateChallenge.Setup(x => x.GenerateChallenge()).Returns(WebSafeBase64Converter.FromBase64String(TestVectors.ServerChallengeAuthBase64));

            var fido = new FidoUniversalTwoFactor(mockGenerateChallenge.Object);

            var deviceRegistration    = CreateTestDeviceRegistration();
            var startedAuthentication = fido.StartAuthentication(new FidoAppId(TestVectors.AppIdEnroll), deviceRegistration);

            var signatureData  = FidoSignatureData.FromWebSafeBase64(TestVectors.SignResponseDataBase64);
            var signatureBytes = signatureData.Signature.ToByteArray();

            signatureBytes[0] ^= 0xFF;

            signatureData = new FidoSignatureData(
                signatureData.UserPresence,
                signatureData.Counter,
                new FidoSignature(signatureBytes));

            var authenticateResponse = new FidoAuthenticateResponse(
                FidoClientData.FromJson(TestVectors.ClientDataAuth),
                signatureData,
                FidoKeyHandle.FromWebSafeBase64(TestVectors.KeyHandle));

            Assert.Throws <InvalidOperationException>(() => fido.FinishAuthentication(startedAuthentication, authenticateResponse, deviceRegistration, TestVectors.TrustedDomains));
        }
        public void Equals_NotEqual()
        {
            var value1 = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
            var value2 = new FidoKeyHandle(Encoding.Default.GetBytes("Keyhandle"));

            Assert.IsFalse(value1.Equals(value2));
        }
        public void UpdateDeviceRegistrationCounter(string userName, FidoKeyHandle keyHandle, uint counter)
        {
            var deviceRegistration = GetDeviceRegistrationsOfUser(userName).FirstOrDefault(x => x.KeyHandle == keyHandle);
            if (deviceRegistration == null)
                throw new InvalidOperationException(String.Format("Could not find device registration for user '{0}' with key handle '{1}'", userName, keyHandle));

            deviceRegistration.UpdateCounter(counter);
        }
        internal static FidoAuthenticateResponse CreateGoodAuthenticateResponse()
        {
            var clientData    = FidoClientData.FromJson(TestVectors.ClientDataAuth);
            var signatureData = FidoSignatureData.FromBytes(TestVectors.AuthenticateResponse);
            var keyHandle     = FidoKeyHandle.FromWebSafeBase64(TestVectors.KeyHandle);

            return(new FidoAuthenticateResponse(clientData, signatureData, keyHandle));
        }
        private static FidoDeviceRegistration CreateTestDeviceRegistration()
        {
            var cert      = FidoAttestationCertificate.FromWebSafeBase64(TestVectors.AttestationCertificate);
            var keyHandle = FidoKeyHandle.FromWebSafeBase64(TestVectors.KeyHandle);
            var publicKey = FidoPublicKey.FromWebSafeBase64(TestVectors.PublicKeyBase64);

            return(new FidoDeviceRegistration(keyHandle, publicKey, cert, 0));
        }
Пример #6
0
        private FidoRegistrationData(FidoPublicKey userPublicKey, FidoKeyHandle keyHandle,
						   FidoAttestationCertificate attestationCertificate,
						   FidoSignature signature)
        {
            UserPublicKey = userPublicKey;
            KeyHandle = keyHandle;
            AttestationCertificate = attestationCertificate;
            Signature = signature;
        }
        public FidoStartedAuthentication(FidoAppId appId, string challenge, FidoKeyHandle keyHandle)
        {
            if (appId == null) throw new ArgumentNullException("appId");
            if (challenge == null) throw new ArgumentNullException("challenge");
            if (keyHandle == null) throw new ArgumentNullException("keyHandle");

            AppId = appId;
            Challenge = challenge;
            KeyHandle = keyHandle;
        }
Пример #8
0
        private static FidoDeviceRegistration CreateTestDeviceRegistration()
        {
            var keyHandle   = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
            var publicKey   = new FidoPublicKey(Encoding.Default.GetBytes("publickey"));
            var certificate = new FidoAttestationCertificate(Encoding.Default.GetBytes("certificate"));

            var deviceRegistration = new FidoDeviceRegistration(keyHandle, publicKey, certificate, 12345);

            return(deviceRegistration);
        }
        public void SerializeObject()
        {
            var randomBytes = new byte[256];
            RandomNumberGenerator.Create().GetBytes(randomBytes);

            var value = new FidoKeyHandle(randomBytes);
            var serialized = JsonConvert.SerializeObject(value);

            var bytes = WebSafeBase64Converter.FromBase64String(serialized.Trim('"'));
            Assert.IsTrue(randomBytes.SequenceEqual(bytes));
        }
        public void UpdateDeviceRegistrationCounter(string userName, FidoKeyHandle keyHandle, uint counter)
        {
            var deviceRegistration = GetDeviceRegistrationsOfUser(userName).FirstOrDefault(x => x.KeyHandle == keyHandle);

            if (deviceRegistration == null)
            {
                throw new InvalidOperationException(String.Format("Could not find device registration for user '{0}' with key handle '{1}'", userName, keyHandle));
            }

            deviceRegistration.UpdateCounter(counter);
        }
        public void DeserializeObject()
        {
            var publicKey = new byte[256];
            RandomNumberGenerator.Create().GetBytes(publicKey);

            var value = new FidoKeyHandle(publicKey);
            var serialized = JsonConvert.SerializeObject(value);

            var deserialized = JsonConvert.DeserializeObject<FidoKeyHandle>(serialized);

            Assert.AreEqual(value, deserialized);
        }
        public void SerializeObject()
        {
            var randomBytes = new byte[256];

            RandomNumberGenerator.Create().GetBytes(randomBytes);

            var value      = new FidoKeyHandle(randomBytes);
            var serialized = JsonConvert.SerializeObject(value);

            var bytes = WebSafeBase64Converter.FromBase64String(serialized.Trim('"'));

            Assert.IsTrue(randomBytes.SequenceEqual(bytes));
        }
        public void DeserializeObject()
        {
            var publicKey = new byte[256];

            RandomNumberGenerator.Create().GetBytes(publicKey);

            var value      = new FidoKeyHandle(publicKey);
            var serialized = JsonConvert.SerializeObject(value);

            var deserialized = JsonConvert.DeserializeObject <FidoKeyHandle>(serialized);

            Assert.AreEqual(value, deserialized);
        }
Пример #14
0
        public void FromJson()
        {
            var deviceRegistration = FidoDeviceRegistration.FromJson("{\"Certificate\":\"Y2VydGlmaWNhdGU\",\"Counter\":12345,\"KeyHandle\":\"a2V5aGFuZGxl\",\"PublicKey\":\"cHVibGlja2V5\"}");

            var keyHandle   = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
            var publicKey   = new FidoPublicKey(Encoding.Default.GetBytes("publickey"));
            var certificate = new FidoAttestationCertificate(Encoding.Default.GetBytes("certificate"));

            Assert.AreEqual(12345, deviceRegistration.Counter);
            Assert.IsTrue(certificate.Equals(deviceRegistration.Certificate));
            Assert.IsTrue(publicKey.Equals(deviceRegistration.PublicKey));
            Assert.IsTrue(keyHandle.Equals(deviceRegistration.KeyHandle));
        }
        public void FinishAuthentication_Works()
        {
            var mockGenerateChallenge = new Mock <IGenerateFidoChallenge>();

            mockGenerateChallenge.Setup(x => x.GenerateChallenge()).Returns(WebSafeBase64Converter.FromBase64String(TestVectors.ServerChallengeAuthBase64));

            var fido = new FidoUniversalTwoFactor(mockGenerateChallenge.Object);

            var deviceRegistration    = CreateTestDeviceRegistration();
            var startedAuthentication = fido.StartAuthentication(new FidoAppId(TestVectors.AppIdEnroll), deviceRegistration);

            var authenticateResponse = new FidoAuthenticateResponse(
                FidoClientData.FromJson(TestVectors.ClientDataAuth),
                FidoSignatureData.FromWebSafeBase64(TestVectors.SignResponseDataBase64),
                FidoKeyHandle.FromWebSafeBase64(TestVectors.KeyHandle));

            fido.FinishAuthentication(startedAuthentication, authenticateResponse, deviceRegistration, TestVectors.TrustedDomains);
        }
Пример #16
0
        public void ToJson()
        {
            var keyHandle   = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
            var publicKey   = new FidoPublicKey(Encoding.Default.GetBytes("publickey"));
            var certificate = new FidoAttestationCertificate(Encoding.Default.GetBytes("certificate"));

            var deviceRegistration = new FidoDeviceRegistration(keyHandle, publicKey, certificate, 12345);

            var serialized = deviceRegistration.ToJson();

            var jsonObject = JObject.Parse(serialized);
            var properties = jsonObject.Properties().ToLookup(x => x.Name.ToLowerInvariant(), x => x.Value.ToString());

            Assert.AreEqual("Y2VydGlmaWNhdGU", properties["certificate"].Single());
            Assert.AreEqual("12345", properties["counter"].Single());
            Assert.AreEqual("a2V5aGFuZGxl", properties["keyhandle"].Single());
            Assert.AreEqual("cHVibGlja2V5", properties["publickey"].Single());
        }
        public void FinishAuthentication_DifferentChallenge()
        {
            var mockGenerateChallenge = new Mock <IGenerateFidoChallenge>();

            mockGenerateChallenge.Setup(x => x.GenerateChallenge()).Returns(WebSafeBase64Converter.FromBase64String(TestVectors.ServerChallengeAuthBase64));

            var fido = new FidoUniversalTwoFactor(mockGenerateChallenge.Object);

            var deviceRegistration    = CreateTestDeviceRegistration();
            var startedAuthentication = fido.StartAuthentication(new FidoAppId(TestVectors.AppIdEnroll), deviceRegistration);

            var clientDataAuth = TestVectors.ClientDataAuth.Replace("challenge\":\"opsXqUifDriAAmWclinfbS0e-USY0CgyJHe_Otd7z8o", "challenge\":\"different");

            var authenticateResponse = new FidoAuthenticateResponse(
                FidoClientData.FromJson(clientDataAuth),
                FidoSignatureData.FromWebSafeBase64(TestVectors.SignResponseDataBase64),
                FidoKeyHandle.FromWebSafeBase64(TestVectors.KeyHandle));

            Assert.Throws <InvalidOperationException>(() => fido.FinishAuthentication(startedAuthentication, authenticateResponse, deviceRegistration, TestVectors.TrustedDomains));
        }
        public void FinishAuthentication_UntrustedOrigin(string origin)
        {
            var mockGenerateChallenge = new Mock <IGenerateFidoChallenge>();

            mockGenerateChallenge.Setup(x => x.GenerateChallenge()).Returns(WebSafeBase64Converter.FromBase64String(TestVectors.ServerChallengeAuthBase64));

            var fido = new FidoUniversalTwoFactor(mockGenerateChallenge.Object);

            var deviceRegistration    = CreateTestDeviceRegistration();
            var startedAuthentication = fido.StartAuthentication(new FidoAppId(TestVectors.AppIdEnroll), deviceRegistration);

            var clientDataAuth = TestVectors.ClientDataAuth.Replace("origin\":\"http://example.com", "origin\":\"" + origin);

            var authenticateResponse = new FidoAuthenticateResponse(
                FidoClientData.FromJson(clientDataAuth),
                FidoSignatureData.FromWebSafeBase64(TestVectors.SignResponseDataBase64),
                FidoKeyHandle.FromWebSafeBase64(TestVectors.KeyHandle));

            Assert.Throws <InvalidOperationException>(() => fido.FinishAuthentication(startedAuthentication, authenticateResponse, deviceRegistration, TestVectors.TrustedDomains));
        }
Пример #19
0
        public ActionResult Login(LoginDeviceViewModel model)
        {
            model = model ?? new LoginDeviceViewModel();

            try
            {
                if (!String.IsNullOrEmpty(model.RawAuthenticationResponse))
                {
                    var u2f   = new FidoUniversalTwoFactor();
                    var appId = new FidoAppId(Request.Url);

                    var deviceRegistration = GetFidoRepository().GetDeviceRegistrationsOfUser(GetCurrentUser()).FirstOrDefault(x => x.KeyHandle.ToWebSafeBase64() == model.KeyHandle);
                    if (deviceRegistration == null)
                    {
                        ModelState.AddModelError("", "Unknown key handle: " + model.KeyHandle);
                        return(View(new LoginDeviceViewModel()));
                    }

                    var challenge = model.Challenge;

                    var startedAuthentication = new FidoStartedAuthentication(appId, challenge,
                                                                              FidoKeyHandle.FromWebSafeBase64(model.KeyHandle ?? ""));

                    var counter = u2f.FinishAuthentication(startedAuthentication, model.RawAuthenticationResponse, deviceRegistration, GetTrustedDomains());

                    // save the counter somewhere, the device registration of the next authentication should use this updated counter
                    //deviceRegistration.Counter = counter;

                    return(RedirectToAction("LoginSuccess"));
                }
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex.GetType().Name + ": " + ex.Message);
            }

            return(View(model));
        }
Пример #20
0
 public void Validate_Good_NoException()
 {
     var value = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
     value.Validate();
 }
Пример #21
0
 public void Equals_NotEqual()
 {
     var value1 = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
     var value2 = new FidoKeyHandle(Encoding.Default.GetBytes("Keyhandle"));
     Assert.IsFalse(value1.Equals(value2));
 }
Пример #22
0
 public void Validate_BytesEmpty_Throws()
 {
     var value = new FidoKeyHandle(new byte[0]);
     Assert.Throws<InvalidOperationException>(() => value.Validate());
 }
Пример #23
0
 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
 {
     return(FidoKeyHandle.FromWebSafeBase64(reader.Value.ToString()));
 }
Пример #24
0
 public void Constructor()
 {
     var value = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
     Assert.AreEqual("keyhandle", Encoding.Default.GetString(value.ToByteArray()));
 }
        public void FromJson()
        {
            var deviceRegistration = FidoDeviceRegistration.FromJson("{\"Certificate\":\"Y2VydGlmaWNhdGU\",\"Counter\":12345,\"KeyHandle\":\"a2V5aGFuZGxl\",\"PublicKey\":\"cHVibGlja2V5\"}");

            var keyHandle = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
            var publicKey = new FidoPublicKey(Encoding.Default.GetBytes("publickey"));
            var certificate = new FidoAttestationCertificate(Encoding.Default.GetBytes("certificate"));

            Assert.AreEqual(12345, deviceRegistration.Counter);
            Assert.IsTrue(certificate.Equals(deviceRegistration.Certificate));
            Assert.IsTrue(publicKey.Equals(deviceRegistration.PublicKey));
            Assert.IsTrue(keyHandle.Equals(deviceRegistration.KeyHandle));
        }
 public FidoAuthenticateResponse(FidoClientData clientData, FidoSignatureData signatureData, FidoKeyHandle keyHandle)
 {
     ClientData = clientData;
     SignatureData = signatureData;
     KeyHandle = keyHandle;
 }
        public void ToJson()
        {
            var keyHandle = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
            var publicKey = new FidoPublicKey(Encoding.Default.GetBytes("publickey"));
            var certificate = new FidoAttestationCertificate(Encoding.Default.GetBytes("certificate"));

            var deviceRegistration = new FidoDeviceRegistration(keyHandle, publicKey, certificate, 12345);

            var serialized = deviceRegistration.ToJson();

            var jsonObject = JObject.Parse(serialized);
            var properties = jsonObject.Properties().ToLookup(x => x.Name.ToLowerInvariant(), x => x.Value.ToString());

            Assert.AreEqual("Y2VydGlmaWNhdGU", properties["certificate"].Single());
            Assert.AreEqual("12345", properties["counter"].Single());
            Assert.AreEqual("a2V5aGFuZGxl", properties["keyhandle"].Single());
            Assert.AreEqual("cHVibGlja2V5", properties["publickey"].Single());
        }
        private static FidoDeviceRegistration CreateTestDeviceRegistration()
        {
            var keyHandle = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));
            var publicKey = new FidoPublicKey(Encoding.Default.GetBytes("publickey"));
            var certificate = new FidoAttestationCertificate(Encoding.Default.GetBytes("certificate"));

            var deviceRegistration = new FidoDeviceRegistration(keyHandle, publicKey, certificate, 12345);
            return deviceRegistration;
        }
        public void Constructor()
        {
            var value = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));

            Assert.AreEqual("keyhandle", Encoding.Default.GetString(value.ToByteArray()));
        }
 public void Equals_Null()
 {
     Assert.IsFalse(FidoKeyHandle.FromWebSafeBase64("").Equals(null));
 }
        public void Validate_BytesEmpty_Throws()
        {
            var value = new FidoKeyHandle(new byte[0]);

            Assert.Throws <InvalidOperationException>(() => value.Validate());
        }
        public void Validate_Good_NoException()
        {
            var value = new FidoKeyHandle(Encoding.Default.GetBytes("keyhandle"));

            value.Validate();
        }
Пример #33
0
        public IActionResult AuthenticateDevice(AuthenticateDeviceModel model)
        {
            if (App.CurrentUser == null)
            {
                return(BadRequest(new { error = "You must login.", code = 401 }));
            }

            if (model == null || string.IsNullOrEmpty(model.KeyHandle))
            {
                return(BadRequest(new { error = "Invalid device id.", code = 400 }));
            }

            var device = App.CurrentUser.Devices.FirstOrDefault(x => x.Identifier.Equals(model.KeyHandle));

            if (device == null)
            {
                return(BadRequest(new { error = "Device not found.", code = 400 }));
            }


            var u2F = new FidoUniversalTwoFactor();

            var deviceRegistration = FidoDeviceRegistration.FromJson(device.Data);

            if (deviceRegistration == null)
            {
                return(BadRequest(new { error = "Unknown key handle.", code = 400 }));
            }

            var challenge = model.Challenge;

            var startedAuthentication = new FidoStartedAuthentication(AppId, challenge, FidoKeyHandle.FromWebSafeBase64(model.KeyHandle ?? ""));
            var facetIds = new List <FidoFacetId> {
                new FidoFacetId(AppId.ToString())
            };

            var counter = u2F.FinishAuthentication(startedAuthentication, model.RawAuthenticateResponse, deviceRegistration, facetIds);

            deviceRegistration.Counter = counter;
            device.Usage++;

            return(Ok(new { message = "Device has been authenticated.", code = 200, redirect = Url.Action("CurrentUser") }));
        }