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