Merge pull request #2092 from kasthack/system-web-stuff-import
[mono.git] / mcs / class / System / System.Net / HttpConnection.cs
index e90cc39e27eb783243ad0dfa92977eccaea98847..263bfcd65f78ebb748764e7e9718ae6a2a65b7c4 100644 (file)
@@ -2,9 +2,10 @@
 // System.Net.HttpConnection
 //
 // Author:
-//     Gonzalo Paniagua Javier (gonzalo@novell.com)
+//     Gonzalo Paniagua Javier (gonzalo.mono@gmail.com)
 //
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
+// Copyright (c) 2005-2009 Novell, Inc. (http://www.novell.com)
+// Copyright (c) 2012 Xamarin, Inc. (http://xamarin.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 
 #if SECURITY_DEP
 
+#if MONOTOUCH || MONODROID
+using Mono.Security.Protocol.Tls;
+#else
+extern alias MonoSecurity;
+using MonoSecurity::Mono.Security.Protocol.Tls;
+#endif
+
 using System.IO;
 using System.Net.Sockets;
 using System.Reflection;
@@ -35,7 +43,6 @@ using System.Text;
 using System.Threading;
 using System.Security.Cryptography;
 using System.Security.Cryptography.X509Certificates;
-using Mono.Security.Protocol.Tls;
 
 namespace System.Net {
        sealed class HttpConnection
@@ -61,6 +68,8 @@ namespace System.Net {
                Timer timer;
                IPEndPoint local_ep;
                HttpListener last_listener;
+               int [] client_cert_errors;
+               X509Certificate2 client_cert;
 
                public HttpConnection (Socket sock, EndPointListener epl, bool secure, X509Certificate2 cert, AsymmetricAlgorithm key)
                {
@@ -71,14 +80,35 @@ namespace System.Net {
                        if (secure == false) {
                                stream = new NetworkStream (sock, false);
                        } else {
-                               SslServerStream ssl_stream = new SslServerStream (new NetworkStream (sock, false), cert, false, false);
+                               SslServerStream ssl_stream = new SslServerStream (new NetworkStream (sock, false), cert, false, true, false);
                                ssl_stream.PrivateKeyCertSelectionDelegate += OnPVKSelection;
+                               ssl_stream.ClientCertValidationDelegate += OnClientCertificateValidation;
                                stream = ssl_stream;
                        }
                        timer = new Timer (OnTimeout, null, Timeout.Infinite, Timeout.Infinite);
                        Init ();
                }
 
+               internal int [] ClientCertificateErrors {
+                       get { return client_cert_errors; }
+               }
+
+               internal X509Certificate2 ClientCertificate {
+                       get { return client_cert; }
+               }
+
+               bool OnClientCertificateValidation (X509Certificate certificate, int[] errors)
+               {
+                       if (certificate == null)
+                               return true;
+                       X509Certificate2 cert = certificate as X509Certificate2;
+                       if (cert == null)
+                               cert = new X509Certificate2 (certificate.GetRawCertData ());
+                       client_cert = cert;
+                       client_cert_errors = errors;
+                       return true;
+               }
+
                AsymmetricAlgorithm OnPVKSelection (X509Certificate certificate, string targetHost)
                {
                        return key;
@@ -415,7 +445,9 @@ namespace System.Net {
                {
                        if (sock != null) {
                                Stream st = GetResponseStream ();
-                               st.Close ();
+                               if (st != null)
+                                       st.Close ();
+
                                o_stream = null;
                        }