From: Vladislav Vaintroub
Date: October 19 2009 8:34pm
Subject: bzr commit into connector-net-trunk branch (vvaintroub:786)
List-Archive: http://lists.mysql.com/commits/87374
Message-Id: <0KRS00FJG3TXUS60@fe-emea-10.sun.com>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="Boundary_(ID_tV+n6ufDbh1UqjX1yKaqOA)"
--Boundary_(ID_tV+n6ufDbh1UqjX1yKaqOA)
MIME-version: 1.0
Content-type: text/plain; CHARSET=US-ASCII
Content-transfer-encoding: 7BIT
Content-disposition: inline
#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
///
Embedded
}
+
+ public enum MySqlCertificateStoreLocation
+ {
+ ///
+ /// Do not use certificate store
+ ///
+ None,
+ ///
+ /// Use certificate store for the current user
+ ///
+ CurrentUser,
+ ///
+ /// User certificate store for the machine
+ ///
+ 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
+ ///
+ /// Retrieve client SSL certificates. Dependent on connection string
+ /// settings we use either file or store based certificates.
+ ///
+ 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);
--Boundary_(ID_tV+n6ufDbh1UqjX1yKaqOA)
MIME-version: 1.0
Content-type: text/bzr-bundle; CHARSET=US-ASCII;
name="bzr/vvaintroub@stripped"
Content-transfer-encoding: 7BIT
Content-disposition: inline;
filename="bzr/vvaintroub@stripped"
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: vvaintroub@stripped
# target_branch: file:///H:/connector_net/trunk/
# testament_sha1: 2c64657d4fe379734ddd4ad151eab2fa60e1ddbc
# timestamp: 2009-10-19 22:34:42 +0200
# source_branch: file:///H:/connector_net/6.1/
# base_revision_id: vvaintroub@stripped\
# u8r6mvnkqa5579mm
#
# Begin bundle
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
hQkHUXBv0A==
--Boundary_(ID_tV+n6ufDbh1UqjX1yKaqOA)--