Преглед на файлове

2009-08-20 Sebastien Pouliot <[email protected]>

	* SslStream.cs : Always use/provide a X509Chain even if this 
	duplicates some of the old/existing logic of Mono.Security.
	This makes it possible to provide a callback using 
	ServicePointManager.ServerCertificateValidationCallback


svn path=/trunk/mcs/; revision=140359
Sebastien Pouliot преди 16 години
родител
ревизия
52a76350d1
променени са 2 файла, в които са добавени 40 реда и са изтрити 6 реда
  1. 7 0
      mcs/class/System/System.Net.Security/ChangeLog
  2. 33 6
      mcs/class/System/System.Net.Security/SslStream.cs

+ 7 - 0
mcs/class/System/System.Net.Security/ChangeLog

@@ -1,3 +1,10 @@
+2009-08-20  Sebastien Pouliot  <[email protected]>
+
+	* SslStream.cs : Always use/provide a X509Chain even if this 
+	duplicates some of the old/existing logic of Mono.Security.
+	This makes it possible to provide a callback using 
+	ServicePointManager.ServerCertificateValidationCallback
+
 2007-08-24  Atsushi Enomoto  <[email protected]>
 
 	* SslStream.cs : uh, fixed the build.

+ 33 - 6
mcs/class/System/System.Net.Security/SslStream.cs

@@ -348,13 +348,40 @@ namespace System.Net.Security
 
 			if (validation_callback != null)
 				s.ServerCertValidationDelegate = delegate (X509Certificate cert, int [] certErrors) {
-					X509Chain chain = null;
-					if (cert is X509Certificate2) {
-						chain = new X509Chain ();
-						chain.Build ((X509Certificate2) cert);
+					X509Chain chain = new X509Chain ();
+					X509Certificate2 x2 = (cert as X509Certificate2);
+					if (x2 == null)
+						x2 = new X509Certificate2 (cert);
+
+					if (!ServicePointManager.CheckCertificateRevocationList)
+						chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
+
+					// SSL specific checks (done by Mono.Security.dll SSL/TLS implementation) 
+					SslPolicyErrors errors = SslPolicyErrors.None;
+					foreach (int i in certErrors) {
+						switch (i) {
+						case -2146762490: // CERT_E_PURPOSE
+							errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
+							break;
+						case -2146762481: // CERT_E_CN_NO_MATCH
+							errors |= SslPolicyErrors.RemoteCertificateNameMismatch;
+							break;
+						default:
+							errors |= SslPolicyErrors.RemoteCertificateChainErrors;
+							break;
+						}
 					}
-					// FIXME: SslPolicyErrors is incomplete
-					SslPolicyErrors errors = certErrors.Length > 0 ? SslPolicyErrors.RemoteCertificateChainErrors : SslPolicyErrors.None;
+
+					chain.Build (x2);
+
+					// non-SSL specific X509 checks (i.e. RFC3280 related checks)
+					foreach (X509ChainStatus status in chain.ChainStatus) {
+						if ((status.Status & X509ChainStatusFlags.PartialChain) != 0)
+							errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
+						else
+							errors |= SslPolicyErrors.RemoteCertificateChainErrors;
+					}
+
 					return validation_callback (this, cert, chain, errors);
 				};
 			if (selection_callback != null)