mirror of
https://github.com/square/okhttp.git
synced 2025-11-24 18:41:06 +03:00
Add bouncy castle platform for tests (#5695)
* Add basic bouncy castle test * Remove other tests * Activate platform for TLS tests
This commit is contained in:
committed by
Jesse Wilson
parent
04b4fbb6b5
commit
604e2705e7
@@ -4,7 +4,7 @@ buildscript {
|
|||||||
ext.versions = [
|
ext.versions = [
|
||||||
'animalSniffer': '1.17',
|
'animalSniffer': '1.17',
|
||||||
'assertj': '3.11.0',
|
'assertj': '3.11.0',
|
||||||
'bouncycastle': '1.62',
|
'bouncycastle': '1.64',
|
||||||
'brotli': '0.1.2',
|
'brotli': '0.1.2',
|
||||||
'checkstyle': '8.15',
|
'checkstyle': '8.15',
|
||||||
'conscrypt': '2.2.1',
|
'conscrypt': '2.2.1',
|
||||||
@@ -29,6 +29,7 @@ buildscript {
|
|||||||
'animalSniffer': "org.codehaus.mojo:animal-sniffer-annotations:${versions.animalSniffer}",
|
'animalSniffer': "org.codehaus.mojo:animal-sniffer-annotations:${versions.animalSniffer}",
|
||||||
'assertj': "org.assertj:assertj-core:${versions.assertj}",
|
'assertj': "org.assertj:assertj-core:${versions.assertj}",
|
||||||
'bouncycastle': "org.bouncycastle:bcprov-jdk15on:${versions.bouncycastle}",
|
'bouncycastle': "org.bouncycastle:bcprov-jdk15on:${versions.bouncycastle}",
|
||||||
|
'bouncycastletls': "org.bouncycastle:bctls-jdk15on:${versions.bouncycastle}",
|
||||||
'brotli': "org.brotli:dec:${versions.brotli}",
|
'brotli': "org.brotli:dec:${versions.brotli}",
|
||||||
'conscrypt': "org.conscrypt:conscrypt-openjdk-uber:${versions.conscrypt}",
|
'conscrypt': "org.conscrypt:conscrypt-openjdk-uber:${versions.conscrypt}",
|
||||||
'corretto': "software.amazon.cryptools:AmazonCorrettoCryptoProvider:${versions.corretto}:linux-x86_64",
|
'corretto': "software.amazon.cryptools:AmazonCorrettoCryptoProvider:${versions.corretto}:linux-x86_64",
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ dependencies {
|
|||||||
api project(':okhttp')
|
api project(':okhttp')
|
||||||
api deps.junit
|
api deps.junit
|
||||||
api deps.assertj
|
api deps.assertj
|
||||||
|
api deps.bouncycastle
|
||||||
|
api deps.bouncycastletls
|
||||||
api deps.conscrypt
|
api deps.conscrypt
|
||||||
api deps.corretto
|
api deps.corretto
|
||||||
api deps.openjsse
|
api deps.openjsse
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import okhttp3.internal.platform.OpenJSSEPlatform
|
|||||||
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 okhttp3.internal.platform.Platform
|
import okhttp3.internal.platform.Platform
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||||
|
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
|
||||||
import org.conscrypt.Conscrypt
|
import org.conscrypt.Conscrypt
|
||||||
import org.hamcrest.BaseMatcher
|
import org.hamcrest.BaseMatcher
|
||||||
import org.hamcrest.CoreMatchers
|
import org.hamcrest.CoreMatchers
|
||||||
@@ -221,6 +223,11 @@ open class PlatformRule @JvmOverloads constructor(
|
|||||||
CORRETTO_PROPERTY))
|
CORRETTO_PROPERTY))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun assumeBouncyCastle() {
|
||||||
|
assumeThat(getPlatformSystemProperty(), equalTo(
|
||||||
|
BOUNCYCASTLE_PROPERTY))
|
||||||
|
}
|
||||||
|
|
||||||
fun assumeHttp2Support() {
|
fun assumeHttp2Support() {
|
||||||
assumeThat(getPlatformSystemProperty(), not(
|
assumeThat(getPlatformSystemProperty(), not(
|
||||||
JDK8_PROPERTY))
|
JDK8_PROPERTY))
|
||||||
@@ -256,6 +263,11 @@ open class PlatformRule @JvmOverloads constructor(
|
|||||||
CORRETTO_PROPERTY))
|
CORRETTO_PROPERTY))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun assumeNotBouncyCastle() {
|
||||||
|
assumeThat(getPlatformSystemProperty(), not(
|
||||||
|
BOUNCYCASTLE_PROPERTY))
|
||||||
|
}
|
||||||
|
|
||||||
fun assumeNotHttp2Support() {
|
fun assumeNotHttp2Support() {
|
||||||
assumeThat(getPlatformSystemProperty(), equalTo(
|
assumeThat(getPlatformSystemProperty(), equalTo(
|
||||||
JDK8_PROPERTY))
|
JDK8_PROPERTY))
|
||||||
@@ -273,6 +285,7 @@ open class PlatformRule @JvmOverloads constructor(
|
|||||||
const val JDK8_ALPN_PROPERTY = "jdk8alpn"
|
const val JDK8_ALPN_PROPERTY = "jdk8alpn"
|
||||||
const val JDK8_PROPERTY = "jdk8"
|
const val JDK8_PROPERTY = "jdk8"
|
||||||
const val OPENJSSE_PROPERTY = "openjsse"
|
const val OPENJSSE_PROPERTY = "openjsse"
|
||||||
|
const val BOUNCYCASTLE_PROPERTY = "bouncycastle"
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (getPlatformSystemProperty() == CONSCRYPT_PROPERTY && Security.getProviders()[0].name != "Conscrypt") {
|
if (getPlatformSystemProperty() == CONSCRYPT_PROPERTY && Security.getProviders()[0].name != "Conscrypt") {
|
||||||
@@ -296,6 +309,9 @@ open class PlatformRule @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Security.insertProviderAt(OpenJSSE(), 1)
|
Security.insertProviderAt(OpenJSSE(), 1)
|
||||||
|
} else if (getPlatformSystemProperty() == BOUNCYCASTLE_PROPERTY && Security.getProviders()[0].name != "BC") {
|
||||||
|
Security.insertProviderAt(BouncyCastleProvider(), 1)
|
||||||
|
Security.insertProviderAt(BouncyCastleJsseProvider(), 2)
|
||||||
} else if (getPlatformSystemProperty() == CORRETTO_PROPERTY) {
|
} else if (getPlatformSystemProperty() == CORRETTO_PROPERTY) {
|
||||||
AmazonCorrettoCryptoProvider.install()
|
AmazonCorrettoCryptoProvider.install()
|
||||||
|
|
||||||
@@ -340,6 +356,9 @@ open class PlatformRule @JvmOverloads constructor(
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun jdk8alpn() = PlatformRule(JDK8_ALPN_PROPERTY)
|
fun jdk8alpn() = PlatformRule(JDK8_ALPN_PROPERTY)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun bouncycastle() = PlatformRule(BOUNCYCASTLE_PROPERTY)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isAlpnBootEnabled(): Boolean = try {
|
fun isAlpnBootEnabled(): Boolean = try {
|
||||||
Class.forName("org.eclipse.jetty.alpn.ALPN", true, null)
|
Class.forName("org.eclipse.jetty.alpn.ALPN", true, null)
|
||||||
|
|||||||
@@ -31,9 +31,11 @@ import javax.net.ServerSocketFactory;
|
|||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
import okhttp3.Handshake;
|
import okhttp3.Handshake;
|
||||||
|
import okhttp3.testing.PlatformRule;
|
||||||
import okio.ByteString;
|
import okio.ByteString;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
@@ -42,6 +44,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
import static org.junit.Assume.assumeFalse;
|
import static org.junit.Assume.assumeFalse;
|
||||||
|
|
||||||
public final class HandshakeCertificatesTest {
|
public final class HandshakeCertificatesTest {
|
||||||
|
@Rule
|
||||||
|
public PlatformRule platform = new PlatformRule();
|
||||||
|
|
||||||
private ExecutorService executorService;
|
private ExecutorService executorService;
|
||||||
private ServerSocket serverSocket;
|
private ServerSocket serverSocket;
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,11 @@ import java.security.cert.X509Certificate;
|
|||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import okhttp3.testing.PlatformRule;
|
||||||
import okio.ByteString;
|
import okio.ByteString;
|
||||||
import org.bouncycastle.asn1.x509.GeneralName;
|
import org.bouncycastle.asn1.x509.GeneralName;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
@@ -34,6 +37,9 @@ import static org.assertj.core.data.Offset.offset;
|
|||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
public final class HeldCertificateTest {
|
public final class HeldCertificateTest {
|
||||||
|
@Rule
|
||||||
|
public PlatformRule platform = new PlatformRule();
|
||||||
|
|
||||||
@Test public void defaultCertificate() throws CertificateParsingException {
|
@Test public void defaultCertificate() throws CertificateParsingException {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
HeldCertificate heldCertificate = new HeldCertificate.Builder().build();
|
HeldCertificate heldCertificate = new HeldCertificate.Builder().build();
|
||||||
|
|||||||
105
okhttp/src/test/java/okhttp3/BouncyCastleTest.kt
Normal file
105
okhttp/src/test/java/okhttp3/BouncyCastleTest.kt
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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
|
||||||
|
|
||||||
|
import okhttp3.TestUtil.assumeNetwork
|
||||||
|
import okhttp3.mockwebserver.MockResponse
|
||||||
|
import okhttp3.mockwebserver.MockWebServer
|
||||||
|
import okhttp3.testing.PlatformRule
|
||||||
|
import okhttp3.tls.HandshakeCertificates
|
||||||
|
import okhttp3.tls.HeldCertificate
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Ignore
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.openjsse.sun.security.ssl.SSLSocketFactoryImpl
|
||||||
|
import org.openjsse.sun.security.ssl.SSLSocketImpl
|
||||||
|
import java.net.InetAddress
|
||||||
|
|
||||||
|
class BouncyCastleTest {
|
||||||
|
@JvmField @Rule var platform = PlatformRule()
|
||||||
|
@JvmField @Rule val clientTestRule = OkHttpClientTestRule()
|
||||||
|
@JvmField @Rule val server = MockWebServer()
|
||||||
|
var client = clientTestRule.newClient()
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
platform.assumeBouncyCastle()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTlsv13Works() {
|
||||||
|
platform.expectFailureOnJdkVersion(8)
|
||||||
|
|
||||||
|
enableTls()
|
||||||
|
|
||||||
|
server.enqueue(MockResponse().setBody("abc"))
|
||||||
|
|
||||||
|
val request = Request.Builder().url(server.url("/")).build()
|
||||||
|
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
response.use {
|
||||||
|
assertEquals(200, response.code)
|
||||||
|
assertEquals(TlsVersion.TLS_1_3, response.handshake?.tlsVersion)
|
||||||
|
assertEquals(Protocol.HTTP_2, response.protocol)
|
||||||
|
|
||||||
|
assertThat(response.exchange?.connection()?.socket()).isInstanceOf(SSLSocketImpl::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSupportedProtocols() {
|
||||||
|
val factory = SSLSocketFactoryImpl()
|
||||||
|
val s = factory.createSocket() as SSLSocketImpl
|
||||||
|
|
||||||
|
assertEquals(listOf("TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1"), s.enabledProtocols.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
fun testMozilla() {
|
||||||
|
assumeNetwork()
|
||||||
|
|
||||||
|
val request = Request.Builder().url("https://mozilla.org/robots.txt").build()
|
||||||
|
|
||||||
|
client.newCall(request).execute().use {
|
||||||
|
assertThat(it.protocol).isEqualTo(Protocol.HTTP_1_1)
|
||||||
|
assertThat(it.handshake!!.tlsVersion).isEqualTo(TlsVersion.TLS_1_3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enableTls() {
|
||||||
|
// Generate a self-signed cert for the server to serve and the client to trust.
|
||||||
|
// can't use TlsUtil.localhost with a non OpenJSSE trust manager
|
||||||
|
val heldCertificate = HeldCertificate.Builder()
|
||||||
|
.commonName("localhost")
|
||||||
|
.addSubjectAlternativeName(InetAddress.getByName("localhost").canonicalHostName)
|
||||||
|
.build()
|
||||||
|
val handshakeCertificates = HandshakeCertificates.Builder()
|
||||||
|
.heldCertificate(heldCertificate)
|
||||||
|
.addTrustedCertificate(heldCertificate.certificate)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
client = client.newBuilder()
|
||||||
|
.sslSocketFactory(
|
||||||
|
handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
|
||||||
|
.build()
|
||||||
|
server.useHttps(handshakeCertificates.sslSocketFactory(), false)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user