Ejemplo n.º 1
0
        public virtual void TestDecodeAuthenticateResponse()
        {
            KeySignResponse keySignResponse = RawMessageCodec
                                              .DecodeKeySignResponse(SIGN_RESPONSE_DATA.Segment());

            Assert.AreEqual(new KeySignResponse(UserPresenceVerifierConstants.UserPresentFlag, COUNTER_VALUE, SIGNATURE_AUTHENTICATE), keySignResponse);
        }
Ejemplo n.º 2
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);
        }