Goderion
Goderion

Reputation: 21

Java SOAP Client JAX-WS: How to use a certificate

Im using NetBeans 7.0.1 to develope an application, thats able to communicate with a server/webservice through secured (HTTPS/SSL) SOAP. In NetBeans i simply click on "New" -> "Web Service Client...", select a wsdl-file and then click finish. This will generate sourcecode for the SOAP-Client. After that, i have many new java-files in an own Folder:

Generated Sources (jax-ws)

I changed the wsdl-file to connect to myself/localhost without HTTPS/SSL to test the SOAP-Client and it seems to work well, but now i need to use a specific certificate for the SOAP/HTTP-connection, wich i got as a .p12 file.

I dont know how to use a certificate in combination with the generated sources. I use the generated SOAP-Client like this:

SoapServiceExample SSA = new ClassSoapServiceExample();
Object Response = SSA.getServicePort().doSomething(Authentification, Data);

If i try to use the SOAP-Client with the unchanged/correct wsdl-file, i get this error:

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

[com.sun.xml.internal.ws.transport.http.client.HttpClientTransport] [getOutput] [-1]
[com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe] [process] [-1]
[com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe] [processRequest] [-1]
[com.sun.xml.internal.ws.transport.DeferredTransportPipe] [processRequest] [-1]
[com.sun.xml.internal.ws.api.pipe.Fiber] [__doRun] [-1]
[com.sun.xml.internal.ws.api.pipe.Fiber] [_doRun] [-1]
[com.sun.xml.internal.ws.api.pipe.Fiber] [doRun] [-1]
[com.sun.xml.internal.ws.api.pipe.Fiber] [runSync] [-1]
[com.sun.xml.internal.ws.client.Stub] [process] [-1]
[com.sun.xml.internal.ws.client.sei.SEIStub] [doProcess] [-1]
[com.sun.xml.internal.ws.client.sei.SyncMethodHandler] [invoke] [-1]
[com.sun.xml.internal.ws.client.sei.SyncMethodHandler] [invoke] [-1]
[com.sun.xml.internal.ws.client.sei.SEIStub] [invoke] [-1]
[$Proxy31] [doSomething] [-1]

Im already able to load a .p12 certificate to use it for a socket.

public static TrustManager[] createTrustManagerWhoTrustAllways()
{
    return new TrustManager[]
    {
        new X509TrustManager()
        {
            @Override
            public X509Certificate[] getAcceptedIssuers()
            {
                return null;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType)
            {
                return;
            }

            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType)
            {
                return;
            }
        }
    };
}

public static SSLContext loadPkcs12CertificateAndGetSslContext(String FileName, String Password) throws Exception
{
    KeyStore KS = KeyStore.getInstance("PKCS12");
    KS.load(new FileInputStream(FileName), Password.toCharArray());

    KeyManagerFactory KMF = KeyManagerFactory.getInstance("SunX509");
    KMF.init(KS, Password.toCharArray());

    SSLContext SSLC = SSLContext.getInstance("TLS");
    SSLC.init(KMF.getKeyManagers(), createTrustManagerWhoTrustAllways(), new SecureRandom());

    return SSLC;
}

public void connect() throws Exception
{
    if(true == m_Secure)
    {
        SSLContext SSLC = loadPkcs12CertificateAndGetSslContext(m_CertificateFileName, m_CertificatePassword);

        m_Socket = SSLC.getSocketFactory().createSocket(m_ServerName, m_ServerPort);
    }
    else
    {
        m_Socket = new Socket(m_ServerName, m_ServerPort);
    }
}

I know/guess this is not well written source and i believe its terrible practice to use stuff like createTrustManagerWhoTrustAllways(), but im new to java and my first goal is to produce a working client, if i have taken this hurdle i will concentrate on more secure sourcecode.

Can anybody tell me, how i use a certificate for the generated SOAP-Client?

Upvotes: 2

Views: 8335

Answers (1)

maasg
maasg

Reputation: 37435

You can declare a system-wide keystore by providing the keystore and truststore configuration through system properties on the command line of your program:

-Djavax.net.ssl.trustStore=<yourtruststore>
-Djavax.net.ssl.trustStorePassword=<pwd>
-Djavax.net.ssl.keyStore=<your-keystore>
-Djavax.net.ssl.keyStorePassword=<pwd>

JAX-WS will pick up this keystore to configure the SSL client connection. Just make sure you have the right certificates in place in your keystore.

Upvotes: 1

Related Questions