2010-03-01 Gonzalo Paniagua Javier <gonzalo@novell.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Mon, 1 Mar 2010 08:51:44 +0000 (08:51 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Mon, 1 Mar 2010 08:51:44 +0000 (08:51 -0000)
* Mono.Security.Protocol.Tls/HttpsClientStream.cs: use Address instead
of RequestUri to get the right host name when the request is
redirected.

* Mono.Security.Protocol.Tls/SslStreamBase.cs:
* Mono.Security.Protocol.Tls/SslClientStream.cs:
* Mono.Security.Protocol.Tls/SslServerStream.cs:
* Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs:
added a new callback for certificate validation that gets all the
certificates received from the server/client. The callee should
build the chain and validate it.

svn path=/trunk/mcs/; revision=152652

mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/HttpsClientStream.cs
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs

index 2ad0fe6fce5493271c1cf44ff09644164e28e962..b3a60e26dcad9545ce2c19ef6f858332bb780ba7 100644 (file)
@@ -1,3 +1,10 @@
+2010-03-01 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * TlsServerCertificate.cs:
+       added a new callback for certificate validation that gets all the
+       certificates received from the server/client. The callee should
+       build the chain and validate it.
+
 2009-08-20  Sebastien Pouliot  <sebastien@ximian.com>
 
        * TlsServerCertificate.cs: If no usage information is available then
index 468ed90b043022d7676c19fa48ddf19edae61c47..a23d70664d14515022dedebc79b2e1ab9900bd28 100644 (file)
@@ -193,6 +193,13 @@ namespace Mono.Security.Protocol.Tls.Handshake.Client
                        ClientContext           context                 = (ClientContext)this.Context;
                        AlertDescription        description             = AlertDescription.BadCertificate;
 
+#if NET_2_0
+                       if (context.SslStream.HaveRemoteValidation2Callback) {
+                               if (context.SslStream.RaiseServerCertificateValidation2 (certificates))
+                                       return;
+                               // Give a chance to the 1.x ICertificatePolicy callback
+                       }
+#endif
                        // the leaf is the web server certificate
                        X509Certificate leaf = certificates [0];
                        X509Cert.X509Certificate cert = new X509Cert.X509Certificate (leaf.RawData);
index 2413ceebd8b025148228487d3217b6ad7b68b99e..9c2265cf2d7ccc4685250e81f7890d07e4cbcf67 100644 (file)
@@ -1,3 +1,16 @@
+2010-03-01 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * HttpsClientStream.cs: use Address instead
+       of RequestUri to get the right host name when the request is
+       redirected.
+
+       * SslStreamBase.cs:
+       * SslClientStream.cs:
+       * SslServerStream.cs:
+       added a new callback for certificate validation that gets all the
+       certificates received from the server/client. The callee should
+       build the chain and validate it.
+
 2009-10-20 Gonzalo Paniagua Javier <gonzalo@novell.com>
 
        * ServerContext.cs:
index 6c971dc39b07ec9c8f002380ea4341a6b289d4eb..5a614874e5b8db98af9ef216fd8ef8c9947391f6 100644 (file)
@@ -46,7 +46,7 @@ namespace Mono.Security.Protocol.Tls {
 
                 public HttpsClientStream (Stream stream, X509CertificateCollection clientCertificates,
                                        HttpWebRequest request, byte [] buffer)
-                        : base (stream, request.RequestUri.Host, false, (Mono.Security.Protocol.Tls.SecurityProtocolType)
+                        : base (stream, request.Address.Host, false, (Mono.Security.Protocol.Tls.SecurityProtocolType)
                                ServicePointManager.SecurityProtocol, clientCertificates)
                 {
                         // this constructor permit access to the WebRequest to call
@@ -96,7 +96,9 @@ namespace Mono.Security.Protocol.Tls {
                                failed = true;
                        }
 #pragma warning restore 618
-
+                       if (HaveRemoteValidation2Callback)
+                               return failed; // The validation already tried the 2.0 callback 
                        SNS.RemoteCertificateValidationCallback cb = ServicePointManager.ServerCertificateValidationCallback;
                        if (cb != null) {
                                SNS.SslPolicyErrors ssl_errors = 0;
index 03d37d79ba2474339461c06d6b2a0acac31c26f8..d157c7d72d63fe8cd269fc4e14be29ae676cb31e 100644 (file)
@@ -40,6 +40,7 @@ namespace Mono.Security.Protocol.Tls
        public delegate bool CertificateValidationCallback(
                X509Certificate certificate, 
                int[]                   certificateErrors);
+       public delegate bool CertificateValidationCallback2 (Mono.Security.X509.X509CertificateCollection collection);
 
        public delegate X509Certificate CertificateSelectionCallback(
                X509CertificateCollection       clientCertificates, 
@@ -105,6 +106,7 @@ namespace Mono.Security.Protocol.Tls
                
                #endregion
 
+               public event CertificateValidationCallback2 ServerCertValidation2;
                #region Constructors
                
                public SslClientStream(
@@ -192,6 +194,7 @@ namespace Mono.Security.Protocol.Tls
                                this.ServerCertValidation = null;
                                this.ClientCertSelection = null;
                                this.PrivateKeySelection = null;
+                               this.ServerCertValidation2 = null;
                        }
                }
 
@@ -372,7 +375,19 @@ namespace Mono.Security.Protocol.Tls
 
                        return null;
                }
-               
+
+               internal override bool HaveRemoteValidation2Callback {
+                       get { return ServerCertValidation2 != null; }
+               }
+
+               internal override bool OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+               {
+                       CertificateValidationCallback2 cb = ServerCertValidation2;
+                       if (cb != null)
+                               return cb (collection);
+                       return false;
+               }
+
                internal override bool OnRemoteCertificateValidation(X509Certificate certificate, int[] errors)
                {
                        if (this.ServerCertValidation != null)
@@ -390,6 +405,11 @@ namespace Mono.Security.Protocol.Tls
                        return base.RaiseRemoteCertificateValidation(certificate, certificateErrors);
                }
 
+               internal virtual bool RaiseServerCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+               {
+                       return base.RaiseRemoteCertificateValidation2 (collection);
+               }
+
                internal X509Certificate RaiseClientCertificateSelection(
                        X509CertificateCollection       clientCertificates, 
                        X509Certificate                         serverCertificate, 
index 750ab44a9403cf3eb29d2e6c6ffb15201e3946cc..ee84396c5d1a74e0c81d745290cff1e97a8be7a9 100644 (file)
@@ -76,6 +76,7 @@ namespace Mono.Security.Protocol.Tls
 
                #endregion
 
+               public event CertificateValidationCallback2 ClientCertValidation2;
                #region Constructors
 
                public SslServerStream(
@@ -304,6 +305,18 @@ namespace Mono.Security.Protocol.Tls
                        return (errors != null && errors.Length == 0);
                }
 
+               internal override bool HaveRemoteValidation2Callback {
+                       get { return ClientCertValidation2 != null; }
+               }
+
+               internal override bool OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+               {
+                       CertificateValidationCallback2 cb = ClientCertValidation2;
+                       if (cb != null)
+                               return cb (collection);
+                       return false;
+               }
+
                internal bool RaiseClientCertificateValidation(
                        X509Certificate certificate, 
                        int[]                   certificateErrors)
index 34f8ceaa73e36c80bad808e87ba03a26063608f1..9006eb5c26ed41c6d7a3efecb6b414d032e73247 100644 (file)
@@ -185,6 +185,8 @@ namespace Mono.Security.Protocol.Tls
                                                                                                                        X509CertificateCollection serverRequestedCertificates);
 
                internal abstract bool OnRemoteCertificateValidation(X509Certificate certificate, int[] errors);
+               internal abstract bool OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection);
+               internal abstract bool HaveRemoteValidation2Callback { get; }
 
                internal abstract AsymmetricAlgorithm OnLocalPrivateKeySelection(X509Certificate certificate, string targetHost);
 
@@ -205,6 +207,11 @@ namespace Mono.Security.Protocol.Tls
                        return OnRemoteCertificateValidation(certificate, errors);
                }
 
+               internal bool RaiseRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+               {
+                       return OnRemoteCertificateValidation2 (collection);
+               }
+
                internal AsymmetricAlgorithm RaiseLocalPrivateKeySelection(
                        X509Certificate certificate,
                        string targetHost)