Пример #1
0
        public KeySignResponse Authenticate(KeySignRequest keySignRequest)
        {
            while (true)
            {
                var result = key.SignAsync(keySignRequest).Result;

                switch (result.Status)
                {
                case KeyResponseStatus.Success:
                    Debug.Assert(result.Data != null, "no data for success");
                    return(result.Data);

                case KeyResponseStatus.TestOfuserPresenceRequired:
                    Console.WriteLine("User presence required");
                    Thread.Sleep(100);
                    continue;

                case KeyResponseStatus.Failure:
                    throw new U2FException("Failure: " + result.Raw.Status);

                case KeyResponseStatus.BadKeyHandle:
                    throw new U2FException("Bad key handle");

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
Пример #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));
        }
Пример #3
0
        public virtual void TestEncodeAuthenticateRequest()
        {
            var authenticateRequest = new KeySignRequest(U2FVersion.V2,
                                                         BROWSER_DATA_SIGN_SHA256, APP_ID_SIGN_SHA256, KEY_HANDLE);
            var encodedBytes = RawMessageCodec.EncodeKeySignRequest(authenticateRequest);

            CollectionAssert.AreEqual(SIGN_REQUEST_DATA, encodedBytes);
        }
Пример #4
0
        public virtual void TestDecodeAuthenticateRequest()
        {
            KeySignRequest keySignRequest = RawMessageCodec
                                            .DecodeKeySignRequest(SIGN_REQUEST_DATA);

            Assert.AreEqual(new KeySignRequest
                                (U2FVersion.V2, BROWSER_DATA_SIGN_SHA256
                                , APP_ID_SIGN_SHA256, KEY_HANDLE), keySignRequest);
        }
Пример #5
0
        SignInfo GenerateSignInfo(SignRequest signRequest)
        {
            var clientDataB64 = ClientDataCodec.EncodeClientData(ClientDataCodec.RequestTypeAuthenticate, signRequest.Challenge,
                                                                 sender.Origin, sender.ChannelId);
            var clientDataSha256 = crypto.ComputeSha256(clientDataB64);
            var appIdSha256      = crypto.ComputeSha256(signRequest.AppId);
            var keyHandle        = WebSafeBase64Converter.FromBase64String(signRequest.KeyHandle);
            var authRequest      = new KeySignRequest(U2FVersion.V2,
                                                      clientDataSha256, appIdSha256, keyHandle);

            return(new SignInfo(signRequest, clientDataB64, authRequest));
        }
        public virtual void TestAuthenticate()
        {
            var authenticateRequest = new KeySignRequest(U2FVersion.V2,
                                                         BROWSER_DATA_SIGN_SHA256, APP_ID_SIGN_SHA256, KEY_HANDLE);
            var authenticateResponse = u2FKey.Authenticate(authenticateRequest);

            Assert.AreEqual(UserPresenceVerifierConstants.UserPresentFlag, authenticateResponse.UserPresence);
            Assert.AreEqual(COUNTER_VALUE, authenticateResponse.Counter);
            var ecdsaSignature = SignerUtilities.GetSigner("SHA-256withECDSA");

            ecdsaSignature.Init(false, USER_PUBLIC_KEY_SIGN);
            ecdsaSignature.BlockUpdate(EXPECTED_AUTHENTICATE_SIGNED_BYTES, 0, EXPECTED_AUTHENTICATE_SIGNED_BYTES.Length);
            Assert.IsTrue(ecdsaSignature.VerifySignature(authenticateResponse.Signature));
        }
Пример #7
0
        public async Task <KeyResponse <KeySignResponse> > SignAsync(KeySignRequest request,
                                                                     CancellationToken cancellationToken = new CancellationToken(),
                                                                     bool noWink = false)
        {
            var flags = noWink
                ? EnforceUserPresenceAndSign | InteractionFlags.TestSignatureOnly
                : EnforceUserPresenceAndSign;

            var message = ApduMessageCodec.EncodeAuthenticateRequest(
                new KeyRequest <KeySignRequest>(request, flags));
            var response = await QueryApduAsync(message, cancellationToken);

            return(ApduMessageCodec.DecodeAuthenticateReponse(response));
        }
Пример #8
0
        /// <exception cref="U2FException"/>
        public static byte[] EncodeKeySignRequest([NotNull] KeySignRequest keySignRequest)
        {
            if (keySignRequest == null)
            {
                throw new ArgumentNullException(nameof(keySignRequest));
            }

            //var controlByte = authenticateRequest.Control;
            var appIdSha256     = keySignRequest.ApplicationSha256;
            var challengeSha256 = keySignRequest.ChallengeSha256;
            var keyHandle       = keySignRequest.KeyHandle;

            if (keyHandle.Length > 255)
            {
                throw new U2FException("keyHandle length cannot be longer than 255 bytes!");
            }

            int size;

            switch (keySignRequest.Version)
            {
            case U2FVersion.V1:
                size = appIdSha256.Length + challengeSha256.Length + keyHandle.Length;
                break;

            case U2FVersion.V2:
                size = appIdSha256.Length + challengeSha256.Length + keyHandle.Length + 1;
                break;

            default:
                throw new ArgumentException("Unknown version: " + keySignRequest.Version, nameof(keySignRequest));
            }

            var result = new byte[size];

            using (var writer = new EndianWriter(new MemoryStream(result), Endianness.BigEndian))
            {
                writer.Write(challengeSha256);
                writer.Write(appIdSha256);
                if (keySignRequest.Version == U2FVersion.V2)
                {
                    writer.Write((byte)keyHandle.Length);
                }
                writer.Write(keyHandle);
            }
            return(result);
        }
Пример #9
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));
        }
