1
votes

I'm facing one issue with SSL handshake, the client is not presenting the client certificate when I host the application on tomcat but same code works fine on standalone java application. I thought this could be a issue with Tomcat not loading the keystore correctly so I followed https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration to create a keystore and then adding the -Djavax.net.ssl.trustStore="C:\Users\xyz.keystore" -Djavax.net.ssl.trustStorePassword="changeit" but this doesn't solve the issue. Not sure what I'm missing here.

Application code:

SSLContext ctx = null;
SSLSocketFactory socketFactory = null;
        KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "abcd".toCharArray();

ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");

ks.load(new FileInputStream("C:/goahead.jks"), passphrase);

kmf.init(ks, passphrase);

ctx.init(kmf.getKeyManagers(), null, null);

socketFactory = ctx.getSocketFactory();
String endpoint = "https://myurl/goahead";
BindingProvider bindingProvider = (BindingProvider) goSOAP;    //goSOAP is derived from wsdl soap class
bindingProvider.getRequestContext()
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
bindingProvider.getRequestContext()
.put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", socketFactory); 

To compare both of the logs I added debug logs for ssl-handshake and the only difference I saw is as below: Tomcat application shows:

Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;action="/Address"
User-Agent: JAX-WS RI 2.2.10 svn-revision#919b322c92f13ad085a933e8dd6dd35d4947364b

where as standalone application shows:

Accept: [application/soap+xml, multipart/related]
Content-Type: [application/soap+xml; charset=utf-8;action="/Address"]
User-Agent: [JAX-WS RI 2.2.4-b01]

And near the end standalone application has

*** ServerHelloDone
matching alias: goaheaduat
*** Certificate chain

the tomcat based application doesn't have the matching alias:

Client certificate has not being presented to the server for the authentication.

*** My certificate chain. found key for : goaheaduat chain [0] = [ [ Version: V3 Subject: CN=WebKYCTest.servicepartnerconsumer.com, OU=ISS-3PTY, O=JabongS Signature Algorithm: SHA256withRSA, OID = 1.3.340.314509.9.0.32

Key: Sun RSA public key, 2048 bits modulus: 27573819147946213043216108193871654407922029181865423070240388390082203239203276484533998399141937338366712797583606436874669271136184327404678172471800553725661929882862711783147991980007784094228604257987704412377010220942071292525488807622245786848032603065210767423710596079119175986038958679485985173914183400986232704952684194291691771747100348011779606334479154902757588018357364139623723065756491506767148994346890208737770932855458704848837399114296416887151154418561578978073777312232789403716198956145390511813892730740350579365196627658126157277478693917625969224935645208986859585794507961203141704075579 public exponent: 65537 Validity: [From: Tue May 03 15:03:50 EDT 2016, To: Mon Apr 22 15:33:49 EDT 2019] Issuer: CN=Entrust Certification Authority - L1K, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US SerialNumber: [ 1051555d 65348b53 00000000 50d7ff44]

*** ClientHello, TLSv1 RandomCookie: GMT: 1451756012 bytes = { 109, 25, 125, 234, 72, 78, 180, 84, 205, 146, 231, 249, 138, 99, 17, 154, 171, 146, 144, 41, 1, 15, 203, 209, 38, 255, 236, 148 } Session ID: {} Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] Compression Methods: { 0 } Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} Extension ec_point_formats, formats: [uncompressed]


found key for : goaheaduat chain [0] = [ [ Version: V3 Subject: CN=WebKYCTest.servicepartnerconsumer.com, OU=ISS-3PTY, O=JabongS Signature Algorithm: SHA256withRSA, OID = 1.3.340.314509.9.0.32

Key: Sun RSA public key, 2048 bits modulus: 27573819147946213043216108193871654407922029181865423070240388390082203239203276484533998399141937338366712797583606436874669271136184327404678172471800553725661929882862711783147991980007784094228604257987704412377010220942071292525488807622245786848032603065210767423710596079119175986038958679485985173914183400986232704952684194291691771747100348011779606334479154902757588018357364139623723065756491506767148994346890208737770932855458704848837399114296416887151154418561578978073777312232789403716198956145390511813892730740350579365196627658126157277478693917625969224935645208986859585794507961203141704075579 public exponent: 65537 Validity: [From: Tue May 03 15:03:50 EDT 2016, To: Mon Apr 22 15:33:49 EDT 2019] Issuer: CN=Entrust Certification Authority - L1K, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US SerialNumber: [ 1051555d 65348b53 00000000 50d7ff44]

server_name, server_name: [host_name: it-internalservicepartner.jabong-dns.com]


http-bio-127.0.0.1-80-exec-1, WRITE: TLSv1 Handshake, length = 199 http-bio-127.0.0.1-80-exec-1, READ: TLSv1 Handshake, length = 16384 *** ServerHello, TLSv1 RandomCookie: GMT: 1451756012 bytes = { 33, 109, 178, 249, 102, 30, 1, 105, 194, 42, 88, 10, 247, 104, 93, 45, 166, 230, 141, 49, 180, 154, 198, 251, 76, 170, 162, 49 } Session ID: {87, 136, 10, 236, 32, 220, 206, 169, 30, 219, 131, 106, 24, 37, 117, 192, 116, 56, 195, 254, 29, 197, 185, 155, 141, 192, 95, 152, 23, 143, 14, 114} Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA Compression Method: 0 Extension renegotiation_info, renegotiated_connection:


%% Initialized: [Session-17, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA] ** TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *** Certificate chain

* ECDH ServerKeyExchange Server key: Sun EC public key, 256 bits public x coord: 68950688134319531882901065943858827597037420392341729344093733189994857259424 public y coord: 103565436179130252254673183632021691038591576368603542556238032190750005197048 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) http-bio-127.0.0.1-80-exec-1, READ: TLSv1 Handshake, length = 1760 * CertificateRequest Cert Types: RSA, DSS, ECDSA Cert Authorities: *** ServerHelloDone

1
There must be another difference. Compare the CertificateRequest messages.user207421
@EJP The random cookies and session ids are different. All the certificate chain, serverhello are same in both the cases. is this something related to tomcat configuration where tomcat uses its own set of keystore/truststore?Ashish
I didn't mention the cookies or the session ID. Of course they are different. Please post the CertificateRequest.user207421
@EJP I got this same message in both cases: *** CertificateRequest Cert Types: RSA, DSS, ECDSA Cert Authorities: <CN=COMODO RSA Organization Validation Secure Server CA, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB> <CN=Entrust Root Certification Authority - G2, OU="(c) 2009 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US> *** ServerHelloDoneAshish
Exactly the same? Same CA list? And is your certificate signed by one of those CAs?user207421

1 Answers

1
votes

The Server has a truststore, inside this truststore is a public certificate of the client. Only if this public certificate of the client inside the truststore has no issuer, or at least one issuer is inside the truststore it matches the alias.

See the sourcecode at https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java#L374

       if (issuers.length == 0) {
            // no issuer specified, match all
            aliases.add(alias); <--- this is important
            if (debug != null && Debug.isOn("keymanager")) {
                System.out.println("matching alias: " + alias);
            }