Search code examples
javasslhttpshttp-unit

HttpUnit WebConversation SSL Issues


How can I ignore SSL certificate issues from the context of the WebConversation or WebRequest object? I know I can create a fake TrustManager that accepts all certificates but how can I set this in the HttpUnit context?

Here is the exception I am getting:

[Security:090508]Certificate chain received from my.domain.com - NUM.NUM.NUM.NUM was incomplete., 
[Security:090477]Certificate chain received from my.domain.com - NUM.NUM.NUM.NUM was not trusted causing SSL handshake failure. 

I need to somehow set the SSLSocket settings to the WebConversation or WebRequest object; looking at the JavaDocs for HttpUnit there is no such method or constructor to do so. Is there a way I can wrap this inside some object which has exposed SSLSocket properties?


Solution

  • According to this FAQ entry, it seems that HttpUnit is using the SSL implementation provided by the Java standard library. Writing and installing an "accept all" TrustManager is straightforward:

    private static class AnyTrustManager implements X509TrustManager
    {
        public void checkClientTrusted(X509Certificate[] chain, String authType)
        {
        }
    
        public void checkServerTrusted(X509Certificate[] chain, String authType)
        {
        }
    
        public X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[0];
        }
    }
    
    static {
        try {
            SSLContext ssl = SSLContext.getInstance("SSL");
            ssl.init(null, new X509TrustManager[] {new AnyTrustManager()}, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(ssl.getSocketFactory());
        } catch (NoSuchAlgorithmException ex) {
            throw new Error(ex);
        } catch (KeyManagementException ex) {
            throw new Error(ex);
        }
    }
    

    However you should keep in mind that this code sample may need some modifications to work with HttpUnit (for instance if the library establishes the connections using a custom SocketFactory)

    Since it seems that HttpUnit does not provide any API to set a custom SSLSocketFactry here is an alternative solution setting the default SSL context (Java 6 only)

    static {
        try {
            SSLContext ssl = SSLContext.getDefault();
            ssl.init(null, new X509TrustManager[] {new AnyTrustManager()}, null);
        } catch (NoSuchAlgorithmException ex) {
            throw new Error(ex);
        } catch (KeyManagementException ex) {
            throw new Error(ex);
        }
    }