public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("ECDSA signature verification requires ECDSA public key");
            }

            // Decode the public key parameters
            string curveOid = DER2OID(publicKey.Parameters);

            if (curveOid == null)
            {
                throw new Exception("Unsupported ECDSA public key parameters");
            }

            // Get parameters from the curve OID
            X9ECParameters ecParams = SecNamedCurves.GetByOid(new DerObjectIdentifier(curveOid));

            if (ecParams == null)
            {
                throw new Exception("Unsupported ECC curve type OID: " + curveOid);
            }

            // Construct domain parameters
            ECDomainParameters domainParameters = new ECDomainParameters(ecParams.Curve,
                                                                         ecParams.G, ecParams.N, ecParams.H,
                                                                         ecParams.GetSeed());

            // Decode the public key data
            byte[] ecPointData = publicKey.KeyValue;
            if (ecPointData[0] != 0x04)
            {
                throw new Exception("Only uncompressed ECDSA keys supported, format: " + ecPointData[0]);
            }
            ECPoint ecPoint = domainParameters.Curve.DecodePoint(ecPointData);
            ECPublicKeyParameters theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters);

            // Hash input data buffer
            byte[] dataHash;
            if (hashAlgorithm == null)
            {
                dataHash = TLSv1HashData(data);
            }
            else
            {
                dataHash = hashAlgorithm.ComputeHash(data);
            }

            // Actually verify the signature
            BigInteger[] sig    = DERDecodeSignature(signature);
            ECDsaSigner  signer = new ECDsaSigner();

            signer.Init(false, theirPublicKey);
            return(signer.VerifySignature(dataHash, sig[0], sig[1]));
        }
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (hashAlgorithm != null && !(hashAlgorithm is SHA1))
            {
                throw new Exception("DSA signature verification requires SHA1 hash algorithm");
            }
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid) || !(publicKey.Algorithm is DSACryptoServiceProvider))
            {
                throw new Exception("DSA signature verification requires DSA public key");
            }

            return(VerifyData(data, (DSACryptoServiceProvider)publicKey.Algorithm, signature));
        }
Example #3
0
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("RSA signature verification requires RSA public key");
            }

            RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)publicKey.Algorithm;

            if (hashAlgorithm == null)
            {
                // Before TLS 1.2 RSA signatures always used MD5+SHA1
                // MD5+SHA1 is not supported by .NET, so we need custom code
                return(TLSv1VerifyData(rsaKey, data, signature));
            }
            else
            {
                // Starting from TLS 1.2 the standard signature is used
                return(rsaKey.VerifyData(data, hashAlgorithm, signature));
            }
        }
        public override bool VerifyData(byte[] buffer, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("ECDSA signature verification requires ECDSA public key");
            }

            string curveOid = DER2OID(publicKey.Parameters);

            if (curveOid == null)
            {
                throw new Exception("Unsupported ECDSA public key parameters");
            }

            byte[] keyData = publicKey.KeyValue;
            if (keyData[0] != 0x04)
            {
                throw new Exception("Only uncompressed ECDSA keys supported, format: " + keyData[0]);
            }

            UInt32 keyLength;

            byte[] blobMagic;
            if (curveOid.Equals(P256OID))
            {
                keyLength = 32;
                blobMagic = Encoding.ASCII.GetBytes("ECS1");
            }
            else if (curveOid.Equals(P384OID))
            {
                keyLength = 48;
                blobMagic = Encoding.ASCII.GetBytes("ECS3");
            }
            else if (curveOid.Equals(P521OID))
            {
                keyLength = 66;
                blobMagic = Encoding.ASCII.GetBytes("ECS5");
            }
            else
            {
                throw new Exception("Unsupported ECC curve type OID: " + curveOid);
            }

            if (2 * keyLength != keyData.Length - 1)
            {
                throw new Exception("Invalid length of ECDSA public key: " + keyData.Length +
                                    " (should be " + (1 + 2 * keyLength) + ")");
            }
            byte[] lengthData = BitConverter.GetBytes(keyLength);

            // Create the ECC public blob for ECDsaCng class
            byte[] eccBlob = new byte[8 + 2 * keyLength];
            Buffer.BlockCopy(blobMagic, 0, eccBlob, 0, 4);
            Buffer.BlockCopy(lengthData, 0, eccBlob, 4, 4);
            Buffer.BlockCopy(keyData, 1, eccBlob, 8, (int)(2 * keyLength));

            CngKey   cngKey   = CngKey.Import(eccBlob, CngKeyBlobFormat.EccPublicBlob);
            ECDsaCng ecdsaKey = new ECDsaCng(cngKey);

            ecdsaKey.HashAlgorithm = GetCngAlgorithm(hashAlgorithm);

            return(ecdsaKey.VerifyData(buffer, DERDecodeSignature(signature, (int)keyLength)));
        }