Search in sources :

Example 6 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class JavaApiConverterTest method createOkResponseForCacheGet_secure.

@Test
public void createOkResponseForCacheGet_secure() throws Exception {
    final String statusLine = "HTTP/1.1 200 Fantastic";
    final Principal localPrincipal = LOCAL_CERT.getSubjectX500Principal();
    final List<Certificate> localCertificates = Arrays.<Certificate>asList(LOCAL_CERT);
    final Principal serverPrincipal = SERVER_CERT.getSubjectX500Principal();
    final List<Certificate> serverCertificates = Arrays.<Certificate>asList(SERVER_CERT);
    URI uri = new URI("https://foo/bar");
    Request request = new Request.Builder().url(uri.toURL()).build();
    SecureCacheResponse cacheResponse = new SecureCacheResponse() {

        @Override
        public Map<String, List<String>> getHeaders() throws IOException {
            Map<String, List<String>> headers = new LinkedHashMap<>();
            headers.put(null, Collections.singletonList(statusLine));
            headers.put("xyzzy", Arrays.asList("bar", "baz"));
            return headers;
        }

        @Override
        public InputStream getBody() throws IOException {
            return new ByteArrayInputStream("HelloWorld".getBytes(StandardCharsets.UTF_8));
        }

        @Override
        public String getCipherSuite() {
            return "SSL_RSA_WITH_NULL_MD5";
        }

        @Override
        public List<Certificate> getLocalCertificateChain() {
            return localCertificates;
        }

        @Override
        public List<Certificate> getServerCertificateChain() throws SSLPeerUnverifiedException {
            return serverCertificates;
        }

        @Override
        public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
            return serverPrincipal;
        }

        @Override
        public Principal getLocalPrincipal() {
            return localPrincipal;
        }
    };
    Response response = JavaApiConverter.createOkResponseForCacheGet(request, cacheResponse);
    Request cacheRequest = response.request();
    assertEquals(request.url(), cacheRequest.url());
    assertEquals(request.method(), cacheRequest.method());
    assertEquals(0, request.headers().size());
    assertEquals(Protocol.HTTP_1_1, response.protocol());
    assertEquals(200, response.code());
    assertEquals("Fantastic", response.message());
    Headers okResponseHeaders = response.headers();
    assertEquals("baz", okResponseHeaders.get("xyzzy"));
    assertEquals("HelloWorld", response.body().string());
    Handshake handshake = response.handshake();
    assertNotNull(handshake);
    assertNotNullAndEquals(CipherSuite.TLS_RSA_WITH_NULL_MD5, handshake.cipherSuite());
    assertEquals(localPrincipal, handshake.localPrincipal());
    assertEquals(serverPrincipal, handshake.peerPrincipal());
    assertEquals(serverCertificates, handshake.peerCertificates());
    assertEquals(localCertificates, handshake.localCertificates());
}
Also used : SecureCacheResponse(java.net.SecureCacheResponse) Headers(okhttp3.Headers) Request(okhttp3.Request) URI(java.net.URI) LinkedHashMap(java.util.LinkedHashMap) CacheResponse(java.net.CacheResponse) Response(okhttp3.Response) SecureCacheResponse(java.net.SecureCacheResponse) ByteArrayInputStream(java.io.ByteArrayInputStream) List(java.util.List) Principal(java.security.Principal) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate) Handshake(okhttp3.Handshake) Test(org.junit.Test)

Example 7 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class JavaApiConverterTest method createJavaUrlConnection_https_extraHttpsMethods.

