Reputation: 51
I am currently working on a SSL client in Java and need to establish a https connection with a third party server which requires client authentication. The server guys have given me a trusted root CA cert that is used to sign both client as well as server certificates. I have put this cert in the truststore on my side. The server folks also have this root CA cert which they use to verify client certificates.
When I try to establish a SSL connection the server I see that the handshake goes through fine when server sends it's cert and my client is able to verify it successfully. But as part of the 'Certificate Request' message, the server DOES NOT return any root CA cert in the 'Cert Authorities' parameter. Due to this my client does not send the client cert back to the server and the handshake fails.
I am writing standard Java code with WSDL stubs. I am leveraging the wsdl stubs generated by wsdl2Java ant task.
So My question is: Can I make my java client send a pre-set client certificate back to the server even when the server sends an empty 'Cert Authorities' list when it requests the client authentication. (I read the TLS RFC and I see that its legal for a server to send an empty list like this in which case the client may send back any certificate it sees fit. I am trying to achieve exactly the same behavior).
Upvotes: 3
Views: 4038
Reputation: 310913
There's no point in this. The server still won't accept it. At least it shouldn't accept it, and if it is using any of SSL implementations in common use it won't accept it. And it isn't at all likely that they've tweaked their own SSL implementation.
The problem is at the server end. It is misconfigured. You can't fix it at the client end. It should be sending you that root CA cert, or one of its signers, in the CertificateRequest
message.
EDIT This answer applies to TLS 1.0. It is obsoleted by TLS 1.1 and successors.
Upvotes: 1
Reputation: 11
We encountered similar issue, and kind of interesting, the library we use is spring-ws and spring-ws-support, there you can create a HttpsUrlMessagenSender bean to make soap calls, by setting custom KeyStoreFactoryBean, you can set your jks keystore(client cert) location. But we got the same issue mentioned here.
But if we use default behavior(no HttpsUrlMessagenSender bean), and passing the keystore via java.net.ssl.keyStore it works, with empty Cert Authority list, it sends the client cert anyway.
It seems to me that the jvm arg triggered some behavior that is different. Some software even has flag to deal with this http://techcommunity.softwareag.com/web/guest/pwiki/-/wiki/Main/Debugging+TLS+SSL+connections+in+Integration+Server
Upvotes: 1
Reputation: 2288
Sorry for replying to this age old post, but I couldn't resist.
I have seen this kind of handshakes work just fine:
according to javax.net.debug=all
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withRSA, Unknown (hash:0x6, signature:0x2), SHA512withECDSA, SHA384withRSA, Unknown (hash:0x5, signature:0x2), SHA384withECDSA, SHA256withRSA, Unknown (hash:0x4, signature:0x2), SHA256withECDSA, SHA224withRSA, Unknown (hash:0x3, signature:0x2), SHA224withECDSA, SHA1withRSA, SHA1withDSA, SHA1withECDSA
Cert Authorities:
<Empty>
*** ServerHelloDone
matching alias: our_client_cert_alias
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=
But it might depend on your HTTP client library and how it handles SSL/TLS (re)negotiation. This was using Java 8 and http://spray.io/documentation/1.2.4/spray-client/
Upvotes: 2