0

I have an application which connects to SAP systems via SSL. The application makes use of JAX-WS (for Web-Service calls) and Apache HttPComponent 4.5.3 for all other SSL calls. Everything works fine unless I run the application with Java 1.8 131 or 144. I'm getting the following exception:

javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException: Certificates does not conform
to algorithm constraints at sun.security.ssl.Alerts.getSSLException(Unknown Source) at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) at sun.security.ssl.Handshaker.fatalSE(Unknown Source) at sun.security.ssl.Handshaker.fatalSE(Unknown Source) at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source) at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source) at sun.security.ssl.Handshaker.processLoop(Unknown Source) at sun.security.ssl.Handshaker.process_record(Unknown Source) at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) Caused by: java.security.cert.CertificateException: Certificates does not conform to algorithm constraints at
security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(Unknow at
security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(Unknown at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unknown

I have read java.security.cert.CertificateException: Certificates does not conform to algorithm constraints but it doesn't apply to my case, because...

  1. Everything works fine when I connect to SAP server 1
  2. When connecting to SAP Server 2 afterwards (also via SSL) I get "certificate does not conform" error
  3. When I reverse the sequence and connect to SAP Server 2 first, everything works fine
  4. but then I get the same error when I connect to SAP server 1 (which worked before)
  5. And this problem only occurs with Java 1.8 131 and 144. It works fine with 1.7 and Java 1.8.121

All this indicates to me that the root cause is not a problem with the certificates and ciphers but something is going wrong when mixing JAX-WS and Apache HTTPS calls in Java 1.8.144

This is code for disabling SSL checks for JAX-WS (based on https://log.rowanto.com/java-8-turning-off-ssl-certificate-check/):

public static final void disableCertificateValidationForWebServices() {
    // Create a trust manager that does not validate certificate chains

    TrustManager[] trustAllCerts = new TrustManager[] {
new X509ExtendedTrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] 

x509Certificates, String s) { }

        @Override
        public void checkServerTrusted(X509Certificate[] 

x509Certificates, String s) { }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] 
            x509Certificates, String s, Socket socket) {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] 
            x509Certificates, String s, Socket socket) {
        }

        @Override
        public void checkClientTrusted(X509Certificate[] 
             x509Certificates, String s, SSLEngine sslEngine) {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] 
           x509Certificates, String s, SSLEngine sslEngine) {
        }
    } };

    // Install the all-trusting trust manager
    try {
        final SSLContext sc = SSLContext.getInstance("SSL"); // or TLS?
        sc.init(null, trustAllCerts, new SecureRandom());     
 HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
       .setDefaultHostnameVerifier(NoopHostnameVerifier.INSTANCE);      } catch (Exception e) {
    }
}

and this is the code for disabling SSL checks for the Apache HTTPS calls (based on http://stackoverflow.com/questions/22606579/apache-httpclient-4-3-and-x509-client-certificate-to-authenticate):

public static SSLConnectionSocketFactory getInstance() {

    if (instance == null) {
        Log.info("Disabling SSL Certificate Checks");

        final SSLContextBuilder builder = SSLContexts.custom();
        // here in the loadTrustMaterial the SSL Provider is loaded.

        try {
            builder.loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] arg0, String 
  arg1) {
                    return true;
                }

            });

            final SSLContext sslContext = builder.build();

            instance = new SSLConnectionSocketFactory(sslContext, 
   NoopHostnameVerifier.INSTANCE);
        } catch (NoSuchAlgorithmException e) {
            Log.error("disableCertificateValidation() failed with 
  NoSuchAlgorithmException. Detail message:", e);
            listTrustManagers(null);
        } catch (KeyStoreException e) {
            Log.error("disableCertificateValidation() failed with 
 KeyStoreException. Detail message: ", e);
            listTrustManagers(null);
        } catch (KeyManagementException e) {
            Log.error("disableCertificateValidation() failed with 
  KeyManagementException. Detail message: ", e);
        }

    }
    return instance;
}

And yes, we are using a PoolingConnectionManager:

public final class MyPoolingHttpClientConnectionManager {

private static PoolingHttpClientConnectionManager instance = null;

private final static Object LOCK = new Object();

protected MyPoolingHttpClientConnectionManager() {
    // Exists only to defeat instantiation.
}

public static PoolingHttpClientConnectionManager getInstance() {
    synchronized (LOCK) {
        if (instance == null) {
            instance = new 
PoolingHttpClientConnectionManager(disableCertificateValidation());
            // Increase max total connection to 50
            instance.setMaxTotal(50);
            // Increase default max connection per route to 20
            instance.setDefaultMaxPerRoute(20);

        }
    }
    return instance;
}

/*
 * This is called when we create the HTTPConnectionPool
 * 
 * 
 */
private final static Registry<ConnectionSocketFactory> 
disableCertificateValidation() {
    return RegistryBuilder.<ConnectionSocketFactory>
create().register("https", MySSLContext.getInstance())
            .register("http", new 
 PlainConnectionSocketFactory()).build();

}

}

Any ideas are highly welcome

eloy
  • 1
  • 1
  • 3

1 Answers1

-1

Installing Java 1.8 161 fixed the issue. Seems to be Java bug in version 131 up to 151.

eloy
  • 1
  • 1
  • 3