#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 Vaintroub | 19 Oct |