@@ -537,36 +537,66 @@ private async Task InitSslAsync(ProtocolCapabilities serverCapabilities, Connect
537
537
catch ( CryptographicException ex )
538
538
{
539
539
if ( ! File . Exists ( cs . CertificateFile ) )
540
- throw new MySqlException ( "Cannot find SSL Certificate File" , ex ) ;
541
- throw new MySqlException ( "Either the SSL Certificate Password is incorrect or the SSL Certificate File is invalid" , ex ) ;
540
+ throw new MySqlException ( "Cannot find Certificate File" , ex ) ;
541
+ throw new MySqlException ( "Either the Certificate Password is incorrect or the Certificate File is invalid" , ex ) ;
542
542
}
543
543
}
544
544
545
- Func < object , string , X509CertificateCollection , X509Certificate , string [ ] , X509Certificate > localCertificateCb =
546
- ( lcbSender , lcbTargetHost , lcbLocalCertificates , lcbRemoteCertificate , lcbAcceptableIssuers ) => lcbLocalCertificates [ 0 ] ;
545
+ X509Chain caCertificateChain = null ;
546
+ if ( cs . CACertificateFile != null )
547
+ {
548
+ try
549
+ {
550
+ var caCertificate = new X509Certificate2 ( cs . CACertificateFile ) ;
551
+ caCertificateChain = new X509Chain
552
+ {
553
+ ChainPolicy =
554
+ {
555
+ RevocationMode = X509RevocationMode . NoCheck ,
556
+ VerificationFlags = X509VerificationFlags . AllowUnknownCertificateAuthority
557
+ }
558
+ } ;
559
+ caCertificateChain . ChainPolicy . ExtraStore . Add ( caCertificate ) ;
560
+ }
561
+ catch ( CryptographicException ex )
562
+ {
563
+ if ( ! File . Exists ( cs . CACertificateFile ) )
564
+ throw new MySqlException ( "Cannot find CA Certificate File" , ex ) ;
565
+ throw new MySqlException ( "The CA Certificate File is invalid" , ex ) ;
566
+ }
567
+ }
568
+
569
+ X509Certificate LocalCertificateCb ( object lcbSender , string lcbTargetHost , X509CertificateCollection lcbLocalCertificates , X509Certificate lcbRemoteCertificate , string [ ] lcbAcceptableIssuers ) => lcbLocalCertificates [ 0 ] ;
570
+
571
+ bool RemoteCertificateCb ( object rcbSender , X509Certificate rcbCertificate , X509Chain rcbChain , SslPolicyErrors rcbPolicyErrors )
572
+ {
573
+ if ( cs . SslMode == MySqlSslMode . Preferred || cs . SslMode == MySqlSslMode . Required )
574
+ return true ;
547
575
548
- Func < object , X509Certificate , X509Chain , SslPolicyErrors , bool > remoteCertificateCb =
549
- ( rcbSender , rcbCertificate , rcbChain , rcbPolicyErrors ) =>
576
+ if ( ( rcbPolicyErrors & SslPolicyErrors . RemoteCertificateChainErrors ) != 0 && caCertificateChain != null )
550
577
{
551
- switch ( rcbPolicyErrors )
578
+ if ( caCertificateChain . Build ( ( X509Certificate2 ) rcbCertificate ) )
552
579
{
553
- case SslPolicyErrors . None :
554
- return true ;
555
- case SslPolicyErrors . RemoteCertificateNameMismatch :
556
- return cs . SslMode != MySqlSslMode . VerifyFull ;
557
- default :
558
- return cs . SslMode == MySqlSslMode . Preferred || cs . SslMode == MySqlSslMode . Required ;
580
+ var chainStatus = caCertificateChain . ChainStatus [ 0 ] . Status & ~ X509ChainStatusFlags . UntrustedRoot ;
581
+ if ( chainStatus == X509ChainStatusFlags . NoError )
582
+ rcbPolicyErrors &= ~ SslPolicyErrors . RemoteCertificateChainErrors ;
559
583
}
560
- } ;
584
+ }
585
+
586
+ if ( cs . SslMode == MySqlSslMode . VerifyCA )
587
+ rcbPolicyErrors &= ~ SslPolicyErrors . RemoteCertificateNameMismatch ;
588
+
589
+ return rcbPolicyErrors == SslPolicyErrors . None ;
590
+ }
561
591
562
592
SslStream sslStream ;
563
593
if ( clientCertificates == null )
564
594
sslStream = new SslStream ( m_networkStream , false ,
565
- new RemoteCertificateValidationCallback ( remoteCertificateCb ) ) ;
595
+ new RemoteCertificateValidationCallback ( ( Func < object , X509Certificate , X509Chain , SslPolicyErrors , bool > ) RemoteCertificateCb ) ) ;
566
596
else
567
597
sslStream = new SslStream ( m_networkStream , false ,
568
- new RemoteCertificateValidationCallback ( remoteCertificateCb ) ,
569
- new LocalCertificateSelectionCallback ( localCertificateCb ) ) ;
598
+ new RemoteCertificateValidationCallback ( ( Func < object , X509Certificate , X509Chain , SslPolicyErrors , bool > ) RemoteCertificateCb ) ,
599
+ new LocalCertificateSelectionCallback ( ( Func < object , string , X509CertificateCollection , X509Certificate , string [ ] , X509Certificate > ) LocalCertificateCb ) ) ;
570
600
571
601
// SslProtocols.Tls1.2 throws an exception in Windows, see https://github.com/mysql-net/MySqlConnector/pull/101
572
602
var sslProtocols = SslProtocols . Tls | SslProtocols . Tls11 ;
0 commit comments