title: Certificates does not conform to algorithm constraints. Only when connecting to 2nd server and only with Java 1.8.144. Why?
body: <p>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:</p>
  
  <blockquote>
    <p>javax.net.ssl.SSLHandshakeException:<br>
         java.security.cert.CertificateException: Certificates does not conform<br>
        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<br>
        security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(Unknow
        at<br>
        security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(Unknown 
        at 
        sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unknown </p>
  </blockquote>
  
  <p>I have read <a href="https://stackoverflow.com/questions/14149545/java-security-cert-certificateexception-certificates-does-not-conform-to-algori">java.security.cert.CertificateException: Certificates does not conform to algorithm constraints</a> but it doesn't apply to my case, because...</p>
  
  <ol>
  <li>Everything works fine when I connect to SAP server 1</li>
  <li>When connecting to SAP Server 2 afterwards (also via SSL) I get  "certificate does not conform" error</li>
  <li>When I reverse the sequence and connect to SAP Server 2 first, everything works fine</li>
  <li>but then I get the same error when I connect to SAP server 1 (which worked before)</li>
  <li>And this problem only occurs with Java 1.8 131 and 144. It works fine with 1.7 and Java 1.8.121 </li>
  </ol>
  
  <p>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</p>
  
  <p>This is code for disabling SSL checks for JAX-WS (based on <a href="https://log.rowanto.com/java-8-turning-off-ssl-certificate-check/" rel="nofollow noreferrer">https://log.rowanto.com/java-8-turning-off-ssl-certificate-check/</a>):</p>
  
  <pre><code>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[] 
  </code></pre>
  
  <p>x509Certificates, String s) {
              }</p>
  
  <pre><code>        @Override
          public void checkServerTrusted(X509Certificate[] 
  </code></pre>
  
  <p>x509Certificates, String s) {
              }</p>
  
  <pre><code>        @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) {
      }
  }
  </code></pre>
  
  <p>and this is the code for disabling SSL checks for the Apache HTTPS calls (based on <a href="http://stackoverflow.com/questions/22606579/apache-httpclient-4-3-and-x509-client-certificate-to-authenticate">http://stackoverflow.com/questions/22606579/apache-httpclient-4-3-and-x509-client-certificate-to-authenticate</a>):</p>
  
  <pre><code>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;
  }
  </code></pre>
  
  <p>And yes, we are using a PoolingConnectionManager:</p>
  
  <pre><code>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&lt;ConnectionSocketFactory&gt; 
  disableCertificateValidation() {
      return RegistryBuilder.&lt;ConnectionSocketFactory&gt;
  create().register("https", MySSLContext.getInstance())
              .register("http", new 
   PlainConnectionSocketFactory()).build();
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Any ideas are highly welcome</p>