diff --git a/benchmarks/src/main/java/okhttp3/benchmarks/ApacheHttpClient.java b/benchmarks/src/main/java/okhttp3/benchmarks/ApacheHttpClient.java
index 2f97519a29f7..a5c632fa0fce 100644
--- a/benchmarks/src/main/java/okhttp3/benchmarks/ApacheHttpClient.java
+++ b/benchmarks/src/main/java/okhttp3/benchmarks/ApacheHttpClient.java
@@ -19,9 +19,8 @@
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
-import javax.net.ssl.SSLContext;
import okhttp3.HttpUrl;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
@@ -42,9 +41,9 @@ class ApacheHttpClient extends SynchronousHttpClient {
super.prepare(benchmark);
ClientConnectionManager connectionManager = new PoolingClientConnectionManager();
if (benchmark.tls) {
- SSLContext sslContext = SslContextBuilder.localhost();
+ SslClient sslClient = SslClient.localhost();
connectionManager.getSchemeRegistry().register(
- new Scheme("https", 443, new SSLSocketFactory(sslContext)));
+ new Scheme("https", 443, new SSLSocketFactory(sslClient.sslContext)));
}
client = new DefaultHttpClient(connectionManager);
}
diff --git a/benchmarks/src/main/java/okhttp3/benchmarks/Benchmark.java b/benchmarks/src/main/java/okhttp3/benchmarks/Benchmark.java
index d69530fe0ea3..8d4d04386ae0 100644
--- a/benchmarks/src/main/java/okhttp3/benchmarks/Benchmark.java
+++ b/benchmarks/src/main/java/okhttp3/benchmarks/Benchmark.java
@@ -26,10 +26,9 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.net.ssl.SSLContext;
import okhttp3.HttpUrl;
import okhttp3.Protocol;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
@@ -161,8 +160,8 @@ private MockWebServer startServer() throws IOException {
MockWebServer server = new MockWebServer();
if (tls) {
- SSLContext sslContext = SslContextBuilder.localhost();
- server.useHttps(sslContext.getSocketFactory(), false);
+ SslClient sslClient = SslClient.localhost();
+ server.useHttps(sslClient.socketFactory, false);
server.setProtocols(protocols);
}
diff --git a/benchmarks/src/main/java/okhttp3/benchmarks/NettyHttpClient.java b/benchmarks/src/main/java/okhttp3/benchmarks/NettyHttpClient.java
index 8caa046c7315..01e6f6e257c4 100644
--- a/benchmarks/src/main/java/okhttp3/benchmarks/NettyHttpClient.java
+++ b/benchmarks/src/main/java/okhttp3/benchmarks/NettyHttpClient.java
@@ -42,10 +42,9 @@
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import okhttp3.HttpUrl;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
/** Netty isn't an HTTP client, but it's almost one. */
class NettyHttpClient implements HttpClient {
@@ -69,8 +68,8 @@ class NettyHttpClient implements HttpClient {
ChannelPipeline pipeline = channel.pipeline();
if (benchmark.tls) {
- SSLContext sslContext = SslContextBuilder.localhost();
- SSLEngine engine = sslContext.createSSLEngine();
+ SslClient sslClient = SslClient.localhost();
+ SSLEngine engine = sslClient.sslContext.createSSLEngine();
engine.setUseClientMode(true);
pipeline.addLast("ssl", new SslHandler(engine));
}
diff --git a/benchmarks/src/main/java/okhttp3/benchmarks/OkHttp.java b/benchmarks/src/main/java/okhttp3/benchmarks/OkHttp.java
index 05eb5044d20b..7c90e5e6b5f3 100644
--- a/benchmarks/src/main/java/okhttp3/benchmarks/OkHttp.java
+++ b/benchmarks/src/main/java/okhttp3/benchmarks/OkHttp.java
@@ -18,7 +18,6 @@
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.Call;
@@ -26,7 +25,7 @@
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
class OkHttp extends SynchronousHttpClient {
private static final boolean VERBOSE = false;
@@ -40,15 +39,15 @@ class OkHttp extends SynchronousHttpClient {
.build();
if (benchmark.tls) {
- SSLContext sslContext = SslContextBuilder.localhost();
- SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+ SslClient sslClient = SslClient.localhost();
+ SSLSocketFactory socketFactory = sslClient.socketFactory;
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession session) {
return true;
}
};
client = new OkHttpClient.Builder()
- .sslSocketFactory(socketFactory)
+ .sslSocketFactory(socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build();
}
diff --git a/benchmarks/src/main/java/okhttp3/benchmarks/OkHttpAsync.java b/benchmarks/src/main/java/okhttp3/benchmarks/OkHttpAsync.java
index 09bd3a73e352..57cb75cacc02 100644
--- a/benchmarks/src/main/java/okhttp3/benchmarks/OkHttpAsync.java
+++ b/benchmarks/src/main/java/okhttp3/benchmarks/OkHttpAsync.java
@@ -21,7 +21,6 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.Call;
@@ -32,7 +31,7 @@
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
class OkHttpAsync implements HttpClient {
private static final boolean VERBOSE = false;
@@ -55,15 +54,15 @@ class OkHttpAsync implements HttpClient {
.build();
if (benchmark.tls) {
- SSLContext sslContext = SslContextBuilder.localhost();
- SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+ SslClient sslClient = SslClient.localhost();
+ SSLSocketFactory socketFactory = sslClient.socketFactory;
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession session) {
return true;
}
};
client = client.newBuilder()
- .sslSocketFactory(socketFactory)
+ .sslSocketFactory(socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build();
}
diff --git a/benchmarks/src/main/java/okhttp3/benchmarks/UrlConnection.java b/benchmarks/src/main/java/okhttp3/benchmarks/UrlConnection.java
index f5c02ce0b6db..f75d16083550 100644
--- a/benchmarks/src/main/java/okhttp3/benchmarks/UrlConnection.java
+++ b/benchmarks/src/main/java/okhttp3/benchmarks/UrlConnection.java
@@ -22,11 +22,10 @@
import java.util.zip.GZIPInputStream;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.HttpUrl;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
class UrlConnection extends SynchronousHttpClient {
private static final boolean VERBOSE = false;
@@ -34,8 +33,8 @@ class UrlConnection extends SynchronousHttpClient {
@Override public void prepare(Benchmark benchmark) {
super.prepare(benchmark);
if (benchmark.tls) {
- SSLContext sslContext = SslContextBuilder.localhost();
- SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+ SslClient sslClient = SslClient.localhost();
+ SSLSocketFactory socketFactory = sslClient.socketFactory;
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession session) {
return true;
diff --git a/mockwebserver/src/main/java/okhttp3/internal/SslContextBuilder.java b/mockwebserver/src/main/java/okhttp3/internal/SslContextBuilder.java
deleted file mode 100644
index b161e106e2aa..000000000000
--- a/mockwebserver/src/main/java/okhttp3/internal/SslContextBuilder.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2012 Square, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package okhttp3.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.List;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManagerFactory;
-
-/**
- * Constructs an SSL context for testing. This uses Bouncy Castle to generate a self-signed
- * certificate for a single hostname such as "localhost".
- *
- *
The crypto performed by this class is relatively slow. Clients should reuse SSL context
- * instances where possible.
- */
-public final class SslContextBuilder {
- private static SSLContext localhost; // Lazily initialized.
-
- /** Returns a new SSL context for this host's current localhost address. */
- public static synchronized SSLContext localhost() {
- if (localhost != null) return localhost;
-
- try {
- // Generate a self-signed cert for the server to serve and the client to trust.
- HeldCertificate heldCertificate = new HeldCertificate.Builder()
- .serialNumber("1")
- .commonName(InetAddress.getByName("localhost").getHostName())
- .build();
-
- localhost = new SslContextBuilder()
- .certificateChain(heldCertificate)
- .addTrustedCertificate(heldCertificate.certificate)
- .build();
-
- return localhost;
- } catch (GeneralSecurityException e) {
- throw new RuntimeException(e);
- } catch (UnknownHostException e) {
- throw new RuntimeException(e);
- }
- }
-
- private HeldCertificate[] chain;
- private List trustedCertificates = new ArrayList<>();
-
- /**
- * Configure the certificate chain to use when serving HTTPS responses. The first certificate
- * in this chain is the server's certificate, further certificates are included in the handshake
- * so the client can build a trusted path to a CA certificate.
- */
- public SslContextBuilder certificateChain(HeldCertificate... chain) {
- this.chain = chain;
- return this;
- }
-
- /**
- * Add a certificate authority that this client trusts. Servers that provide certificate chains
- * signed by these roots (or their intermediates) will be accepted.
- */
- public SslContextBuilder addTrustedCertificate(X509Certificate certificate) {
- trustedCertificates.add(certificate);
- return this;
- }
-
- public SSLContext build() throws GeneralSecurityException {
- // Put the certificate in a key store.
- char[] password = "password".toCharArray();
- KeyStore keyStore = newEmptyKeyStore(password);
-
- if (chain != null) {
- Certificate[] certificates = new Certificate[chain.length];
- for (int i = 0; i < chain.length; i++) {
- certificates[i] = chain[i].certificate;
- }
- keyStore.setKeyEntry("private", chain[0].keyPair.getPrivate(), password, certificates);
- }
-
- for (int i = 0; i < trustedCertificates.size(); i++) {
- keyStore.setCertificateEntry("cert_" + i, trustedCertificates.get(i));
- }
-
- // Wrap it up in an SSL context.
- KeyManagerFactory keyManagerFactory =
- KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- keyManagerFactory.init(keyStore, password);
- TrustManagerFactory trustManagerFactory =
- TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- trustManagerFactory.init(keyStore);
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(),
- new SecureRandom());
- return sslContext;
- }
-
- private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
- try {
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- InputStream in = null; // By convention, 'null' creates an empty key store.
- keyStore.load(in, password);
- return keyStore;
- } catch (IOException e) {
- throw new AssertionError(e);
- }
- }
-}
diff --git a/mockwebserver/src/main/java/okhttp3/internal/framed/FramedServer.java b/mockwebserver/src/main/java/okhttp3/internal/framed/FramedServer.java
index 4ac8159d6c3b..2a555be68e35 100644
--- a/mockwebserver/src/main/java/okhttp3/internal/framed/FramedServer.java
+++ b/mockwebserver/src/main/java/okhttp3/internal/framed/FramedServer.java
@@ -29,8 +29,8 @@
import javax.net.ssl.SSLSocketFactory;
import okhttp3.Protocol;
import okhttp3.internal.Platform;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.Util;
+import okhttp3.internal.tls.SslClient;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
@@ -184,7 +184,7 @@ public static void main(String... args) throws Exception {
}
FramedServer server = new FramedServer(new File(args[0]),
- SslContextBuilder.localhost().getSocketFactory());
+ SslClient.localhost().sslContext.getSocketFactory());
server.run();
}
}
diff --git a/mockwebserver/src/main/java/okhttp3/internal/HeldCertificate.java b/mockwebserver/src/main/java/okhttp3/internal/tls/HeldCertificate.java
similarity index 99%
rename from mockwebserver/src/main/java/okhttp3/internal/HeldCertificate.java
rename to mockwebserver/src/main/java/okhttp3/internal/tls/HeldCertificate.java
index d6c45bd30be2..a7fe81f0ef64 100644
--- a/mockwebserver/src/main/java/okhttp3/internal/HeldCertificate.java
+++ b/mockwebserver/src/main/java/okhttp3/internal/tls/HeldCertificate.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package okhttp3.internal;
+package okhttp3.internal.tls;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
diff --git a/mockwebserver/src/main/java/okhttp3/internal/tls/SslClient.java b/mockwebserver/src/main/java/okhttp3/internal/tls/SslClient.java
new file mode 100644
index 000000000000..7cc061b66881
--- /dev/null
+++ b/mockwebserver/src/main/java/okhttp3/internal/tls/SslClient.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2012 Square, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package okhttp3.internal.tls;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Combines an SSL socket factory and trust manager, a pairing enough for OkHttp or MockWebServer to
+ * create a secure connection.
+ */
+public final class SslClient {
+ private static SslClient localhost; // Lazily initialized.
+
+ public final SSLContext sslContext;
+ public final SSLSocketFactory socketFactory;
+ public final X509TrustManager trustManager;
+
+ private SslClient(SSLContext sslContext, X509TrustManager trustManager) {
+ this.sslContext = sslContext;
+ this.socketFactory = sslContext.getSocketFactory();
+ this.trustManager = trustManager;
+ }
+
+ /** Returns an SSL client for this host's localhost address. */
+ public static synchronized SslClient localhost() {
+ if (localhost != null) return localhost;
+
+ try {
+ // Generate a self-signed cert for the server to serve and the client to trust.
+ HeldCertificate heldCertificate = new HeldCertificate.Builder()
+ .serialNumber("1")
+ .commonName(InetAddress.getByName("localhost").getHostName())
+ .build();
+
+ localhost = new Builder()
+ .certificateChain(heldCertificate.keyPair, heldCertificate.certificate)
+ .addTrustedCertificate(heldCertificate.certificate)
+ .build();
+
+ return localhost;
+ } catch (GeneralSecurityException | UnknownHostException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static class Builder {
+ private final List chainCertificates = new ArrayList<>();
+ private final List certificates = new ArrayList<>();
+ private KeyPair keyPair;
+
+ /**
+ * Configure the certificate chain to use when serving HTTPS responses. The first certificate is
+ * the server's certificate, further certificates are included in the handshake so the client
+ * can build a trusted path to a CA certificate.
+ */
+ public Builder certificateChain(HeldCertificate serverCert, HeldCertificate... chain) {
+ X509Certificate[] certificates = new X509Certificate[chain.length];
+ for (int i = 0; i < chain.length; i++) {
+ certificates[i] = chain[i].certificate;
+ }
+ return certificateChain(serverCert.keyPair, serverCert.certificate, certificates);
+ }
+
+ public SslClient.Builder certificateChain(KeyPair keyPair, X509Certificate keyCert,
+ X509Certificate... certificates) {
+ this.keyPair = keyPair;
+ this.chainCertificates.add(keyCert);
+ this.chainCertificates.addAll(Arrays.asList(certificates));
+ this.certificates.addAll(Arrays.asList(certificates));
+ return this;
+ }
+
+ /**
+ * Add a certificate authority that this client trusts. Servers that provide certificate chains
+ * signed by these roots (or their intermediates) will be accepted.
+ */
+ public Builder addTrustedCertificate(X509Certificate certificate) {
+ this.certificates.add(certificate);
+ return this;
+ }
+
+ public SslClient build() {
+ try {
+ // Put the certificate in a key store.
+ char[] password = "password".toCharArray();
+ KeyStore keyStore = newEmptyKeyStore(password);
+
+ if (keyPair != null) {
+ Certificate[] certificates = chainCertificates.toArray(
+ new Certificate[chainCertificates.size()]);
+ keyStore.setKeyEntry("private", keyPair.getPrivate(), password, certificates);
+ }
+
+ for (int i = 0; i < certificates.size(); i++) {
+ keyStore.setCertificateEntry("cert_" + i, certificates.get(i));
+ }
+
+ // Wrap it up in an SSL context.
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(keyStore, password);
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init(keyStore);
+ TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
+
+ if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
+ throw new IllegalStateException("Unexpected default trust managers:"
+ + Arrays.toString(trustManagers));
+ }
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, new SecureRandom());
+
+ return new SslClient(sslContext, (X509TrustManager) trustManagers[0]);
+ } catch (GeneralSecurityException gse) {
+ throw new AssertionError(gse);
+ }
+ }
+
+ private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
+ try {
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ InputStream in = null; // By convention, 'null' creates an empty key store.
+ keyStore.load(in, password);
+ return keyStore;
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+ }
+}
diff --git a/okcurl/src/main/java/okhttp3/curl/Main.java b/okcurl/src/main/java/okhttp3/curl/Main.java
index 15e4f030d198..aa8f4872c199 100644
--- a/okcurl/src/main/java/okhttp3/curl/Main.java
+++ b/okcurl/src/main/java/okhttp3/curl/Main.java
@@ -23,7 +23,6 @@
import io.airlift.airline.SingleCommand;
import java.io.IOException;
import java.io.InputStream;
-import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Properties;
@@ -179,7 +178,9 @@ private OkHttpClient createClient() {
builder.readTimeout(readTimeout, SECONDS);
}
if (allowInsecure) {
- builder.sslSocketFactory(createInsecureSslSocketFactory());
+ X509TrustManager trustManager = createInsecureTrustManager();
+ SSLSocketFactory sslSocketFactory = createInsecureSslSocketFactory(trustManager);
+ builder.sslSocketFactory(sslSocketFactory, trustManager);
builder.hostnameVerifier(createInsecureHostnameVerifier());
}
return builder.build();
@@ -240,23 +241,24 @@ private void close() {
client.connectionPool().evictAll(); // Close any persistent connections.
}
- private static SSLSocketFactory createInsecureSslSocketFactory() {
- try {
- SSLContext context = SSLContext.getInstance("TLS");
- TrustManager permissive = new X509TrustManager() {
- @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- }
+ private static X509TrustManager createInsecureTrustManager() {
+ return new X509TrustManager() {
+ @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {
+ }
- @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- }
+ @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {
+ }
- @Override public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[0];
- }
- };
- context.init(null, new TrustManager[] {permissive}, null);
+ @Override public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+ };
+ }
+
+ private static SSLSocketFactory createInsecureSslSocketFactory(TrustManager trustManager) {
+ try {
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, new TrustManager[] {trustManager}, null);
return context.getSocketFactory();
} catch (Exception e) {
throw new AssertionError(e);
diff --git a/okhttp-android-support/src/test/java/okhttp3/internal/huc/CacheAdapterTest.java b/okhttp-android-support/src/test/java/okhttp3/internal/huc/CacheAdapterTest.java
index 81aeaf2b9a2b..e24c7264ad60 100644
--- a/okhttp-android-support/src/test/java/okhttp3/internal/huc/CacheAdapterTest.java
+++ b/okhttp-android-support/src/test/java/okhttp3/internal/huc/CacheAdapterTest.java
@@ -29,16 +29,15 @@
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
import okhttp3.AbstractResponseCache;
import okhttp3.OkHttpClient;
import okhttp3.OkUrlFactory;
+import okhttp3.RecordingHostnameVerifier;
import okhttp3.internal.Internal;
import okhttp3.internal.InternalCache;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
-import okhttp3.RecordingHostnameVerifier;
import okio.Buffer;
import org.junit.After;
import org.junit.Before;
@@ -59,7 +58,7 @@
*
*/
public class CacheAdapterTest {
- private SSLContext sslContext = SslContextBuilder.localhost();
+ private SslClient sslClient = SslClient.localhost();
private HostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
private MockWebServer server;
private OkHttpClient client;
@@ -116,7 +115,7 @@ public class CacheAdapterTest {
};
setInternalCache(new CacheAdapter(responseCache));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build();
@@ -234,7 +233,7 @@ public class CacheAdapterTest {
};
setInternalCache(new CacheAdapter(responseCache));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build();
@@ -262,7 +261,7 @@ private URL configureServer(MockResponse mockResponse) throws Exception {
}
private URL configureHttpsServer(MockResponse mockResponse) throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false /* tunnelProxy */);
+ server.useHttps(sslClient.socketFactory, false /* tunnelProxy */);
server.enqueue(mockResponse);
server.start();
return server.url("/").url();
diff --git a/okhttp-android-support/src/test/java/okhttp3/internal/huc/ResponseCacheTest.java b/okhttp-android-support/src/test/java/okhttp3/internal/huc/ResponseCacheTest.java
index a73ca5485457..a533b919b768 100644
--- a/okhttp-android-support/src/test/java/okhttp3/internal/huc/ResponseCacheTest.java
+++ b/okhttp-android-support/src/test/java/okhttp3/internal/huc/ResponseCacheTest.java
@@ -54,21 +54,20 @@
import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
import okhttp3.AbstractResponseCache;
import okhttp3.AndroidInternal;
import okhttp3.AndroidShimResponseCache;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.OkUrlFactory;
+import okhttp3.RecordingHostnameVerifier;
import okhttp3.internal.Internal;
import okhttp3.internal.InternalCache;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import okhttp3.mockwebserver.SocketPolicy;
-import okhttp3.RecordingHostnameVerifier;
import okio.Buffer;
import okio.BufferedSink;
import okio.GzipSink;
@@ -96,7 +95,7 @@ public final class ResponseCacheTest {
@Rule public MockWebServer server2 = new MockWebServer();
private HostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
- private SSLContext sslContext = SslContextBuilder.localhost();
+ private SslClient sslClient = SslClient.localhost();
private ResponseCache cache;
private CookieManager cookieManager;
private OkUrlFactory urlFactory;
@@ -267,14 +266,14 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
}
@Test public void secureResponseCaching() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()
.addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
.setBody("ABC"));
HttpsURLConnection c1 = (HttpsURLConnection) openConnection(server.url("/").url());
- c1.setSSLSocketFactory(sslContext.getSocketFactory());
+ c1.setSSLSocketFactory(sslClient.socketFactory);
c1.setHostnameVerifier(hostnameVerifier);
assertEquals("ABC", readAscii(c1));
@@ -286,7 +285,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
Principal localPrincipal = c1.getLocalPrincipal();
HttpsURLConnection c2 = (HttpsURLConnection) openConnection(server.url("/").url()); // cached!
- c2.setSSLSocketFactory(sslContext.getSocketFactory());
+ c2.setSSLSocketFactory(sslClient.socketFactory);
c2.setHostnameVerifier(hostnameVerifier);
assertEquals("ABC", readAscii(c2));
@@ -345,7 +344,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
}
@Test public void secureResponseCachingAndRedirects() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()
.addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
@@ -359,7 +358,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
.setBody("DEF"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
@@ -383,7 +382,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
* https://github.com/square/okhttp/issues/214
*/
@Test public void secureResponseCachingAndProtocolRedirects() throws IOException {
- server2.useHttps(sslContext.getSocketFactory(), false);
+ server2.useHttps(sslClient.socketFactory, false);
server2.enqueue(new MockResponse()
.addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
@@ -398,7 +397,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
.addHeader("Location: " + server2.url("/").url()));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
@@ -1461,7 +1460,7 @@ private RecordedRequest assertClientSuppliedCondition(MockResponse seed, String
}
@Test public void varyAndHttps() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()
.addHeader("Cache-Control: max-age=60")
.addHeader("Vary: Accept-Language")
@@ -1470,7 +1469,7 @@ private RecordedRequest assertClientSuppliedCondition(MockResponse seed, String
.setBody("B"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
@@ -1981,20 +1980,20 @@ private InsecureResponseCache(ResponseCache delegate) {
}
@Test public void cacheReturnsInsecureResponseForSecureRequest() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setBody("ABC"));
server.enqueue(new MockResponse().setBody("DEF"));
AndroidInternal.setResponseCache(urlFactory, new InsecureResponseCache(cache));
HttpsURLConnection connection1 = (HttpsURLConnection) openConnection(server.url("/").url());
- connection1.setSSLSocketFactory(sslContext.getSocketFactory());
+ connection1.setSSLSocketFactory(sslClient.socketFactory);
connection1.setHostnameVerifier(hostnameVerifier);
assertEquals("ABC", readAscii(connection1));
// Not cached!
HttpsURLConnection connection2 = (HttpsURLConnection) openConnection(server.url("/").url());
- connection2.setSSLSocketFactory(sslContext.getSocketFactory());
+ connection2.setSSLSocketFactory(sslClient.socketFactory);
connection2.setHostnameVerifier(hostnameVerifier);
assertEquals("DEF", readAscii(connection2));
}
diff --git a/okhttp-tests/pom.xml b/okhttp-tests/pom.xml
index 5585632fc252..fd07ff95086e 100644
--- a/okhttp-tests/pom.xml
+++ b/okhttp-tests/pom.xml
@@ -1,6 +1,8 @@
-
+
4.0.0
diff --git a/okhttp-tests/src/test/java/okhttp3/CacheTest.java b/okhttp-tests/src/test/java/okhttp3/CacheTest.java
index 418f7bd293af..33565e31e9f9 100644
--- a/okhttp-tests/src/test/java/okhttp3/CacheTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/CacheTest.java
@@ -37,12 +37,11 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import okhttp3.internal.Internal;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.Util;
import okhttp3.internal.io.InMemoryFileSystem;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
@@ -75,7 +74,7 @@ public final class CacheTest {
@Rule public MockWebServer server2 = new MockWebServer();
@Rule public InMemoryFileSystem fileSystem = new InMemoryFileSystem();
- private final SSLContext sslContext = SslContextBuilder.localhost();
+ private final SslClient sslClient = SslClient.localhost();
private OkHttpClient client;
private Cache cache;
private final CookieManager cookieManager = new CookieManager();
@@ -256,14 +255,14 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
}
@Test public void secureResponseCaching() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()
.addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
.setBody("ABC"));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(NULL_HOSTNAME_VERIFIER)
.build();
@@ -352,7 +351,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
}
@Test public void secureResponseCachingAndRedirects() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()
.addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
@@ -366,7 +365,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
.setBody("DEF"));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(NULL_HOSTNAME_VERIFIER)
.build();
@@ -392,7 +391,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
* https://github.com/square/okhttp/issues/214
*/
@Test public void secureResponseCachingAndProtocolRedirects() throws IOException {
- server2.useHttps(sslContext.getSocketFactory(), false);
+ server2.useHttps(sslClient.socketFactory, false);
server2.enqueue(new MockResponse()
.addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
@@ -407,7 +406,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
.addHeader("Location: " + server2.url("/")));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(NULL_HOSTNAME_VERIFIER)
.build();
@@ -1681,7 +1680,7 @@ private RecordedRequest assertClientSuppliedCondition(MockResponse seed, String
}
@Test public void varyAndHttps() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()
.addHeader("Cache-Control: max-age=60")
.addHeader("Vary: Accept-Language")
@@ -1690,7 +1689,7 @@ private RecordedRequest assertClientSuppliedCondition(MockResponse seed, String
.setBody("B"));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(NULL_HOSTNAME_VERIFIER)
.build();
diff --git a/okhttp-tests/src/test/java/okhttp3/CallTest.java b/okhttp-tests/src/test/java/okhttp3/CallTest.java
index 18ede8338d0f..c2470c920bd4 100644
--- a/okhttp-tests/src/test/java/okhttp3/CallTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/CallTest.java
@@ -47,7 +47,6 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;
import javax.net.ServerSocketFactory;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLProtocolException;
@@ -56,11 +55,11 @@
import okhttp3.internal.DoubleInetAddressDns;
import okhttp3.internal.RecordingOkAuthenticator;
import okhttp3.internal.SingleInetAddressDns;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.Util;
import okhttp3.internal.Version;
import okhttp3.internal.http.RecordingProxySelector;
import okhttp3.internal.io.InMemoryFileSystem;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
@@ -94,7 +93,7 @@ public final class CallTest {
@Rule public final MockWebServer server2 = new MockWebServer();
@Rule public final InMemoryFileSystem fileSystem = new InMemoryFileSystem();
- private SSLContext sslContext = SslContextBuilder.localhost();
+ private SslClient sslClient = SslClient.localhost();
private OkHttpClient client = defaultClient();
private RecordingCallback callback = new RecordingCallback();
private TestLogHandler logHandler = new TestLogHandler();
@@ -964,14 +963,14 @@ private void postBodyRetransmittedAfterAuthorizationFail(String body) throws Exc
}
@Test public void recoverFromTlsHandshakeFailure() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setBody("abc"));
client = client.newBuilder()
.hostnameVerifier(new RecordingHostnameVerifier())
.dns(new SingleInetAddressDns())
- .sslSocketFactory(suppressTlsFallbackClientSocketFactory())
+ .sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager)
.build();
executeSynchronously("/").assertBody("abc");
@@ -980,19 +979,19 @@ private void postBodyRetransmittedAfterAuthorizationFail(String body) throws Exc
@Test public void recoverFromTlsHandshakeFailure_tlsFallbackScsvEnabled() throws Exception {
final String tlsFallbackScsv = "TLS_FALLBACK_SCSV";
List supportedCiphers =
- Arrays.asList(sslContext.getSocketFactory().getSupportedCipherSuites());
+ Arrays.asList(sslClient.socketFactory.getSupportedCipherSuites());
if (!supportedCiphers.contains(tlsFallbackScsv)) {
// This only works if the client socket supports TLS_FALLBACK_SCSV.
return;
}
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
RecordingSSLSocketFactory clientSocketFactory =
- new RecordingSSLSocketFactory(sslContext.getSocketFactory());
+ new RecordingSSLSocketFactory(sslClient.socketFactory);
client = client.newBuilder()
- .sslSocketFactory(clientSocketFactory)
+ .sslSocketFactory(clientSocketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.dns(new SingleInetAddressDns())
.build();
@@ -1012,13 +1011,13 @@ private void postBodyRetransmittedAfterAuthorizationFail(String body) throws Exc
}
@Test public void recoverFromTlsHandshakeFailure_Async() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setBody("abc"));
client = client.newBuilder()
.hostnameVerifier(new RecordingHostnameVerifier())
- .sslSocketFactory(suppressTlsFallbackClientSocketFactory())
+ .sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager)
.build();
Request request = new Request.Builder()
@@ -1034,10 +1033,10 @@ private void postBodyRetransmittedAfterAuthorizationFail(String body) throws Exc
.connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
.hostnameVerifier(new RecordingHostnameVerifier())
.dns(new SingleInetAddressDns())
- .sslSocketFactory(suppressTlsFallbackClientSocketFactory())
+ .sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager)
.build();
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
Request request = new Request.Builder().url(server.url("/")).build();
@@ -2206,7 +2205,7 @@ private InetSocketAddress startNullServer() throws IOException {
/** Test which headers are sent unencrypted to the HTTP proxy. */
@Test public void proxyConnectOmitsApplicationHeaders() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.enqueue(new MockResponse()
.setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
.clearHeaders());
@@ -2215,7 +2214,7 @@ private InetSocketAddress startNullServer() throws IOException {
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.proxy(server.toProxyAddress())
.hostnameVerifier(hostnameVerifier)
.build();
@@ -2243,7 +2242,7 @@ private InetSocketAddress startNullServer() throws IOException {
/** Respond to a proxy authorization challenge. */
@Test public void proxyAuthenticateOnConnect() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.enqueue(new MockResponse()
.setResponseCode(407)
.addHeader("Proxy-Authenticate: Basic realm=\"localhost\""));
@@ -2254,7 +2253,7 @@ private InetSocketAddress startNullServer() throws IOException {
.setBody("response body"));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.proxy(server.toProxyAddress())
.proxyAuthenticator(new RecordingOkAuthenticator("password"))
.hostnameVerifier(new RecordingHostnameVerifier())
@@ -2312,7 +2311,7 @@ private InetSocketAddress startNullServer() throws IOException {
* a TLS tunnel. https://github.com/square/okhttp/issues/2426
*/
@Test public void proxyAuthenticateOnConnectWithConnectionClose() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.setProtocols(Collections.singletonList(Protocol.HTTP_1_1));
server.enqueue(new MockResponse()
.setResponseCode(407)
@@ -2325,7 +2324,7 @@ private InetSocketAddress startNullServer() throws IOException {
.setBody("response body"));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.proxy(server.toProxyAddress())
.proxyAuthenticator(new RecordingOkAuthenticator("password"))
.hostnameVerifier(new RecordingHostnameVerifier())
@@ -2348,7 +2347,7 @@ private InetSocketAddress startNullServer() throws IOException {
}
@Test public void tooManyProxyAuthFailuresWithConnectionClose() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.setProtocols(Collections.singletonList(Protocol.HTTP_1_1));
for (int i = 0; i < 21; i++) {
server.enqueue(new MockResponse()
@@ -2358,7 +2357,7 @@ private InetSocketAddress startNullServer() throws IOException {
}
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.proxy(server.toProxyAddress())
.proxyAuthenticator(new RecordingOkAuthenticator("password"))
.hostnameVerifier(new RecordingHostnameVerifier())
@@ -2380,7 +2379,7 @@ private InetSocketAddress startNullServer() throws IOException {
* credentials. Worse, that approach leaks proxy credentials to the origin server.
*/
@Test public void noProactiveProxyAuthorization() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.enqueue(new MockResponse()
.setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
.clearHeaders());
@@ -2388,7 +2387,7 @@ private InetSocketAddress startNullServer() throws IOException {
.setBody("response body"));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.proxy(server.toProxyAddress())
.hostnameVerifier(new RecordingHostnameVerifier())
.build();
@@ -2536,7 +2535,7 @@ private void upload(
/** https://github.com/square/okhttp/issues/2344 */
@Test public void ipv6HostHasSquareBraces() throws Exception {
// Use a proxy to fake IPv6 connectivity, even if localhost doesn't have IPv6.
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.setProtocols(Collections.singletonList(Protocol.HTTP_1_1));
server.enqueue(new MockResponse()
.setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
@@ -2545,7 +2544,7 @@ private void upload(
.setBody("response body"));
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.proxy(server.toProxyAddress())
.build();
@@ -2658,10 +2657,10 @@ private void enableProtocol(Protocol protocol) {
private void enableTls() {
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build();
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
}
private Buffer gzip(String data) throws IOException {
@@ -2710,6 +2709,6 @@ public List getSocketsCreated() {
* for details.
*/
private FallbackTestClientSocketFactory suppressTlsFallbackClientSocketFactory() {
- return new FallbackTestClientSocketFactory(sslContext.getSocketFactory());
+ return new FallbackTestClientSocketFactory(sslClient.socketFactory);
}
}
diff --git a/okhttp-tests/src/test/java/okhttp3/CertificateChainCleanerTest.java b/okhttp-tests/src/test/java/okhttp3/CertificateChainCleanerTest.java
index 8bfcb8c2aed2..261c99f8b65b 100644
--- a/okhttp-tests/src/test/java/okhttp3/CertificateChainCleanerTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/CertificateChainCleanerTest.java
@@ -21,7 +21,7 @@
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLPeerUnverifiedException;
-import okhttp3.internal.HeldCertificate;
+import okhttp3.internal.tls.HeldCertificate;
import okhttp3.internal.tls.CertificateChainCleaner;
import org.junit.Test;
diff --git a/okhttp-tests/src/test/java/okhttp3/CertificatePinnerTest.java b/okhttp-tests/src/test/java/okhttp3/CertificatePinnerTest.java
index 9442ddaf713f..54a51b5d7dd6 100644
--- a/okhttp-tests/src/test/java/okhttp3/CertificatePinnerTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/CertificatePinnerTest.java
@@ -21,7 +21,7 @@
import java.util.List;
import javax.net.ssl.SSLPeerUnverifiedException;
import okhttp3.CertificatePinner.Pin;
-import okhttp3.internal.HeldCertificate;
+import okhttp3.internal.tls.HeldCertificate;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
diff --git a/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java b/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java
index 2dc6bd9fd6ed..5d45f0b7217b 100644
--- a/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java
@@ -21,7 +21,7 @@
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocketFactory;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.SocketPolicy;
@@ -39,7 +39,7 @@ public final class ConnectionReuseTest {
@Rule public final TestRule timeout = new Timeout(30_000);
@Rule public final MockWebServer server = new MockWebServer();
- private SSLContext sslContext = SslContextBuilder.localhost();
+ private SslClient sslClient = SslClient.localhost();
private OkHttpClient client = defaultClient();
@Test public void connectionsAreReused() throws Exception {
@@ -335,11 +335,11 @@ private void enableHttp2() {
private void enableHttpsAndAlpn(Protocol... protocols) {
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.protocols(Arrays.asList(protocols))
.build();
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.setProtocols(client.protocols());
}
diff --git a/okhttp-tests/src/test/java/okhttp3/DelegatingSSLSocket.java b/okhttp-tests/src/test/java/okhttp3/DelegatingSSLSocket.java
index f07559387b6a..fc863c202205 100644
--- a/okhttp-tests/src/test/java/okhttp3/DelegatingSSLSocket.java
+++ b/okhttp-tests/src/test/java/okhttp3/DelegatingSSLSocket.java
@@ -18,10 +18,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
+import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
+import java.net.SocketOption;
import java.nio.channels.SocketChannel;
+import java.util.Set;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
@@ -280,4 +284,55 @@ public DelegatingSSLSocket(SSLSocket delegate) {
@Override public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
delegate.setPerformancePreferences(connectionTime, latency, bandwidth);
}
+
+ // Java 9 methods.
+
+ public SSLSession getHandshakeSession() {
+ try {
+ return (SSLSession) SSLSocket.class.getMethod("getHandshakeSession").invoke(delegate);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+ }
+
+ public String getApplicationProtocol() {
+ try {
+ return (String) SSLSocket.class.getMethod("getApplicationProtocol").invoke(delegate);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+ }
+
+ public String getHandshakeApplicationProtocol() {
+ try {
+ return (String) SSLSocket.class.getMethod("getHandshakeApplicationProtocol").invoke(delegate);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+ }
+
+ public Socket setOption(SocketOption name, T value) throws IOException {
+ try {
+ SSLSocket.class.getMethod("setOption", SocketOption.class, Object.class).invoke(delegate, name, value);
+ return this;
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+ }
+
+ public T getOption(SocketOption name) throws IOException {
+ try {
+ return (T) SSLSocket.class.getMethod("getOption", SocketOption.class).invoke(delegate, name);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+ }
+
+ public Set> supportedOptions() {
+ try {
+ return (Set>) SSLSocket.class.getMethod("supportedOptions").invoke(delegate);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+ }
}
diff --git a/okhttp-tests/src/test/java/okhttp3/URLConnectionTest.java b/okhttp-tests/src/test/java/okhttp3/URLConnectionTest.java
index 2c3c8bde1e68..cdfc26a76d91 100644
--- a/okhttp-tests/src/test/java/okhttp3/URLConnectionTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/URLConnectionTest.java
@@ -34,7 +34,7 @@
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
-import java.security.SecureRandom;
+import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -56,16 +56,16 @@
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.internal.DoubleInetAddressDns;
import okhttp3.internal.Internal;
-import okhttp3.internal.Platform;
import okhttp3.internal.RecordingAuthenticator;
import okhttp3.internal.RecordingOkAuthenticator;
import okhttp3.internal.SingleInetAddressDns;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.Util;
import okhttp3.internal.Version;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
@@ -101,6 +101,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
/** Android's URLConnectionTest. */
public final class URLConnectionTest {
@@ -108,7 +109,7 @@ public final class URLConnectionTest {
@Rule public final MockWebServer server2 = new MockWebServer();
@Rule public final TemporaryFolder tempDir = new TemporaryFolder();
- private SSLContext sslContext = SslContextBuilder.localhost();
+ private SslClient sslClient = SslClient.localhost();
private OkUrlFactory urlFactory;
private HttpURLConnection connection;
private Cache cache;
@@ -519,11 +520,11 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
}
@Test public void connectViaHttps() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
connection = urlFactory.open(server.url("/foo").url());
@@ -535,11 +536,11 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
}
@Test public void inspectHandshakeThroughoutRequestLifecycle() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse());
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
@@ -567,16 +568,16 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
}
@Test public void connectViaHttpsReusingConnections() throws IOException, InterruptedException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
server.enqueue(new MockResponse().setBody("another response via HTTPS"));
// The pool will only reuse sockets if the SSL socket factories are the same.
- SSLSocketFactory clientSocketFactory = sslContext.getSocketFactory();
+ SSLSocketFactory clientSocketFactory = sslClient.socketFactory;
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(clientSocketFactory)
+ .sslSocketFactory(clientSocketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
connection = urlFactory.open(server.url("/").url());
@@ -590,13 +591,13 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
}
@Test public void connectViaHttpsReusingConnectionsDifferentFactories() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
server.enqueue(new MockResponse().setBody("another response via HTTPS"));
// install a custom SSL socket factory so the server can be authorized
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
HttpURLConnection connection1 = urlFactory.open(server.url("/").url());
@@ -605,8 +606,14 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
SSLContext sslContext2 = SSLContext.getInstance("TLS");
sslContext2.init(null, null, null);
SSLSocketFactory sslSocketFactory2 = sslContext2.getSocketFactory();
+
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init((KeyStore) null);
+ X509TrustManager trustManager = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
+
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslSocketFactory2)
+ .sslSocketFactory(sslSocketFactory2, trustManager)
.build());
HttpURLConnection connection2 = urlFactory.open(server.url("/").url());
try {
@@ -619,13 +626,13 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
// TODO(jwilson): tests below this marker need to be migrated to OkHttp's request/response API.
@Test public void connectViaHttpsWithSSLFallback() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setBody("this response comes via SSL"));
urlFactory.setClient(urlFactory.client().newBuilder()
.hostnameVerifier(new RecordingHostnameVerifier())
- .sslSocketFactory(suppressTlsFallbackClientSocketFactory())
+ .sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager)
.build());
connection = urlFactory.open(server.url("/foo").url());
@@ -640,14 +647,14 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
}
@Test public void connectViaHttpsWithSSLFallbackFailuresRecorded() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setSocketPolicy(FAIL_HANDSHAKE));
urlFactory.setClient(urlFactory.client().newBuilder()
.dns(new SingleInetAddressDns())
.hostnameVerifier(new RecordingHostnameVerifier())
- .sslSocketFactory(suppressTlsFallbackClientSocketFactory())
+ .sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager)
.build());
connection = urlFactory.open(server.url("/foo").url());
@@ -666,7 +673,7 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
* https://github.com/square/okhttp/issues/515
*/
@Test public void sslFallbackNotUsedWhenRecycledConnectionFails() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()
.setBody("abc")
.setSocketPolicy(DISCONNECT_AT_END));
@@ -674,7 +681,7 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
urlFactory.setClient(urlFactory.client().newBuilder()
.hostnameVerifier(new RecordingHostnameVerifier())
- .sslSocketFactory(suppressTlsFallbackClientSocketFactory())
+ .sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager)
.build());
assertContent("abc", urlFactory.open(server.url("/").url()));
@@ -700,7 +707,7 @@ private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Excep
* http://code.google.com/p/android/issues/detail?id=13178
*/
@Test public void connectViaHttpsToUntrustedServer() throws IOException, InterruptedException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse()); // unused
connection = urlFactory.open(server.url("/foo").url());
@@ -782,9 +789,9 @@ public Socket createSocket(String host, int port, InetAddress localHost, int loc
};
if (useHttps) {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
}
@@ -862,12 +869,12 @@ public Socket createSocket(String host, int port, InetAddress localHost, int loc
}
private void testConnectViaDirectProxyToHttps(ProxyConfig proxyConfig) throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
URL url = server.url("/foo").url();
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
connection = proxyConfig.connect(server, urlFactory, url);
@@ -901,14 +908,14 @@ private void testConnectViaDirectProxyToHttps(ProxyConfig proxyConfig) throws Ex
private void testConnectViaHttpProxyToHttps(ProxyConfig proxyConfig) throws Exception {
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.enqueue(
new MockResponse().setSocketPolicy(UPGRADE_TO_SSL_AT_END).clearHeaders());
server.enqueue(new MockResponse().setBody("this response comes via a secure proxy"));
URL url = new URL("https://android.com/foo");
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
connection = proxyConfig.connect(server, urlFactory, url);
@@ -930,7 +937,7 @@ private void testConnectViaHttpProxyToHttps(ProxyConfig proxyConfig) throws Exce
@Test public void connectViaHttpProxyToHttpsUsingBadProxyAndHttpResponseCache() throws Exception {
initResponseCache();
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
// The inclusion of a body in the response to a CONNECT is key to reproducing b/6754912.
MockResponse badProxyResponse = new MockResponse()
.setSocketPolicy(UPGRADE_TO_SSL_AT_END)
@@ -942,7 +949,7 @@ private void testConnectViaHttpProxyToHttps(ProxyConfig proxyConfig) throws Exce
// failure to fail permanently.
urlFactory.setClient(urlFactory.client().newBuilder()
.dns(new SingleInetAddressDns())
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.connectionSpecs(Util.immutableList(ConnectionSpec.MODERN_TLS))
.hostnameVerifier(new RecordingHostnameVerifier())
.proxy(server.toProxyAddress())
@@ -969,14 +976,14 @@ private void initResponseCache() throws IOException {
throws IOException, InterruptedException {
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.enqueue(
new MockResponse().setSocketPolicy(UPGRADE_TO_SSL_AT_END).clearHeaders());
server.enqueue(new MockResponse().setBody("encrypted response from the origin server"));
urlFactory.setClient(urlFactory.client().newBuilder()
.proxy(server.toProxyAddress())
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
@@ -1001,7 +1008,7 @@ private void initResponseCache() throws IOException {
@Test public void proxyAuthenticateOnConnect() throws Exception {
Authenticator.setDefault(new RecordingAuthenticator());
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.enqueue(new MockResponse().setResponseCode(407)
.addHeader("Proxy-Authenticate: Basic realm=\"localhost\""));
server.enqueue(
@@ -1011,7 +1018,7 @@ private void initResponseCache() throws IOException {
urlFactory.setClient(urlFactory.client().newBuilder()
.proxyAuthenticator(new JavaNetAuthenticator())
.proxy(server.toProxyAddress())
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
@@ -1036,14 +1043,14 @@ private void initResponseCache() throws IOException {
// Don't disconnect after building a tunnel with CONNECT
// http://code.google.com/p/android/issues/detail?id=37221
@Test public void proxyWithConnectionClose() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), true);
+ server.useHttps(sslClient.socketFactory, true);
server.enqueue(
new MockResponse().setSocketPolicy(UPGRADE_TO_SSL_AT_END).clearHeaders());
server.enqueue(new MockResponse().setBody("this response comes via a proxy"));
urlFactory.setClient(urlFactory.client().newBuilder()
.proxy(server.toProxyAddress())
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
@@ -1055,7 +1062,7 @@ private void initResponseCache() throws IOException {
}
@Test public void proxyWithConnectionReuse() throws IOException {
- SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+ SSLSocketFactory socketFactory = sslClient.socketFactory;
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
server.useHttps(socketFactory, true);
@@ -1066,7 +1073,7 @@ private void initResponseCache() throws IOException {
urlFactory.setClient(urlFactory.client().newBuilder()
.proxy(server.toProxyAddress())
- .sslSocketFactory(socketFactory)
+ .sslSocketFactory(socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
URL url = new URL("https://android.com/foo");
@@ -1304,11 +1311,11 @@ private void testMarkAndReset(TransferKind transferKind) throws IOException {
private void testClientConfiguredGzipContentEncodingAndConnectionReuse(TransferKind transferKind,
boolean tls) throws Exception {
if (tls) {
- SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+ SSLSocketFactory socketFactory = sslClient.socketFactory;
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
server.useHttps(socketFactory, false);
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(socketFactory)
+ .sslSocketFactory(socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build());
}
@@ -1744,11 +1751,11 @@ private void assertInvalidRequestMethod(String requestMethod) throws Exception {
* http://code.google.com/p/android/issues/detail?id=12860
*/
private void testSecureStreamingPost(StreamingMode streamingMode) throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setBody("Success!"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
connection = urlFactory.open(server.url("/").url());
@@ -1929,14 +1936,14 @@ private void testRedirected(TransferKind transferKind, boolean reuse) throws Exc
}
@Test public void redirectedOnHttps() throws IOException, InterruptedException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
.addHeader("Location: /foo")
.setBody("This page has moved!"));
server.enqueue(new MockResponse().setBody("This is the new location!"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
connection = urlFactory.open(server.url("/").url());
@@ -1951,14 +1958,14 @@ private void testRedirected(TransferKind transferKind, boolean reuse) throws Exc
}
@Test public void notRedirectedFromHttpsToHttp() throws IOException, InterruptedException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
.addHeader("Location: http://anyhost/foo")
.setBody("This page has moved!"));
urlFactory.setClient(urlFactory.client().newBuilder()
.followSslRedirects(false)
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
connection = urlFactory.open(server.url("/").url());
@@ -1980,13 +1987,13 @@ private void testRedirected(TransferKind transferKind, boolean reuse) throws Exc
@Test public void redirectedFromHttpsToHttpFollowingProtocolRedirects() throws Exception {
server2.enqueue(new MockResponse().setBody("This is insecure HTTP!"));
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
.addHeader("Location: " + server2.url("/").url())
.setBody("This page has moved!"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.followSslRedirects(true)
.build());
@@ -2000,7 +2007,7 @@ private void testRedirected(TransferKind transferKind, boolean reuse) throws Exc
}
@Test public void redirectedFromHttpToHttpsFollowingProtocolRedirects() throws Exception {
- server2.useHttps(sslContext.getSocketFactory(), false);
+ server2.useHttps(sslClient.socketFactory, false);
server2.enqueue(new MockResponse().setBody("This is secure HTTPS!"));
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
@@ -2008,7 +2015,7 @@ private void testRedirected(TransferKind transferKind, boolean reuse) throws Exc
.setBody("This page has moved!"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.followSslRedirects(true)
.build());
@@ -2027,11 +2034,11 @@ private void testRedirected(TransferKind transferKind, boolean reuse) throws Exc
private void redirectToAnotherOriginServer(boolean https) throws Exception {
if (https) {
- server.useHttps(sslContext.getSocketFactory(), false);
- server2.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
+ server2.useHttps(sslClient.socketFactory, false);
server2.setProtocolNegotiationEnabled(false);
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build());
}
@@ -2309,15 +2316,15 @@ private void testRedirect(boolean temporary, String method) throws Exception {
@Test public void httpsWithCustomTrustManager() throws Exception {
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
- RecordingTrustManager trustManager = new RecordingTrustManager(sslContext);
- SSLContext sc = SSLContext.getInstance("TLS");
- sc.init(null, new TrustManager[] {trustManager}, new SecureRandom());
+ RecordingTrustManager trustManager = new RecordingTrustManager(sslClient.trustManager);
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, new TrustManager[] { trustManager }, null);
urlFactory.setClient(urlFactory.client().newBuilder()
.hostnameVerifier(hostnameVerifier)
- .sslSocketFactory(sc.getSocketFactory())
+ .sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.build());
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setBody("ABC"));
server.enqueue(new MockResponse().setBody("DEF"));
server.enqueue(new MockResponse().setBody("GHI"));
@@ -3451,6 +3458,18 @@ private void zeroLengthPayload(String method)
testInstanceFollowsRedirects("https://www.google.com/");
}
+ @Test public void setSslSocketFactoryFailsOnJdk9() throws Exception {
+ assumeTrue(getPlatform().equals("jdk9"));
+
+ URL url = server.url("/").url();
+ HttpsURLConnection connection = (HttpsURLConnection) urlFactory.open(url);
+ try {
+ connection.setSSLSocketFactory(sslClient.socketFactory);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
private void testInstanceFollowsRedirects(String spec) throws Exception {
URL url = new URL(spec);
HttpURLConnection urlConnection = urlFactory.open(url);
@@ -3589,8 +3608,8 @@ private static class RecordingTrustManager implements X509TrustManager {
private final List calls = new ArrayList();
private final X509TrustManager delegate;
- public RecordingTrustManager(SSLContext sslContext) {
- this.delegate = Platform.get().trustManager(sslContext.getSocketFactory());
+ public RecordingTrustManager(X509TrustManager delegate) {
+ this.delegate = delegate;
}
public X509Certificate[] getAcceptedIssuers() {
@@ -3622,11 +3641,11 @@ private String certificatesToString(X509Certificate[] certificates) {
*/
private void enableProtocol(Protocol protocol) {
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.protocols(Arrays.asList(protocol, Protocol.HTTP_1_1))
.build());
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.setProtocolNegotiationEnabled(true);
server.setProtocols(urlFactory.client().protocols());
}
@@ -3637,6 +3656,10 @@ private void enableProtocol(Protocol protocol) {
* for details.
*/
private FallbackTestClientSocketFactory suppressTlsFallbackClientSocketFactory() {
- return new FallbackTestClientSocketFactory(sslContext.getSocketFactory());
+ return new FallbackTestClientSocketFactory(sslClient.socketFactory);
+ }
+
+ private String getPlatform() {
+ return System.getProperty("okhttp.platform", "platform");
}
}
diff --git a/okhttp-tests/src/test/java/okhttp3/internal/ConnectionSpecSelectorTest.java b/okhttp-tests/src/test/java/okhttp3/internal/ConnectionSpecSelectorTest.java
index b6aa5344c2c8..96c6585a3415 100644
--- a/okhttp-tests/src/test/java/okhttp3/internal/ConnectionSpecSelectorTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/internal/ConnectionSpecSelectorTest.java
@@ -20,11 +20,11 @@
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import okhttp3.ConnectionSpec;
import okhttp3.TlsVersion;
+import okhttp3.internal.tls.SslClient;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -39,7 +39,7 @@ public class ConnectionSpecSelectorTest {
public static final SSLHandshakeException RETRYABLE_EXCEPTION = new SSLHandshakeException(
"Simulated handshake exception");
- private SSLContext sslContext = SslContextBuilder.localhost();
+ private SslClient sslClient = SslClient.localhost();
@Test
public void nonRetryableIOException() throws Exception {
@@ -120,7 +120,7 @@ private static ConnectionSpecSelector createConnectionSpecSelector(
}
private SSLSocket createSocketWithEnabledProtocols(TlsVersion... tlsVersions) throws IOException {
- SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket();
+ SSLSocket socket = (SSLSocket) sslClient.socketFactory.createSocket();
socket.setEnabledProtocols(javaNames(tlsVersions));
return socket;
}
diff --git a/okhttp-tests/src/test/java/okhttp3/internal/framed/HttpOverSpdyTest.java b/okhttp-tests/src/test/java/okhttp3/internal/framed/HttpOverSpdyTest.java
index c189d6be1a3b..23923d9cb4b3 100644
--- a/okhttp-tests/src/test/java/okhttp3/internal/framed/HttpOverSpdyTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/internal/framed/HttpOverSpdyTest.java
@@ -25,7 +25,6 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Cookie;
@@ -41,8 +40,8 @@
import okhttp3.internal.DoubleInetAddressDns;
import okhttp3.internal.RecordingOkAuthenticator;
import okhttp3.internal.SingleInetAddressDns;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.Util;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
@@ -74,7 +73,7 @@ public abstract class HttpOverSpdyTest {
private final Protocol protocol;
protected String hostHeader = ":host";
- protected SSLContext sslContext = SslContextBuilder.localhost();
+ protected SslClient sslClient = SslClient.localhost();
protected HostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
protected OkHttpClient client;
protected Cache cache;
@@ -84,12 +83,12 @@ protected HttpOverSpdyTest(Protocol protocol) {
}
@Before public void setUp() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
cache = new Cache(tempDir.getRoot(), Integer.MAX_VALUE);
client = new OkHttpClient.Builder()
.protocols(Arrays.asList(protocol, Protocol.HTTP_1_1))
.dns(new SingleInetAddressDns())
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(hostnameVerifier)
.build();
}
diff --git a/okhttp-tests/src/test/java/okhttp3/internal/http/RouteSelectorTest.java b/okhttp-tests/src/test/java/okhttp3/internal/http/RouteSelectorTest.java
index 7f0b47037d30..b1e3fca3052f 100644
--- a/okhttp-tests/src/test/java/okhttp3/internal/http/RouteSelectorTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/internal/http/RouteSelectorTest.java
@@ -30,7 +30,6 @@
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.Address;
import okhttp3.Authenticator;
@@ -39,8 +38,8 @@
import okhttp3.Protocol;
import okhttp3.Route;
import okhttp3.internal.RouteDatabase;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.Util;
+import okhttp3.internal.tls.SslClient;
import org.junit.Before;
import org.junit.Test;
@@ -68,8 +67,8 @@ public final class RouteSelectorTest {
private int uriPort = 1003;
private SocketFactory socketFactory;
- private final SSLContext sslContext = SslContextBuilder.localhost();
- private final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+ private final SslClient sslClient = SslClient.localhost();
+ private final SSLSocketFactory sslSocketFactory = sslClient.socketFactory;
private HostnameVerifier hostnameVerifier;
private final Authenticator authenticator = Authenticator.NONE;
diff --git a/okhttp-tests/src/test/java/okhttp3/internal/tls/CertificatePinnerChainValidationTest.java b/okhttp-tests/src/test/java/okhttp3/internal/tls/CertificatePinnerChainValidationTest.java
index 8c50399878e8..4b59edbf6e1e 100644
--- a/okhttp-tests/src/test/java/okhttp3/internal/tls/CertificatePinnerChainValidationTest.java
+++ b/okhttp-tests/src/test/java/okhttp3/internal/tls/CertificatePinnerChainValidationTest.java
@@ -15,7 +15,6 @@
*/
package okhttp3.internal.tls;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import okhttp3.Call;
@@ -24,8 +23,6 @@
import okhttp3.RecordingHostnameVerifier;
import okhttp3.Request;
import okhttp3.Response;
-import okhttp3.internal.HeldCertificate;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.SocketPolicy;
@@ -60,19 +57,19 @@ public final class CertificatePinnerChainValidationTest {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(server.getHostName(), CertificatePinner.pin(rootCa.certificate))
.build();
- SSLContext clientContext = new SslContextBuilder()
+ SslClient sslClient = new SslClient.Builder()
.addTrustedCertificate(rootCa.certificate)
.build();
OkHttpClient client = new OkHttpClient.Builder()
- .sslSocketFactory(clientContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.certificatePinner(certificatePinner)
.build();
- SSLContext serverSslContext = new SslContextBuilder()
+ SslClient serverSslClient = new SslClient.Builder()
.certificateChain(certificate, intermediateCa)
.build();
- server.useHttps(serverSslContext.getSocketFactory(), false);
+ server.useHttps(serverSslClient.socketFactory, false);
// The request should complete successfully.
server.enqueue(new MockResponse()
@@ -116,19 +113,19 @@ public final class CertificatePinnerChainValidationTest {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(server.getHostName(), CertificatePinner.pin(intermediateCa.certificate))
.build();
- SSLContext clientContext = new SslContextBuilder()
+ SslClient contextBuilder = new SslClient.Builder()
.addTrustedCertificate(rootCa.certificate)
.build();
OkHttpClient client = new OkHttpClient.Builder()
- .sslSocketFactory(clientContext.getSocketFactory())
+ .sslSocketFactory(contextBuilder.socketFactory, contextBuilder.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.certificatePinner(certificatePinner)
.build();
- SSLContext serverSslContext = new SslContextBuilder()
- .certificateChain(certificate, intermediateCa)
+ SslClient serverSslContext = new SslClient.Builder()
+ .certificateChain(certificate.keyPair, certificate.certificate, intermediateCa.certificate)
.build();
- server.useHttps(serverSslContext.getSocketFactory(), false);
+ server.useHttps(serverSslContext.socketFactory, false);
// The request should complete successfully.
server.enqueue(new MockResponse()
@@ -176,11 +173,11 @@ public final class CertificatePinnerChainValidationTest {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(server.getHostName(), CertificatePinner.pin(goodCertificate.certificate))
.build();
- SSLContext clientContext = new SslContextBuilder()
+ SslClient clientContextBuilder = new SslClient.Builder()
.addTrustedCertificate(rootCa.certificate)
.build();
OkHttpClient client = new OkHttpClient.Builder()
- .sslSocketFactory(clientContext.getSocketFactory())
+ .sslSocketFactory(clientContextBuilder.socketFactory, clientContextBuilder.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.certificatePinner(certificatePinner)
.build();
@@ -200,10 +197,10 @@ public final class CertificatePinnerChainValidationTest {
.issuedBy(compromisedIntermediateCa)
.commonName(server.getHostName())
.build();
- SSLContext serverSslContext = new SslContextBuilder()
- .certificateChain(rogueCertificate, compromisedIntermediateCa, goodCertificate, rootCa)
+ SslClient serverSslContext = new SslClient.Builder()
+ .certificateChain(rogueCertificate.keyPair, rogueCertificate.certificate, compromisedIntermediateCa.certificate, goodCertificate.certificate, rootCa.certificate)
.build();
- server.useHttps(serverSslContext.getSocketFactory(), false);
+ server.useHttps(serverSslContext.socketFactory, false);
server.enqueue(new MockResponse()
.setBody("abc")
.addHeader("Content-Type: text/plain"));
@@ -249,12 +246,12 @@ public final class CertificatePinnerChainValidationTest {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(server.getHostName(), CertificatePinner.pin(goodIntermediateCa.certificate))
.build();
- SSLContext clientContext = new SslContextBuilder()
+ SslClient clientContextBuilder = new SslClient.Builder()
.addTrustedCertificate(rootCa.certificate)
.addTrustedCertificate(compromisedRootCa.certificate)
.build();
OkHttpClient client = new OkHttpClient.Builder()
- .sslSocketFactory(clientContext.getSocketFactory())
+ .sslSocketFactory(clientContextBuilder.socketFactory, clientContextBuilder.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.certificatePinner(certificatePinner)
.build();
@@ -274,11 +271,11 @@ public final class CertificatePinnerChainValidationTest {
.issuedBy(compromisedIntermediateCa)
.commonName(server.getHostName())
.build();
- SSLContext serverSslContext = new SslContextBuilder()
+ SslClient serverSslContext = new SslClient.Builder()
.certificateChain(
- rogueCertificate, goodIntermediateCa, compromisedIntermediateCa, compromisedRootCa)
+ rogueCertificate.keyPair, rogueCertificate.certificate, goodIntermediateCa.certificate, compromisedIntermediateCa.certificate, compromisedRootCa.certificate)
.build();
- server.useHttps(serverSslContext.getSocketFactory(), false);
+ server.useHttps(serverSslContext.socketFactory, false);
server.enqueue(new MockResponse()
.setBody("abc")
.addHeader("Content-Type: text/plain"));
diff --git a/okhttp-urlconnection/src/main/java/okhttp3/internal/huc/HttpsURLConnectionImpl.java b/okhttp-urlconnection/src/main/java/okhttp3/internal/huc/HttpsURLConnectionImpl.java
index 1bf1fa6566ee..05e26353c415 100644
--- a/okhttp-urlconnection/src/main/java/okhttp3/internal/huc/HttpsURLConnectionImpl.java
+++ b/okhttp-urlconnection/src/main/java/okhttp3/internal/huc/HttpsURLConnectionImpl.java
@@ -63,6 +63,7 @@ public HttpsURLConnectionImpl(HttpURLConnectionImpl delegate) {
}
@Override public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
+ // This fails in JDK 9 because OkHttp is unable to extract the trust manager.
delegate.client = delegate.client.newBuilder()
.sslSocketFactory(sslSocketFactory)
.build();
diff --git a/okhttp-urlconnection/src/test/java/okhttp3/OkUrlFactoryTest.java b/okhttp-urlconnection/src/test/java/okhttp3/OkUrlFactoryTest.java
index 39f6066805dd..985e545c7fd1 100644
--- a/okhttp-urlconnection/src/test/java/okhttp3/OkUrlFactoryTest.java
+++ b/okhttp-urlconnection/src/test/java/okhttp3/OkUrlFactoryTest.java
@@ -11,11 +11,10 @@
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.URLFilter;
import okhttp3.internal.http.OkHeaders;
import okhttp3.internal.io.InMemoryFileSystem;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okio.BufferedSource;
@@ -184,10 +183,10 @@ public void testURLFilterRedirect() throws Exception {
.setBody("Blocked!"));
final URL blockedURL = cleartextServer.url("/").url();
- SSLContext context = SslContextBuilder.localhost();
- server.useHttps(context.getSocketFactory(), false);
+ SslClient contextBuilder = SslClient.localhost();
+ server.useHttps(contextBuilder.socketFactory, false);
factory.setClient(factory.client().newBuilder()
- .sslSocketFactory(context.getSocketFactory())
+ .sslSocketFactory(contextBuilder.socketFactory, contextBuilder.trustManager)
.followSslRedirects(true)
.build());
factory.setUrlFilter(new URLFilter() {
diff --git a/okhttp-urlconnection/src/test/java/okhttp3/UrlConnectionCacheTest.java b/okhttp-urlconnection/src/test/java/okhttp3/UrlConnectionCacheTest.java
index a5b1107868f6..693af67443ab 100644
--- a/okhttp-urlconnection/src/test/java/okhttp3/UrlConnectionCacheTest.java
+++ b/okhttp-urlconnection/src/test/java/okhttp3/UrlConnectionCacheTest.java
@@ -40,12 +40,11 @@
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import okhttp3.internal.Internal;
-import okhttp3.internal.SslContextBuilder;
import okhttp3.internal.Util;
import okhttp3.internal.io.InMemoryFileSystem;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
@@ -66,6 +65,7 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
/** Test caching with {@link OkUrlFactory}. */
public final class UrlConnectionCacheTest {
@@ -79,7 +79,7 @@ public final class UrlConnectionCacheTest {
@Rule public MockWebServer server2 = new MockWebServer();
@Rule public InMemoryFileSystem fileSystem = new InMemoryFileSystem();
- private final SSLContext sslContext = SslContextBuilder.localhost();
+ private final SslClient sslClient = SslClient.localhost();
private OkUrlFactory urlFactory = new OkUrlFactory(new OkHttpClient());
private Cache cache;
private final CookieManager cookieManager = new CookieManager();
@@ -257,13 +257,15 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
}
@Test public void secureResponseCaching() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ assumeFalse(getPlatform().equals("jdk9"));
+
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
.setBody("ABC"));
HttpsURLConnection c1 = (HttpsURLConnection) urlFactory.open(server.url("/").url());
- c1.setSSLSocketFactory(sslContext.getSocketFactory());
+ c1.setSSLSocketFactory(sslClient.socketFactory);
c1.setHostnameVerifier(NULL_HOSTNAME_VERIFIER);
assertEquals("ABC", readAscii(c1));
@@ -275,7 +277,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
Principal localPrincipal = c1.getLocalPrincipal();
HttpsURLConnection c2 = (HttpsURLConnection) urlFactory.open(server.url("/").url()); // cached!
- c2.setSSLSocketFactory(sslContext.getSocketFactory());
+ c2.setSSLSocketFactory(sslClient.socketFactory);
c2.setHostnameVerifier(NULL_HOSTNAME_VERIFIER);
assertEquals("ABC", readAscii(c2));
@@ -335,7 +337,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
}
@Test public void secureResponseCachingAndRedirects() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
.setResponseCode(HttpURLConnection.HTTP_MOVED_PERM)
@@ -346,7 +348,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
server.enqueue(new MockResponse().setBody("DEF"));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(NULL_HOSTNAME_VERIFIER)
.build());
@@ -372,7 +374,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
* https://github.com/square/okhttp/issues/214
*/
@Test public void secureResponseCachingAndProtocolRedirects() throws IOException {
- server2.useHttps(sslContext.getSocketFactory(), false);
+ server2.useHttps(sslClient.socketFactory, false);
server2.enqueue(new MockResponse().addHeader("Last-Modified: " + formatDate(-1, TimeUnit.HOURS))
.addHeader("Expires: " + formatDate(1, TimeUnit.HOURS))
.setBody("ABC"));
@@ -384,7 +386,7 @@ private void testResponseCaching(TransferKind transferKind) throws IOException {
.addHeader("Location: " + server2.url("/").url()));
urlFactory.setClient(urlFactory.client().newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(NULL_HOSTNAME_VERIFIER)
.build());
@@ -1400,7 +1402,9 @@ private RecordedRequest assertClientSuppliedCondition(MockResponse seed, String
}
@Test public void varyAndHttps() throws Exception {
- server.useHttps(sslContext.getSocketFactory(), false);
+ assumeFalse(getPlatform().equals("jdk9"));
+
+ server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().addHeader("Cache-Control: max-age=60")
.addHeader("Vary: Accept-Language")
.setBody("A"));
@@ -1408,13 +1412,13 @@ private RecordedRequest assertClientSuppliedCondition(MockResponse seed, String
URL url = server.url("/").url();
HttpsURLConnection connection1 = (HttpsURLConnection) urlFactory.open(url);
- connection1.setSSLSocketFactory(sslContext.getSocketFactory());
+ connection1.setSSLSocketFactory(sslClient.socketFactory);
connection1.setHostnameVerifier(NULL_HOSTNAME_VERIFIER);
connection1.addRequestProperty("Accept-Language", "en-US");
assertEquals("A", readAscii(connection1));
HttpsURLConnection connection2 = (HttpsURLConnection) urlFactory.open(url);
- connection2.setSSLSocketFactory(sslContext.getSocketFactory());
+ connection2.setSSLSocketFactory(sslClient.socketFactory);
connection2.setHostnameVerifier(NULL_HOSTNAME_VERIFIER);
connection2.addRequestProperty("Accept-Language", "en-US");
assertEquals("A", readAscii(connection2));
@@ -1834,4 +1838,8 @@ public Buffer gzip(String data) throws IOException {
sink.close();
return result;
}
+
+ private String getPlatform() {
+ return System.getProperty("okhttp.platform", "platform");
+ }
}
diff --git a/okhttp-ws-tests/src/test/java/okhttp3/ws/WebSocketCallTest.java b/okhttp-ws-tests/src/test/java/okhttp3/ws/WebSocketCallTest.java
index 2e66deca89cc..06dd4a2e281c 100644
--- a/okhttp-ws-tests/src/test/java/okhttp3/ws/WebSocketCallTest.java
+++ b/okhttp-ws-tests/src/test/java/okhttp3/ws/WebSocketCallTest.java
@@ -21,16 +21,15 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import javax.net.ssl.SSLContext;
import okhttp3.OkHttpClient;
+import okhttp3.RecordingHostnameVerifier;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
-import okhttp3.internal.SslContextBuilder;
+import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
-import okhttp3.RecordingHostnameVerifier;
import okio.Buffer;
import org.junit.After;
import org.junit.Rule;
@@ -41,7 +40,7 @@
public final class WebSocketCallTest {
@Rule public final MockWebServer server = new MockWebServer();
- private final SSLContext sslContext = SslContextBuilder.localhost();
+ private final SslClient sslClient = SslClient.localhost();
private final WebSocketRecorder listener = new WebSocketRecorder();
private final Random random = new Random(0);
private OkHttpClient client = new OkHttpClient();
@@ -185,9 +184,9 @@ public final class WebSocketCallTest {
}
@Test public void wssScheme() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build();
@@ -195,9 +194,9 @@ public final class WebSocketCallTest {
}
@Test public void httpsScheme() throws IOException {
- server.useHttps(sslContext.getSocketFactory(), false);
+ server.useHttps(sslClient.socketFactory, false);
client = client.newBuilder()
- .sslSocketFactory(sslContext.getSocketFactory())
+ .sslSocketFactory(sslClient.socketFactory, sslClient.trustManager)
.hostnameVerifier(new RecordingHostnameVerifier())
.build();
diff --git a/okhttp/src/main/java/okhttp3/internal/Jdk9Platform.java b/okhttp/src/main/java/okhttp3/internal/Jdk9Platform.java
index 94677ebe225c..1cd04f965af0 100644
--- a/okhttp/src/main/java/okhttp3/internal/Jdk9Platform.java
+++ b/okhttp/src/main/java/okhttp3/internal/Jdk9Platform.java
@@ -20,6 +20,8 @@
import java.util.List;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509TrustManager;
import okhttp3.Protocol;
/**
@@ -36,14 +38,14 @@ public Jdk9Platform(Method setProtocolMethod, Method getProtocolMethod) {
@Override
public void configureTlsExtensions(SSLSocket sslSocket, String hostname,
- List protocols) {
+ List protocols) {
try {
SSLParameters sslParameters = sslSocket.getSSLParameters();
List names = alpnProtocolNames(protocols);
setProtocolMethod.invoke(sslParameters,
- new Object[]{names.toArray(new String[names.size()])});
+ new Object[] {names.toArray(new String[names.size()])});
sslSocket.setSSLParameters(sslParameters);
} catch (IllegalAccessException | InvocationTargetException e) {
@@ -68,6 +70,15 @@ public String getSelectedProtocol(SSLSocket socket) {
}
}
+ @Override public X509TrustManager trustManager(SSLSocketFactory sslSocketFactory) {
+ // Not supported due to access checks on JDK 9+:
+ // java.lang.reflect.InaccessibleObjectException: Unable to make member of class
+ // sun.security.ssl.SSLSocketFactoryImpl accessible: module java.base does not export
+ // sun.security.ssl to unnamed module @xxx
+ throw new UnsupportedOperationException(
+ "clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on JDK 9+");
+ }
+
public static Jdk9Platform buildIfSupported() {
// Find JDK 9 new methods
try {
diff --git a/pom.xml b/pom.xml
index 52054e950364..4be0178ea073 100644
--- a/pom.xml
+++ b/pom.xml
@@ -304,7 +304,7 @@
jdk9
- 1.9
+ 9
jdk9