diff options
author | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2010-03-26 23:13:27 +0300 |
---|---|---|
committer | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2010-03-26 23:13:27 +0300 |
commit | d5df37a35360f07a9ddfa676a5039a9c5a16a623 (patch) | |
tree | fc1908c3ba651d82f1657f960ba8281b93737531 /mcs | |
parent | 4e3e3a0e5d542168c2b8d8d6e76f571f7c086f5b (diff) |
2010-03-26 Gonzalo Paniagua Javier <gonzalo@novell.com>
* ServicePointManager.cs: errors parsing the certificate don't prevent
calling the callback now. Exceptions thrown parsing the certificate
are printed to stderr in case they are library errors.
svn path=/branches/mono-2-6/mcs/; revision=154317
Diffstat (limited to 'mcs')
-rw-r--r-- | mcs/class/System/System.Net/ChangeLog | 6 | ||||
-rw-r--r-- | mcs/class/System/System.Net/ServicePointManager.cs | 118 |
2 files changed, 75 insertions, 49 deletions
diff --git a/mcs/class/System/System.Net/ChangeLog b/mcs/class/System/System.Net/ChangeLog index 39f3bf3fb7a..14bd22ea129 100644 --- a/mcs/class/System/System.Net/ChangeLog +++ b/mcs/class/System/System.Net/ChangeLog @@ -1,3 +1,9 @@ +2010-03-26 Gonzalo Paniagua Javier <gonzalo@novell.com> + + * ServicePointManager.cs: errors parsing the certificate don't prevent + calling the callback now. Exceptions thrown parsing the certificate + are printed to stderr in case they are library errors. + 2010-03-18 Gonzalo Paniagua Javier <gonzalo@novell.com> * FtpWebResponse.cs: diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs index 79e242726ab..8a18f8c33b8 100644 --- a/mcs/class/System/System.Net/ServicePointManager.cs +++ b/mcs/class/System/System.Net/ServicePointManager.cs @@ -423,12 +423,20 @@ namespace System.Net X509Certificate2 leaf = new X509Certificate2 (certs [0].RawData); int status11 = 0; // Error code passed to the obsolete ICertificatePolicy callback SslPolicyErrors errors = 0; - if (!chain.Build (leaf)) - errors |= GetErrorsFromChain (chain); + try { + if (!chain.Build (leaf)) + errors |= GetErrorsFromChain (chain); + } catch (Exception e) { + Console.Error.WriteLine ("ERROR building certificate chain: {0}", e); + Console.Error.WriteLine ("Please, report this problem to the Mono team"); + errors |= SslPolicyErrors.RemoteCertificateChainErrors; + } + if (!CheckCertificateUsage (leaf)) { errors |= SslPolicyErrors.RemoteCertificateChainErrors; status11 = -2146762490; //CERT_E_PURPOSE 0x800B0106 } + if (!CheckServerIdentity (leaf, Host)) { errors |= SslPolicyErrors.RemoteCertificateNameMismatch; status11 = -2146762481; // CERT_E_CN_NO_MATCH 0x800B010F @@ -561,37 +569,43 @@ namespace System.Net // DH certificates requires some changes - does anyone use one ? static bool CheckCertificateUsage (X509Certificate2 cert) { - // certificate extensions are required for this - // we "must" accept older certificates without proofs - if (cert.Version < 3) - return true; - - X509KeyUsageExtension kux = (X509KeyUsageExtension) cert.Extensions ["2.5.29.15"]; - X509EnhancedKeyUsageExtension eku = (X509EnhancedKeyUsageExtension) cert.Extensions ["2.5.29.37"]; - if (kux != null && eku != null) { - // RFC3280 states that when both KeyUsageExtension and - // ExtendedKeyUsageExtension are present then BOTH should - // be valid - if ((kux.KeyUsages & s_flags) == 0) - return false; - return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null || - eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null; - } else if (kux != null) { - return ((kux.KeyUsages & s_flags) != 0); - } else if (eku != null) { - // Server Authentication (1.3.6.1.5.5.7.3.1) or - // Netscape Server Gated Crypto (2.16.840.1.113730.4) - return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null || - eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null; - } + try { + // certificate extensions are required for this + // we "must" accept older certificates without proofs + if (cert.Version < 3) + return true; + + X509KeyUsageExtension kux = (X509KeyUsageExtension) cert.Extensions ["2.5.29.15"]; + X509EnhancedKeyUsageExtension eku = (X509EnhancedKeyUsageExtension) cert.Extensions ["2.5.29.37"]; + if (kux != null && eku != null) { + // RFC3280 states that when both KeyUsageExtension and + // ExtendedKeyUsageExtension are present then BOTH should + // be valid + if ((kux.KeyUsages & s_flags) == 0) + return false; + return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null || + eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null; + } else if (kux != null) { + return ((kux.KeyUsages & s_flags) != 0); + } else if (eku != null) { + // Server Authentication (1.3.6.1.5.5.7.3.1) or + // Netscape Server Gated Crypto (2.16.840.1.113730.4) + return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null || + eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null; + } - // last chance - try with older (deprecated) Netscape extensions - X509Extension ext = cert.Extensions ["2.16.840.1.113730.1.1"]; - if (ext != null) { - string text = ext.NetscapeCertType (false); - return text.IndexOf ("SSL Server Authentication") != -1; + // last chance - try with older (deprecated) Netscape extensions + X509Extension ext = cert.Extensions ["2.16.840.1.113730.1.1"]; + if (ext != null) { + string text = ext.NetscapeCertType (false); + return text.IndexOf ("SSL Server Authentication") != -1; + } + return true; + } catch (Exception e) { + Console.Error.WriteLine ("ERROR processing certificate: {0}", e); + Console.Error.WriteLine ("Please, report this problem to the Mono team"); + return false; } - return true; } // RFC2818 - HTTP Over TLS, Section 3.1 @@ -606,26 +620,32 @@ namespace System.Net // 3.1 Existing practice but DEPRECATED static bool CheckServerIdentity (X509Certificate2 cert, string targetHost) { - X509Extension ext = cert.Extensions ["2.5.29.17"]; - // 1. subjectAltName - if (ext != null) { - ASN1 asn = new ASN1 (ext.RawData); - SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (asn); - // 1.1 - multiple dNSName - foreach (string dns in subjectAltName.DNSNames) { - // 1.2 TODO - wildcard support - if (Match (targetHost, dns)) - return true; - } - // 2. ipAddress - foreach (string ip in subjectAltName.IPAddresses) { - // 2.1. Exact match required - if (ip == targetHost) - return true; + try { + X509Extension ext = cert.Extensions ["2.5.29.17"]; + // 1. subjectAltName + if (ext != null) { + ASN1 asn = new ASN1 (ext.RawData); + SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (asn); + // 1.1 - multiple dNSName + foreach (string dns in subjectAltName.DNSNames) { + // 1.2 TODO - wildcard support + if (Match (targetHost, dns)) + return true; + } + // 2. ipAddress + foreach (string ip in subjectAltName.IPAddresses) { + // 2.1. Exact match required + if (ip == targetHost) + return true; + } } + // 3. Common Name (CN=) + return CheckDomainName (cert.SubjectName.Format (false), targetHost); + } catch (Exception e) { + Console.Error.WriteLine ("ERROR processing certificate: {0}", e); + Console.Error.WriteLine ("Please, report this problem to the Mono team"); + return false; } - // 3. Common Name (CN=) - return CheckDomainName (cert.SubjectName.Format (false), targetHost); } static bool CheckDomainName (string subjectName, string targetHost) |