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));
        }
        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));
        }
Beispiel #3
0
        public void Deserialize()
        {
            var clientData = FidoClientData.FromJson("{\"challenge\":\"Y2VydGlmaWNhdGU\",\"origin\":\"http://example.com\",\"typ\":\"sometype\"}");

            Assert.AreEqual("Y2VydGlmaWNhdGU", clientData.Challenge);
            Assert.AreEqual("http://example.com", clientData.Origin);
            Assert.AreEqual("sometype", clientData.Type);
        }
        private static FidoRegisterResponse GetValidRegisterResponse()
        {
            var registerResponse = new FidoRegisterResponse
            {
                RegistrationData = FidoRegistrationData.FromWebSafeBase64(TestVectors.RegistrationResponseDataBase64),
                ClientData       = FidoClientData.FromJson(TestVectors.ClientDataRegister)
            };

            return(registerResponse);
        }
Beispiel #5
0
        private static void ExpectClientDataType(FidoClientData clientData, string expectedType)
        {
            if (clientData.Type == expectedType)
            {
                return;
            }

            var message = String.Format("Unexpected type in client data (expected '{0}' but was '{1}')",
                                        expectedType, clientData.Type);

            throw new InvalidOperationException(message);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jsonObject = JObject.Load(reader);
            var properties = jsonObject.Properties().ToLookup(x => x.Name.ToLowerInvariant());

            var serializedRegistrationData = properties["registrationdata"].Single().Value.ToString();
            var serializedClientData       = properties["clientdata"].Single().Value.ToString();

            return(new FidoRegisterResponse
            {
                RegistrationData = FidoRegistrationData.FromWebSafeBase64(serializedRegistrationData),
                ClientData = FidoClientData.FromWebSafeBase64(serializedClientData)
            });
        }
        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);
        }
Beispiel #8
0
        public void Serialize()
        {
            var clientData = new FidoClientData
            {
                Challenge = "challenge",
                Origin    = "http://example.com",
                Type      = "sometype"
            };

            var serialized = clientData.ToJson();

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

            Assert.AreEqual("challenge", properties["challenge"].Single());
            Assert.AreEqual("http://example.com", properties["origin"].Single());
            Assert.AreEqual("sometype", properties["typ"].Single());
        }
        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));
        }
        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));
        }
Beispiel #11
0
        private void VerifyAuthSignature(FidoAppId appId, FidoSignatureData signatureData, FidoClientData clientData,
                                         FidoDeviceRegistration deviceRegistration)
        {
            if (appId == null)
            {
                throw new ArgumentNullException("appId");
            }
            if (signatureData == null)
            {
                throw new ArgumentNullException("signatureData");
            }
            if (clientData == null)
            {
                throw new ArgumentNullException("clientData");
            }
            if (deviceRegistration == null)
            {
                throw new ArgumentNullException("deviceRegistration");
            }

            if (String.IsNullOrEmpty(clientData.RawJsonValue))
            {
                throw new InvalidOperationException("Client data has no JSON representation");
            }

            var counterBytes = BitConverter.GetBytes(signatureData.Counter);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(counterBytes);
            }

            var signedBytes = PackBytes(
                Helpers.Sha256(appId.ToString()),
                new [] { signatureData.UserPresence },
                counterBytes,
                Helpers.Sha256(clientData.RawJsonValue));

            VerifySignature(deviceRegistration, signatureData.Signature, signedBytes);

            if (signatureData.UserPresence != UserPresentFlag)
            {
                throw new InvalidOperationException("User presence invalid during authentication");
            }
        }
Beispiel #12
0
        private void VerifyResponseSignature(FidoAppId appId, FidoRegistrationData registrationData, FidoClientData clientData)
        {
            if (appId == null)
            {
                throw new ArgumentNullException("appId");
            }
            if (registrationData == null)
            {
                throw new ArgumentNullException("registrationData");
            }
            if (clientData == null)
            {
                throw new ArgumentNullException("clientData");
            }

            if (String.IsNullOrEmpty(clientData.RawJsonValue))
            {
                throw new InvalidOperationException("Client data has no JSON representation");
            }

            var signedBytes = PackBytes(
                new byte[] { 0 },
                Helpers.Sha256(appId.ToString()),
                Helpers.Sha256(clientData.RawJsonValue),
                registrationData.KeyHandle.ToByteArray(),
                registrationData.UserPublicKey.ToByteArray());

            VerifySignature(registrationData.AttestationCertificate, registrationData.Signature, signedBytes);
        }
Beispiel #13
0
 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
 {
     return(FidoClientData.FromWebSafeBase64(reader.Value.ToString()));
 }