Convert blocking operations in HttpWebRequest and SslClientStream to non-blocking...
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls / SslServerStream.cs
index 750ab44a9403cf3eb29d2e6c6ffb15201e3946cc..b0d8bba6ffc99cc8b92675f31d8318bc32d43ef7 100644 (file)
@@ -34,7 +34,12 @@ using Mono.Security.Protocol.Tls.Handshake;
 
 namespace Mono.Security.Protocol.Tls
 {
-       public class SslServerStream : SslStreamBase
+#if INSIDE_SYSTEM
+       internal
+#else
+       public
+#endif
+       class SslServerStream : SslStreamBase
        {
                #region Internal Events
                
@@ -76,6 +81,7 @@ namespace Mono.Security.Protocol.Tls
 
                #endregion
 
+               public event CertificateValidationCallback2 ClientCertValidation2;
                #region Constructors
 
                public SslServerStream(
@@ -190,7 +196,7 @@ namespace Mono.Security.Protocol.Tls
                                        Fig. 1 - Message flow for a full handshake              
                */
 
-               internal override IAsyncResult OnBeginNegotiateHandshake(AsyncCallback callback, object state)
+               internal override IAsyncResult BeginNegotiateHandshake(AsyncCallback callback, object state)
                {
                        // Reset the context if needed
                        if (this.context.HandshakeState != HandshakeState.None)
@@ -209,7 +215,7 @@ namespace Mono.Security.Protocol.Tls
 
                }
 
-               internal override void OnNegotiateHandshakeCallback(IAsyncResult asyncResult)
+               internal override void EndNegotiateHandshake(IAsyncResult asyncResult)
                {
                        // Receive Client Hello message and ignore it
                        this.protocol.EndReceiveRecord(asyncResult);
@@ -233,8 +239,6 @@ namespace Mono.Security.Protocol.Tls
                                this.protocol.SendRecord(HandshakeType.ServerKeyExchange);
                        }
 
-                       bool certRequested = false;
-
                        // If the negotiated cipher is a KeyEx cipher or
                        // the client certificate is required send the CertificateRequest message
                        if (this.context.Negotiating.Cipher.IsExportable ||
@@ -242,7 +246,6 @@ namespace Mono.Security.Protocol.Tls
                                ((ServerContext)this.context).RequestClientCertificate)
                        {
                                this.protocol.SendRecord(HandshakeType.CertificateRequest);
-                               certRequested = true;
                        }
 
                        // Send ServerHelloDone message
@@ -262,15 +265,6 @@ namespace Mono.Security.Protocol.Tls
                                }
                        }
 
-                       if (certRequested) {
-                               X509Certificate client_cert = this.context.ClientSettings.ClientCertificate;
-                               if (client_cert == null && ((ServerContext)this.context).ClientCertificateRequired)
-                                       throw new TlsException (AlertDescription.BadCertificate, "No certificate received from client.");
-
-                               if (!RaiseClientCertificateValidation (client_cert, new int[0]))
-                                       throw new TlsException (AlertDescription.BadCertificate, "Client certificate not accepted.");
-                       }
-
                        // Send ChangeCipherSpec and ServerFinished messages
                        this.protocol.SendChangeCipherSpec();
                        this.protocol.SendRecord (HandshakeType.Finished);
@@ -304,6 +298,18 @@ namespace Mono.Security.Protocol.Tls
                        return (errors != null && errors.Length == 0);
                }
 
+               internal override bool HaveRemoteValidation2Callback {
+                       get { return ClientCertValidation2 != null; }
+               }
+
+               internal override ValidationResult OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+               {
+                       CertificateValidationCallback2 cb = ClientCertValidation2;
+                       if (cb != null)
+                               return cb (collection);
+                       return null;
+               }
+
                internal bool RaiseClientCertificateValidation(
                        X509Certificate certificate, 
                        int[]                   certificateErrors)