4747import io .grpc .internal .GrpcUtil ;
4848import io .grpc .internal .NoopSslSession ;
4949import io .grpc .internal .ObjectPool ;
50+ import io .netty .channel .Channel ;
5051import io .netty .channel .ChannelDuplexHandler ;
5152import io .netty .channel .ChannelFutureListener ;
5253import io .netty .channel .ChannelHandler ;
6162import io .netty .handler .codec .http2 .Http2ClientUpgradeCodec ;
6263import io .netty .handler .proxy .HttpProxyHandler ;
6364import io .netty .handler .proxy .ProxyConnectionEvent ;
65+ import io .netty .handler .ssl .ClientAuth ;
6466import io .netty .handler .ssl .OpenSsl ;
6567import io .netty .handler .ssl .OpenSslEngine ;
6668import io .netty .handler .ssl .SslContext ;
7072import io .netty .handler .ssl .SslProvider ;
7173import io .netty .util .AsciiString ;
7274import java .io .ByteArrayInputStream ;
75+ import java .lang .reflect .InvocationTargetException ;
76+ import java .lang .reflect .Method ;
7377import java .net .SocketAddress ;
7478import java .net .URI ;
7579import java .nio .channels .ClosedChannelException ;
97101import javax .net .ssl .SSLSession ;
98102import javax .net .ssl .TrustManager ;
99103import javax .net .ssl .TrustManagerFactory ;
100- import javax .net .ssl .X509ExtendedTrustManager ;
104+ import javax .net .ssl .X509TrustManager ;
101105import org .codehaus .mojo .animal_sniffer .IgnoreJRERequirement ;
102106
103107/**
@@ -111,7 +115,16 @@ final class ProtocolNegotiators {
111115 private static final EnumSet <TlsServerCredentials .Feature > understoodServerTlsFeatures =
112116 EnumSet .of (
113117 TlsServerCredentials .Feature .MTLS , TlsServerCredentials .Feature .CUSTOM_MANAGERS );
114-
118+ private static Class <?> x509ExtendedTrustManagerClass ;
119+ private static final Logger logger = Logger .getLogger (ProtocolNegotiators .class .getName ());
120+ static {
121+ try {
122+ x509ExtendedTrustManagerClass = Class .forName ("javax.net.ssl.X509ExtendedTrustManager" );
123+ } catch (ClassNotFoundException e ) {
124+ logger .info ("javax.net.ssl.X509ExtendedTrustManager is not available. Authority override via call options" +
125+ "via call options will not be allowed." );
126+ }
127+ }
115128
116129 private ProtocolNegotiators () {
117130 }
@@ -149,14 +162,16 @@ public static FromChannelCredentialsResult from(ChannelCredentials creds) {
149162 }
150163 builder .trustManager (new FixedTrustManagerFactory (trustManagers ));
151164 TrustManager x509ExtendedTrustManager = null ;
152- for (TrustManager trustManager : trustManagers ) {
153- if (trustManager instanceof X509ExtendedTrustManager ) {
154- x509ExtendedTrustManager = trustManager ;
155- break ;
165+ if (x509ExtendedTrustManagerClass != null ) {
166+ for (TrustManager trustManager : trustManagers ) {
167+ if (x509ExtendedTrustManagerClass .isInstance (trustManager )) {
168+ x509ExtendedTrustManager = trustManager ;
169+ break ;
170+ }
156171 }
157172 }
158173 return FromChannelCredentialsResult .negotiator (tlsClientFactory (builder .build (),
159- (X509ExtendedTrustManager ) x509ExtendedTrustManager ));
174+ (X509TrustManager ) x509ExtendedTrustManager ));
160175 } catch (SSLException | GeneralSecurityException ex ) {
161176 log .log (Level .FINE , "Exception building SslContext" , ex );
162177 return FromChannelCredentialsResult .error (
@@ -222,15 +237,15 @@ public static FromServerCredentialsResult from(ServerCredentials creds) {
222237 } // else use system default
223238 switch (tlsCreds .getClientAuth ()) {
224239 case OPTIONAL :
225- builder .clientAuth (io . netty . handler . ssl . ClientAuth .OPTIONAL );
240+ builder .clientAuth (ClientAuth .OPTIONAL );
226241 break ;
227242
228243 case REQUIRE :
229- builder .clientAuth (io . netty . handler . ssl . ClientAuth .REQUIRE );
244+ builder .clientAuth (ClientAuth .REQUIRE );
230245 break ;
231246
232247 case NONE :
233- builder .clientAuth (io . netty . handler . ssl . ClientAuth .NONE );
248+ builder .clientAuth (ClientAuth .NONE );
234249 break ;
235250
236251 default :
@@ -286,17 +301,17 @@ private FromChannelCredentialsResult(ProtocolNegotiator.ClientFactory negotiator
286301
287302 public static FromChannelCredentialsResult error (String error ) {
288303 return new FromChannelCredentialsResult (
289- null , null , Preconditions . checkNotNull (error , "error" ));
304+ null , null , checkNotNull (error , "error" ));
290305 }
291306
292307 public static FromChannelCredentialsResult negotiator (
293308 ProtocolNegotiator .ClientFactory factory ) {
294309 return new FromChannelCredentialsResult (
295- Preconditions . checkNotNull (factory , "factory" ), null , null );
310+ checkNotNull (factory , "factory" ), null , null );
296311 }
297312
298313 public FromChannelCredentialsResult withCallCredentials (CallCredentials callCreds ) {
299- Preconditions . checkNotNull (callCreds , "callCreds" );
314+ checkNotNull (callCreds , "callCreds" );
300315 if (error != null ) {
301316 return this ;
302317 }
@@ -317,11 +332,11 @@ private FromServerCredentialsResult(ProtocolNegotiator.ServerFactory negotiator,
317332 }
318333
319334 public static FromServerCredentialsResult error (String error ) {
320- return new FromServerCredentialsResult (null , Preconditions . checkNotNull (error , "error" ));
335+ return new FromServerCredentialsResult (null , checkNotNull (error , "error" ));
321336 }
322337
323338 public static FromServerCredentialsResult negotiator (ProtocolNegotiator .ServerFactory factory ) {
324- return new FromServerCredentialsResult (Preconditions . checkNotNull (factory , "factory" ), null );
339+ return new FromServerCredentialsResult (checkNotNull (factory , "factory" ), null );
325340 }
326341 }
327342
@@ -336,7 +351,7 @@ private static final class FixedProtocolNegotiatorServerFactory
336351
337352 public FixedProtocolNegotiatorServerFactory (ProtocolNegotiator protocolNegotiator ) {
338353 this .protocolNegotiator =
339- Preconditions . checkNotNull (protocolNegotiator , "protocolNegotiator" );
354+ checkNotNull (protocolNegotiator , "protocolNegotiator" );
340355 }
341356
342357 @ Override
@@ -378,7 +393,7 @@ static final class TlsProtocolNegotiatorServerFactory
378393 private final SslContext sslContext ;
379394
380395 public TlsProtocolNegotiatorServerFactory (SslContext sslContext ) {
381- this .sslContext = Preconditions . checkNotNull (sslContext , "sslContext" );
396+ this .sslContext = checkNotNull (sslContext , "sslContext" );
382397 }
383398
384399 @ Override
@@ -393,7 +408,7 @@ public ProtocolNegotiator newNegotiator(ObjectPool<? extends Executor> offloadEx
393408 */
394409 public static ProtocolNegotiator serverTls (final SslContext sslContext ,
395410 final ObjectPool <? extends Executor > executorPool ) {
396- Preconditions . checkNotNull (sslContext , "sslContext" );
411+ checkNotNull (sslContext , "sslContext" );
397412 final Executor executor ;
398413 if (executorPool != null ) {
399414 // The handlers here can out-live the {@link ProtocolNegotiator}.
@@ -575,6 +590,20 @@ protected void userEventTriggered0(ChannelHandlerContext ctx, Object evt) throws
575590 }
576591
577592 static final class ClientTlsProtocolNegotiator implements ProtocolNegotiator {
593+ private static final Logger logger = Logger .getLogger (ClientTlsProtocolNegotiator .class .getName ());
594+ private static Method checkServerTrustedMethod ;
595+ static {
596+ try {
597+ Class <?> x509ExtendedTrustManagerClass = Class .forName ("javax.net.ssl.X509ExtendedTrustManager" );
598+ checkServerTrustedMethod = x509ExtendedTrustManagerClass .getMethod ("checkServerTrusted" ,
599+ X509Certificate [].class , String .class , SSLEngine .class );
600+ } catch (ClassNotFoundException e ) {
601+ } catch (NoSuchMethodException e ) {
602+ // Should never happen.
603+ logger .warning ("Method checkServerTrusted not found in javax.net.ssl.X509ExtendedTrustManager" );
604+ }
605+ }
606+
578607 @ GuardedBy ("this" )
579608 private final LinkedHashMap <String , Status > peerVerificationResults =
580609 new LinkedHashMap <String , Status >() {
@@ -587,7 +616,7 @@ protected boolean removeEldestEntry(Map.Entry<String, Status> eldest) {
587616
588617 public ClientTlsProtocolNegotiator (SslContext sslContext ,
589618 ObjectPool <? extends Executor > executorPool , Optional <Runnable > handshakeCompleteRunnable ,
590- X509ExtendedTrustManager x509ExtendedTrustManager ) {
619+ X509TrustManager x509ExtendedTrustManager ) {
591620 this .sslContext = checkNotNull (sslContext , "sslContext" );
592621 this .executorPool = executorPool ;
593622 if (this .executorPool != null ) {
@@ -600,7 +629,7 @@ public ClientTlsProtocolNegotiator(SslContext sslContext,
600629 private final SslContext sslContext ;
601630 private final ObjectPool <? extends Executor > executorPool ;
602631 private final Optional <Runnable > handshakeCompleteRunnable ;
603- private final X509ExtendedTrustManager x509ExtendedTrustManager ;
632+ private final X509TrustManager x509ExtendedTrustManager ;
604633 private Executor executor ;
605634
606635 @ Override
@@ -640,7 +669,7 @@ public synchronized Status verifyAuthority(@Nonnull String authority) {
640669 try {
641670 verifyAuthorityAllowedForPeerCert (authority );
642671 peerVerificationStatus = Status .OK ;
643- } catch (SSLPeerUnverifiedException | CertificateException e ) {
672+ } catch (SSLPeerUnverifiedException | CertificateException | InvocationTargetException | IllegalAccessException e ) {
644673 peerVerificationStatus = Status .UNAVAILABLE .withDescription (
645674 String .format ("Peer hostname verification during rpc failed for authority '%s'" ,
646675 authority )).withCause (e );
@@ -655,7 +684,11 @@ public void setSslEngine(SSLEngine sslEngine) {
655684 }
656685
657686 private void verifyAuthorityAllowedForPeerCert (String authority )
658- throws SSLPeerUnverifiedException , CertificateException {
687+ throws SSLPeerUnverifiedException , CertificateException , InvocationTargetException ,
688+ IllegalAccessException {
689+ if (checkServerTrustedMethod == null ) {
690+ throw new IllegalStateException ("Method checkServerTrusted not found in javax.net.ssl.X509ExtendedTrustManager" );
691+ }
659692 SSLEngine sslEngineWrapper = new SslEngineWrapper (sslEngine , authority );
660693 // The typecasting of Certificate to X509Certificate should work because this method will only
661694 // be called when using TLS and thus X509.
@@ -664,7 +697,7 @@ private void verifyAuthorityAllowedForPeerCert(String authority)
664697 for (int i = 0 ; i < peerCertificates .length ; i ++) {
665698 x509PeerCertificates [i ] = (X509Certificate ) peerCertificates [i ];
666699 }
667- x509ExtendedTrustManager . checkServerTrusted ( x509PeerCertificates , "RSA" , sslEngineWrapper );
700+ checkServerTrustedMethod . invoke ( x509ExtendedTrustManager , x509PeerCertificates , "RSA" , sslEngineWrapper );
668701 }
669702
670703 @ VisibleForTesting
@@ -768,7 +801,7 @@ private void propagateTlsComplete(ChannelHandlerContext ctx, SSLSession session)
768801
769802 @ VisibleForTesting
770803 static HostPort parseAuthority (String authority ) {
771- URI uri = GrpcUtil .authorityToUri (Preconditions . checkNotNull (authority , "authority" ));
804+ URI uri = GrpcUtil .authorityToUri (checkNotNull (authority , "authority" ));
772805 String host ;
773806 int port ;
774807 if (uri .getHost () != null ) {
@@ -791,42 +824,42 @@ static HostPort parseAuthority(String authority) {
791824
792825 /**
793826 * Returns a {@link ProtocolNegotiator} that ensures the pipeline is set up so that TLS will
794- * be negotiated, the {@code handler} is added and writes to the {@link io.netty.channel. Channel}
827+ * be negotiated, the {@code handler} is added and writes to the {@link Channel}
795828 * may happen immediately, even before the TLS Handshake is complete.
796829 * @param executorPool a dedicated {@link Executor} pool for time-consuming TLS tasks
797830 */
798831 public static ProtocolNegotiator tls (SslContext sslContext ,
799832 ObjectPool <? extends Executor > executorPool , Optional <Runnable > handshakeCompleteRunnable ,
800- X509ExtendedTrustManager x509ExtendedTrustManager ) {
833+ X509TrustManager x509ExtendedTrustManager ) {
801834 return new ClientTlsProtocolNegotiator (sslContext , executorPool , handshakeCompleteRunnable ,
802835 x509ExtendedTrustManager );
803836 }
804837
805838 /**
806839 * Returns a {@link ProtocolNegotiator} that ensures the pipeline is set up so that TLS will
807- * be negotiated, the {@code handler} is added and writes to the {@link io.netty.channel. Channel}
840+ * be negotiated, the {@code handler} is added and writes to the {@link Channel}
808841 * may happen immediately, even before the TLS Handshake is complete.
809842 */
810843 public static ProtocolNegotiator tls (SslContext sslContext ,
811- X509ExtendedTrustManager x509ExtendedTrustManager ) {
844+ X509TrustManager x509ExtendedTrustManager ) {
812845 return tls (sslContext , null , Optional .absent (),
813846 x509ExtendedTrustManager );
814847 }
815848
816849 public static ProtocolNegotiator .ClientFactory tlsClientFactory (SslContext sslContext ,
817- X509ExtendedTrustManager x509ExtendedTrustManager ) {
850+ X509TrustManager x509ExtendedTrustManager ) {
818851 return new TlsProtocolNegotiatorClientFactory (sslContext , x509ExtendedTrustManager );
819852 }
820853
821854 @ VisibleForTesting
822855 static final class TlsProtocolNegotiatorClientFactory
823856 implements ProtocolNegotiator .ClientFactory {
824857 private final SslContext sslContext ;
825- private final X509ExtendedTrustManager x509ExtendedTrustManager ;
858+ private final X509TrustManager x509ExtendedTrustManager ;
826859
827860 public TlsProtocolNegotiatorClientFactory (SslContext sslContext ,
828- X509ExtendedTrustManager x509ExtendedTrustManager ) {
829- this .sslContext = Preconditions . checkNotNull (sslContext , "sslContext" );
861+ X509TrustManager x509ExtendedTrustManager ) {
862+ this .sslContext = checkNotNull (sslContext , "sslContext" );
830863 this .x509ExtendedTrustManager = x509ExtendedTrustManager ;
831864 }
832865
@@ -951,7 +984,7 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc
951984
952985 /**
953986 * Returns a {@link ChannelHandler} that ensures that the {@code handler} is added to the
954- * pipeline writes to the {@link io.netty.channel. Channel} may happen immediately, even before it
987+ * pipeline writes to the {@link Channel} may happen immediately, even before it
955988 * is active.
956989 */
957990 public static ProtocolNegotiator plaintext () {
0 commit comments