internal static bool VerifyServerCertificate(TlsContext context, MX.X509Certificate certificate, ExchangeAlgorithmType algorithm) { if (context.NegotiatedProtocol == TlsProtocolCode.Tls12 && certificate.Version < 3) { throw new TlsException(AlertDescription.UnsupportedCertificate, "X.509v3 server certificate required"); } if (certificate.KeyAlgorithm != null && !certificate.KeyAlgorithm.Equals(OidKeyAlgorithmRsa)) { return(false); } if (certificate.SignatureAlgorithm != null && !VerifySignatureAlgorithm(certificate.SignatureAlgorithm)) { return(false); } switch (algorithm) { case ExchangeAlgorithmType.Rsa: return(VerifyKeyUsage(certificate, KeyUsages.keyEncipherment, OidServerAuth)); case ExchangeAlgorithmType.Dhe: case ExchangeAlgorithmType.EcDhe: return(VerifyKeyUsage(certificate, KeyUsages.digitalSignature, OidServerAuth)); default: throw new TlsException(AlertDescription.InternalError); } }
internal static bool VerifyKeyUsage(MX.X509Certificate certificate, KeyUsages keyUsages, string purpose) { if (certificate.Extensions == null) { return(true); } KeyUsageExtension kux = null; ExtendedKeyUsageExtension eku = null; var xtn = certificate.Extensions [OidKeyUsage]; if (xtn != null) { kux = new KeyUsageExtension(xtn); } xtn = certificate.Extensions [OidExtendedKeyUsage]; if (xtn != null) { eku = new ExtendedKeyUsageExtension(xtn); } if ((kux != null) && (eku != null)) { // RFC3280 states that when both KeyUsageExtension and // ExtendedKeyUsageExtension are present then BOTH should // be valid if (!kux.Support(keyUsages)) { return(false); } return(eku.KeyPurpose.Contains(purpose)); } else if (kux != null) { return(kux.Support(keyUsages)); } else if (eku != null) { return(eku.KeyPurpose.Contains(purpose)); } return(true); }