MySQL.Data/src/common/Ssl.cs | 45 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/MySQL.Data/src/common/Ssl.cs b/MySQL.Data/src/common/Ssl.cs
index 60e053f9..a0c0a1b0 100644
--- a/MySQL.Data/src/common/Ssl.cs
+++ b/MySQL.Data/src/common/Ssl.cs
@@ -38,6 +38,7 @@ using System.Collections.Generic;
using System.IO;
using System.Net.Security;
using System.Security.Authentication;
+using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
@@ -145,6 +146,45 @@ namespace MySql.Data.Common
return certs;
}
+ private X509CertificateCollection GetPEMClientCertificates()
+ {
+ X509CertificateCollection certs = new X509CertificateCollection();
+#if !NETSTANDARD1_6
+ if (_settings.SslCert != null && _settings.SslKey != null)
+ {
+ var pemcert = ReadSslCertificate(_settings.SslCert);
+ var pemkey = ReadKey(_settings.SslKey);
+
+ var pemkeyparams = (Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)pemkey.Private;
+ var keyparams = new RSAParameters();
+ keyparams.Modulus = pemkeyparams.Modulus.ToByteArrayUnsigned();
+ keyparams.P = pemkeyparams.P.ToByteArrayUnsigned();
+ keyparams.Q = pemkeyparams.Q.ToByteArrayUnsigned();
+ keyparams.DP = pemkeyparams.DP.ToByteArrayUnsigned();
+ keyparams.DQ = pemkeyparams.DQ.ToByteArrayUnsigned();
+ keyparams.InverseQ = pemkeyparams.QInv.ToByteArrayUnsigned();
+ keyparams.D = pemkeyparams.Exponent.ToByteArrayUnsigned();
+ keyparams.Exponent = pemkeyparams.PublicExponent.ToByteArrayUnsigned();
+
+ var key = new RSACryptoServiceProvider(new CspParameters
+ {
+ // SslStream isn't happy on windows if a name isn't set
+ KeyContainerName = "test",
+ });
+ key.ImportParameters(keyparams);
+
+ var cert = new X509Certificate2(pemcert.GetEncoded());
+#if NETCOREAPP2_0
+ cert = cert.CopyWithPrivateKey(key);
+#else
+ cert.PrivateKey = key;
+#endif
+ certs.Add(cert);
+ }
+#endif
+ return certs;
+ }
+
///
/// Initiates the SSL connection.
///
@@ -167,7 +207,7 @@ namespace MySql.Data.Common
new RemoteCertificateValidationCallback(ServerCheckValidation);
SslStream ss = new SslStream(baseStream, false, sslValidateCallback, null);
X509CertificateCollection certs = _treatCertificatesAsPemFormat
- ? new X509CertificateCollection()
+ ? GetPEMClientCertificates()
: GetPFXClientCertificates();
string connectionId = connectionString.GetHashCode().ToString();
@@ -489,7 +529,8 @@ namespace MySql.Data.Common
/// The server certificate.
private void VerifyIssuer(Org.BouncyCastle.X509.X509Certificate CACertificate, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate)
{
- if (CACertificate.IssuerDN.ToString() != serverCertificate.Issuer)
+ var cacert = new System.Security.Cryptography.X509Certificates.X509Certificate(CACertificate.GetEncoded());
+ if (cacert.Issuer != serverCertificate.Issuer)
throw new MySqlException(Resources.SslConnectionError, new Exception(Resources.SslCertificateCAMismatch));
}