@Test
public void createJavaUrlConnection_https_extraHttpsMethods() throws Exception {
    Request okRequest = createArbitraryOkRequest().newBuilder().get().url("https://secure/request").build();
    Handshake handshake = Handshake.get(null, CipherSuite.TLS_RSA_WITH_NULL_MD5, Arrays.<Certificate>asList(SERVER_CERT), Arrays.<Certificate>asList(LOCAL_CERT));
    Response okResponse = createArbitraryOkResponse(okRequest).newBuilder().handshake(handshake).build();
    HttpsURLConnection httpsUrlConnection = (HttpsURLConnection) JavaApiConverter.createJavaUrlConnectionForCachePut(okResponse);
    assertEquals("SSL_RSA_WITH_NULL_MD5", httpsUrlConnection.getCipherSuite());
    assertEquals(SERVER_CERT.getSubjectX500Principal(), httpsUrlConnection.getPeerPrincipal());
    assertArrayEquals(new Certificate[] { LOCAL_CERT }, httpsUrlConnection.getLocalCertificates());
    assertArrayEquals(new Certificate[] { SERVER_CERT }, httpsUrlConnection.getServerCertificates());
    assertEquals(LOCAL_CERT.getSubjectX500Principal(), httpsUrlConnection.getLocalPrincipal());
}
Also used : CacheResponse(java.net.CacheResponse) Response(okhttp3.Response) SecureCacheResponse(java.net.SecureCacheResponse) Request(okhttp3.Request) HttpsURLConnection(javax.net.ssl.HttpsURLConnection) Handshake(okhttp3.Handshake) Test(org.junit.Test)

Example 8 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class JavaApiConverter method createOkResponseForCacheGet.

/**
   * Creates an OkHttp {@link Response} using the supplied {@link Request} and {@link CacheResponse}
   * to supply the data.
   */
static Response createOkResponseForCacheGet(Request request, CacheResponse javaResponse) throws IOException {
    // Build a cache request for the response to use.
    Headers responseHeaders = createHeaders(javaResponse.getHeaders());
    Headers varyHeaders;
    if (HttpHeaders.hasVaryAll(responseHeaders)) {
        // "*" means that this will be treated as uncacheable anyway.
        varyHeaders = new Headers.Builder().build();
    } else {
        varyHeaders = HttpHeaders.varyHeaders(request.headers(), responseHeaders);
    }
    Request cacheRequest = new Request.Builder().url(request.url()).method(request.method(), null).headers(varyHeaders).build();
    Response.Builder okResponseBuilder = new Response.Builder();
    // Request: Use the cacheRequest we built.
    okResponseBuilder.request(cacheRequest);
    // Status line: Java has this as one of the headers.
    StatusLine statusLine = StatusLine.parse(extractStatusLine(javaResponse));
    okResponseBuilder.protocol(statusLine.protocol);
    okResponseBuilder.code(statusLine.code);
    okResponseBuilder.message(statusLine.message);
    // Response headers
    Headers okHeaders = extractOkHeaders(javaResponse, okResponseBuilder);
    okResponseBuilder.headers(okHeaders);
    // Response body
    ResponseBody okBody = createOkBody(okHeaders, javaResponse);
    okResponseBuilder.body(okBody);
    // Handle SSL handshake information as needed.
    if (javaResponse instanceof SecureCacheResponse) {
        SecureCacheResponse javaSecureCacheResponse = (SecureCacheResponse) javaResponse;
        // Handshake doesn't support null lists.
        List<Certificate> peerCertificates;
        try {
            peerCertificates = javaSecureCacheResponse.getServerCertificateChain();
        } catch (SSLPeerUnverifiedException e) {
            peerCertificates = Collections.emptyList();
        }
        List<Certificate> localCertificates = javaSecureCacheResponse.getLocalCertificateChain();
        if (localCertificates == null) {
            localCertificates = Collections.emptyList();
        }
        String cipherSuiteString = javaSecureCacheResponse.getCipherSuite();
        CipherSuite cipherSuite = CipherSuite.forJavaName(cipherSuiteString);
        Handshake handshake = Handshake.get(null, cipherSuite, peerCertificates, localCertificates);
        okResponseBuilder.handshake(handshake);
    }
    return okResponseBuilder.build();
}
Also used : SecureCacheResponse(java.net.SecureCacheResponse) HttpHeaders(okhttp3.internal.http.HttpHeaders) Headers(okhttp3.Headers) JavaNetHeaders(okhttp3.internal.JavaNetHeaders) CipherSuite(okhttp3.CipherSuite) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) CacheRequest(okhttp3.internal.cache.CacheRequest) Request(okhttp3.Request) ResponseBody(okhttp3.ResponseBody) CacheResponse(java.net.CacheResponse) Response(okhttp3.Response) SecureCacheResponse(java.net.SecureCacheResponse) StatusLine(okhttp3.internal.http.StatusLine) Certificate(java.security.cert.Certificate) Handshake(okhttp3.Handshake)

Example 9 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class JavaApiConverter method createJavaCacheResponse.

