3

I have a Java based client which talks to my Java server via Tomcat 8. I need to get ClientAuth SSL working between the client and server. I have 2 different problems depending on whether I configure Tomcat to use Http11NioProtocol for SSL or native APR (openssl) for SSL. I need either Tomcat config to work. I tried both to narrow down the problem.

Client code is below. I switched to using custom X509ExtendedTrustManager (ServerTrustManager) and X509ExtendedKeyManager (ClientAuthKeyManager) classes in order to ensure the proper data is provided and to help debug.

ServerTrustManager serverTm = new ServerTrustManager(getCaCertificates());
TrustManager [] trustManagers = new TrustManager[] { serverTm };
                ClientAuthKeyManager mykm = 
                        new ClientAuthKeyManager(getSessionContext().getProductAgentCertificate(), getSessionContext());
KeyManager[] keyManagers = new KeyManager[] { mykm };

SSLContext sslContext = SSLContexts.createDefault();
sslContext.init(keyManagers, trustManagers, null);
Client clientHttps = ClientBuilder.newBuilder()
                    .withConfig(getClientConfig())
                    .sslContext(sslContext)
                    .build();

TOMCAT WITH APR (OPENSSL)

Tomcat 8 configured with:

<Connector port="8443"  
protocol="org.apache.coyote.http11.Http11AprProtocol"
SSLEnabled="true" 
SSLVerifyClient="require"
SSLCertificateFile="...\dim.magnicomp.com-productserver.crt"
SSLCertificateKeyFile="...\dim.magnicomp.com-productserver.key" 
SSLPassword="..."
SSLCertificateChainFile="...\ca-bundle.crt"
maxThreads="200" 
scheme="https" 
secure="true"/>

QUESTION: Is there debug output/logging I can enable for the Apr/OpenSSL code? I couldn't find any results from google on this.

With this Tomcat config my Java client fails to connect (ssl debug from client):

... snip ...
*** CertificateVerify
Signature Algorithm SHA512withRSA
main, WRITE: TLSv1.2 Handshake, length = 264
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
main, handling exception: java.net.SocketException: Software caused connection abort: socket write error
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
main, SEND TLSv1.2 ALERT:  fatal, description = unexpected_message
main, WRITE: TLSv1.2 Alert, length = 2
main, Exception sending alert: java.net.SocketException: Software caused connection abort: socket write error
main, called closeSocket()
17:05:17,709 ERROR JAX-RS ProcessingException for https://dim.magnicomp.com:8443/cabridge/v1/device/configuration - java.net.SocketException: Software caused connection abort: socket write error

With this same config the "openssl s_client ..." command with the ClientAuth cert works:

# openssl s_client -connect localhost:8443 -CAfile ca-bundle.crt -cert dim.magnicomp.com-productagent.crt -key dim.magnicomp.com-productagent.key
CONNECTED(00000003)
depth=2 CN = MagniComp Root CA
verify return:1
depth=1 DC = com, DC = magnicomp, CN = MagniComp Issuing CA3
verify return:1
depth=0 CN = dim.magnicomp.com
verify return:1
write:errno=113
---
Certificate chain
 0 s:/CN=dim.magnicomp.com
   i:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
 1 s:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
   i:/CN=MagniComp Root CA
 2 s:/CN=MagniComp Root CA
   i:/CN=MagniComp Root CA
---
... snip ...

TOMCAT WITH Http11NioProtocol

The Tomcat side appears to fail to accept the ClientAuth cert (output from Tomcat/Apr):

http-nio-8443-exec-2, fatal error: 46: General SSLEngine problem
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
http-nio-8443-exec-2, SEND TLSv1.2 ALERT:  fatal, description = certificate_unknown

The above Tomcat errors occur from either my Java client or "openssl s_connect":

# openssl s_client -connect localhost:8443 -CAfile ca-bundle.crt -cert dim.magnicomp.com-productagent.crt -key dim.magnicomp.com-productagent.key
CONNECTED(00000003)
depth=2 CN = MagniComp Root CA
verify return:1
depth=1 DC = com, DC = magnicomp, CN = MagniComp Issuing CA3
verify return:1
depth=0 CN = dim.magnicomp.com
verify return:1
6870300:error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:s3_pkt.c:1472:SSL alert number 46
6870300:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
---
Certificate chain
 0 s:/CN=dim.magnicomp.com
   i:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
 1 s:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
   i:/CN=MagniComp Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
... snip ...
-----END CERTIFICATE-----
subject=/CN=dim.magnicomp.com
issuer=/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
---
Acceptable client certificate CA names
/CN=MagniComp Root CA
/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:ECDSA+SHA224:RSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1:RSA+MD5
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:ECDSA+SHA224:RSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4528 bytes and written 5835 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 57102D9B932A1CBBCEFB687A74885A204D3473D8154EBA09D8E073173B18CC17
    Session-ID-ctx:
    Master-Key: 9BDC26F7CD11D05F2EFF07764F280D167E1547306B6626EF9955C97805816A13F7A0ABB9CCC3BF883282998881DDFFB3
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1460678043
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

The Tomcat server.xml:

<Connector 
protocol="org.apache.coyote.http11.Http11NioProtocol" 
SSLEnabled="true" 
clientAuth="true" 
keyAlias="privatekey" 
keyPass="..."
keystoreFile="...\dim.magnicomp.com-productserver.jks" 
keystorePass="..."
keystoreType="JKS"
maxThreads="200" 
port="8443" 
scheme="https"
secure="true" 
truststoreFile="...\cacerts.jks" 
truststorePass="changeit"/>

DEV ENVIRONMENT I'm using Oracle Java 1.8.65. I have installed the full JCE in the JVM and verified its enabled. The Agent and server are the same Windows 10 system.

1 Answer 1

2
  1. In the APR environment you haven't configured OpenSSL to trust any certificate authorities. You need to set either

    SSLCACertificatePath
    

    or

    SSLCACertificateFile
    

    See the documentation.

  2. In the non-APR case, your truststore doesn't trust the client certificate. If it is self-signed it needs to be imported into the truststore, which implies you should copy the JDK/JRE truststore to a local one and import into that so you don't get clobbered by the next Java update. If it isn't self-signed, the CA's certificate needs to be imported as above. In both case the keytool -trustcacerts option must be used.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, the SSLCACertificatePath for the APR config was just what I was missing. I had it confused with the SSLCertificateChainFile which I realize now is meant for the SSLCertificateFile. Thank you EJP!!!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.