55using Grpc . Core ;
66using Grpc . Net . Client ;
77using Microsoft . Extensions . Logging ;
8- using Org . BouncyCastle . Security ;
98
109namespace Ydb . Sdk . Pool ;
1110
@@ -79,14 +78,14 @@ public interface IChannelFactory<out T> where T : ChannelBase, IDisposable
7978internal class GrpcChannelFactory : IChannelFactory < GrpcChannel >
8079{
8180 private readonly ILoggerFactory _loggerFactory ;
82- private readonly X509Certificate ? _x509Certificate ;
8381 private readonly ILogger < GrpcChannelFactory > _logger ;
82+ private readonly X509Certificate2Collection _x509Certificate2Collection ;
8483
8584 internal GrpcChannelFactory ( ILoggerFactory loggerFactory , DriverConfig config )
8685 {
8786 _loggerFactory = loggerFactory ;
88- _x509Certificate = config . CustomServerCertificate ;
8987 _logger = loggerFactory . CreateLogger < GrpcChannelFactory > ( ) ;
88+ _x509Certificate2Collection = config . CustomServerCertificates ;
9089 }
9190
9291 public GrpcChannel CreateChannel ( string endpoint )
@@ -98,47 +97,48 @@ public GrpcChannel CreateChannel(string endpoint)
9897 LoggerFactory = _loggerFactory
9998 } ;
10099
101- if ( _x509Certificate == null )
100+ var httpHandler = new SocketsHttpHandler ( ) ;
101+
102+ // https://github.com/grpc/grpc-dotnet/issues/2312#issuecomment-1790661801
103+ httpHandler . Properties [ "__GrpcLoadBalancingDisabled" ] = true ;
104+
105+ channelOptions . HttpHandler = httpHandler ;
106+ channelOptions . DisposeHttpClient = true ;
107+
108+ if ( _x509Certificate2Collection . Count == 0 )
102109 {
103110 return GrpcChannel . ForAddress ( endpoint , channelOptions ) ;
104111 }
105112
106- var httpHandler = new SocketsHttpHandler ( ) ;
107-
108- var customCertificate = DotNetUtilities . FromX509Certificate ( _x509Certificate ) ;
109-
110- httpHandler . SslOptions . RemoteCertificateValidationCallback =
111- ( _ , certificate , _ , sslPolicyErrors ) =>
113+ httpHandler . SslOptions . RemoteCertificateValidationCallback +=
114+ ( _ , certificate , chain , sslPolicyErrors ) =>
112115 {
113116 if ( sslPolicyErrors == SslPolicyErrors . None )
114117 {
115118 return true ;
116119 }
117120
118- if ( certificate is null )
121+ if ( certificate is null || chain is null )
119122 {
120123 return false ;
121124 }
122125
123126 try
124127 {
125- var cert = DotNetUtilities . FromX509Certificate ( certificate ) ;
126- cert . Verify ( customCertificate . GetPublicKey ( ) ) ;
128+ chain . ChainPolicy . VerificationFlags = X509VerificationFlags . AllowUnknownCertificateAuthority ;
129+ chain . ChainPolicy . ExtraStore . AddRange ( _x509Certificate2Collection ) ;
130+
131+ return chain . Build ( new X509Certificate2 ( certificate ) ) && chain . ChainElements . Any ( chainElement =>
132+ _x509Certificate2Collection . Any ( trustedCert =>
133+ chainElement . Certificate . Thumbprint == trustedCert . Thumbprint ) ) ;
127134 }
128135 catch ( Exception e )
129136 {
130137 _logger . LogError ( e , "Failed to verify remote certificate!" ) ;
131138
132139 return false ;
133140 }
134-
135- return true ;
136141 } ;
137- // https://github.com/grpc/grpc-dotnet/issues/2312#issuecomment-1790661801
138- httpHandler . Properties [ "__GrpcLoadBalancingDisabled" ] = true ;
139-
140- channelOptions . HttpHandler = httpHandler ;
141- channelOptions . DisposeHttpClient = true ;
142142
143143 return GrpcChannel . ForAddress ( endpoint , channelOptions ) ;
144144 }
0 commit comments