Esempio n. 1
0
        public static void VerifySignature(PublicKeyCredential cred, byte[] authData, byte[] clientData, byte[] signature, string rpid)
        {
            if (cred == null)
            {
                throw new ArgumentNullException(nameof(cred));
            }

            var payload      = authData.Concat(CredentialUtility.Hash(clientData)).ToArray();
            var rawSignature = DERSignature.Deserialize(signature);

            var authDataSpan = authData.AsSpan();
            var rpidHash     = authDataSpan.Slice(0, 32);
            var flags        = (AuthenticatorDataFlags)authDataSpan[32];

            var counterSpan = authDataSpan.Slice(33, 4);

            counterSpan.Reverse();
            uint counter = BitConverter.ToUInt32(counterSpan);

            if ((flags & AuthenticatorDataFlags.UserPresent) == 0)
            {
                throw new Exception("user does not present");
            }

            if (!rpidHash.SequenceEqual(CredentialUtility.Hash(Encoding.UTF8.GetBytes(rpid))))
            {
                throw new Exception("RP ID Hash does not match");
            }

            var publicKey = CBORObject.DecodeFromBytes(cred.PublicKey);
            var x         = publicKey.MapGet(-2).GetByteString();
            var y         = publicKey.MapGet(-3).GetByteString();

            var ecDsa = ECDsa.Create(new ECParameters
            {
                Curve = ECCurve.NamedCurves.nistP256,
                Q     = new ECPoint {
                    X = x, Y = y
                }
            });
            var isValid = ecDsa.VerifyData(payload, rawSignature, HashAlgorithmName.SHA256);

            if (!isValid)
            {
                throw new Exception("invalid signature");
            }

            if (cred.SignCounter >= counter)
            {
                throw new Exception("invalid signature counter");
            }

            cred.SignCounter = counter;
        }
Esempio n. 2
0
 public void Add(PublicKeyCredential cred) => _data.Add(cred);