org.qi4j.library.http.AbstractSecureJettyTest.java Source code

Java tutorial

Introduction

Here is the source code for org.qi4j.library.http.AbstractSecureJettyTest.java

Source

/*
 * Copyright (c) 2011, Paul Merlin. All Rights Reserved.
 *
 * 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 org.qi4j.library.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManagerFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

/**
 * Base class for SecureJettyMixin tests.
 *
 * Use HttpClient in order to easily use different {@link SSLContext}s between server and client.
 */
public abstract class AbstractSecureJettyTest extends AbstractJettyTest {

    private static final String HTTPS = "https";
    protected static final int HTTPS_PORT = 8441;
    protected static final String KS_PASSWORD = "changeit";
    protected static final String CLIENT_KEYSTORE_PATH = "src/test/resources/org/qi4j/library/http/qi4j-lib-http-unittests-client-cert.jceks";
    protected static final File CLIENT_KEYSTORE_FILE = new File(CLIENT_KEYSTORE_PATH);
    protected static final String SERVER_KEYSTORE_PATH = "src/test/resources/org/qi4j/library/http/qi4j-lib-http-unittests-server-cert.jceks";
    protected static final File SERVER_KEYSTORE_FILE = new File(SERVER_KEYSTORE_PATH);
    protected static final String TRUSTSTORE_PATH = "src/test/resources/org/qi4j/library/http/qi4j-lib-http-unittests-ca.jceks";
    protected static final File TRUSTSTORE_FILE = new File(TRUSTSTORE_PATH);
    // These two clients use a HostnameVerifier that don't do any check, don't do this in production code
    protected HttpClient trustHttpClient;
    protected HttpClient mutualHttpClient;

    @Before
    public void beforeSecure() throws GeneralSecurityException, IOException {
        // Trust HTTP Client
        KeyStore truststore = KeyStore.getInstance("JCEKS");
        truststore.load(new FileInputStream(TRUSTSTORE_FILE), KS_PASSWORD.toCharArray());

        AllowAllHostnameVerifier verifier = new AllowAllHostnameVerifier();

        DefaultHttpClient trustClient = new DefaultHttpClient();
        SSLSocketFactory trustSslFactory = new SSLSocketFactory(truststore);
        trustSslFactory.setHostnameVerifier(verifier);
        SchemeRegistry trustSchemeRegistry = trustClient.getConnectionManager().getSchemeRegistry();
        trustSchemeRegistry.unregister(HTTPS);
        trustSchemeRegistry.register(new Scheme(HTTPS, HTTPS_PORT, trustSslFactory));
        trustHttpClient = trustClient;

        // Mutual HTTP Client
        KeyStore keystore = KeyStore.getInstance("JCEKS");
        keystore.load(new FileInputStream(CLIENT_KEYSTORE_FILE), KS_PASSWORD.toCharArray());

        DefaultHttpClient mutualClient = new DefaultHttpClient();
        SSLSocketFactory mutualSslFactory = new SSLSocketFactory(keystore, KS_PASSWORD, truststore);
        mutualSslFactory.setHostnameVerifier(verifier);
        SchemeRegistry mutualSchemeRegistry = mutualClient.getConnectionManager().getSchemeRegistry();
        mutualSchemeRegistry.unregister(HTTPS);
        mutualSchemeRegistry.register(new Scheme(HTTPS, HTTPS_PORT, mutualSslFactory));
        mutualHttpClient = mutualClient;
    }

    private static HostnameVerifier defaultHostnameVerifier;
    private static javax.net.ssl.SSLSocketFactory defaultSSLSocketFactory;

    @BeforeClass
    public static void beforeSecureClass() throws IOException, GeneralSecurityException {
        defaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
        defaultSSLSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

            public boolean verify(String string, SSLSession ssls) {
                return true;
            }

        });
        KeyStore truststore = KeyStore.getInstance("JCEKS");
        truststore.load(new FileInputStream(TRUSTSTORE_FILE), KS_PASSWORD.toCharArray());
        SSLContext sslCtx = SSLContext.getInstance("TLS");
        TrustManagerFactory caTrustManagerFactory = TrustManagerFactory.getInstance(getX509Algorithm());
        caTrustManagerFactory.init(truststore);
        sslCtx.init(null, caTrustManagerFactory.getTrustManagers(), null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory());
    }

    @AfterClass
    public static void afterSecureClass() {
        HttpsURLConnection.setDefaultHostnameVerifier(defaultHostnameVerifier);
        HttpsURLConnection.setDefaultSSLSocketFactory(defaultSSLSocketFactory);
    }

    protected static String getX509Algorithm() {
        return System.getProperty("java.vendor").contains("IBM") ? "IbmX509" : "SunX509";
    }

}