0

I'm having trouble understanding why Weblogic/Java are not sending the Client certificate requested by the server(IIS server) during SSL Handshake via the CertificateRequest message.

I have already checked and tried all the other questions/answer in SO such as : Java not providing client certificate for mutual SSL? and similar.

I have created a custom keystore called Identity.jks with only one Certificate entry and I've follwed the WL guides (and everything else I could find on the Internet) to do the right settings.

Here are the debug logs for the SSL handshake:

*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA256withRSA, SHA384withRSA, SHA1withRSA, SHA256withECDSA, SHA384withECDSA, SHA1withECDSA, SHA1withDSA
Cert Authorities:
<Empty>
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>

As you can see the server sends a CertificateRequest message but for some reasons the Cert Authorities is Empty. The client (Weblogic) in this case doesn't send the certificate. As you can see there is a warning message by the developers saying:

no suitable certificate found - continuing without client authentication

When I use SoapUI instead of Weblogic to communicate with the server the handshake succeeds. SoapUI sends the certificate contained in the Identity.jks keystore.

Can it be that SoapUI is less restrictive and sends the only certificate present in the keystore anyway while Weblogic is expecting from the server to find something in the Cert Authorities: <Empty> ?

Since I've setup weblogic to use only that key with that alias I expect it to send it...

Anyone knows what are the criteria that Weblogic uses to find a matching client certificate?

Is my interpretation of the logs correct?

Any idea/help is welcome.

Alboz
  • 1,833
  • 20
  • 29
  • are they both Weblogic and SOAPUI running the exact same JVM ? – Eugène Adell Jun 29 '18 at 09:43
  • @EugèneAdell Yes they are running both in Java 8 specifically: jdk1.8.0_151 – Alboz Jun 29 '18 at 10:12
  • When the server sends an empty cert authorities list it is up to the client as to whether it's sends a cert or not. This you should fix the incorrect server configuration so that the server send the correct CAs list. – President James K. Polk Jun 29 '18 at 23:44
  • @JamesKPolk even with the server sending the list of cert authorities the problem still persists... Seems some WL specific behaviour. – Alboz Jun 30 '18 at 00:02
  • What did you set up exactly in WL ? If you're talking about the SSL configuration for an instance, that's for inbound communication. That configuration won't be used for outbound communication. – Andre Gelinas Jul 05 '18 at 02:51
  • @AndreGelinas what do you mean? There is an "Identity Store" and an alias that can be used for outbound SSL communication. Check the "SSL" tab and expand the "Advanced" section. Plenty of guides in the Oracle website on how to enable mutual-ssl (both inbound and outbound). – Alboz Jul 05 '18 at 16:42
  • What version of WL are you using ? My comments might have been unclear. Typically, the identity store host a certificate for inbound communication with Extended Key Usage set with ServerAuth. When used for outbound communication the certificate must have also (or only) the value ClientAuth to be used. By default the server certificate would be used, but if lacking ClientAuth, it won't work. What can be done is specifying a Client certificate for outbound. https://docs.oracle.com/middleware/1213/wls/SECMG/clientcert_for_2wayssl.htm#SECMG602 Sorry for the confusion – Andre Gelinas Jul 05 '18 at 17:10
  • @AndreGelinas that is exactly the guide I followed. I did all the settings using wlst as described there. I'm using WL 12.2.1.0. Interestingly enough, I installed another instance of WL to act as a server with "Client certificate Requested". I signed its identity with the same root CA and in this case it worked only after specifying the Identity keystore as JVM arguments on WL startup script. I cannot understand why doesn't send the same client certificate to IIS. It does trust the certificate exchanged by IIS because it's on the cacerts trust store and also custom trust store. – Alboz Jul 05 '18 at 21:27
  • Did you checked the value of Extended Key Usage of both your cert ? – Andre Gelinas Jul 05 '18 at 21:30
  • @AndreGelinas My certificate doesn't have extensions because they're not mandatory. I don't want the server to specify a different certificate for outbound connection, I want it to always use its identity, its https certificate. One my identity store there is only one certificate, that has to be shared on a CertificateRequest from the server. It's working between two Weblogics signed by the same root CA but not with a third system using IIS. Does it make sense? – Alboz Jul 05 '18 at 21:49
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/174464/discussion-between-andre-gelinas-and-alboz). – Andre Gelinas Jul 06 '18 at 00:37
  • "I have this problem" @AndreGelinas, did you get to the bottom of it? – The Archetypal Paul Aug 24 '20 at 11:12
  • @TheArchetypalPaul sorry, was 2 years ago, can't remember well and the chat is not there anymore. I think Alboz found the solution without me if memory serves me well though. – Andre Gelinas Aug 24 '20 at 11:34
  • Oops,. Sorry, meant that to be for @Alboz anyway! Thanks for the swift response - it was a long shot anyway. Back to banging my head on weblogic's configuration ... – The Archetypal Paul Aug 24 '20 at 11:50
  • @TheArchetypalPaul if I remember correctly in my case it was not enough to configure the Identity and TrustStore in the WebLogic admin console. You also have to set it as JVM arguments, when running client code in the JVM. – Alboz Aug 25 '20 at 21:57

