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 = [
|
||||
'animalSniffer': '1.17',
|
||||
'assertj': '3.11.0',
|
||||
'bouncycastle': '1.62',
|
||||
'bouncycastle': '1.64',
|
||||
'brotli': '0.1.2',
|
||||
'checkstyle': '8.15',
|
||||
'conscrypt': '2.2.1',
|
||||
@@ -29,6 +29,7 @@ buildscript {
|
||||
'animalSniffer': "org.codehaus.mojo:animal-sniffer-annotations:${versions.animalSniffer}",
|
||||
'assertj': "org.assertj:assertj-core:${versions.assertj}",
|
||||
'bouncycastle': "org.bouncycastle:bcprov-jdk15on:${versions.bouncycastle}",
|
||||
'bouncycastletls': "org.bouncycastle:bctls-jdk15on:${versions.bouncycastle}",
|
||||
'brotli': "org.brotli:dec:${versions.brotli}",
|
||||
'conscrypt': "org.conscrypt:conscrypt-openjdk-uber:${versions.conscrypt}",
|
||||
'corretto': "software.amazon.cryptools:AmazonCorrettoCryptoProvider:${versions.corretto}:linux-x86_64",
|
||||
|
||||
@@ -2,6 +2,8 @@ dependencies {
|
||||
api project(':okhttp')
|
||||
api deps.junit
|
||||
api deps.assertj
|
||||
api deps.bouncycastle
|
||||
api deps.bouncycastletls
|
||||
api deps.conscrypt
|
||||
api deps.corretto
|
||||
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.SelfTestStatus
|
||||
import okhttp3.internal.platform.Platform
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
|
||||
import org.conscrypt.Conscrypt
|
||||
import org.hamcrest.BaseMatcher
|
||||
import org.hamcrest.CoreMatchers
|
||||
@@ -221,6 +223,11 @@ open class PlatformRule @JvmOverloads constructor(
|
||||
CORRETTO_PROPERTY))
|
||||
}
|
||||
|
||||
fun assumeBouncyCastle() {
|
||||
assumeThat(getPlatformSystemProperty(), equalTo(
|
||||
BOUNCYCASTLE_PROPERTY))
|
||||
}
|
||||
|
||||
fun assumeHttp2Support() {
|
||||
assumeThat(getPlatformSystemProperty(), not(
|
||||
JDK8_PROPERTY))
|
||||
@@ -256,6 +263,11 @@ open class PlatformRule @JvmOverloads constructor(
|
||||
CORRETTO_PROPERTY))
|
||||
}
|
||||
|
||||
fun assumeNotBouncyCastle() {
|
||||
assumeThat(getPlatformSystemProperty(), not(
|
||||
BOUNCYCASTLE_PROPERTY))
|
||||
}
|
||||
|
||||
fun assumeNotHttp2Support() {
|
||||
assumeThat(getPlatformSystemProperty(), equalTo(
|
||||
JDK8_PROPERTY))
|
||||
@@ -273,6 +285,7 @@ open class PlatformRule @JvmOverloads constructor(
|
||||
const val JDK8_ALPN_PROPERTY = "jdk8alpn"
|
||||
const val JDK8_PROPERTY = "jdk8"
|
||||
const val OPENJSSE_PROPERTY = "openjsse"
|
||||
const val BOUNCYCASTLE_PROPERTY = "bouncycastle"
|
||||
|
||||
init {
|
||||
if (getPlatformSystemProperty() == CONSCRYPT_PROPERTY && Security.getProviders()[0].name != "Conscrypt") {
|
||||
@@ -296,6 +309,9 @@ open class PlatformRule @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
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) {
|
||||
AmazonCorrettoCryptoProvider.install()
|
||||
|
||||
@@ -340,6 +356,9 @@ open class PlatformRule @JvmOverloads constructor(
|
||||
@JvmStatic
|
||||
fun jdk8alpn() = PlatformRule(JDK8_ALPN_PROPERTY)
|
||||
|
||||
@JvmStatic
|
||||
fun bouncycastle() = PlatformRule(BOUNCYCASTLE_PROPERTY)
|
||||
|
||||
@JvmStatic
|
||||
fun isAlpnBootEnabled(): Boolean = try {
|
||||
Class.forName("org.eclipse.jetty.alpn.ALPN", true, null)
|
||||
|
||||
@@ -31,9 +31,11 @@ import javax.net.ServerSocketFactory;
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import okhttp3.Handshake;
|
||||
import okhttp3.testing.PlatformRule;
|
||||
import okio.ByteString;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
@@ -42,6 +44,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
|
||||
public final class HandshakeCertificatesTest {
|
||||
@Rule
|
||||
public PlatformRule platform = new PlatformRule();
|
||||
|
||||
private ExecutorService executorService;
|
||||
private ServerSocket serverSocket;
|
||||
|
||||
|
||||
@@ -24,8 +24,11 @@ import java.security.cert.X509Certificate;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.testing.PlatformRule;
|
||||
import okio.ByteString;
|
||||
import org.bouncycastle.asn1.x509.GeneralName;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
@@ -34,6 +37,9 @@ import static org.assertj.core.data.Offset.offset;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public final class HeldCertificateTest {
|
||||
@Rule
|
||||
public PlatformRule platform = new PlatformRule();
|
||||
|
||||
@Test public void defaultCertificate() throws CertificateParsingException {
|
||||
long now = System.currentTimeMillis();
|
||||
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