@@ -102,15 +102,6 @@ final class ProtocolNegotiators {
102102 private static final EnumSet <TlsServerCredentials .Feature > understoodServerTlsFeatures =
103103 EnumSet .of (
104104 TlsServerCredentials .Feature .MTLS , TlsServerCredentials .Feature .CUSTOM_MANAGERS );
105- private static Class <?> x509ExtendedTrustManagerClass ;
106-
107- static {
108- try {
109- x509ExtendedTrustManagerClass = Class .forName ("javax.net.ssl.X509ExtendedTrustManager" );
110- } catch (ClassNotFoundException e ) {
111- // Will disallow per-rpc authority override via call option.
112- }
113- }
114105
115106 private ProtocolNegotiators () {
116107 }
@@ -147,15 +138,8 @@ public static FromChannelCredentialsResult from(ChannelCredentials creds) {
147138 trustManagers = Arrays .asList (tmf .getTrustManagers ());
148139 }
149140 builder .trustManager (new FixedTrustManagerFactory (trustManagers ));
150- TrustManager x509ExtendedTrustManager = null ;
151- if (x509ExtendedTrustManagerClass != null ) {
152- for (TrustManager trustManager : trustManagers ) {
153- if (x509ExtendedTrustManagerClass .isInstance (trustManager )) {
154- x509ExtendedTrustManager = trustManager ;
155- break ;
156- }
157- }
158- }
141+ TrustManager x509ExtendedTrustManager =
142+ CertificateUtils .getX509ExtendedTrustManager (trustManagers );
159143 return FromChannelCredentialsResult .negotiator (tlsClientFactory (builder .build (),
160144 (X509TrustManager ) x509ExtendedTrustManager ));
161145 } catch (SSLException | GeneralSecurityException ex ) {
@@ -579,20 +563,22 @@ static final class ClientTlsProtocolNegotiator implements ProtocolNegotiator {
579563
580564 public ClientTlsProtocolNegotiator (SslContext sslContext ,
581565 ObjectPool <? extends Executor > executorPool , Optional <Runnable > handshakeCompleteRunnable ,
582- X509TrustManager x509ExtendedTrustManager ) {
566+ X509TrustManager x509ExtendedTrustManager , String sni ) {
583567 this .sslContext = Preconditions .checkNotNull (sslContext , "sslContext" );
584568 this .executorPool = executorPool ;
585569 if (this .executorPool != null ) {
586570 this .executor = this .executorPool .getObject ();
587571 }
588572 this .handshakeCompleteRunnable = handshakeCompleteRunnable ;
589573 this .x509ExtendedTrustManager = x509ExtendedTrustManager ;
574+ this .sni = sni ;
590575 }
591576
592577 private final SslContext sslContext ;
593578 private final ObjectPool <? extends Executor > executorPool ;
594579 private final Optional <Runnable > handshakeCompleteRunnable ;
595580 private final X509TrustManager x509ExtendedTrustManager ;
581+ private final String sni ;
596582 private Executor executor ;
597583
598584 @ Override
@@ -604,9 +590,17 @@ public AsciiString scheme() {
604590 public ChannelHandler newHandler (GrpcHttp2ConnectionHandler grpcHandler ) {
605591 ChannelHandler gnh = new GrpcNegotiationHandler (grpcHandler );
606592 ChannelLogger negotiationLogger = grpcHandler .getNegotiationLogger ();
607- ChannelHandler cth = new ClientTlsHandler (gnh , sslContext , grpcHandler .getAuthority (),
608- this .executor , negotiationLogger , handshakeCompleteRunnable , this ,
609- x509ExtendedTrustManager );
593+ String authority ;
594+ if ("" .equals (sni )) {
595+ authority = null ;
596+ } else if (sni != null ) {
597+ authority = sni ;
598+ } else {
599+ authority = grpcHandler .getAuthority ();
600+ }
601+ ChannelHandler cth = new ClientTlsHandler (gnh , sslContext ,
602+ authority , this .executor , negotiationLogger , handshakeCompleteRunnable , this ,
603+ x509ExtendedTrustManager );
610604 return new WaitUntilActiveHandler (cth , negotiationLogger );
611605 }
612606
@@ -630,28 +624,40 @@ static final class ClientTlsHandler extends ProtocolNegotiationHandler {
630624 private final int port ;
631625 private Executor executor ;
632626 private final Optional <Runnable > handshakeCompleteRunnable ;
633- private final X509TrustManager x509ExtendedTrustManager ;
627+ private final X509TrustManager x509TrustManager ;
634628 private SSLEngine sslEngine ;
635629
636630 ClientTlsHandler (ChannelHandler next , SslContext sslContext , String authority ,
637631 Executor executor , ChannelLogger negotiationLogger ,
638632 Optional <Runnable > handshakeCompleteRunnable ,
639633 ClientTlsProtocolNegotiator clientTlsProtocolNegotiator ,
640- X509TrustManager x509ExtendedTrustManager ) {
634+ X509TrustManager x509TrustManager ) {
641635 super (next , negotiationLogger );
642636 this .sslContext = Preconditions .checkNotNull (sslContext , "sslContext" );
643- HostPort hostPort = parseAuthority (authority );
644- this .host = hostPort .host ;
645- this .port = hostPort .port ;
637+ // TODO: For empty authority and fallback flag
638+ // GRPC_USE_CHANNEL_AUTHORITY_IF_NO_SNI_APPLICABLE present, we should parse authority
639+ // but prevent it from being used for SAN validation in the TrustManager.
640+ if (authority != null ) {
641+ HostPort hostPort = parseAuthority (authority );
642+ this .host = hostPort .host ;
643+ this .port = hostPort .port ;
644+ } else {
645+ this .host = null ;
646+ this .port = 0 ;
647+ }
646648 this .executor = executor ;
647649 this .handshakeCompleteRunnable = handshakeCompleteRunnable ;
648- this .x509ExtendedTrustManager = x509ExtendedTrustManager ;
650+ this .x509TrustManager = x509TrustManager ;
649651 }
650652
651653 @ Override
652654 @ IgnoreJRERequirement
653655 protected void handlerAdded0 (ChannelHandlerContext ctx ) {
654- sslEngine = sslContext .newEngine (ctx .alloc (), host , port );
656+ if (host != null ) {
657+ sslEngine = sslContext .newEngine (ctx .alloc (), host , port );
658+ } else {
659+ sslEngine = sslContext .newEngine (ctx .alloc ());
660+ }
655661 SSLParameters sslParams = sslEngine .getSSLParameters ();
656662 sslParams .setEndpointIdentificationAlgorithm ("HTTPS" );
657663 sslEngine .setSSLParameters (sslParams );
@@ -709,7 +715,7 @@ private void propagateTlsComplete(ChannelHandlerContext ctx, SSLSession session)
709715 .set (GrpcAttributes .ATTR_SECURITY_LEVEL , SecurityLevel .PRIVACY_AND_INTEGRITY )
710716 .set (Grpc .TRANSPORT_ATTR_SSL_SESSION , session )
711717 .set (GrpcAttributes .ATTR_AUTHORITY_VERIFIER , new X509AuthorityVerifier (
712- sslEngine , x509ExtendedTrustManager ))
718+ sslEngine , x509TrustManager ))
713719 .build ();
714720 replaceProtocolNegotiationEvent (existingPne .withAttributes (attrs ).withSecurity (security ));
715721 if (handshakeCompleteRunnable .isPresent ()) {
@@ -746,13 +752,14 @@ static HostPort parseAuthority(String authority) {
746752 * Returns a {@link ProtocolNegotiator} that ensures the pipeline is set up so that TLS will
747753 * be negotiated, the {@code handler} is added and writes to the {@link io.netty.channel.Channel}
748754 * may happen immediately, even before the TLS Handshake is complete.
755+ *
749756 * @param executorPool a dedicated {@link Executor} pool for time-consuming TLS tasks
750757 */
751758 public static ProtocolNegotiator tls (SslContext sslContext ,
752759 ObjectPool <? extends Executor > executorPool , Optional <Runnable > handshakeCompleteRunnable ,
753- X509TrustManager x509ExtendedTrustManager ) {
760+ X509TrustManager x509ExtendedTrustManager , String sni ) {
754761 return new ClientTlsProtocolNegotiator (sslContext , executorPool , handshakeCompleteRunnable ,
755- x509ExtendedTrustManager );
762+ x509ExtendedTrustManager , sni );
756763 }
757764
758765 /**
@@ -762,7 +769,7 @@ public static ProtocolNegotiator tls(SslContext sslContext,
762769 */
763770 public static ProtocolNegotiator tls (SslContext sslContext ,
764771 X509TrustManager x509ExtendedTrustManager ) {
765- return tls (sslContext , null , Optional .absent (), x509ExtendedTrustManager );
772+ return tls (sslContext , null , Optional .absent (), x509ExtendedTrustManager , null );
766773 }
767774
768775 public static ProtocolNegotiator .ClientFactory tlsClientFactory (SslContext sslContext ,
0 commit comments