2 Answers2

0

I've had a similar problem with a Java HTTP client. Depending on your IIS version the server may or may not be sending the certificate list back. Newer version don't.

Ensure that you have the full certificate chain and your client certificate in the keystore.

Marinus
  • 2,210
  • 2
  • 15
  • 15
0

Since there seems to be an interest, I'm answering my own question on how we fixed it.

When writing Java clients to communicate with other servers via Two-Way SSL we need to make sure that the SSL Context used to initiate the communication has been set with the Custom Identity Keystore and the Custom Trust keystore.

One convenient way to do this is to pass the Identity and Trust keystores as JVM options when a JVM process starts (on start of WebLogic or other web app server). JVM arguments can be passed in the server startup script (if present) or as command line argument.

The following is an example:

-Djavax.net.ssl.keyStore=D:\Path-to\identity.jks -Djavax.net.ssl.keyStoreType=JKS -Djavax.net.ssl.keyStorePassword=MyReallyComplexPassword -Djavax.net.ssl.trustStore=D:\Path-to\trust_keystore.jks  -Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.trustStorePassword=MyTrustStorePassword

Where the value of javax.net.ssl.keyStore is what we called the Custom Identity Keystore and the value of javax.net.ssl.trustStore is what we called the Custom Trust Keystore.

Note: Another way to accomplish the same thing would be to load-and-set the Identity & Trust keystores directly in the client's code itself, before firing the request to the server. There are multiple examples on-line that explain how to do this.

Important: When writing a client that should communicate via Two-Way SSL make sure to never blindly trust all certificates. Many client libraries give you a boolean option TrustAllCerts that can be useful during development however if you leave it in production Two-Way SSL will NOT work. This is because by telling the SSL context to trust any certificate, the Server Certificate Exchange Key is not checked (since you trust it anyway) and thus the CertificateRequest from the server is ignored. The client will continue without sending its client certificates but, because the server expects the client to send one, the handshake process will end in failure.

Alboz
  • 1,833
  • 20
  • 29
  • Thank you very much for this. I don't have control over my client code but allegedly it's been seen to work before. "Many client libraries give you a boolean option TrustAllCerts" - would some of the Weblogic start up options (e.g. to ignore hostname checking) have a similar impact? I do have the certificate request from the server, but the weblogic client never sends back a certificate. At some point I should ask my own question, I guess :) – The Archetypal Paul Aug 26 '20 at 08:13
  • Have you given the IdentityStore and TrustStore as arguments to the JVM? I would keep the startup arguments clean when it comes to SSL negotiations. – Alboz Aug 26 '20 at 09:49
  • Tried that (javax.net.ssl.keyStore, javax.net.ssl.keyStorePassword, javax.net.ssl.keyAlias, javax.net.ssl.keyType) and also tried using the default keystores. The debug output shows WL knows about my certiifcates, but still doesn't send any back to the client. Hence I thought it might be related to your accept-any-certs point – The Archetypal Paul Aug 26 '20 at 12:36
  • Also tried using the server certificates, and my custom ones. Same thing – The Archetypal Paul Aug 26 '20 at 12:38
  • @Alboz, I am having JVM arguments in weblogic startup as well I am loading certs in KeyManager by alias & TrustManager in SSLContext still getting handshack_failure because weblogic client is not passing certificate ! Confusing part is, when I tried to pick particular cert from identity store by alias in X509ExtendedKeyManager wrapper , the overriding methods are not being called at all ! I verified by adding log statements. Any guess ? – Ankit Sep 17 '20 at 00:00