Search code examples
javaweb-servicesssljax-ws

Java Root CA Certificate present - getting SSL Handshake Exception


I have coded a java JAX-WS web service client. When I attempt to hit a server using a public CA signed certificate, I am getting an SSL Handshake exception:

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: 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

I've investigated further and have turned on the JVM's network tracing and discovered that the issuer of the server's public CA signed certificate is:

Issuer: CN=Symantec Class 3 Secure Server SHA256 SSL CA, OU=Symantec Trust Network, O=Symantec Corporation, C=US

I have verified that the root CA certificate for this issuer is:

CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US

And I have also verified via log trace that this certificate is indeed loaded.

Here is a portion of the SSL logging trace:

keyStore is : 
keyStore type is : jks
keyStore provider is : 

init keystore
init keymanager of type SunX509
trustStore is: C:\Program Files\Java\jdk1.7.0_79\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is : 
init truststore

[ omitted]

        adding as trusted cert:
      Subject: CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign
, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
      Issuer:  CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign
, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
      Algorithm: RSA; Serial number: 0x401ac46421b31321030ebbe4121ac51d
      Valid from Tue Apr 01 17:00:00 PDT 2008 until Tue Dec 01 15:59:59 PST 2037
[ omitted]

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1468680588 bytes = 
Session ID:  {}
Cipher Suites: [ ... ]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names:
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: redacted]
***
[write] MD5 and SHA1 hashes:  len = 181

[omitted]

*** ServerHello, TLSv1
RandomCookie:  GMT: 1524806833 
Session ID:  
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
Extension server_name, server_name: 
***
%% Initialized:  [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]
** TLS_DHE_RSA_WITH_AES_128_CBC_SHA
[read] MD5 and SHA1 hashes:  len = 85

[omitted]

*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=redacted, OU=redacted, O=redacted, L=redacted, ST=redacted, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  modulus:
  public exponent: 65537
  Validity: [From: Sun Oct 16 17:00:00 PDT 2016,
               To: Thu Nov 02 16:59:59 PDT 2017]
  Issuer: CN=Symantec Class 3 Secure Server SHA256 SSL CA, 
          OU=Symantec Trust Network, O=Symantec Corporation, C=US
  SerialNumber: [ ... ]

Certificate Extensions: 9
[1]: ObjectId: 1.3.6.1.4.1.11129.2.4.2 Criticality=false
Extension unknown: DER encoded OCTET string =

[omitted]

***
%% Invalidated:  [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT:  fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 01 00 02 02 2E                               .......
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException:

Does anyone have any suggestions as to what might be causing this problem?


Solution

  • unable to find valid certification path to requested target means the client is not trusting the server certificate due to

    1. incomplete chain from leaf certificate to root or
    2. root certificate is not present in truststore

    I have checked that Symantec Class 3 Secure Server SHA256 SSL CA is issued by VeriSign Universal Root Certification Authority (see Symantec page)

    Symantec & Verisign

    And Verisign root is effectively included in jdk1.7.0_79, so I discard 2). Therefore, my guess is an incomplete chain in server side.

    Actions

    1. Check server in https://www.ssllabs.com looking for 'incomplete chain errors'.

    2. Verify that the intermediate CA is really Symantec Class 3 Secure Server SHA256 SSL CA with serial number 69 87 94 19 d9 e3 62 70 74 9d bb e5 9d c6 68 5e

    3. On errors in step 1, download Symantec cert (from above link) and import into your truststore

    4. If the intermediate certificate is not the expected from Symantec, then get the root CA and import it into your trustore

    EDITED SSL trust verification

    Certificates are issued in a hierarchy. Each certificate is signed by the issuer of the upper level, from the root CA to the leaf certificates. The digital signature allows checking the certification chain.

    The SSL server must provide the certificate and the chain (not including the root). The trust manager checks the certification chain from leaf to root. If anyone of the certificates is found in the truststore then the certificate is "trusted" ( even if it is expired...)

    You should include the root CA in the truststore, not the leaf