Monday, 25 July 2016

Spring Bean for (HTTPS) SSL Connectivity - JAXWS - Spring configuration for WSDL

Below code was used to consume a rest service Used this implementation to inject a factory bean with a trustFactory into my JaxWS spring bean to autowire on startup with the required certs .

Some commands useful in this context :

Adding certificates to local JDK on windows - To be Added Later

Add single Certificate to local JDK on linux servers
keytool -import -trustcacerts -keystore /filepath/java/jre/lib/security/cacerts -storepass changeit -noprompt -alias aliasName -file /certificateFilePath/certifcate.cer

Add keystore
keytool -importkeystore -trustcacerts -keystore /filepath/java/jre/lib/security/cacerts -storepass changeit -noprompt -alias aliasName -srckeystore /keyStorePath/KeyStore.jks

Delete Certificate
keytool -delete -v -keystore /filepath/java/jre/lib/security/cacerts -alias aliasName

List All Certificates
keytool -list -v -keystore /filepath/java/jre/lib/security/cacerts > cert.txt 


Example to use spring for JAXWS via JaxWsPortProxyFactoryBean

<beans:bean id="SOAPService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
        <beans:property name="serviceInterface" value="${service.interface}" />
        <beans:property name="wsdlDocumentUrl" value="WEB-INF/wsdl/service.wsdl" />
        <beans:property name="namespaceUri" value="${service.namespace}" />
        <beans:property name="serviceName" value="${service.name}" />
        <beans:property name="endpointAddress" value="${service.wsdl}" />
        <beans:property name="customProperties" ref="jaxwsCustomProperties" />
        <beans:property name="lookupServiceOnStartup" value="false"/>
    </beans:bean>


    <!-- Maintaining the timeout and ssl bean to connect over https -->
    <util:map id="jaxwsCustomProperties">
        <beans:entry key="com.sun.xml.ws.request.timeout">
            <beans:value type="java.lang.Integer">${service.timeout}</beans:value>
        </beans:entry>
        <beans:entry key="com.sun.xml.ws.connect.timeout">
            <beans:value type="java.lang.Integer">${service.timeout}</beans:value>
        </beans:entry>
        <beans:entry key="com.sun.xml.ws.transport.https.client.SSLSocketFactory" value-ref="mySSLSocketFactoryBean"/>
    </util:map>



 
       

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;


public class MySSLSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory factory;
    private static final String propPath = System.getProperty("intprops.pDir");
    private static String certKey = Encryptor.decryptPass(CERT_PWD);

    public MySSLSocketFactory() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException {

        char[] passphrase;
        File certFile = new File(FILEPATH);
        InputStream in = new FileInputStream(certFile);
        String key =certKey;
        passphrase = key.toCharArray();
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();

        SSLContext context = getSSLContext();
        context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        KeyManagerFactory kmfactory = KeyManagerFactory.getInstance("SunX509");
        kmfactory.init(ks, passphrase);
        KeyManager[] kmf = kmfactory.getKeyManagers();
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        SecureRandom random = new SecureRandom();
        context.init(kmf, new TrustManager[]{tm}, random);
        factory = context.getSocketFactory();
     }

    public static MySSLSocketFactory getDefault(){
    try {
        return new MySSLSocketFactory();

    } catch (KeyManagementException e)
    {
        System.out.println("KeyManagementException");

    } catch (KeyStoreException e)
    {
        System.out.println("KeyStoreException");

    } catch (NoSuchAlgorithmException e)

    {
        System.out.println("NoSuchAlgorithmException");

    } catch (CertificateException e)

    {
        System.out.println("CertificateException");

    } catch (IOException e)

    {
        System.out.println("IOException");

    }catch (UnrecoverableKeyException e)

    {
        System.out.println("UnrecoverableKeyException");

    }
    return null;

    }

    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;
        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        public X509Certificate[] getAcceptedIssuers() {
           return chain;
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType)  throws CertificateException {
            throw new UnsupportedOperationException();
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)  throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }

    }

    @Override
    public String[] getDefaultCipherSuites() {
        return factory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return factory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException {
        return factory.createSocket(socket, string, i, bln);
    }

    @Override
    public Socket createSocket(String string, int i) throws IOException, UnknownHostException {
        return factory.createSocket(string, i);
    }

    @Override
    public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException, UnknownHostException {
        return factory.createSocket(string, i, ia, i1);
    }

    @Override
    public Socket createSocket(InetAddress ia, int i) throws IOException {
        return factory.createSocket(ia, i);
    }

    @Override
    public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException {
        return factory.createSocket(ia, i, ia1, i1);
    }

    public static SSLContext getSSLContext() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException{
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    System.out.println("KEYSTORE INIT");
    File certFile = new File(FILEPATH);
    InputStream in = new FileInputStream(certFile);
    trustStore.load(in,  certKey.toCharArray());
    try{
        return SSLContexts.custom().loadKeyMaterial(trustStore, certKey.toCharArray()).build();
    } catch (UnrecoverableKeyException e) {
        throw new EXCEPTION("CONNECTION FAILED ");
    }

    }

}

AWS Certificate Manager - Import Certificate

How to import a certificate. Use Key Store Explorer to open the cert and export keypair in PEM format  This will save a file cert.pem. Make ...