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