Esempio n. 1
0
        public virtual void TestDecodeRegisterResponse()
        {
            var registerResponse = RawMessageCodec.DecodeKeyRegisterResponse(REGISTRATION_RESPONSE_DATA.Segment());

            Assert.AreEqual(
                new KeyRegisterResponse(USER_PUBLIC_KEY_ENROLL_HEX, KEY_HANDLE, VENDOR_CERTIFICATE, SIGNATURE_ENROLL),
                registerResponse);
        }
Esempio n. 2
0
        /// <exception cref="U2FException" />
        public SecurityKeyData ProcessRegistrationResponse(RegisterResponse registrationResponse,
                                                           long currentTimeInMillis)
        {
            log.Info(">> processRegistrationResponse");

            var sessionId                 = registrationResponse.SessionId;
            var browserDataBase64         = registrationResponse.Bd;
            var rawRegistrationDataBase64 = registrationResponse.RegistrationData;
            var sessionData               = dataStore.GetEnrollSessionData(sessionId);

            if (sessionData == null)
            {
                throw new U2FException("Unknown session_id");
            }
            var appId               = sessionData.AppId;
            var rawBrowserData      = WebSafeBase64Converter.FromBase64String(browserDataBase64);
            var browserData         = Encoding.UTF8.GetString(rawBrowserData, 0, rawBrowserData.Length);
            var rawRegistrationData = WebSafeBase64Converter.FromBase64String(rawRegistrationDataBase64);

            log.Info("-- Input --");
            log.Info("  sessionId: " + sessionId);
            log.Info("  challenge: " + sessionData.Challenge.ToHexString());
            log.Info("  accountName: " + sessionData.AccountName);
            log.Info("  browserData: " + browserData);
            log.Info("  rawRegistrationData: " + rawRegistrationData.ToHexString());

            var registerResponse       = RawMessageCodec.DecodeKeyRegisterResponse(rawRegistrationData.Segment());
            var userPublicKey          = registerResponse.UserPublicKey;
            var keyHandle              = registerResponse.KeyHandle;
            var attestationCertificate = registerResponse.AttestationCertificate;
            var signature              = registerResponse.Signature;
            IList <SecurityKeyDataTransports> transports = null;

            try
            {
                transports = ParseTransportsExtension(attestationCertificate);
            }
            catch (CertificateParsingException e1)
            {
                log.Warn("Could not parse transports extension " + e1.Message);
            }
            log.Info("-- Parsed rawRegistrationResponse --");
            log.Info("  userPublicKey: " + userPublicKey.ToHexString
                         ());
            log.Info("  keyHandle: " + keyHandle.ToHexString());
            log.Info("  attestationCertificate: " + SecurityKeyData.SafeCertificateToString(attestationCertificate));
            log.Info("  transports: " + transports);
            log.Info("  attestationCertificate bytes: " + attestationCertificate.GetEncoded().ToHexString());
            log.Info("  signature: " + signature.ToHexString());

            var appIdSha256       = cryto.ComputeSha256(Encoding.UTF8.GetBytes(appId));
            var browserDataSha256 = cryto.ComputeSha256(Encoding.UTF8.GetBytes(browserData));
            var signedBytes       = RawMessageCodec.EncodeKeyRegisterSignedBytes(appIdSha256, browserDataSha256, keyHandle,
                                                                                 userPublicKey);
            var trustedCertificates = dataStore.GetTrustedCertificates();

            if (!trustedCertificates.Contains(attestationCertificate))
            {
                log.Warn("Attestion cert is not trusted");
            }

            VerifyBrowserData(browserData, "navigator.id.finishEnrollment", sessionData);

            log.Info("Verifying signature of bytes " + signedBytes.ToHexString());
            if (!cryto.VerifySignature(attestationCertificate, signedBytes, signature))
            {
                throw new U2FException("Signature is invalid");
            }

            // The first time we create the SecurityKeyData, we set the counter value to -1.
            // We don't actually know what the counter value of the real device is - but it will
            // be something bigger than -1, so subsequent signatures will check out ok.
            var securityKeyData = new SecurityKeyData(currentTimeInMillis, transports, keyHandle, userPublicKey,
                                                      attestationCertificate, -1);

            /* initial counter value */
            dataStore.AddSecurityKeyData(sessionData.AccountName, securityKeyData);
            log.Info("<< processRegistrationResponse");
            return(securityKeyData);
        }