Пример #1
0
        internal void Validate(U2fResponse<U2fRegisterResponseData> response, string origin, string challenge)
        {
            if (response.Type != "u2f_register_response"
                || response.ResponseData.Version != "U2F_V2"
                || response.ResponseData.AppId != origin
                || response.ResponseData.Challenge != challenge
                || response.ResponseData.ClientData.Typ != "navigator.id.finishEnrollment"
                || response.ResponseData.ClientData.Challenge != challenge
                || response.ResponseData.ClientData.Origin != origin
                || response.ResponseData.ClientData.CId_PubKey != ""
                || response.ResponseData.RegistrationData.ReservedByte != 5
                || response.ResponseData.RegistrationData.KeyHandle.Length != 64 //NOTE: 64 is characterisation value; strictly speaking it only needs entropy
                )
            {
                throw new ApplicationException();
            }

            using (var stream = new MemoryStream(response.ResponseData.RegistrationData.AttestationCertificateAndSignature, false))
            {
                var attestationCertificate = Certificate.Load(stream);
                attestationCertificate.ThrowIfChainNotOkay(RootCertificates.Yubico);

                var signature = stream.ToArray().Skip((int) stream.Position).ToArray();
                attestationCertificate.PublicKey.ThrowIfSignatureNotOkay(signature,
                    new byte[] { 0 },
                    Hash.String(origin),
                    Hash.Array(response.ResponseData.ClientData.Raw),
                    response.ResponseData.RegistrationData.KeyHandle,
                    response.ResponseData.RegistrationData.UserPublicKey);
            }
        }
Пример #2
0
        internal void Validate(U2fResponse<U2fSignResponseData> response, string origin, byte[] userPublicKey, byte[] keyHandle, string challenge, uint counter)
        {
            if (response.Type != "u2f_sign_response"
                || !response.ResponseData.KeyHandle.SequenceEqual(keyHandle)
                || response.ResponseData.ClientData.Typ != "navigator.id.getAssertion"
                || response.ResponseData.ClientData.Challenge != challenge
                || response.ResponseData.ClientData.Origin != origin
                || response.ResponseData.ClientData.CId_PubKey != ""
                || response.ResponseData.SignatureData.UserPresenceByte != 1
                || response.ResponseData.SignatureData.CounterValue != counter
                )
            {
                throw new ApplicationException();
            }

            EllipticCurve.LoadPublicKey(userPublicKey).ThrowIfSignatureNotOkay(response.ResponseData.SignatureData.Signature,
                Hash.String(origin),
                new[] { response.ResponseData.SignatureData.UserPresenceByte },
                response.ResponseData.SignatureData.CounterBytes,
                Hash.Array(response.ResponseData.ClientData.Raw));
        }