Example #1
0
        public virtual void TestEncodeAuthenticateSignedBytes()
        {
            var encodedBytes = RawMessageCodec.EncodeKeySignSignedBytes(APP_ID_SIGN_SHA256,
                                                                        UserPresenceVerifierConstants.UserPresentFlag, COUNTER_VALUE, BROWSER_DATA_SIGN_SHA256);

            CollectionAssert.AreEqual(EXPECTED_AUTHENTICATE_SIGNED_BYTES, encodedBytes);
        }
Example #2
0
        /// <exception cref="U2FException" />
        public KeySignResponse Authenticate(KeySignRequest keySignRequest)
        {
            if (keySignRequest == null)
            {
                throw new ArgumentNullException(nameof(keySignRequest));
            }

            log.Info(">> authenticate");

            var applicationSha256 = keySignRequest.ApplicationSha256;
            var challengeSha256   = keySignRequest.ChallengeSha256;
            var keyHandle         = keySignRequest.KeyHandle;

            log.Info(" -- Inputs --");
            log.Info("  applicationSha256: " + applicationSha256.ToHexString());
            log.Info("  challengeSha256: " + challengeSha256.ToHexString());
            log.Info("  keyHandle: " + keyHandle.ToHexString());

            var keyPair      = dataStore.GetKeyPair(keyHandle);
            var counter      = dataStore.IncrementCounter();
            var userPresence = userPresenceVerifier.VerifyUserPresence();
            var signedData   = RawMessageCodec.EncodeKeySignSignedBytes(applicationSha256, userPresence, counter,
                                                                        challengeSha256);

            log.Info("Signing bytes " + signedData.ToHexString());
            var signature = crypto.Sign(signedData, keyPair.PrivateKey);

            log.Info(" -- Outputs --");
            log.Info("  userPresence: " + userPresence);
            log.Info("  counter: " + counter);
            log.Info("  signature: " + signature.ToHexString());
            log.Info("<< authenticate");

            return(new KeySignResponse(userPresence, counter, signature));
        }
Example #3
0
        public Task <KeyResponse <KeySignResponse> > SignAsync(KeySignRequest request, CancellationToken cancellationToken = new CancellationToken(),
                                                               bool noWink = false)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            log.Info(">> authenticate");

            var applicationSha256 = request.ApplicationSha256;
            var challengeSha256   = request.ChallengeSha256;
            var keyHandle         = request.KeyHandle;

            log.Info(" -- Inputs --");
            log.Info("  applicationSha256: " + applicationSha256.ToHexString());
            log.Info("  challengeSha256: " + challengeSha256.ToHexString());
            log.Info("  keyHandle: " + keyHandle.ToHexString());

            var keyPair     = dataStore.GetKeyPair(keyHandle);
            var counter     = dataStore.IncrementCounter();
            var userPresent = userPresenceVerifier.VerifyUserPresence();

            if ((userPresent & UserPresenceVerifierConstants.UserPresentFlag) == 0)
            {
                return(TestOfUserPresenceRequired <KeySignResponse>());
            }

            var signedData = RawMessageCodec.EncodeKeySignSignedBytes(applicationSha256, userPresent, counter,
                                                                      challengeSha256);

            log.Info("Signing bytes " + signedData.ToHexString());
            var signature = crypto.Sign(signedData, keyPair.PrivateKey);

            log.Info(" -- Outputs --");
            log.Info("  userPresence: " + userPresent);
            log.Info("  counter: " + counter);
            log.Info("  signature: " + signature.ToHexString());
            log.Info("<< authenticate");

            var response     = new KeySignResponse(userPresent, counter, signature);
            var responseData = RawMessageCodec.EncodeKeySignResponse(response).Segment();
            var apdu         = new ApduResponse(ApduResponseStatus.NoError, responseData);
            var keyResponse  = new KeyResponse <KeySignResponse>(apdu, response, KeyResponseStatus.Success);

            return(TaskEx.FromResult(keyResponse));
        }
Example #4
0
        public SecurityKeyData ProcessSignResponse(SignResponse signResponse)
        {
            log.Info(">> processSignResponse");
            var sessionId         = signResponse.SessionId;
            var browserDataBase64 = signResponse.Bd;
            var rawSignDataBase64 = signResponse.Sign;
            var sessionData       = dataStore.GetSignSessionData(sessionId);

            if (sessionData == null)
            {
                throw new U2FException("Unknown session_id");
            }

            var appId           = sessionData.AppId;
            var securityKeyData = dataStore
                                  .GetSecurityKeyData(sessionData.AccountName)
                                  .FirstOrDefault(k => sessionData.GetPublicKey().SequenceEqual(k.PublicKey));

            if (securityKeyData == null)
            {
                throw new U2FException("No security keys registered for this user");
            }

            var browserDataBytes = WebSafeBase64Converter.FromBase64String(browserDataBase64);
            var browserData      = Encoding.UTF8.GetString(browserDataBytes, 0, browserDataBytes.Length);
            var rawSignData      = WebSafeBase64Converter.FromBase64String(rawSignDataBase64);

            log.Info("-- Input --");
            log.Info("  sessionId: " + sessionId);
            log.Info("  publicKey: " + securityKeyData.PublicKey.ToHexString());
            log.Info("  challenge: " + sessionData.Challenge.ToHexString());
            log.Info("  accountName: " + sessionData.AccountName);
            log.Info("  browserData: " + browserData);
            log.Info("  rawSignData: " + rawSignData.ToHexString());

            VerifyBrowserData(browserData, "navigator.id.getAssertion", sessionData);
            var authenticateResponse = RawMessageCodec.DecodeKeySignResponse(rawSignData.Segment());
            var userPresence         = authenticateResponse.UserPresence;
            var counter   = authenticateResponse.Counter;
            var signature = authenticateResponse.Signature;

            log.Info("-- Parsed rawSignData --");
            log.Info("  userPresence: " + userPresence.ToString("X2"));
            log.Info("  counter: " + counter);
            log.Info("  signature: " + signature.ToHexString());

            if (userPresence != UserPresenceVerifierConstants.UserPresentFlag)
            {
                throw new U2FException("User presence invalid during authentication");
            }
            if (counter <= securityKeyData.Counter)
            {
                throw new U2FException("Counter value smaller than expected!");
            }

            var appIdSha256       = cryto.ComputeSha256(Encoding.UTF8.GetBytes(appId));
            var browserDataSha256 = cryto.ComputeSha256(Encoding.UTF8.GetBytes(browserData));
            var signedBytes       = RawMessageCodec.EncodeKeySignSignedBytes(appIdSha256, userPresence, counter,
                                                                             browserDataSha256);

            log.Info("Verifying signature of bytes " + signedBytes.ToHexString());
            if (!cryto.VerifySignature(cryto.DecodePublicKey(securityKeyData.PublicKey), signedBytes, signature))
            {
                throw new U2FException("Signature is invalid");
            }
            dataStore.UpdateSecurityKeyCounter(sessionData.AccountName, securityKeyData.PublicKey, counter);
            log.Info("<< processSignResponse");
            return(securityKeyData);
        }