List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:October 19 2009 8:34pm
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/MysqlDefs.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 20:34:41 +0000
@@ -321,6 +321,59 @@ 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 for client certificates")]
+        [DefaultValue(MySqlCertificateStoreLocation.None)]
+        public MySqlCertificateStoreLocation CertificateStoreLocation
+        {
+            get { return (MySqlCertificateStoreLocation)values["Certificate Store Location"]; }
+            set
+            {
+                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 Thumbprint"]; }
+            set
+            {
+                SetValue("Certificate Thumbprint", value);
+            }
+        }
         #endregion
 
         #region Other Properties

=== modified file 'MySql.Data/Provider/Source/MysqlDefs.cs'
--- a/MySql.Data/Provider/Source/MysqlDefs.cs	2009-10-09 21:44:54 +0000
+++ b/MySql.Data/Provider/Source/MysqlDefs.cs	2009-10-19 20:34:41 +0000
@@ -390,4 +390,20 @@ namespace MySql.Data.MySqlClient
         /// </summary>
         Embedded
     }
+
+    public enum MySqlCertificateStoreLocation
+    {
+        /// <summary>
+        /// Do not use certificate store
+        /// </summary>
+        None,
+        /// <summary>
+        /// Use certificate store for the current user
+        /// </summary>
+        CurrentUser,
+        /// <summary>
+        /// User certificate store for the machine
+        /// </summary>
+        LocalMachine
+    }
 }
\ No newline at end of file

=== 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 20:34:41 +0000
@@ -259,12 +259,61 @@ 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 == MySqlCertificateStoreLocation.None)
+                return certs;
+
+            StoreLocation location =
+                (Settings.CertificateStoreLocation == MySqlCertificateStoreLocation.CurrentUser) ?
+                StoreLocation.CurrentUser : StoreLocation.LocalMachine;
+
+            // Check for store-based certificate
+            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-20091019203441-qajt7250pjpxyxq6.bundle
Thread
bzr commit into connector-net-trunk branch (vvaintroub:786)Vladislav Vaintroub19 Oct