Пример #10
0
 /// <exception cref="System.IO.IOException"/>
 /// <exception cref="U2FException"/>
 public static void SendAuthenticateRequest(Stream outputStream, KeySignRequest keySignRequest)
 {
     SendRequest(outputStream, CommandAuthenticate,
                 RawMessageCodec.EncodeKeySignRequest(keySignRequest));
 }
Пример #11
0
 public SignInfo(SignRequest signRequest, string clientDataBase64, KeySignRequest keySignRequest)
 {
     ClientDataBase64 = clientDataBase64;
     KeySignRequest   = keySignRequest;
     SignRequest      = signRequest;
 }
Пример #12
0
        async Task <SignOperationResult?> TrySignOneRequest(IKey key, bool isFirstPass, KeySignRequest request,
                                                            CancellationToken cancellationToken)
        {
            try
            {
                var result = await key.SignAsync(request, cancellationToken, isFirstPass);

                log.Info(result.Status.ToString());
                switch (result.Status)
                {
                case KeyResponseStatus.BadKeyHandle:
                    // No use retrying
                    blacklistedKeyHandles.Add(request.KeyHandle);
                    break;

                case KeyResponseStatus.Success:
                    return(SignOperationResult.Success(request, result.Data));
                }
            }
            catch (KeyGoneException)
            {
                // No sense in continuing with this signer, the key isn't physically present anymore
                log.DebugFormat("Key '{0}' is gone", keyId);
                throw;
            }
            catch (TaskCanceledException)
            {
                // Let cancellation bubble up
                throw;
            }
            catch (KeyBusyException)
            {
                // Maybe it won't be busy later
            }
            catch (Exception exception)
            {
                log.Error("Authenticate request failed", exception);
            }
            return(null);
        }
Пример #13
0
 private bool IsBlacklisted(KeySignRequest request)
 {
     return(blacklistedKeyHandles.Any(h => h.SequenceEqual(request.KeyHandle)));
 }
Пример #14
0
 public static SignOperationResult Success(KeySignRequest request, KeySignResponse response)
 {
     return(new SignOperationResult(KeyResponseStatus.Success, request, response));
 }
Пример #15
0
 private SignOperationResult(KeyResponseStatus status, KeySignRequest request, KeySignResponse response)
 {
     Status   = status;
     Request  = request;
     Response = response;
 }