1
0
mirror of https://github.com/square/okhttp.git synced 2025-08-07 12:42:57 +03:00

Get more TLS stuff passing on BouncyCastle (#7602)

There's something up with ECDSA on BouncyCastle, and rather
than figuring it out I've just switched to RSA signatures
with that provider.
This commit is contained in:
Jesse Wilson
2022-12-31 20:39:55 -05:00
committed by GitHub
parent 60d5b73fb8
commit fe6db78647
26 changed files with 123 additions and 124 deletions

View File

@@ -50,17 +50,14 @@ import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.junit.runners.model.Statement; import org.junit.runners.model.Statement;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static okhttp3.tls.internal.TlsUtil.localhost;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset; import static org.assertj.core.data.Offset.offset;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
@SuppressWarnings({"ArraysAsListWithZeroOrOneArgument", "deprecation"}) @SuppressWarnings({"ArraysAsListWithZeroOrOneArgument", "deprecation"})
@Timeout(30) @Timeout(30)
@@ -71,7 +68,6 @@ public final class MockWebServerTest {
private final MockWebServer server = new MockWebServer(); private final MockWebServer server = new MockWebServer();
@BeforeEach public void setUp() throws IOException { @BeforeEach public void setUp() throws IOException {
platform.assumeNotBouncyCastle();
server.start(); server.start();
} }
@@ -540,7 +536,7 @@ public final class MockWebServerTest {
} }
@Test public void https() throws Exception { @Test public void https() throws Exception {
HandshakeCertificates handshakeCertificates = localhost(); HandshakeCertificates handshakeCertificates = platform.localhostHandshakeCertificates();
server.useHttps(handshakeCertificates.sslSocketFactory(), false); server.useHttps(handshakeCertificates.sslSocketFactory(), false);
server.enqueue(new MockResponse().setBody("abc")); server.enqueue(new MockResponse().setBody("abc"));
@@ -566,7 +562,8 @@ public final class MockWebServerTest {
} }
@Test public void httpsWithClientAuth() throws Exception { @Test public void httpsWithClientAuth() throws Exception {
assumeFalse(getPlatform().equals("conscrypt")); platform.assumeNotBouncyCastle();
platform.assumeNotConscrypt();
HeldCertificate clientCa = new HeldCertificate.Builder() HeldCertificate clientCa = new HeldCertificate.Builder()
.certificateAuthority(0) .certificateAuthority(0)

View File

@@ -25,7 +25,6 @@ import java.net.ProtocolException
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
import java.nio.charset.StandardCharsets.UTF_8 import java.nio.charset.StandardCharsets.UTF_8
import java.time.Duration import java.time.Duration
import java.util.Arrays
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
import okhttp3.Headers import okhttp3.Headers
@@ -38,13 +37,11 @@ import okhttp3.TestUtil.assumeNotWindows
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.HeldCertificate import okhttp3.tls.HeldCertificate
import okhttp3.tls.internal.TlsUtil.localhost
import okio.Buffer import okio.Buffer
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.data.Offset import org.assertj.core.data.Offset
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.Assumptions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
@@ -64,7 +61,6 @@ class MockWebServerTest {
@BeforeEach @BeforeEach
fun setUp(server: MockWebServer) { fun setUp(server: MockWebServer) {
this.server = server this.server = server
platform.assumeNotBouncyCastle()
server.start() server.start()
} }
@@ -564,7 +560,7 @@ class MockWebServerTest {
@Test @Test
fun https() { fun https() {
val handshakeCertificates = localhost() val handshakeCertificates = platform.localhostHandshakeCertificates()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
server.enqueue(MockResponse.Builder() server.enqueue(MockResponse.Builder()
.body("abc") .body("abc")
@@ -589,7 +585,9 @@ class MockWebServerTest {
@Test @Test
fun httpsWithClientAuth() { fun httpsWithClientAuth() {
Assumptions.assumeFalse(getPlatform() == "conscrypt") platform.assumeNotBouncyCastle()
platform.assumeNotConscrypt()
val clientCa = HeldCertificate.Builder() val clientCa = HeldCertificate.Builder()
.certificateAuthority(0) .certificateAuthority(0)
.build() .build()

View File

@@ -45,9 +45,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import static okhttp3.RequestBody.gzip; import static okhttp3.RequestBody.gzip;
import static okhttp3.tls.internal.TlsUtil.localhost;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue;
@@ -59,7 +57,8 @@ public final class HttpLoggingInterceptorTest {
@RegisterExtension public final PlatformRule platform = new PlatformRule(); @RegisterExtension public final PlatformRule platform = new PlatformRule();
private MockWebServer server; private MockWebServer server;
private final HandshakeCertificates handshakeCertificates = localhost(); private final HandshakeCertificates handshakeCertificates
= platform.localhostHandshakeCertificates();
private final HostnameVerifier hostnameVerifier = new RecordingHostnameVerifier(); private final HostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
private OkHttpClient client; private OkHttpClient client;
private String host; private String host;
@@ -848,8 +847,6 @@ public final class HttpLoggingInterceptorTest {
} }
@Test public void http2() throws Exception { @Test public void http2() throws Exception {
platform.assumeNotBouncyCastle();
server.useHttps(handshakeCertificates.sslSocketFactory()); server.useHttps(handshakeCertificates.sslSocketFactory());
url = server.url("/"); url = server.url("/");
@@ -930,7 +927,6 @@ public final class HttpLoggingInterceptorTest {
@Test public void duplexRequestsAreNotLogged() throws Exception { @Test public void duplexRequestsAreNotLogged() throws Exception {
platform.assumeHttp2Support(); platform.assumeHttp2Support();
platform.assumeNotBouncyCastle();
server.useHttps(handshakeCertificates.sslSocketFactory()); // HTTP/2 server.useHttps(handshakeCertificates.sslSocketFactory()); // HTTP/2
url = server.url("/"); url = server.url("/");

View File

@@ -37,11 +37,9 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static okhttp3.Protocol.HTTP_1_1; import static okhttp3.Protocol.HTTP_1_1;
import static okhttp3.Protocol.HTTP_2; import static okhttp3.Protocol.HTTP_2;
import static okhttp3.tls.internal.TlsUtil.localhost;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@@ -53,7 +51,8 @@ public final class LoggingEventListenerTest {
@RegisterExtension public final OkHttpClientTestRule clientTestRule = new OkHttpClientTestRule(); @RegisterExtension public final OkHttpClientTestRule clientTestRule = new OkHttpClientTestRule();
private MockWebServer server; private MockWebServer server;
private final HandshakeCertificates handshakeCertificates = localhost(); private final HandshakeCertificates handshakeCertificates
= platform.localhostHandshakeCertificates();
private final LogRecorder logRecorder = new LogRecorder(); private final LogRecorder logRecorder = new LogRecorder();
private final LoggingEventListener.Factory loggingEventListenerFactory = private final LoggingEventListener.Factory loggingEventListenerFactory =
new LoggingEventListener.Factory(logRecorder); new LoggingEventListener.Factory(logRecorder);
@@ -153,7 +152,6 @@ public final class LoggingEventListenerTest {
@Test @Test
public void secureGet() throws Exception { public void secureGet() throws Exception {
TestUtil.assumeNotWindows(); TestUtil.assumeNotWindows();
platform.assumeNotBouncyCastle();
server.useHttps(handshakeCertificates.sslSocketFactory()); server.useHttps(handshakeCertificates.sslSocketFactory());
url = server.url("/"); url = server.url("/");
@@ -222,7 +220,6 @@ public final class LoggingEventListenerTest {
@Test @Test
public void connectFail() { public void connectFail() {
TestUtil.assumeNotWindows(); TestUtil.assumeNotWindows();
platform.assumeNotBouncyCastle();
server.useHttps(handshakeCertificates.sslSocketFactory()); server.useHttps(handshakeCertificates.sslSocketFactory());
server.setProtocols(asList(HTTP_2, HTTP_1_1)); server.setProtocols(asList(HTTP_2, HTTP_1_1));
@@ -246,9 +243,9 @@ public final class LoggingEventListenerTest {
.assertLogMatch("connectStart: " + url.host() + "/.+ DIRECT") .assertLogMatch("connectStart: " + url.host() + "/.+ DIRECT")
.assertLogMatch("secureConnectStart") .assertLogMatch("secureConnectStart")
.assertLogMatch( .assertLogMatch(
"connectFailed: null javax\\.net\\.ssl\\.(?:SSLProtocolException|SSLHandshakeException): (?:Unexpected handshake message: client_hello|Handshake message sequence violation, 1|Read error|Handshake failed).*") "connectFailed: null \\S+(?:SSLProtocolException|SSLHandshakeException|TlsFatalAlert): (?:Unexpected handshake message: client_hello|Handshake message sequence violation, 1|Read error|Handshake failed|unexpected_message\\(10\\)).*")
.assertLogMatch( .assertLogMatch(
"callFailed: javax\\.net\\.ssl\\.(?:SSLProtocolException|SSLHandshakeException): (?:Unexpected handshake message: client_hello|Handshake message sequence violation, 1|Read error|Handshake failed).*") "callFailed: \\S+(?:SSLProtocolException|SSLHandshakeException|TlsFatalAlert): (?:Unexpected handshake message: client_hello|Handshake message sequence violation, 1|Read error|Handshake failed|unexpected_message\\(10\\)).*")
.assertNoMoreLogs(); .assertNoMoreLogs();
} }

View File

@@ -18,12 +18,18 @@ package okhttp3.testing
import android.os.Build import android.os.Build
import com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider import com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider
import com.amazon.corretto.crypto.provider.SelfTestStatus import com.amazon.corretto.crypto.provider.SelfTestStatus
import java.lang.reflect.Method
import java.net.InetAddress
import java.security.Security
import okhttp3.TestUtil import okhttp3.TestUtil
import okhttp3.internal.platform.ConscryptPlatform import okhttp3.internal.platform.ConscryptPlatform
import okhttp3.internal.platform.Jdk8WithJettyBootPlatform import okhttp3.internal.platform.Jdk8WithJettyBootPlatform
import okhttp3.internal.platform.Jdk9Platform import okhttp3.internal.platform.Jdk9Platform
import okhttp3.internal.platform.OpenJSSEPlatform import okhttp3.internal.platform.OpenJSSEPlatform
import okhttp3.internal.platform.Platform import okhttp3.internal.platform.Platform
import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.HeldCertificate
import okhttp3.tls.internal.TlsUtil.localhost
import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
import org.conscrypt.Conscrypt import org.conscrypt.Conscrypt
@@ -43,8 +49,6 @@ import org.junit.jupiter.api.extension.InvocationInterceptor
import org.junit.jupiter.api.extension.ReflectiveInvocationContext import org.junit.jupiter.api.extension.ReflectiveInvocationContext
import org.openjsse.net.ssl.OpenJSSE import org.openjsse.net.ssl.OpenJSSE
import org.opentest4j.TestAbortedException import org.opentest4j.TestAbortedException
import java.lang.reflect.Method
import java.security.Security
/** /**
* Marks a test as Platform aware, before the test runs a consistent Platform will be * Marks a test as Platform aware, before the test runs a consistent Platform will be
@@ -323,6 +327,13 @@ open class PlatformRule @JvmOverloads constructor(
} }
} }
fun localhostHandshakeCertificates(): HandshakeCertificates {
return when {
isBouncyCastle() -> localhostHandshakeCertificatesWithRsa2048
else -> localhost()
}
}
val isAndroid: Boolean val isAndroid: Boolean
get() = Platform.Companion.isAndroid get() = Platform.Companion.isAndroid
@@ -336,6 +347,24 @@ open class PlatformRule @JvmOverloads constructor(
const val OPENJSSE_PROPERTY = "openjsse" const val OPENJSSE_PROPERTY = "openjsse"
const val BOUNCYCASTLE_PROPERTY = "bouncycastle" const val BOUNCYCASTLE_PROPERTY = "bouncycastle"
/**
* For whatever reason our BouncyCastle provider doesn't work with ECDSA keys. Just configure it
* to use RSA-2048 instead.
*
* (We otherwise prefer ECDSA because it's faster.)
*/
private val localhostHandshakeCertificatesWithRsa2048: HandshakeCertificates by lazy {
val heldCertificate = HeldCertificate.Builder()
.commonName("localhost")
.addSubjectAlternativeName(InetAddress.getByName("localhost").canonicalHostName)
.rsa2048()
.build()
return@lazy HandshakeCertificates.Builder()
.heldCertificate(heldCertificate)
.addTrustedCertificate(heldCertificate.certificate)
.build()
}
init { init {
val platformSystemProperty = getPlatformSystemProperty() val platformSystemProperty = getPlatformSystemProperty()

View File

@@ -56,6 +56,7 @@ class HandshakeCertificatesTest {
@Test fun clientAndServer() { @Test fun clientAndServer() {
platform.assumeNotConscrypt() platform.assumeNotConscrypt()
platform.assumeNotBouncyCastle() platform.assumeNotBouncyCastle()
val clientRoot = HeldCertificate.Builder() val clientRoot = HeldCertificate.Builder()
.certificateAuthority(1) .certificateAuthority(1)
.build() .build()

View File

@@ -31,7 +31,6 @@ import okhttp3.Headers.Companion.headersOf
import okhttp3.internal.buildCache import okhttp3.internal.buildCache
import okhttp3.okio.LoggingFilesystem import okhttp3.okio.LoggingFilesystem
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil.localhost
import okio.Path.Companion.toPath import okio.Path.Companion.toPath
import okio.fakefilesystem.FakeFileSystem import okio.fakefilesystem.FakeFileSystem
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@@ -51,7 +50,7 @@ class CacheCorruptionTest {
@RegisterExtension @RegisterExtension
val platform = PlatformRule() val platform = PlatformRule()
private val handshakeCertificates = localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
private lateinit var client: OkHttpClient private lateinit var client: OkHttpClient
private lateinit var cache: Cache private lateinit var cache: Cache
private val NULL_HOSTNAME_VERIFIER = HostnameVerifier { _: String?, _: SSLSession? -> true } private val NULL_HOSTNAME_VERIFIER = HostnameVerifier { _: String?, _: SSLSession? -> true }
@@ -63,7 +62,6 @@ class CacheCorruptionTest {
this.server = server this.server = server
platform.assumeNotOpenJSSE() platform.assumeNotOpenJSSE()
platform.assumeNotBouncyCastle()
server.protocolNegotiationEnabled = false server.protocolNegotiationEnabled = false
val loggingFileSystem = LoggingFilesystem(fileSystem) val loggingFileSystem = LoggingFilesystem(fileSystem)
cache = buildCache("/cache/".toPath(), Int.MAX_VALUE.toLong(), loggingFileSystem) cache = buildCache("/cache/".toPath(), Int.MAX_VALUE.toLong(), loggingFileSystem)

View File

@@ -58,7 +58,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import static mockwebserver3.SocketPolicy.DISCONNECT_AT_END; import static mockwebserver3.SocketPolicy.DISCONNECT_AT_END;
import static okhttp3.internal.Internal.cacheGet; import static okhttp3.internal.Internal.cacheGet;
import static okhttp3.tls.internal.TlsUtil.localhost;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset; import static org.assertj.core.data.Offset.offset;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@@ -73,7 +72,8 @@ public final class CacheTest {
private MockWebServer server; private MockWebServer server;
private MockWebServer server2; private MockWebServer server2;
private final HandshakeCertificates handshakeCertificates = localhost(); private final HandshakeCertificates handshakeCertificates
= platform.localhostHandshakeCertificates();
private OkHttpClient client; private OkHttpClient client;
private Cache cache; private Cache cache;
private final CookieManager cookieManager = new CookieManager(); private final CookieManager cookieManager = new CookieManager();
@@ -87,7 +87,6 @@ public final class CacheTest {
this.server2 = server2; this.server2 = server2;
platform.assumeNotOpenJSSE(); platform.assumeNotOpenJSSE();
platform.assumeNotBouncyCastle();
server.setProtocolNegotiationEnabled(false); server.setProtocolNegotiationEnabled(false);
fileSystem.emulateUnix(); fileSystem.emulateUnix();

View File

@@ -31,7 +31,6 @@ import okhttp3.CipherSuite.Companion.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
import okhttp3.internal.effectiveCipherSuites import okhttp3.internal.effectiveCipherSuites
import okhttp3.internal.platform.Platform import okhttp3.internal.platform.Platform
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil.localhost
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@@ -40,7 +39,6 @@ import org.junit.jupiter.api.extension.RegisterExtension
class CallHandshakeTest { class CallHandshakeTest {
private lateinit var client: OkHttpClient private lateinit var client: OkHttpClient
private lateinit var server: MockWebServer private lateinit var server: MockWebServer
val handshakeCertificates = localhost()
@RegisterExtension @RegisterExtension
@JvmField @JvmField
@@ -50,6 +48,8 @@ class CallHandshakeTest {
@JvmField @JvmField
var platform = PlatformRule() var platform = PlatformRule()
private val handshakeCertificates = platform.localhostHandshakeCertificates()
private lateinit var handshakeEnabledCipherSuites: List<String> private lateinit var handshakeEnabledCipherSuites: List<String>
private lateinit var defaultEnabledCipherSuites: List<String> private lateinit var defaultEnabledCipherSuites: List<String>
private lateinit var defaultSupportedCipherSuites: List<String> private lateinit var defaultSupportedCipherSuites: List<String>
@@ -131,9 +131,7 @@ class CallHandshakeTest {
@Test @Test
fun testDefaultHandshakeCipherSuiteOrderingTls13Modern() { fun testDefaultHandshakeCipherSuiteOrderingTls13Modern() {
// handshake_failure(40) // We are avoiding making guarantees on ordering of secondary Platforms.
// org.bouncycastle.tls.TlsFatalAlertReceived: handshake_failure(40)
// at app//org.bouncycastle.tls.TlsProtocol.handleAlertMessage(Unknown Source)
platform.assumeNotBouncyCastle() platform.assumeNotBouncyCastle()
val client = makeClient(ConnectionSpec.MODERN_TLS, TlsVersion.TLS_1_3) val client = makeClient(ConnectionSpec.MODERN_TLS, TlsVersion.TLS_1_3)
@@ -162,10 +160,6 @@ class CallHandshakeTest {
@Test @Test
fun testHandshakeCipherSuiteOrderingWhenReversed() { fun testHandshakeCipherSuiteOrderingWhenReversed() {
// handshake_failure(40)
// org.bouncycastle.tls.TlsFatalAlertReceived: handshake_failure(40)
// at app//org.bouncycastle.tls.TlsProtocol.handleAlertMessage(Unknown Source)
// We are avoiding making guarantees on ordering of secondary Platforms. // We are avoiding making guarantees on ordering of secondary Platforms.
platform.assumeNotConscrypt() platform.assumeNotConscrypt()
platform.assumeNotBouncyCastle() platform.assumeNotBouncyCastle()
@@ -185,11 +179,6 @@ class CallHandshakeTest {
@Test @Test
fun defaultOrderMaintained() { fun defaultOrderMaintained() {
// Flaky in CI
// CallHandshakeTest[jvm] > defaultOrderMaintained()[jvm] FAILED
// org.bouncycastle.tls.TlsFatalAlertReceived: handshake_failure(40)
platform.assumeNotBouncyCastle()
val client = makeClient() val client = makeClient()
makeRequest(client) makeRequest(client)

View File

@@ -32,7 +32,6 @@ import okhttp3.internal.connection.RealConnection.Companion.IDLE_CONNECTION_HEAL
import okhttp3.internal.http.RecordingProxySelector import okhttp3.internal.http.RecordingProxySelector
import okhttp3.testing.Flaky import okhttp3.testing.Flaky
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil.localhost
import okio.BufferedSink import okio.BufferedSink
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
@@ -52,13 +51,12 @@ class CallKotlinTest {
} }
private var client = clientTestRule.newClient() private var client = clientTestRule.newClient()
private val handshakeCertificates = localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
private lateinit var server: MockWebServer private lateinit var server: MockWebServer
@BeforeEach @BeforeEach
fun setUp(server: MockWebServer) { fun setUp(server: MockWebServer) {
this.server = server this.server = server
platform.assumeNotBouncyCastle()
} }
@Test @Test

View File

@@ -75,7 +75,6 @@ import okhttp3.testing.Flaky
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.HeldCertificate import okhttp3.tls.HeldCertificate
import okhttp3.tls.internal.TlsUtil.localhost
import okio.Buffer import okio.Buffer
import okio.BufferedSink import okio.BufferedSink
import okio.ForwardingSource import okio.ForwardingSource
@@ -88,7 +87,7 @@ import org.assertj.core.data.Offset
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertArrayEquals import org.junit.jupiter.api.Assertions.assertArrayEquals
import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.Assumptions import org.junit.jupiter.api.Assumptions.assumeFalse
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
@@ -114,7 +113,7 @@ open class CallTest {
private lateinit var server2: MockWebServer private lateinit var server2: MockWebServer
private var listener = RecordingEventListener() private var listener = RecordingEventListener()
private val handshakeCertificates = localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
private var client = clientTestRule.newClientBuilder() private var client = clientTestRule.newClientBuilder()
.eventListenerFactory(clientTestRule.wrap(listener)) .eventListenerFactory(clientTestRule.wrap(listener))
.build() .build()
@@ -134,7 +133,6 @@ open class CallTest {
this.server2 = server2 this.server2 = server2
platform.assumeNotOpenJSSE() platform.assumeNotOpenJSSE()
platform.assumeNotBouncyCastle()
} }
@AfterEach @AfterEach
@@ -1205,6 +1203,8 @@ open class CallTest {
@Test @Test
fun tlsHandshakeFailure_noFallbackByDefault() { fun tlsHandshakeFailure_noFallbackByDefault() {
platform.assumeNotBouncyCastle()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE)) server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE))
server.enqueue(MockResponse(body = "response that will never be received")) server.enqueue(MockResponse(body = "response that will never be received"))
@@ -1219,6 +1219,8 @@ open class CallTest {
@Test @Test
fun recoverFromTlsHandshakeFailure() { fun recoverFromTlsHandshakeFailure() {
platform.assumeNotBouncyCastle()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE)) server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE))
server.enqueue(MockResponse(body = "abc")) server.enqueue(MockResponse(body = "abc"))
@@ -1271,6 +1273,8 @@ open class CallTest {
@Test @Test
fun recoverFromTlsHandshakeFailure_Async() { fun recoverFromTlsHandshakeFailure_Async() {
platform.assumeNotBouncyCastle()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE)) server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE))
server.enqueue(MockResponse(body = "abc")) server.enqueue(MockResponse(body = "abc"))
@@ -1291,6 +1295,8 @@ open class CallTest {
@Test @Test
fun noRecoveryFromTlsHandshakeFailureWhenTlsFallbackIsDisabled() { fun noRecoveryFromTlsHandshakeFailureWhenTlsFallbackIsDisabled() {
platform.assumeNotBouncyCastle()
client = client.newBuilder() client = client.newBuilder()
.connectionSpecs(listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT)) .connectionSpecs(listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
.hostnameVerifier(RecordingHostnameVerifier()) .hostnameVerifier(RecordingHostnameVerifier())
@@ -1319,6 +1325,8 @@ open class CallTest {
@Test @Test
fun tlsHostnameVerificationFailure() { fun tlsHostnameVerificationFailure() {
assumeNotWindows() assumeNotWindows()
platform.assumeNotBouncyCastle()
server.enqueue(MockResponse()) server.enqueue(MockResponse())
val serverCertificate = HeldCertificate.Builder() val serverCertificate = HeldCertificate.Builder()
.commonName("localhost") // Unusued for hostname verification. .commonName("localhost") // Unusued for hostname verification.
@@ -1345,9 +1353,10 @@ open class CallTest {
@Test @Test
fun anonCipherSuiteUnsupported() { fun anonCipherSuiteUnsupported() {
platform.assumeNotConscrypt() platform.assumeNotConscrypt()
platform.assumeNotBouncyCastle()
// The _anon_ suites became unsupported in "1.8.0_201" and "11.0.2". // The _anon_ suites became unsupported in "1.8.0_201" and "11.0.2".
Assumptions.assumeFalse( assumeFalse(
System.getProperty("java.version", "unknown").matches(Regex("1\\.8\\.0_1\\d\\d")) System.getProperty("java.version", "unknown").matches(Regex("1\\.8\\.0_1\\d\\d"))
) )
server.enqueue(MockResponse()) server.enqueue(MockResponse())
@@ -3964,6 +3973,8 @@ open class CallTest {
@Test @Test
fun httpsWithIpAddress() { fun httpsWithIpAddress() {
platform.assumeNotBouncyCastle()
val localIpAddress = InetAddress.getLoopbackAddress().hostAddress val localIpAddress = InetAddress.getLoopbackAddress().hostAddress
// Create a certificate with an IP address in the subject alt name. // Create a certificate with an IP address in the subject alt name.

View File

@@ -27,8 +27,8 @@ import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.internal.closeQuietly import okhttp3.internal.closeQuietly
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.internal.TlsUtil.localhost
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.bouncycastle.tls.TlsFatalAlert
import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
@@ -46,7 +46,7 @@ class ConnectionReuseTest {
val clientTestRule: OkHttpClientTestRule = OkHttpClientTestRule() val clientTestRule: OkHttpClientTestRule = OkHttpClientTestRule()
private lateinit var server: MockWebServer private lateinit var server: MockWebServer
private val handshakeCertificates: HandshakeCertificates = localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
private var client: OkHttpClient = clientTestRule.newClient() private var client: OkHttpClient = clientTestRule.newClient()
@BeforeEach @BeforeEach
@@ -75,7 +75,6 @@ class ConnectionReuseTest {
@Test @Test
fun connectionsAreReusedWithHttp2() { fun connectionsAreReusedWithHttp2() {
platform.assumeNotBouncyCastle()
enableHttp2() enableHttp2()
server.enqueue(MockResponse(body = "a")) server.enqueue(MockResponse(body = "a"))
server.enqueue(MockResponse(body = "b")) server.enqueue(MockResponse(body = "b"))
@@ -191,7 +190,6 @@ class ConnectionReuseTest {
@Test @Test
fun http2ConnectionsAreSharedBeforeResponseIsConsumed() { fun http2ConnectionsAreSharedBeforeResponseIsConsumed() {
platform.assumeNotBouncyCastle()
enableHttp2() enableHttp2()
server.enqueue(MockResponse(body = "a")) server.enqueue(MockResponse(body = "a"))
server.enqueue(MockResponse(body = "b")) server.enqueue(MockResponse(body = "b"))
@@ -225,7 +223,6 @@ class ConnectionReuseTest {
@Test @Test
fun connectionsAreNotReusedIfSslSocketFactoryChanges() { fun connectionsAreNotReusedIfSslSocketFactoryChanges() {
platform.assumeNotBouncyCastle()
enableHttps() enableHttps()
server.enqueue(MockResponse()) server.enqueue(MockResponse())
server.enqueue(MockResponse()) server.enqueue(MockResponse())
@@ -246,12 +243,12 @@ class ConnectionReuseTest {
anotherClient.newCall(request).execute() anotherClient.newCall(request).execute()
fail<Any?>() fail<Any?>()
} catch (expected: SSLException) { } catch (expected: SSLException) {
} catch (expected: TlsFatalAlert) {
} }
} }
@Test @Test
fun connectionsAreNotReusedIfHostnameVerifierChanges() { fun connectionsAreNotReusedIfHostnameVerifierChanges() {
platform.assumeNotBouncyCastle()
enableHttps() enableHttps()
server.enqueue(MockResponse()) server.enqueue(MockResponse())
server.enqueue(MockResponse()) server.enqueue(MockResponse())

View File

@@ -43,7 +43,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static okhttp3.tls.internal.TlsUtil.localhost;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@@ -56,7 +55,8 @@ public final class DuplexTest {
private MockWebServer server; private MockWebServer server;
private RecordingEventListener listener = new RecordingEventListener(); private RecordingEventListener listener = new RecordingEventListener();
private final HandshakeCertificates handshakeCertificates = localhost(); private final HandshakeCertificates handshakeCertificates
= platform.localhostHandshakeCertificates();
private OkHttpClient client = clientTestRule.newClientBuilder() private OkHttpClient client = clientTestRule.newClientBuilder()
.eventListenerFactory(clientTestRule.wrap(listener)) .eventListenerFactory(clientTestRule.wrap(listener))
.build(); .build();
@@ -67,7 +67,6 @@ public final class DuplexTest {
this.server = server; this.server = server;
platform.assumeNotOpenJSSE(); platform.assumeNotOpenJSSE();
platform.assumeHttp2Support(); platform.assumeHttp2Support();
platform.assumeNotBouncyCastle();
} }
@AfterEach public void tearDown() { @AfterEach public void tearDown() {

View File

@@ -74,7 +74,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static okhttp3.tls.internal.TlsUtil.localhost;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.any; import static org.hamcrest.CoreMatchers.any;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
@@ -92,7 +91,8 @@ public final class EventListenerTest {
private MockWebServer server; private MockWebServer server;
private final RecordingEventListener listener = new RecordingEventListener(); private final RecordingEventListener listener = new RecordingEventListener();
private final HandshakeCertificates handshakeCertificates = localhost(); private final HandshakeCertificates handshakeCertificates
= platform.localhostHandshakeCertificates();
private OkHttpClient client = clientTestRule.newClientBuilder() private OkHttpClient client = clientTestRule.newClientBuilder()
.eventListenerFactory(clientTestRule.wrap(listener)) .eventListenerFactory(clientTestRule.wrap(listener))
@@ -104,7 +104,6 @@ public final class EventListenerTest {
this.server = server; this.server = server;
platform.assumeNotOpenJSSE(); platform.assumeNotOpenJSSE();
platform.assumeNotBouncyCastle();
listener.forbidLock(RealConnectionPool.Companion.get(client.connectionPool())); listener.forbidLock(RealConnectionPool.Companion.get(client.connectionPool()));
listener.forbidLock(client.dispatcher()); listener.forbidLock(client.dispatcher());

View File

@@ -21,7 +21,6 @@ import mockwebserver3.MockWebServer
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.HeldCertificate import okhttp3.tls.HeldCertificate
import okhttp3.tls.internal.TlsUtil.localhost
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@@ -43,7 +42,7 @@ class InsecureForHostTest {
} }
@Test fun `untrusted host in insecureHosts connects successfully`() { @Test fun `untrusted host in insecureHosts connects successfully`() {
val serverCertificates = localhost() val serverCertificates = platform.localhostHandshakeCertificates()
server.useHttps(serverCertificates.sslSocketFactory()) server.useHttps(serverCertificates.sslSocketFactory())
server.enqueue(MockResponse()) server.enqueue(MockResponse())
@@ -95,7 +94,7 @@ class InsecureForHostTest {
} }
@Test fun `untrusted host not in insecureHosts fails with SSLException`() { @Test fun `untrusted host not in insecureHosts fails with SSLException`() {
val serverCertificates = localhost() val serverCertificates = platform.localhostHandshakeCertificates()
server.useHttps(serverCertificates.sslSocketFactory()) server.useHttps(serverCertificates.sslSocketFactory())
server.enqueue(MockResponse()) server.enqueue(MockResponse())

View File

@@ -15,13 +15,14 @@
*/ */
package okhttp3 package okhttp3
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import okhttp3.TestUtil.assumeNetwork import okhttp3.TestUtil.assumeNetwork
import okhttp3.internal.connection import okhttp3.internal.connection
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.testing.PlatformVersion import okhttp3.testing.PlatformVersion
import okhttp3.tls.internal.TlsUtil
import okio.ByteString.Companion.toByteString import okio.ByteString.Companion.toByteString
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
@@ -30,14 +31,12 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
class JSSETest { class JSSETest {
@JvmField @RegisterExtension var platform = PlatformRule() @JvmField @RegisterExtension var platform = PlatformRule()
@JvmField @RegisterExtension val clientTestRule = OkHttpClientTestRule() @JvmField @RegisterExtension val clientTestRule = OkHttpClientTestRule()
private val handshakeCertificates = TlsUtil.localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
var client = clientTestRule.newClient() var client = clientTestRule.newClient()

View File

@@ -24,7 +24,6 @@ import mockwebserver3.SocketPolicy
import mockwebserver3.junit5.internal.MockWebServerInstance import mockwebserver3.junit5.internal.MockWebServerInstance
import okhttp3.internal.http2.ErrorCode import okhttp3.internal.http2.ErrorCode
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil.localhost
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@@ -45,7 +44,7 @@ class RouteFailureTest {
private var listener = RecordingEventListener() private var listener = RecordingEventListener()
private val handshakeCertificates = localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
val dns = FakeDns() val dns = FakeDns()

View File

@@ -23,7 +23,6 @@ import okhttp3.Headers.Companion.headersOf
import okhttp3.internal.duplex.AsyncRequestBody import okhttp3.internal.duplex.AsyncRequestBody
import okhttp3.internal.http2.ErrorCode import okhttp3.internal.http2.ErrorCode
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil.localhost
import okio.BufferedSink import okio.BufferedSink
import okio.IOException import okio.IOException
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@@ -47,7 +46,7 @@ class ServerTruncatesRequestTest {
var clientTestRule = OkHttpClientTestRule() var clientTestRule = OkHttpClientTestRule()
private val listener = RecordingEventListener() private val listener = RecordingEventListener()
private val handshakeCertificates = localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
private var client = clientTestRule.newClientBuilder() private var client = clientTestRule.newClientBuilder()
.eventListenerFactory(clientTestRule.wrap(listener)) .eventListenerFactory(clientTestRule.wrap(listener))
@@ -60,7 +59,6 @@ class ServerTruncatesRequestTest {
this.server = server this.server = server
platform.assumeNotOpenJSSE() platform.assumeNotOpenJSSE()
platform.assumeHttp2Support() platform.assumeHttp2Support()
platform.assumeNotBouncyCastle()
} }
@Test @Test

View File

@@ -15,12 +15,12 @@
*/ */
package okhttp3 package okhttp3
import javax.net.ssl.SSLSocket
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import okhttp3.testing.Flaky import okhttp3.testing.Flaky
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.testing.PlatformVersion import okhttp3.testing.PlatformVersion
import okhttp3.tls.internal.TlsUtil
import okio.ByteString.Companion.toByteString import okio.ByteString.Companion.toByteString
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
@@ -30,13 +30,12 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource import org.junit.jupiter.params.provider.ValueSource
import javax.net.ssl.SSLSocket
class SessionReuseTest { class SessionReuseTest {
@JvmField @RegisterExtension var platform = PlatformRule() @JvmField @RegisterExtension var platform = PlatformRule()
@JvmField @RegisterExtension val clientTestRule = OkHttpClientTestRule() @JvmField @RegisterExtension val clientTestRule = OkHttpClientTestRule()
private val handshakeCertificates = TlsUtil.localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
var client = clientTestRule.newClient() var client = clientTestRule.newClient()
@@ -50,9 +49,7 @@ class SessionReuseTest {
// System.setProperty("jdk.tls.client.enableSessionTicketExtension", "true") // System.setProperty("jdk.tls.client.enableSessionTicketExtension", "true")
// System.setProperty("jdk.tls.server.enableSessionTicketExtension", "true") // System.setProperty("jdk.tls.server.enableSessionTicketExtension", "true")
// Session reuse not tested // IllegalStateException: Cannot resume session and session creation is disabled
// org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40); No selectable cipher suite
// at org.bouncycastle.tls.AbstractTlsServer.getSelectedCipherSuite(Unknown Source)
platform.assumeNotBouncyCastle() platform.assumeNotBouncyCastle()
} }

View File

@@ -15,6 +15,15 @@
*/ */
package okhttp3 package okhttp3
import java.io.IOException
import java.net.InetAddress
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit.SECONDS
import javax.net.ssl.SNIHostName
import javax.net.ssl.SNIMatcher
import javax.net.ssl.SNIServerName
import javax.net.ssl.SSLSocket
import javax.net.ssl.StandardConstants
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import okhttp3.Protocol.HTTP_1_1 import okhttp3.Protocol.HTTP_1_1
@@ -31,21 +40,12 @@ import okhttp3.tls.HeldCertificate
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assumptions.assumeFalse import org.junit.jupiter.api.Assumptions.assumeFalse
import org.junit.jupiter.api.Assumptions.assumeTrue import org.junit.jupiter.api.Assumptions.assumeTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Timeout import org.junit.jupiter.api.Timeout
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource import org.junit.jupiter.params.provider.MethodSource
import java.io.IOException
import java.net.InetAddress
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit.SECONDS
import javax.net.ssl.SNIHostName
import javax.net.ssl.SNIMatcher
import javax.net.ssl.SNIServerName
import javax.net.ssl.SSLSocket
import javax.net.ssl.StandardConstants
import org.junit.jupiter.api.BeforeEach
@Suppress("UsePropertyAccessSyntax") @Suppress("UsePropertyAccessSyntax")
@Timeout(6) @Timeout(6)

View File

@@ -71,13 +71,13 @@ import okhttp3.internal.platform.Platform.Companion.get
import okhttp3.internal.userAgent import okhttp3.internal.userAgent
import okhttp3.testing.Flaky import okhttp3.testing.Flaky
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil.localhost
import okio.Buffer import okio.Buffer
import okio.BufferedSink import okio.BufferedSink
import okio.GzipSink import okio.GzipSink
import okio.buffer import okio.buffer
import okio.utf8Size import okio.utf8Size
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.bouncycastle.tls.TlsFatalAlert
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
@@ -102,7 +102,7 @@ class URLConnectionTest {
private lateinit var server: MockWebServer private lateinit var server: MockWebServer
private lateinit var server2: MockWebServer private lateinit var server2: MockWebServer
private val handshakeCertificates = localhost() private val handshakeCertificates = platform.localhostHandshakeCertificates()
private var client = clientTestRule.newClient() private var client = clientTestRule.newClient()
private var cache: Cache? = null private var cache: Cache? = null
@@ -110,7 +110,6 @@ class URLConnectionTest {
fun setUp(server: MockWebServer, @MockWebServerInstance("server2") server2: MockWebServer) { fun setUp(server: MockWebServer, @MockWebServerInstance("server2") server2: MockWebServer) {
this.server = server this.server = server
this.server2 = server2 this.server2 = server2
platform.assumeNotBouncyCastle()
server.protocolNegotiationEnabled = false server.protocolNegotiationEnabled = false
} }
@@ -571,12 +570,15 @@ class URLConnectionTest {
"without an SSL socket factory, the connection should fail" "without an SSL socket factory, the connection should fail"
) )
} catch (expected: SSLException) { } catch (expected: SSLException) {
} catch (expected: TlsFatalAlert) {
} }
} }
// TODO(jwilson): tests below this marker need to be migrated to OkHttp's request/response API. // TODO(jwilson): tests below this marker need to be migrated to OkHttp's request/response API.
@Test @Test
fun connectViaHttpsWithSSLFallback() { fun connectViaHttpsWithSSLFallback() {
platform.assumeNotBouncyCastle()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE)) server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE))
server.enqueue(MockResponse(body = "this response comes via SSL")) server.enqueue(MockResponse(body = "this response comes via SSL"))
@@ -600,6 +602,8 @@ class URLConnectionTest {
@Test @Test
fun connectViaHttpsWithSSLFallbackFailuresRecorded() { fun connectViaHttpsWithSSLFallbackFailuresRecorded() {
platform.assumeNotBouncyCastle()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE)) server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE))
server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE)) server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE))
@@ -679,6 +683,7 @@ class URLConnectionTest {
CertificateException::class.java CertificateException::class.java
) )
} }
} catch (expected: TlsFatalAlert) {
} }
assertThat(server.requestCount).isEqualTo(0) assertThat(server.requestCount).isEqualTo(0)
} }
@@ -3749,6 +3754,8 @@ class URLConnectionTest {
@Test @Test
fun testNoSslFallback() { fun testNoSslFallback() {
platform.assumeNotBouncyCastle()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE)) server.enqueue(MockResponse(socketPolicy = SocketPolicy.FAIL_HANDSHAKE))
server.enqueue(MockResponse(body = "Response that would have needed fallbacks")) server.enqueue(MockResponse(body = "Response that would have needed fallbacks"))

View File

@@ -15,6 +15,13 @@
*/ */
package okhttp3.internal.http package okhttp3.internal.http
import java.io.IOException
import java.net.ServerSocket
import java.net.Socket
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit.MILLISECONDS
import javax.net.ServerSocketFactory
import javax.net.SocketFactory
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import okhttp3.Call import okhttp3.Call
@@ -44,7 +51,6 @@ import okhttp3.internal.http.CancelTest.ConnectionType.H2
import okhttp3.internal.http.CancelTest.ConnectionType.HTTP import okhttp3.internal.http.CancelTest.ConnectionType.HTTP
import okhttp3.internal.http.CancelTest.ConnectionType.HTTPS import okhttp3.internal.http.CancelTest.ConnectionType.HTTPS
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil
import okio.Buffer import okio.Buffer
import okio.BufferedSink import okio.BufferedSink
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@@ -55,13 +61,6 @@ import org.junit.jupiter.api.extension.RegisterExtension
import org.junit.jupiter.api.fail import org.junit.jupiter.api.fail
import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ArgumentsSource import org.junit.jupiter.params.provider.ArgumentsSource
import java.io.IOException
import java.net.ServerSocket
import java.net.Socket
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit.MILLISECONDS
import javax.net.ServerSocketFactory
import javax.net.SocketFactory
@Timeout(30) @Timeout(30)
@Tag("Slow") @Tag("Slow")
@@ -85,7 +84,8 @@ class CancelTest {
} }
@JvmField @RegisterExtension val clientTestRule = OkHttpClientTestRule() @JvmField @RegisterExtension val clientTestRule = OkHttpClientTestRule()
val handshakeCertificates = TlsUtil.localhost()
val handshakeCertificates = platform.localhostHandshakeCertificates()
private lateinit var server: MockWebServer private lateinit var server: MockWebServer
private lateinit var client: OkHttpClient private lateinit var client: OkHttpClient
@@ -100,8 +100,6 @@ class CancelTest {
platform.assumeHttp2Support() platform.assumeHttp2Support()
} }
platform.assumeNotBouncyCastle()
// Sockets on some platforms can have large buffers that mean writes do not block when // Sockets on some platforms can have large buffers that mean writes do not block when
// required. These socket factories explicitly set the buffer sizes on sockets created. // required. These socket factories explicitly set the buffer sizes on sockets created.
server = MockWebServer() server = MockWebServer()

View File

@@ -70,7 +70,6 @@ import okhttp3.internal.discard
import okhttp3.testing.Flaky import okhttp3.testing.Flaky
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.internal.TlsUtil.localhost
import okio.Buffer import okio.Buffer
import okio.BufferedSink import okio.BufferedSink
import okio.GzipSink import okio.GzipSink
@@ -109,6 +108,11 @@ class HttpOverHttp2Test {
@RegisterExtension @RegisterExtension
val testLogHandler: TestLogHandler = TestLogHandler(Http2::class.java) val testLogHandler: TestLogHandler = TestLogHandler(Http2::class.java)
// Flaky https://github.com/square/okhttp/issues/4632
// Flaky https://github.com/square/okhttp/issues/4633
private val handshakeCertificates: HandshakeCertificates =
platform.localhostHandshakeCertificates()
private lateinit var server: MockWebServer private lateinit var server: MockWebServer
private lateinit var protocol: Protocol private lateinit var protocol: Protocol
private lateinit var client: OkHttpClient private lateinit var client: OkHttpClient
@@ -125,7 +129,6 @@ class HttpOverHttp2Test {
this.server = server this.server = server
this.protocol = protocol this.protocol = protocol
platform.assumeNotOpenJSSE() platform.assumeNotOpenJSSE()
platform.assumeNotBouncyCastle()
if (protocol === Protocol.HTTP_2) { if (protocol === Protocol.HTTP_2) {
platform.assumeHttp2Support() platform.assumeHttp2Support()
server.useHttps(handshakeCertificates.sslSocketFactory()) server.useHttps(handshakeCertificates.sslSocketFactory())
@@ -2050,10 +2053,4 @@ class HttpOverHttp2Test {
assertThat(get.requestLine).isEqualTo("GET /foo HTTP/1.1") assertThat(get.requestLine).isEqualTo("GET /foo HTTP/1.1")
assertThat(get.headers["Proxy-Authorization"]).isNull() assertThat(get.headers["Proxy-Authorization"]).isNull()
} }
companion object {
// Flaky https://github.com/square/okhttp/issues/4632
// Flaky https://github.com/square/okhttp/issues/4633
private val handshakeCertificates: HandshakeCertificates = localhost()
}
} }

View File

@@ -28,7 +28,6 @@ import okhttp3.internal.canParseAsIpAddress
import okhttp3.internal.platform.Platform.Companion.isAndroid import okhttp3.internal.platform.Platform.Companion.isAndroid
import okhttp3.testing.PlatformRule import okhttp3.testing.PlatformRule
import okhttp3.tls.HeldCertificate import okhttp3.tls.HeldCertificate
import okhttp3.tls.internal.TlsUtil.localhost
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
@@ -775,7 +774,8 @@ class HostnameVerifierTest {
// Since this is public API, okhttp3.internal.tls.OkHostnameVerifier.verify is also // Since this is public API, okhttp3.internal.tls.OkHostnameVerifier.verify is also
assertThat(verifier).isInstanceOf(OkHostnameVerifier::class.java) assertThat(verifier).isInstanceOf(OkHostnameVerifier::class.java)
val session = localhost().sslContext().createSSLEngine().session val handshakeCertificates = platform.localhostHandshakeCertificates()
val session = handshakeCertificates.sslContext().createSSLEngine().session
assertThat(localVerifier.verify("\uD83D\uDCA9.com", session)).isFalse assertThat(localVerifier.verify("\uD83D\uDCA9.com", session)).isFalse
} }

View File

@@ -57,7 +57,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static okhttp3.TestUtil.repeat; import static okhttp3.TestUtil.repeat;
import static okhttp3.tls.internal.TlsUtil.localhost;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset; import static org.assertj.core.data.Offset.offset;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@@ -73,7 +72,8 @@ public final class WebSocketHttpTest {
@RegisterExtension TestLogHandler testLogHandler = new TestLogHandler(OkHttpClient.class); @RegisterExtension TestLogHandler testLogHandler = new TestLogHandler(OkHttpClient.class);
private MockWebServer webServer; private MockWebServer webServer;
private final HandshakeCertificates handshakeCertificates = localhost(); private final HandshakeCertificates handshakeCertificates
= platform.localhostHandshakeCertificates();
private final WebSocketRecorder clientListener = new WebSocketRecorder("client"); private final WebSocketRecorder clientListener = new WebSocketRecorder("client");
private final WebSocketRecorder serverListener = new WebSocketRecorder("server"); private final WebSocketRecorder serverListener = new WebSocketRecorder("server");
private final Random random = new Random(0); private final Random random = new Random(0);
@@ -98,7 +98,6 @@ public final class WebSocketHttpTest {
this.webServer = webServer; this.webServer = webServer;
platform.assumeNotOpenJSSE(); platform.assumeNotOpenJSSE();
platform.assumeNotBouncyCastle();
} }
@AfterEach public void tearDown() throws InterruptedException { @AfterEach public void tearDown() throws InterruptedException {

View File

@@ -33,8 +33,6 @@ class OkHttpClientTest {
@JvmField @RegisterExtension val platform = PlatformRule() @JvmField @RegisterExtension val platform = PlatformRule()
@Test fun get(server: MockWebServer) { @Test fun get(server: MockWebServer) {
platform.assumeNotBouncyCastle()
server.enqueue(MockResponse(body = "hello, OkHttp")) server.enqueue(MockResponse(body = "hello, OkHttp"))
val client = OkHttpClient() val client = OkHttpClient()