use of okhttp3.tls.HeldCertificate in project okhttp by square.
the class CertificatePinnerChainValidationTest method pinRootNotPresentInChain.
/**
* The pinner should pull the root certificate from the trust manager.
*/
@Test
public void pinRootNotPresentInChain() throws Exception {
// Fails on 11.0.1 https://github.com/square/okhttp/issues/4703
HeldCertificate rootCa = new HeldCertificate.Builder().serialNumber(1L).certificateAuthority(1).commonName("root").build();
HeldCertificate intermediateCa = new HeldCertificate.Builder().signedBy(rootCa).certificateAuthority(0).serialNumber(2L).commonName("intermediate_ca").build();
HeldCertificate certificate = new HeldCertificate.Builder().signedBy(intermediateCa).serialNumber(3L).commonName(server.getHostName()).build();
CertificatePinner certificatePinner = new CertificatePinner.Builder().add(server.getHostName(), CertificatePinner.pin(rootCa.certificate())).build();
HandshakeCertificates handshakeCertificates = new HandshakeCertificates.Builder().addTrustedCertificate(rootCa.certificate()).build();
OkHttpClient client = clientTestRule.newClientBuilder().sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager()).hostnameVerifier(new RecordingHostnameVerifier()).certificatePinner(certificatePinner).build();
HandshakeCertificates serverHandshakeCertificates = new HandshakeCertificates.Builder().heldCertificate(certificate, intermediateCa.certificate()).build();
server.useHttps(serverHandshakeCertificates.sslSocketFactory(), false);
// The request should complete successfully.
server.enqueue(new MockResponse().setBody("abc"));
Call call1 = client.newCall(new Request.Builder().url(server.url("/")).build());
Response response1 = call1.execute();
assertThat(response1.body().string()).isEqualTo("abc");
}
use of okhttp3.tls.HeldCertificate in project okhttp by square.
the class CertificatePinnerChainValidationTest method unrelatedPinnedIntermediateCertificateInChain.
@Test
public void unrelatedPinnedIntermediateCertificateInChain() throws Exception {
// https://github.com/square/okhttp/issues/4729
platform.expectFailureOnConscryptPlatform();
platform.expectFailureOnCorrettoPlatform();
// Start with two root CA certificates, one is good and the other is compromised.
HeldCertificate rootCa = new HeldCertificate.Builder().serialNumber(1L).certificateAuthority(1).commonName("root").build();
HeldCertificate compromisedRootCa = new HeldCertificate.Builder().serialNumber(2L).certificateAuthority(1).commonName("compromised_root").build();
// Add a good intermediate CA, and have that issue a good certificate to localhost. Prepare an
// SSL context for an HTTP client under attack. It includes the trusted CA and a pinned
// certificate.
HeldCertificate goodIntermediateCa = new HeldCertificate.Builder().signedBy(rootCa).certificateAuthority(0).serialNumber(3L).commonName("intermediate_ca").build();
CertificatePinner certificatePinner = new CertificatePinner.Builder().add(server.getHostName(), CertificatePinner.pin(goodIntermediateCa.certificate())).build();
HandshakeCertificates handshakeCertificates = new HandshakeCertificates.Builder().addTrustedCertificate(rootCa.certificate()).addTrustedCertificate(compromisedRootCa.certificate()).build();
OkHttpClient client = clientTestRule.newClientBuilder().sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager()).hostnameVerifier(new RecordingHostnameVerifier()).certificatePinner(certificatePinner).build();
// The attacker compromises the root CA, issues an intermediate with the same common name
// "intermediate_ca" as the good CA. This signs a rogue certificate for localhost. The server
// serves the good CAs certificate in the chain, which means the certificate pinner sees a
// different set of certificates than the SSL verifier.
HeldCertificate compromisedIntermediateCa = new HeldCertificate.Builder().signedBy(compromisedRootCa).certificateAuthority(0).serialNumber(4L).commonName("intermediate_ca").build();
HeldCertificate rogueCertificate = new HeldCertificate.Builder().serialNumber(5L).signedBy(compromisedIntermediateCa).commonName(server.getHostName()).build();
SSLSocketFactory socketFactory = newServerSocketFactory(rogueCertificate, goodIntermediateCa.certificate(), compromisedIntermediateCa.certificate());
server.useHttps(socketFactory, false);
server.enqueue(new MockResponse().setBody("abc").addHeader("Content-Type: text/plain"));
// Make a request from client to server. It should succeed certificate checks (unfortunately the
// rogue CA is trusted) but it should fail certificate pinning.
Request request = new Request.Builder().url(server.url("/")).build();
Call call = client.newCall(request);
try {
call.execute();
fail();
} catch (SSLHandshakeException expected) {
// On Android, the handshake fails before the certificate pinner runs.
String message = expected.getMessage();
assertThat(message).contains("Could not validate certificate");
} catch (SSLPeerUnverifiedException expected) {
// On OpenJDK, the handshake succeeds but the certificate pinner fails.
String message = expected.getMessage();
assertThat(message).startsWith("Certificate pinning failure!");
}
}
use of okhttp3.tls.HeldCertificate in project okhttp by square.
the class CertificatePinnerChainValidationTest method unrelatedPinnedLeafCertificateInChain.
@Test
public void unrelatedPinnedLeafCertificateInChain() throws Exception {
// https://github.com/square/okhttp/issues/4729
platform.expectFailureOnConscryptPlatform();
platform.expectFailureOnCorrettoPlatform();
// Start with a trusted root CA certificate.
HeldCertificate rootCa = new HeldCertificate.Builder().serialNumber(1L).certificateAuthority(1).commonName("root").build();
// Add a good intermediate CA, and have that issue a good certificate to localhost. Prepare an
// SSL context for an HTTP client under attack. It includes the trusted CA and a pinned
// certificate.
HeldCertificate goodIntermediateCa = new HeldCertificate.Builder().signedBy(rootCa).certificateAuthority(0).serialNumber(2L).commonName("good_intermediate_ca").build();
HeldCertificate goodCertificate = new HeldCertificate.Builder().signedBy(goodIntermediateCa).serialNumber(3L).commonName(server.getHostName()).build();
CertificatePinner certificatePinner = new CertificatePinner.Builder().add(server.getHostName(), CertificatePinner.pin(goodCertificate.certificate())).build();
HandshakeCertificates handshakeCertificates = new HandshakeCertificates.Builder().addTrustedCertificate(rootCa.certificate()).build();
OkHttpClient client = clientTestRule.newClientBuilder().sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager()).hostnameVerifier(new RecordingHostnameVerifier()).certificatePinner(certificatePinner).build();
// Add a bad intermediate CA and have that issue a rogue certificate for localhost. Prepare
// an SSL context for an attacking webserver. It includes both these rogue certificates plus the
// trusted good certificate above. The attack is that by including the good certificate in the
// chain, we may trick the certificate pinner into accepting the rouge certificate.
HeldCertificate compromisedIntermediateCa = new HeldCertificate.Builder().signedBy(rootCa).certificateAuthority(0).serialNumber(4L).commonName("bad_intermediate_ca").build();
HeldCertificate rogueCertificate = new HeldCertificate.Builder().serialNumber(5L).signedBy(compromisedIntermediateCa).commonName(server.getHostName()).build();
SSLSocketFactory socketFactory = newServerSocketFactory(rogueCertificate, compromisedIntermediateCa.certificate(), goodCertificate.certificate());
server.useHttps(socketFactory, false);
server.enqueue(new MockResponse().setBody("abc").addHeader("Content-Type: text/plain"));
// Make a request from client to server. It should succeed certificate checks (unfortunately the
// rogue CA is trusted) but it should fail certificate pinning.
Request request = new Request.Builder().url(server.url("/")).build();
Call call = client.newCall(request);
try {
call.execute();
fail();
} catch (SSLPeerUnverifiedException expected) {
// Certificate pinning fails!
String message = expected.getMessage();
assertThat(message).startsWith("Certificate pinning failure!");
}
}
use of okhttp3.tls.HeldCertificate in project okhttp by square.
the class HttpsServer method run.
public void run() throws Exception {
String localhost = InetAddress.getByName("localhost").getCanonicalHostName();
HeldCertificate localhostCertificate = new HeldCertificate.Builder().addSubjectAlternativeName(localhost).build();
HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder().heldCertificate(localhostCertificate).build();
MockWebServer server = new MockWebServer();
server.useHttps(serverCertificates.sslSocketFactory(), false);
server.enqueue(new MockResponse());
HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder().addTrustedCertificate(localhostCertificate.certificate()).build();
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager()).build();
Call call = client.newCall(new Request.Builder().url(server.url("/")).build());
Response response = call.execute();
System.out.println(response.handshake().tlsVersion());
}
use of okhttp3.tls.HeldCertificate in project okhttp by square.
the class ClientAuthTest method invalidClientAuthFails.
@Test
public void invalidClientAuthFails() throws Throwable {
// Fails with https://github.com/square/okhttp/issues/4598
// StreamReset stream was reset: PROT...
HeldCertificate clientCert2 = new HeldCertificate.Builder().serialNumber(4L).commonName("Jethro Willis").build();
OkHttpClient client = buildClient(clientCert2);
SSLSocketFactory socketFactory = buildServerSslSocketFactory();
server.useHttps(socketFactory, false);
server.requireClientAuth();
Call call = client.newCall(new Request.Builder().url(server.url("/")).build());
try {
call.execute();
fail();
} catch (SSLHandshakeException expected) {
// JDK 11+
} catch (SSLException expected) {
// javax.net.ssl.SSLException: readRecord
} catch (SocketException expected) {
// Conscrypt, JDK 8 (>= 292), JDK 9
} catch (ConnectionShutdownException expected) {
// It didn't fail until it reached the application layer.
} catch (IOException expected) {
assertThat(expected.getMessage()).isEqualTo("exhausted all routes");
}
}
Aggregations