Search code examples
web-servicessslweblogicjax-wsweblogic11g

Using JAX-WS in Weblogic 10.3.6 combining 2waySSL and Proxy


I have implemented a connector to different kinds of webservice with JAX-WS in weblogic 10.3.6, the connector can be configured with 2waySSL, proxy and combine both of them.

  • The implementation to use proxy works properly using ClientProxyFeature.
  • In the same way with 2waySSL using a custom SSLSocketFactory as Oracle says in the documentation. Persisting the State of a Request over SSL (JAX-WS Only)

    ((BindingProvider) port).getRequestContext().put(
      JAXWSProperties.SSL_SOCKET_FACTORY, 
      SSLClientUtil.getSSLSocketFactoryFromSysProperties());
    

The issue occurs when combine both features. The handshake does not happend (ClientHello)

The error is:

    ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', READ: TLSv1.2 Alert, length = 64
Padded plaintext after DECRYPTION:  len = 64
0000: F0 E5 6E 9F 6F F4 BB 2E   07 29 56 FE 34 0A 10 0B  ..n.o....)V.4...
0010: 02 28 7E 75 92 F7 03 4E   CD 3A 7E 0B E2 6A 7C 8E  .(.u...N.:...j..
0020: 3B F8 4E F5 98 A3 D3 B4   67 76 20 49 1B 77 07 5E  ;.N.....gv I.w.^
0030: 9D 66 0D 0D 0D 0D 0D 0D   0D 0D 0D 0D 0D 0D 0D 0D  .f..............
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', RECV TLSv1.2 ALERT:  fatal, handshake_failure
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
<13-sep-2017 09H32' CEST> <Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]weblogic.security.SSL.jsseadapter: SSLENGINE: Exception occurred during SSLEngine.unwrap(ByteBuffer,ByteBuffer[]).
javax.net.ssl.SSLException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:188)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1614)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1582)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1751)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1043)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:865)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:740)

Debuging and decompiling weblogic source I can see that the HttpsClient when use proxy does not use the custom SSLSocketFactory.

1) In the transport class weblogic.wsee.jaxws.transport.http.client.HttpClientTransport weblogic opens the connection:

    protected HttpURLConnection openConnection(Packet paramPacket)
                              …

 localSSLSocketFactory = (javax.net.ssl.SSLSocketFactory)this.context.invocationProperties.get("com.sun.xml.ws.transport.https.client.SSLSocketFactory");
        if ((localSSLSocketFactory != null) && ((localSSLSocketFactory instanceof javax.net.ssl.SSLSocketFactory)))
        {
          if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine("set (jdk) ssl socketfactory to wls socketfactory");
          }
          ((weblogic.net.http.HttpsURLConnection)localObject3).setSSLSocketFactory(new MySSLSocketFactory((javax.net.ssl.SSLSocketFactory)localSSLSocketFactory));
        }
…

As you can see, set the custom SSLSocketFactory.

2) Without a proxy, the weblogic.net.http.HttpsClient uses the custom SSLSocketFactory to create the socket

this.serverSocket = localSocketFactory.createSocket(arrayOfInetAddress[i], paramInt);

The localSocketFactory is the custom SSLSocketFactory.

3) But if uses proxy then create a new SSLSocketFactory

private void makeConnectionUsingProxy(String s, int i, boolean flag)
    throws IOException
{
    javax.net.ssl.SSLSocketFactory sslsocketfactory;
    int j;
    SSLContextWrapper sslcontextwrapper = SSLSetup.getSSLContext(sslInfo);
    sslcontextwrapper.getHostnameVerifier().setProxyMapping(s, host);
    sslcontextwrapper.getTrustManager().setProxyMapping(s, host);
    sslsocketfactory = sslcontextwrapper.getSSLSocketFactory();

The sslInfo is an object without the keystore or truststore informed in the SSLSocketFactory. I haven't seen any way to inform the object sslInfo (weblogic.security.SSL.SSLClientInfo)

The variables to start the weblogic are the next:

-Dweblogic.security.SSL.nojce=true -Djavax.net.debug=all -Dssl.debug=true
-Djavax.net.ssl.keyStore=XXXXXs -Djavax.net.ssl.keyStorePassword=XXXXX
-Djdk.tls.enableRC4CipherSuites=true -Djsse.enableSNIExtension=false -Dweblogic.ssl.JSSEEnabled=true -Dweblogic.security.SSL.enableJSSE=true -Dweblogic.security.SSL.nojce=true -Dweblogic.security.SSL.ignoreHostnameVerification=true

The custom SSLSocketFactory is create with this params and with the default trustore. When no proxy is used everything works propertly.

I don't understand why to make the connection with a proxy weblogic does not use the same SSLSocketFactory.

Any ideas?


Solution

  • Oracle people have confirm us that is a "bug" in this implementation, it is only possible to solve with the property -DUseSunHttpHandler=true.

    In Oracle 12 you can use the setter method setUseSunHttpHandler of the ClientProxyFeature. But with the weblogic implementation is not possible to solve.