title: Java SSL handshake error - Tomcat keystore
body: <p>I've tried to connect (send some data between) my standalone app and my other app served by Tomcat via SSL:</p>
  
  <pre><code>https://tomcat_server:8843/app
  </code></pre>
  
  <p>Unfortunately an error appears in my standalone app:</p>
  
  <blockquote>
    <p>Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
        at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
        at java.io.BufferedOutputStream.flush(Unknown Source)
        at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:827)
        at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.java:1525)
        at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1975)
        at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993)
        at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397)
        at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)
        at org.apache.commons.vfs.provider.http.HttpClientFactory.createConnection(HttpClientFactory.java:101)
        ... 9 more</p>
  </blockquote>
  
  <p>If I define url as a http it works fine:</p>
  
  <pre><code>http://tomcat_server:8080/app
  </code></pre>
  
  <p>It is also not a problem of app I think. I've tried the same thing with the same app on the other Tomcat server and it works via https. The only difference between these servers is I did not create the keystore file (pfx) on that server which works. I can't of course use the same keystore, because its different domain (I access this app also via browser).
  There is nothing in the Tomcat's log on the server. Maybe I did something wrong while creating the keystore.</p>
  
  <p>Here's how I generated the keystore file using openssl tool with my key, certificate and intermediate cert:</p>
  
  <pre><code>openssl pkcs12 -export -out certificate.pfx -inkey server.key -in server.crt -certfile intermediate.crt
  </code></pre>
  
  <p>Here is my connector config:</p>
  
  <pre><code>protocol="org.apache.coyote.http11.Http11Protocol"
         port="8443" maxThreads="200"
         scheme="https" secure="true" SSLEnabled="true"
         keystoreFile="/path/to/keystore/certificate.pfx" keystorePass="changeit"  ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA"
         keystoreType="PKCS12" clientAuth="false" sslProtocol="TLS"/&gt;
  </code></pre>
  
  <p>Both servers have same configs so I assume it must be certificate. Does anyone knows how to fix it?</p>