Skip to content

Commit dd95f8f

Browse files
committed
in-progress changes.
1 parent c31995e commit dd95f8f

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

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

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import io.grpc.internal.ClientStream;
4848
import io.grpc.internal.ClientStreamListener.RpcProgress;
4949
import io.grpc.internal.ConnectionClientTransport;
50+
import io.grpc.internal.FailingClientStream;
5051
import io.grpc.internal.GrpcAttributes;
5152
import io.grpc.internal.GrpcUtil;
5253
import io.grpc.internal.Http2Ping;
@@ -71,12 +72,19 @@
7172
import io.grpc.okhttp.internal.framed.Variant;
7273
import io.grpc.okhttp.internal.proxy.HttpUrl;
7374
import io.grpc.okhttp.internal.proxy.Request;
75+
import io.grpc.util.CertificateUtils;
7476
import io.perfmark.PerfMark;
77+
import java.io.ByteArrayInputStream;
7578
import java.io.EOFException;
7679
import java.io.IOException;
80+
import java.io.InputStream;
7781
import java.net.InetSocketAddress;
7882
import java.net.Socket;
7983
import java.net.URI;
84+
import java.security.GeneralSecurityException;
85+
import java.security.KeyStore;
86+
import java.security.cert.X509Certificate;
87+
import java.util.Arrays;
8088
import java.util.Collections;
8189
import java.util.Deque;
8290
import java.util.EnumMap;
@@ -104,7 +112,10 @@
104112
import javax.net.ssl.SSLSession;
105113
import javax.net.ssl.SSLSocket;
106114
import javax.net.ssl.SSLSocketFactory;
115+
import javax.net.ssl.TrustManager;
116+
import javax.net.ssl.TrustManagerFactory;
107117
import javax.net.ssl.X509ExtendedTrustManager;
118+
import javax.security.auth.x500.X500Principal;
108119
import okio.Buffer;
109120
import okio.BufferedSink;
110121
import okio.BufferedSource;
@@ -212,7 +223,7 @@ private static Map<ErrorCode, Status> buildErrorCodeToStatusMap() {
212223
private final boolean useGetForSafeMethods;
213224
@GuardedBy("lock")
214225
private final TransportTracer transportTracer;
215-
private Optional<X509ExtendedTrustManager> x509ExtendedTrustManager;
226+
private Optional<TrustManager> x509ExtendedTrustManager;
216227

217228
@GuardedBy("lock")
218229
private final InUseStateAggregator<OkHttpClientStream> inUseState =
@@ -412,7 +423,19 @@ public ClientStream newStream(
412423
StatsTraceContext.newClientContext(tracers, getAttributes(), headers);
413424
if (callOptions.getAuthority() != null && channelCredentials instanceof TlsChannelCredentials) {
414425
if (x509ExtendedTrustManager == null) {
415-
426+
try {
427+
x509ExtendedTrustManager = getX509ExtendedTrustManager(
428+
(TlsChannelCredentials) channelCredentials);
429+
} catch (GeneralSecurityException e) {
430+
log.log(Level.FINE, "Failure getting X509ExtendedTrustManager from TlsCredentials", e);
431+
return new FailingClientStream(Status.INTERNAL.withDescription(
432+
"Failure getting X509ExtendedTrustManager from TlsCredentials"),
433+
tracers);
434+
}
435+
} else if (!x509ExtendedTrustManager.isPresent()) {
436+
return new FailingClientStream(Status.INTERNAL.withDescription(
437+
"Can't allow authority override in rpc when X509ExtendedTrustManager is not available"),
438+
tracers);
416439
}
417440
}
418441
// FIXME: it is likely wrong to pass the transportTracer here as it'll exit the lock's scope
@@ -435,6 +458,47 @@ public ClientStream newStream(
435458
}
436459
}
437460

461+
private Optional<TrustManager> getX509ExtendedTrustManager(TlsChannelCredentials tlsCreds)
462+
throws GeneralSecurityException {
463+
Optional<TrustManager> x509ExtendedTrustManager;
464+
if (tlsCreds.getTrustManagers() != null) {
465+
x509ExtendedTrustManager = tlsCreds.getTrustManagers().stream().filter(
466+
trustManager -> trustManager instanceof X509ExtendedTrustManager).findFirst();
467+
} else if (tlsCreds.getRootCertificates() != null) {
468+
x509ExtendedTrustManager = getX509ExtendedTrustManager(new ByteArrayInputStream(
469+
tlsCreds.getRootCertificates()));
470+
} else { // else use system default
471+
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
472+
TrustManagerFactory.getDefaultAlgorithm());
473+
tmf.init((KeyStore) null);
474+
x509ExtendedTrustManager = Arrays.stream(tmf.getTrustManagers())
475+
.filter(trustManager -> trustManager instanceof X509ExtendedTrustManager).findFirst();
476+
}
477+
return x509ExtendedTrustManager;
478+
}
479+
480+
private static Optional<TrustManager> getX509ExtendedTrustManager(InputStream rootCerts)
481+
throws GeneralSecurityException {
482+
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
483+
try {
484+
ks.load(null, null);
485+
} catch (IOException ex) {
486+
// Shouldn't really happen, as we're not loading any data.
487+
throw new GeneralSecurityException(ex);
488+
}
489+
X509Certificate[] certs = CertificateUtils.getX509Certificates(rootCerts);
490+
for (X509Certificate cert : certs) {
491+
X500Principal principal = cert.getSubjectX500Principal();
492+
ks.setCertificateEntry(principal.getName("RFC2253"), cert);
493+
}
494+
495+
TrustManagerFactory trustManagerFactory =
496+
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
497+
trustManagerFactory.init(ks);
498+
return Arrays.stream(trustManagerFactory.getTrustManagers())
499+
.filter(trustManager -> trustManager instanceof X509ExtendedTrustManager).findFirst();
500+
}
501+
438502
@GuardedBy("lock")
439503
void streamReadyToStart(OkHttpClientStream clientStream) {
440504
if (goAwayStatus != null) {

0 commit comments

Comments
 (0)