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)); }
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))); }