use of javax.net.ssl.SSLHandshakeException in project okhttp by square.
the class CertificatePinnerChainValidationTest method unrelatedPinnedIntermediateCertificateInChain.
@Test
public void unrelatedPinnedIntermediateCertificateInChain() throws Exception {
// Start with two root CA certificates, one is good and the other is compromised.
HeldCertificate rootCa = new HeldCertificate.Builder().serialNumber("1").ca(3).commonName("root").build();
HeldCertificate compromisedRootCa = new HeldCertificate.Builder().serialNumber("2").ca(3).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().issuedBy(rootCa).ca(2).serialNumber("3").commonName("intermediate_ca").build();
CertificatePinner certificatePinner = new CertificatePinner.Builder().add(server.getHostName(), CertificatePinner.pin(goodIntermediateCa.certificate)).build();
SslClient clientContextBuilder = new SslClient.Builder().addTrustedCertificate(rootCa.certificate).addTrustedCertificate(compromisedRootCa.certificate).build();
OkHttpClient client = defaultClient().newBuilder().sslSocketFactory(clientContextBuilder.socketFactory, clientContextBuilder.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().issuedBy(compromisedRootCa).ca(2).serialNumber("4").commonName("intermediate_ca").build();
HeldCertificate rogueCertificate = new HeldCertificate.Builder().serialNumber("5").issuedBy(compromisedIntermediateCa).commonName(server.getHostName()).build();
SslClient.Builder sslBuilder = new SslClient.Builder();
// http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/2c1c21d11e58/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java#l596
if (getPlatform().equals("jdk9")) {
sslBuilder.keyStoreType("JKS");
}
SslClient serverSslContext = sslBuilder.certificateChain(rogueCertificate.keyPair, rogueCertificate.certificate, goodIntermediateCa.certificate, compromisedIntermediateCa.certificate, compromisedRootCa.certificate).build();
server.useHttps(serverSslContext.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();
assertTrue(message, message.contains("Could not validate certificate"));
} catch (SSLPeerUnverifiedException expected) {
// On OpenJDK, the handshake succeeds but the certificate pinner fails.
String message = expected.getMessage();
assertTrue(message, message.startsWith("Certificate pinning failure!"));
}
}
use of javax.net.ssl.SSLHandshakeException in project okhttp by square.
the class ClientAuthTest method invalidClientAuthFails.
@Test
public void invalidClientAuthFails() throws Throwable {
HeldCertificate clientCert2 = new HeldCertificate.Builder().serialNumber("4").commonName("Jethro Willis").build();
OkHttpClient client = buildClient(clientCert2);
SSLSocketFactory socketFactory = buildServerSslSocketFactory(ClientAuth.NEEDS);
server.useHttps(socketFactory, false);
Call call = client.newCall(new Request.Builder().url(server.url("/")).build());
try {
call.execute();
fail();
} catch (SSLHandshakeException expected) {
} catch (SocketException expected) {
// JDK 9
}
}
use of javax.net.ssl.SSLHandshakeException in project okhttp by square.
the class URLConnectionTest method testNoSslFallback.
@Test
public void testNoSslFallback() throws Exception {
server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setBody("Response that would have needed fallbacks"));
HttpsURLConnection connection = (HttpsURLConnection) server.url("/").url().openConnection();
connection.setSSLSocketFactory(sslClient.socketFactory);
try {
connection.getInputStream();
fail();
} catch (SSLProtocolException expected) {
// RI response to the FAIL_HANDSHAKE
} catch (SSLHandshakeException expected) {
// Android's response to the FAIL_HANDSHAKE
}
}
use of javax.net.ssl.SSLHandshakeException in project okhttp by square.
the class CallTest method noRecoveryFromTlsHandshakeFailureWhenTlsFallbackIsDisabled.
@Test
public void noRecoveryFromTlsHandshakeFailureWhenTlsFallbackIsDisabled() throws Exception {
client = client.newBuilder().connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT)).hostnameVerifier(new RecordingHostnameVerifier()).dns(new SingleInetAddressDns()).sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager).build();
server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
Request request = new Request.Builder().url(server.url("/")).build();
try {
client.newCall(request).execute();
fail();
} catch (SSLProtocolException expected) {
// RI response to the FAIL_HANDSHAKE
} catch (SSLHandshakeException expected) {
// Android's response to the FAIL_HANDSHAKE
}
}
use of javax.net.ssl.SSLHandshakeException in project okhttp by square.
the class CallTest method recoverFromTlsHandshakeFailure_tlsFallbackScsvEnabled.
@Test
public void recoverFromTlsHandshakeFailure_tlsFallbackScsvEnabled() throws Exception {
final String tlsFallbackScsv = "TLS_FALLBACK_SCSV";
List<String> supportedCiphers = Arrays.asList(sslClient.socketFactory.getSupportedCipherSuites());
if (!supportedCiphers.contains(tlsFallbackScsv)) {
// This only works if the client socket supports TLS_FALLBACK_SCSV.
return;
}
server.useHttps(sslClient.socketFactory, false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
RecordingSSLSocketFactory clientSocketFactory = new RecordingSSLSocketFactory(sslClient.socketFactory);
client = client.newBuilder().sslSocketFactory(clientSocketFactory, sslClient.trustManager).connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS)).hostnameVerifier(new RecordingHostnameVerifier()).dns(new SingleInetAddressDns()).build();
Request request = new Request.Builder().url(server.url("/")).build();
try {
client.newCall(request).execute();
fail();
} catch (SSLHandshakeException expected) {
}
List<SSLSocket> clientSockets = clientSocketFactory.getSocketsCreated();
SSLSocket firstSocket = clientSockets.get(0);
assertFalse(Arrays.asList(firstSocket.getEnabledCipherSuites()).contains(tlsFallbackScsv));
SSLSocket secondSocket = clientSockets.get(1);
assertTrue(Arrays.asList(secondSocket.getEnabledCipherSuites()).contains(tlsFallbackScsv));
}
Aggregations