Author: spouliot
Date: 2005-06-14 13:45:51 -0400 (Tue, 14 Jun 2005)
New Revision: 45984

Modified:
   
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
   
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientCertificate.cs
Log:
2005-06-14  Sebastien Pouliot  <[EMAIL PROTECTED]>

        * TlsClientCertificate.cs: Add support for _optional_ mutual 
        authentication. SSL3 and TLS1 deals differently with this. SSL3 tested
        with OpenSSL, TSL1 tested with OpenSSL and LDAPS/AD.



Modified: 
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
===================================================================
--- 
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
 2005-06-14 17:44:44 UTC (rev 45983)
+++ 
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
 2005-06-14 17:45:51 UTC (rev 45984)
@@ -1,3 +1,9 @@
+2005-06-14  Sebastien Pouliot  <[EMAIL PROTECTED]>
+
+       * TlsClientCertificate.cs: Add support for _optional_ mutual 
+       authentication. SSL3 and TLS1 deals differently with this. SSL3 tested
+       with OpenSSL, TSL1 tested with OpenSSL and LDAPS/AD.
+
 2005-04-12  Sebastien Pouliot  <[EMAIL PROTECTED]>
 
        * TlsClientCertificateVerify.cs: Add missing data length (16 bits - 

Modified: 
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientCertificate.cs
===================================================================
--- 
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientCertificate.cs
   2005-06-14 17:44:44 UTC (rev 45983)
+++ 
trunk/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientCertificate.cs
   2005-06-14 17:45:51 UTC (rev 45984)
@@ -31,6 +31,9 @@
 {
        internal class TlsClientCertificate : HandshakeMessage
        {
+               private bool clientCertSelected;
+               private X509Certificate clientCert;
+
                #region Constructors
 
                public TlsClientCertificate(Context context) 
@@ -40,6 +43,21 @@
 
                #endregion
 
+               #region Properties
+
+               public X509Certificate ClientCertificate {
+                       get {
+                               if (!clientCertSelected)
+                               {
+                                       GetClientCertificate ();
+                                       clientCertSelected = true;
+                               }
+                               return clientCert;
+                       }
+               }
+
+               #endregion
+
                #region Methods
 
                public override void Update()
@@ -52,49 +70,63 @@
 
                #region Protected Methods
 
-               protected override void ProcessAsSsl3()
+               private void GetClientCertificate ()
                {
-                       this.ProcessAsTls1();
-               }
-
-               protected override void ProcessAsTls1()
-               {
 #warning "Client certificate selection is unfinished"
                        ClientContext context = (ClientContext)this.Context;
-                       string msg = "Client certificate requested by the 
server and no client certificate specified.";
 
-                       if (context.ClientSettings.Certificates == null ||
-                               context.ClientSettings.Certificates.Count == 0)
+                       // note: the server may ask for mutual authentication 
+                       // but may not require it (i.e. it can be optional).
+                       if (context.ClientSettings.Certificates != null &&
+                               context.ClientSettings.Certificates.Count > 0)
                        {
-                               throw new 
TlsException(AlertDescription.UserCancelled, msg);
+                               clientCert = 
context.SslStream.RaiseClientCertificateSelection(
+                                       
this.Context.ClientSettings.Certificates,
+                                       new 
X509Certificate(this.Context.ServerSettings.Certificates[0].RawData),
+                                       this.Context.ClientSettings.TargetHost,
+                                       null);
+                               // Note: the application code can raise it's 
+                               // own exception to stop the connection too.
                        }
-                       
-                       // Select a valid certificate
-                       X509Certificate clientCert = 
this.Context.ClientSettings.Certificates[0];
 
-                       clientCert = 
context.SslStream.RaiseClientCertificateSelection(
-                               this.Context.ClientSettings.Certificates,
-                               new 
X509Certificate(this.Context.ServerSettings.Certificates[0].RawData),
-                               this.Context.ClientSettings.TargetHost,
-                               null);
-
-                       if (clientCert == null)
-                       {
-                               throw new 
TlsException(AlertDescription.UserCancelled, msg);
-                       }
-
                        // Update the selected client certificate
                        context.ClientSettings.ClientCertificate = clientCert;
+               }
 
-                       // Write client certificates information to a stream
-                       TlsStream stream = new TlsStream();
+               private void Write (X509Certificate clientCert)
+               {
+                       byte[] rawdata = clientCert.GetRawCertData();
+                       // Compose the message
+                       this.WriteInt24(rawdata.Length + 3);
+                       this.WriteInt24(rawdata.Length);
+                       this.Write(rawdata);
+               }
 
-                       stream.WriteInt24(clientCert.GetRawCertData().Length);
-                       stream.Write(clientCert.GetRawCertData());
+               protected override void ProcessAsSsl3()
+               {
+                       if (this.ClientCertificate != null)
+                       {
+                               Write (this.ClientCertificate);
+                       }
+                       else
+                       {
+                               // an Alert warning for NoCertificate (41) 
+                               // should be sent from here - but that would
+                               // break the current message handling
+                       }
+               }
 
-                       // Compose the message
-                       this.WriteInt24((int)stream.Length);
-                       this.Write(stream.ToArray());
+               protected override void ProcessAsTls1()
+               {
+                       if (this.ClientCertificate != null)
+                       {
+                               Write (this.ClientCertificate);
+                       }
+                       else
+                       {
+                               // return message with empty certificate (see 
7.4.6 in RFC2246)
+                               this.WriteInt24 (0);
+                       }
                }
 
                #endregion

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to