/**
   * Creates a {@link java.net.CacheResponse} of the correct (sub)type using information gathered
   * from the supplied {@link Response}.
   */
public static CacheResponse createJavaCacheResponse(final Response response) {
    final Headers headers = withSyntheticHeaders(response);
    final ResponseBody body = response.body();
    if (response.request().isHttps()) {
        final Handshake handshake = response.handshake();
        return new SecureCacheResponse() {

            @Override
            public String getCipherSuite() {
                return handshake != null ? handshake.cipherSuite().javaName() : null;
            }

            @Override
            public List<Certificate> getLocalCertificateChain() {
                if (handshake == null)
                    return null;
                // Java requires null, not an empty list here.
                List<Certificate> certificates = handshake.localCertificates();
                return certificates.size() > 0 ? certificates : null;
            }

            @Override
            public List<Certificate> getServerCertificateChain() throws SSLPeerUnverifiedException {
                if (handshake == null)
                    return null;
                // Java requires null, not an empty list here.
                List<Certificate> certificates = handshake.peerCertificates();
                return certificates.size() > 0 ? certificates : null;
            }

            @Override
            public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
                if (handshake == null)
                    return null;
                return handshake.peerPrincipal();
            }

            @Override
            public Principal getLocalPrincipal() {
                if (handshake == null)
                    return null;
                return handshake.localPrincipal();
            }

            @Override
            public Map<String, List<String>> getHeaders() throws IOException {
                // Java requires that the entry with a null key be the status line.
                return JavaNetHeaders.toMultimap(headers, StatusLine.get(response).toString());
            }

            @Override
            public InputStream getBody() throws IOException {
                if (body == null)
                    return null;
                return body.byteStream();
            }
        };
    } else {
        return new CacheResponse() {

            @Override
            public Map<String, List<String>> getHeaders() throws IOException {
                // Java requires that the entry with a null key be the status line.
                return JavaNetHeaders.toMultimap(headers, StatusLine.get(response).toString());
            }

            @Override
            public InputStream getBody() throws IOException {
                if (body == null)
                    return null;
                return body.byteStream();
            }
        };
    }
}
Also used : CacheResponse(java.net.CacheResponse) SecureCacheResponse(java.net.SecureCacheResponse) SecureCacheResponse(java.net.SecureCacheResponse) HttpHeaders(okhttp3.internal.http.HttpHeaders) Headers(okhttp3.Headers) JavaNetHeaders(okhttp3.internal.JavaNetHeaders) List(java.util.List) ResponseBody(okhttp3.ResponseBody) Handshake(okhttp3.Handshake) Certificate(java.security.cert.Certificate)

Example 10 with Handshake

use of okhttp3.Handshake 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!"));
    }
}
Also used : MockResponse(okhttp3.mockwebserver.MockResponse) Call(okhttp3.Call) OkHttpClient(okhttp3.OkHttpClient) CertificatePinner(okhttp3.CertificatePinner) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) Request(okhttp3.Request) SSLHandshakeException(javax.net.ssl.SSLHandshakeException) RecordingHostnameVerifier(okhttp3.RecordingHostnameVerifier) Test(org.junit.Test)

Aggregations

Handshake (okhttp3.Handshake)9 Certificate (java.security.cert.Certificate)8 Test (org.junit.Test)8 Request (okhttp3.Request)7 CacheResponse (java.net.CacheResponse)6 SecureCacheResponse (java.net.SecureCacheResponse)6 Response (okhttp3.Response)6 MockResponse (okhttp3.mockwebserver.MockResponse)5 SSLPeerUnverifiedException (javax.net.ssl.SSLPeerUnverifiedException)4 Headers (okhttp3.Headers)4 ResponseBody (okhttp3.ResponseBody)4 IOException (java.io.IOException)3 List (java.util.List)3 HttpsURLConnection (javax.net.ssl.HttpsURLConnection)3 JavaNetHeaders (okhttp3.internal.JavaNetHeaders)3 HttpHeaders (okhttp3.internal.http.HttpHeaders)3 Principal (java.security.Principal)2 X509Certificate (java.security.cert.X509Certificate)2 CipherSuite (okhttp3.CipherSuite)2 ConnectionSpec (okhttp3.ConnectionSpec)2