Skip to content

Commit ecbf7b7

Browse files
committed
Use reflection to access X509ExtendedTrustManager.
1 parent 60b1ee0 commit ecbf7b7

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,14 @@
7777
import io.perfmark.PerfMark;
7878
import java.io.EOFException;
7979
import java.io.IOException;
80+
import java.lang.reflect.InvocationTargetException;
81+
import java.lang.reflect.Method;
8082
import java.net.InetSocketAddress;
8183
import java.net.Socket;
8284
import java.net.URI;
8385
import java.security.GeneralSecurityException;
8486
import java.security.KeyStore;
8587
import java.security.cert.Certificate;
86-
import java.security.cert.CertificateException;
8788
import java.security.cert.X509Certificate;
8889
import java.util.Collections;
8990
import java.util.Deque;
@@ -116,7 +117,6 @@
116117
import javax.net.ssl.SSLSocketFactory;
117118
import javax.net.ssl.TrustManager;
118119
import javax.net.ssl.TrustManagerFactory;
119-
import javax.net.ssl.X509ExtendedTrustManager;
120120
import okio.Buffer;
121121
import okio.BufferedSink;
122122
import okio.BufferedSource;
@@ -168,6 +168,23 @@ private static Map<ErrorCode, Status> buildErrorCodeToStatusMap() {
168168
return Collections.unmodifiableMap(errorToStatus);
169169
}
170170

171+
private static Class<?> x509ExtendedTrustManagerClass;
172+
private static Method checkServerTrustedMethod;
173+
174+
static {
175+
try {
176+
x509ExtendedTrustManagerClass = Class.forName("javax.net.ssl.X509ExtendedTrustManager");
177+
checkServerTrustedMethod = x509ExtendedTrustManagerClass.getMethod("checkServerTrusted",
178+
X509Certificate[].class, String.class, Socket.class);
179+
} catch (ClassNotFoundException e) {
180+
// Per-rpc authority override via call options will be disallowed.
181+
} catch (NoSuchMethodException e) {
182+
// Should never happen.
183+
Logger.getLogger(OkHttpClientTransport.class.getName()).warning("Method checkServerTrusted "
184+
+ "not found in javax.net.ssl.X509ExtendedTrustManager");
185+
}
186+
}
187+
171188
private final InetSocketAddress address;
172189
private final String defaultAuthority;
173190
private final String userAgent;
@@ -453,8 +470,8 @@ public ClientStream newStream(
453470
TrustManager x509ExtendedTrustManager = null;
454471
boolean warningLogged = false;
455472
try {
456-
x509ExtendedTrustManager = getX509ExtendedTrustManager(
457-
(TlsChannelCredentials) channelCredentials);
473+
x509ExtendedTrustManager = x509ExtendedTrustManagerClass != null
474+
? getX509ExtendedTrustManager((TlsChannelCredentials) channelCredentials) : null;
458475
} catch (GeneralSecurityException e) {
459476
if (GrpcUtil.getFlag(GRPC_ENABLE_PER_RPC_AUTHORITY_CHECK, false)) {
460477
return new FailingClientStream(Status.UNAVAILABLE.withDescription(
@@ -482,11 +499,18 @@ public ClientStream newStream(
482499
for (int i = 0; i < peerCertificates.length; i++) {
483500
x509PeerCertificates[i] = (X509Certificate) peerCertificates[i];
484501
}
485-
((X509ExtendedTrustManager) x509ExtendedTrustManager).checkServerTrusted(
486-
x509PeerCertificates, "RSA",
487-
new SslSocketWrapper((SSLSocket) socket, callOptions.getAuthority()));
488-
peerVerificationStatus = Status.OK;
489-
} catch (SSLPeerUnverifiedException | CertificateException e) {
502+
// Should never happen
503+
if (checkServerTrustedMethod == null) {
504+
peerVerificationStatus = Status.UNAVAILABLE.withDescription(
505+
"Method checkServerTrusted not found in "
506+
+ "javax.net.ssl.X509ExtendedTrustManager");
507+
} else {
508+
checkServerTrustedMethod.invoke(x509ExtendedTrustManager, x509PeerCertificates,
509+
"RSA", new SslSocketWrapper((SSLSocket) socket, callOptions.getAuthority()));
510+
peerVerificationStatus = Status.OK;
511+
}
512+
} catch (SSLPeerUnverifiedException | InvocationTargetException
513+
| IllegalAccessException e) {
490514
peerVerificationStatus = Status.UNAVAILABLE.withDescription(
491515
String.format("Failure in verifying authority '%s' against peer during rpc",
492516
callOptions.getAuthority())).withCause(e);
@@ -533,7 +557,7 @@ private TrustManager getX509ExtendedTrustManager(TlsChannelCredentials tlsCreds)
533557
tm = tmf.getTrustManagers();
534558
}
535559
for (TrustManager trustManager: tm) {
536-
if (trustManager instanceof X509ExtendedTrustManager) {
560+
if (x509ExtendedTrustManagerClass.isInstance(trustManager)) {
537561
return trustManager;
538562
}
539563
}

0 commit comments

Comments
 (0)