List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:October 19 2009 3:49pm
Subject:bzr commit into connector-net-trunk branch (vvaintroub:786)
View as plain text  
#At file:///H:/connector_net/trunk/ based on revid:vvaintroub@stripped

  786 Vladislav Vaintroub	2009-10-19
      Implement support for client SSL certificates

    modified:
      MySql.Data/Provider/Source/MySqlConnectionStringBuilder.cs
      MySql.Data/Provider/Source/NativeDriver.cs
=== modified file 'MySql.Data/Provider/Source/MySqlConnectionStringBuilder.cs'
--- a/MySql.Data/Provider/Source/MySqlConnectionStringBuilder.cs	2009-10-09 21:44:54 +0000
+++ b/MySql.Data/Provider/Source/MySqlConnectionStringBuilder.cs	2009-10-19 15:49:09 +0000
@@ -28,6 +28,7 @@ using System.Text;
 using MySql.Data.MySqlClient.Properties;
 using System.Collections;
 using System.Globalization;
+using System.Security.Cryptography.X509Certificates;
 
 namespace MySql.Data.MySqlClient
 {
@@ -321,8 +322,75 @@ namespace MySql.Data.MySqlClient
             }
         }
 
+        [Category("Authentication")]
+        [DisplayName("Certificate File")]
+        [Description("Certificate file in PKCS#12 format (.pfx)")]
+        [DefaultValue(null)]
+        public string CertificateFile
+        {
+            get { return (string) values["Certificate File"];}
+            set
+            {
+                SetValue("Certificate File", value);
+            }
+        }
+
+        [Category("Authentication")]
+        [DisplayName("Certificate Password")]
+        [Description("Password for certificate file")]
+        [DefaultValue(null)]
+        public string CertificatePassword
+        {
+            get { return (string)values["Certificate Password"];}
+            set
+            {
+                SetValue("Certificate Password", value);
+            }
+        }
+
+        [Category("Authentication")]
+        [DisplayName("Certificate Store Location")]
+        [Description("Certificate Store Location (CurrentUser or LocalMachine)")]
+        [DefaultValue(null)]
+        public string CertificateStoreLocation
+        {
+            get { return (string)values["Certificate Store Location"]; }
+            set
+            {
+                if (value != null)
+                {
+                    try
+                    {
+                        Enum.Parse(typeof(StoreLocation), value);
+                    }
+                    catch (ArgumentException)
+                    {
+                        throw new InvalidOperationException(String.Format(
+                            Resources.InvalidConnectionStringValue, value, 
+                            "Certificate Store Location"));
+                    }
+                }
+                SetValue("Certificate Store Location", value);
+            }
+        }
+
+        [Category("Authentication")]
+        [DisplayName("Certificate Thumbprint")]
+        [Description("Certificate thumbprint. Can be used together with Certificate "+ 
+            "Store Location parameter to uniquely identify certificate to be used "+
+            "for SSL authentication.")]
+        [DefaultValue(null)]
+        public string CertificateThumbprint
+        {
+            get { return (string)values["Certificate Store Location"]; }
+            set
+            {
+                SetValue("Certificate Store Location", value);
+            }
+        }
         #endregion
 
+
         #region Other Properties
 
         /// <summary>

=== modified file 'MySql.Data/Provider/Source/NativeDriver.cs'
--- a/MySql.Data/Provider/Source/NativeDriver.cs	2009-10-09 21:44:54 +0000
+++ b/MySql.Data/Provider/Source/NativeDriver.cs	2009-10-19 15:49:09 +0000
@@ -259,12 +259,59 @@ namespace MySql.Data.MySqlClient
 
         #region SSL
 
+        /// <summary>
+        /// Retrieve client SSL certificates. Dependent on connection string 
+        /// settings we use either file or store based certificates.
+        /// </summary>
+        private X509CertificateCollection GetClientCertificates()
+        {
+            X509CertificateCollection certs = new X509CertificateCollection();
+
+            // Check for file-based certificate
+            if (Settings.CertificateFile != null)
+            {
+                X509Certificate2 clientCert = new X509Certificate2(Settings.CertificateFile,
+                    Settings.CertificatePassword);
+                certs.Add(clientCert);
+                return certs;
+            }
+
+            if (Settings.CertificateStoreLocation != null)
+                return certs;
+
+            // Check for store-based certificate
+            StoreLocation location = (StoreLocation)
+                  Enum.Parse(typeof(StoreLocation), Settings.CertificateStoreLocation);
+            X509Store store = new X509Store(StoreName.My, location);
+            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
+
+
+            if (Settings.CertificateThumbprint == null)
+            {
+                // Return all certificates from the store.
+                certs.AddRange(store.Certificates);
+                return certs;
+            }
+
+            // Find certificate with given thumbprint
+            certs.AddRange(store.Certificates.Find(X509FindType.FindByThumbprint,
+                      Settings.CertificateThumbprint, true));
+
+            if (certs.Count == 0)
+            {
+                throw new MySqlException("Certificate with Thumbprint " +
+                   Settings.CertificateThumbprint + " not found");
+            }
+            return certs;
+        }
+
+
         private void StartSSL()
         {
             RemoteCertificateValidationCallback sslValidateCallback =
                 new RemoteCertificateValidationCallback(ServerCheckValidation);
             SslStream ss = new SslStream(baseStream, true, sslValidateCallback, null);
-            X509CertificateCollection certs = new X509CertificateCollection();
+            X509CertificateCollection certs = GetClientCertificates();
             ss.AuthenticateAsClient(Settings.Server, certs, SslProtocols.Default, false);
             baseStream = ss;
             stream = new MySqlStream(ss, Encoding, false);


Attachment: [text/bzr-bundle] bzr/vvaintroub@mysql.com-20091019154909-m3r4vebd0uy6qrdf.bundle
Thread
bzr commit into connector-net-trunk branch (vvaintroub:786)Vladislav Vaintroub19 Oct