7272import io .grpc .okhttp .internal .framed .Variant ;
7373import io .grpc .okhttp .internal .proxy .HttpUrl ;
7474import io .grpc .okhttp .internal .proxy .Request ;
75- import io .grpc .util .CertificateUtils ;
7675import io .perfmark .PerfMark ;
77- import java .io .ByteArrayInputStream ;
7876import java .io .EOFException ;
7977import java .io .IOException ;
8078import java .net .InetSocketAddress ;
8684import java .security .cert .Certificate ;
8785import java .security .cert .CertificateException ;
8886import java .security .cert .X509Certificate ;
89- import java .util .Arrays ;
90- import java .util .Collections ;
91- import java .util .Deque ;
92- import java .util .EnumMap ;
93- import java .util .HashMap ;
94- import java .util .Iterator ;
95- import java .util .LinkedList ;
96- import java .util .List ;
97- import java .util .Locale ;
98- import java .util .Map ;
99- import java .util .Optional ;
100- import java .util .Random ;
87+ import java .util .*;
10188import java .util .concurrent .BrokenBarrierException ;
102- import java .util .concurrent .ConcurrentHashMap ;
10389import java .util .concurrent .CountDownLatch ;
10490import java .util .concurrent .CyclicBarrier ;
10591import java .util .concurrent .Executor ;
@@ -231,8 +217,13 @@ private static Map<ErrorCode, Status> buildErrorCodeToStatusMap() {
231217 private final boolean useGetForSafeMethods ;
232218 @ GuardedBy ("lock" )
233219 private final TransportTracer transportTracer ;
234- private final ConcurrentHashMap <String , Boolean > authorityVerificationStatuses =
235- new ConcurrentHashMap <>();
220+ private final LinkedHashMap <String , Status > peerVerificationResults =
221+ new LinkedHashMap <String , Status >() {
222+ @ Override
223+ protected boolean removeEldestEntry (Map .Entry <String , Status > eldest ) {
224+ return size () > 100 ;
225+ }
226+ };
236227
237228 @ GuardedBy ("lock" )
238229 private final InUseStateAggregator <OkHttpClientStream > inUseState =
@@ -432,45 +423,51 @@ public ClientStream newStream(
432423 StatsTraceContext .newClientContext (tracers , getAttributes (), headers );
433424 if (socket instanceof SSLSocket && callOptions .getAuthority () != null
434425 && channelCredentials != null && channelCredentials instanceof TlsChannelCredentials ) {
435- if (hostnameVerifier != null ) {
436- hostnameVerifier .verify (callOptions .getAuthority (), ((SSLSocket ) socket ).getSession ());
437- }
438- boolean isAuthorityValid ;
439- if (authorityVerificationStatuses .containsKey (callOptions .getAuthority ())) {
440- isAuthorityValid = authorityVerificationStatuses .get (callOptions .getAuthority ());
426+ Status peerVerificationStatus ;
427+ if (peerVerificationResults .containsKey (callOptions .getAuthority ())) {
428+ peerVerificationStatus = peerVerificationResults .get (callOptions .getAuthority ());
441429 } else {
442- Optional <TrustManager > x509ExtendedTrustManager ;
443- try {
444- x509ExtendedTrustManager = getX509ExtendedTrustManager (
445- (TlsChannelCredentials ) channelCredentials );
446- } catch (GeneralSecurityException e ) {
447- log .log (Level .FINE , "Failure getting X509ExtendedTrustManager from TlsCredentials" , e );
448- return new FailingClientStream (Status .INTERNAL .withDescription (
449- "Failure getting X509ExtendedTrustManager from TlsCredentials" ),
450- tracers );
451- }
452- if (!x509ExtendedTrustManager .isPresent ()) {
453- return new FailingClientStream (Status .INTERNAL .withDescription (
454- "Can't allow authority override in rpc when X509ExtendedTrustManager is not "
455- + "available" ), tracers );
456- }
457- try {
458- Certificate [] peerCertificates = sslSession .getPeerCertificates ();
459- X509Certificate [] x509PeerCertificates = new X509Certificate [peerCertificates .length ];
460- for (int i = 0 ; i < peerCertificates .length ; i ++) {
461- x509PeerCertificates [i ] = (X509Certificate ) peerCertificates [i ];
430+ if (hostnameVerifier != null &&
431+ !hostnameVerifier .verify (callOptions .getAuthority (),
432+ ((SSLSocket ) socket ).getSession ())) {
433+ peerVerificationStatus = Status .UNAVAILABLE .withDescription (
434+ String .format ("HostNameVerifier verification failed for authority '%s'." ,
435+ callOptions .getAuthority ()));
436+ } else {
437+ Optional <TrustManager > x509ExtendedTrustManager ;
438+ try {
439+ x509ExtendedTrustManager = getX509ExtendedTrustManager (
440+ (TlsChannelCredentials ) channelCredentials );
441+ } catch (GeneralSecurityException e ) {
442+ return new FailingClientStream (Status .UNAVAILABLE .withDescription (
443+ "Failure getting X509ExtendedTrustManager from TlsCredentials" ).withCause (e ),
444+ tracers );
445+ }
446+ if (!x509ExtendedTrustManager .isPresent ()) {
447+ return new FailingClientStream (Status .UNAVAILABLE .withDescription (
448+ "Can't allow authority override in rpc when X509ExtendedTrustManager is not "
449+ + "available" ), tracers );
450+ }
451+ try {
452+ Certificate [] peerCertificates = sslSession .getPeerCertificates ();
453+ X509Certificate [] x509PeerCertificates = new X509Certificate [peerCertificates .length ];
454+ for (int i = 0 ; i < peerCertificates .length ; i ++) {
455+ x509PeerCertificates [i ] = (X509Certificate ) peerCertificates [i ];
456+ }
457+ ((X509ExtendedTrustManager ) x509ExtendedTrustManager .get ()).checkServerTrusted (
458+ x509PeerCertificates , "RSA" ,
459+ new SslSocketWrapper ((SSLSocket ) socket , callOptions .getAuthority ()));
460+ peerVerificationStatus = Status .OK ;
461+ } catch (SSLPeerUnverifiedException | CertificateException e ) {
462+ peerVerificationStatus = Status .INTERNAL .withDescription (
463+ String .format ("Failure in verifying authority '%s' against peer" ,
464+ callOptions .getAuthority ())).withCause (e );
462465 }
463- ((X509ExtendedTrustManager ) x509ExtendedTrustManager .get ()).checkServerTrusted (
464- x509PeerCertificates , "RSA" ,
465- new SslSocketWrapper ((SSLSocket ) socket , callOptions .getAuthority ()));
466- authorityVerificationStatuses .put (callOptions .getAuthority (), true );
467- } catch (SSLPeerUnverifiedException | CertificateException e ) {
468- log .log (Level .FINE , "Failure in verifying authority against peer" , e );
469- authorityVerificationStatuses .put (callOptions .getAuthority (), false );
470- return new FailingClientStream (Status .INTERNAL .withDescription (
471- "Failure in verifying authority against peer" ),
472- tracers );
473466 }
467+ peerVerificationResults .put (callOptions .getAuthority (), peerVerificationStatus );
468+ }
469+ if (!peerVerificationStatus .isOk ()) {
470+ return new FailingClientStream (peerVerificationStatus , tracers );
474471 }
475472 }
476473 // FIXME: it is likely wrong to pass the transportTracer here as it'll exit the lock's scope
@@ -495,21 +492,19 @@ public ClientStream newStream(
495492
496493 private Optional <TrustManager > getX509ExtendedTrustManager (TlsChannelCredentials tlsCreds )
497494 throws GeneralSecurityException {
498- Optional <TrustManager > x509ExtendedTrustManager ;
495+ TrustManager [] tm = null ;
496+ // Using the same way of creating TrustManager from {@link OkHttpChannelBuilder#sslSocketFactoryFrom}.
499497 if (tlsCreds .getTrustManagers () != null ) {
500- x509ExtendedTrustManager = tlsCreds .getTrustManagers ().stream ().filter (
501- trustManager -> trustManager instanceof X509ExtendedTrustManager ).findFirst ();
498+ tm = tlsCreds .getTrustManagers ().toArray (new TrustManager [0 ]);
502499 } else if (tlsCreds .getRootCertificates () != null ) {
503- x509ExtendedTrustManager = CertificateUtils .getX509ExtendedTrustManager (
504- new ByteArrayInputStream (tlsCreds .getRootCertificates ()));
500+ tm = io .grpc .internal .CertificateUtils .createTrustManager (tlsCreds .getRootCertificates ());
505501 } else { // else use system default
506502 TrustManagerFactory tmf = TrustManagerFactory .getInstance (
507503 TrustManagerFactory .getDefaultAlgorithm ());
508504 tmf .init ((KeyStore ) null );
509- x509ExtendedTrustManager = Arrays .stream (tmf .getTrustManagers ())
510- .filter (trustManager -> trustManager instanceof X509ExtendedTrustManager ).findFirst ();
505+ tm = tmf .getTrustManagers ();
511506 }
512- return x509ExtendedTrustManager ;
507+ return Arrays . stream ( tm ). filter ( trustManager -> trustManager instanceof X509ExtendedTrustManager ). findFirst () ;
513508 }
514509
515510 @ GuardedBy ("lock" )
0 commit comments