failed https with self signed client certificates

Hi guys,

After hours spent trying and also going through million entries in wM forums I am still stuck with following:

I need to prove that we can connect to outside system (payment platform) with client certs.
The platform requires client authentification.
To simulate the platform, we have a mockup running on Tomcat server with following settings:

<Connector port=“443” maxHttpHeaderSize=“8192”
maxThreads=“150” minSpareThreads=“25” maxSpareThreads=“75”
enableLookups=“false” disableUploadTimeout=“true”
acceptCount=“100” scheme=“https” secure=“true”
clientAuth=“want” sslProtocol=“TLS”
keystoreFile=“C:\entwicklung\ca\server\server.ks”
keystorePass=“keystore” keystoreType=“JKS”
trustStoreFile=“C:\entwicklung\ca\server\server.ks”
truststorePass=“keystore” />

So for simple test I just invoke pub.security:setKeyAndChain and pub.client:http.
I set the cert chain with private key and client cert supplied, which is self signed (no CA or intermediate certificate)
I enabled the debugging for SSL in the IS and get following trace:

ssl_debug(31): Starting handshake (iSaSiLk 3.03)…
ssl_debug(31): Sending v2 client_hello message, requesting version 3.1…
ssl_debug(31): Received v3 server_hello handshake message.
ssl_debug(31): Server selected SSL version 3.1.
ssl_debug(31): Server created new session 48:B8:20:4B:6B:8E:99:A4…
ssl_debug(31): CipherSuite selected by server: SSL_RSA_WITH_RC4_128_MD5
ssl_debug(31): CompressionMethod selected by server: NULL
ssl_debug(31): Received certificate handshake message with server certificate.
ssl_debug(31): Server sent a 1024 bit RSA certificate, chain has 1 elements.
ssl_debug(31): Received server_hello_done handshake message.
ssl_debug(31): Sending client_key_exchange handshake message (1024 bit)…
ssl_debug(31): Sending change_cipher_spec message…
ssl_debug(31): Sending finished message…
ssl_debug(31): Received change_cipher_spec message.
ssl_debug(31): Received finished message.
ssl_debug(31): Session added to session cache.
ssl_debug(31): Handshake completed, statistics:
ssl_debug(31): Read 737 bytes in 3 records, wrote 182 bytes in 3 records.
2008-08-29 18:14:03 CEST [ISC.0038.0002D] → GET /ldsws/ HTTP/1.1
2008-08-29 18:14:03 CEST [ISC.0038.0002D] → User-Agent: Mozilla/4.0 [en] (WinN
T; I)
2008-08-29 18:14:03 CEST [ISC.0038.0002D] → Accept: image/gif, /
2008-08-29 18:14:03 CEST [ISC.0038.0002D] → Host: localhost:443
2008-08-29 18:14:03 CEST [ISC.0038.0002D] → Content-Type: application/x-www-fo
rm-urlencoded
ssl_debug(31): Received hello_request handshake message from server, restarting
handshake…
ssl_debug(31): Acquiring locks for renegotiation…
ssl_debug(31): Starting renegotiation…
ssl_debug(31): Sending v3 client_hello message, requesting version 3.1…
ssl_debug(31): Trying to resume session 48:B8:20:4B:6B:8E:99:A4…
ssl_debug(31): Received v3 server_hello handshake message.
ssl_debug(31): Server selected SSL version 3.1.
ssl_debug(31): Server created new session 48:B8:20:4B:DC:F4:09:BF…
ssl_debug(31): CipherSuite selected by server: SSL_RSA_WITH_RC4_128_MD5
ssl_debug(31): CompressionMethod selected by server: NULL
ssl_debug(31): Received certificate handshake message with server certificate.
ssl_debug(31): Server sent a 1024 bit RSA certificate, chain has 1 elements.
ssl_debug(31): Received certificate_request handshake message.
ssl_debug(31): Accepted certificate types: RSA, DSS
ssl_debug(31): Accepted certificate authorities:

ssl_debug(31): Received server_hello_done handshake message.
ssl_debug(31): No client certificate available, sending empty certificate messag
e…
ssl_debug(31): Sending client_key_exchange handshake message (1024 bit)…
ssl_debug(31): Sending change_cipher_spec message…
ssl_debug(31): Sending finished message…
ssl_debug(31): Exception sending message: java.net.SocketException: Software cau
sed connection abort: socket write error
ssl_debug(31): Shutting down SSL layer…

So somehow the IS is not sending my own client certificate, even if I put it in the chain.

This error corresponds to error thrown on the Tomcat:

29.08.2008 18:14:03 org.apache.coyote.http11.Http11Processor action
WARNUNG: Exception getting SSL attributes
javax.net.ssl.SSLHandshakeException: null cert chain
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)

IS is set up to ignore empty chains and also to trust all CA’s, so the CA trusted dir is not used for this first attempt.

I also tried to do it other way, when I set up the certs in the ADMIN/certificates Outbound SSL Certificates page, but that throws the same error UNLESS I put the same client certificate as server’s CA certificate
For this case, I disabled the pub.security:setKeyAndChain call in the test flow and did the https directly.

Then the errors are different:

IS:
ssl_debug(34): Received server_hello_done handshake message.
ssl_debug(34): Sending certificate handshake message with RSA client

ssl_debug(34): Sending client_key_exchange handshake message (102
ssl_debug(34): Sending certificate_verify handshake message…
ssl_debug(34): Sending change_cipher_spec message…
ssl_debug(34): Exception sending message: java.net.SocketExceptio
sed connection abort: socket write error
ssl_debug(34): Shutting down SSL layer…

(As you can see, now the client cert is being sent, but only if I put it as server’s CA folder in the Admin/Certificates settings page)

Tomcat:

29.08.2008 18:30:59 org.apache.coyote.http11.Http11Processor action
WARNUNG: Exception getting SSL attributes
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: End user tried to act as a CA
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)

Any idea?

At last, I imported the certs into IE and FireFox and was able to connect to the site from both  without any problems.

One strange thing is that I am not able import those certs as client certificates to IS (‘Could not import certificate. Please ensure that the file is a valid certificate’), eventhough they are in the correct format (otherwise setKeyAndChain wouldn’t work)

Any suggestions are greatly appreciated

versions: IS 7.1.1, clean installation

Thanks

//Matt

Matt,

IS certs have to be in DER format which would be different from the format that you import to browsers. OpenSSL can convert between formats.

Also, the open source Portecle tool has a SSL client utility built in that lets you see which certs are being returned from an SSL server. Not necessarily, relevant in your situation, but handy for confirming that a target server is returning well-formed certs.

Mark

Hi Mark,

Thanks for your reply.

All the certs are in DER format, I have them properly converted. If there was anything wrong with them, the setKeyAndChain would complain.
Which might not be the case for the IS when reading the certs from the Certificates Admin page settings.

I have already tested the SSL handshake (see my other post here) with s_server and I am almost certain that the certs are not sent by IS when using the built in service, and are only sent when configured on the Admin Certificates page.
And only when the server ca AND the server cert paths are configured.

Needless to say, that in both cases its the same files.

But I will have a look at the Portecle tool, might give me more info.

//Matt

Ok, got it working - lessons learned:

  1. To have SELF SIGNED server certificate setup and working globally on the Admin Page/Certificates - you neeed to put the certificate in both the server’s certificate field AND the server’s CA field.
    Both fields must be pointing to the SAME certificate file.

Otherwise the IS won’t send any certificate inside the chain, it will be left empty and you will see this error message:
‘ssl_debug(6): No client certificate available, sending empty certificate message’

Don’t ask me why, though.

  1. Other way is to use pub.security:setKeyAndChain, but check your certificate at least twice. If IS doesn’t send anything, there is 99% chance that there is something wrong with the certificates itself (my case).

Beware: 1st works fine with IS->IS, but not with Tomcat, for example. Tomcat complains that the ‘end user is trying to act as CA’.
Therefore the 2nd method is preferred.

//Matt

I think my scenario is the opposite as Matt’s.

We are trying to enable Weblogic to invoke wM IS712 over wM’s HTTPS port. Weblogic is using .jks keystores to store their certs and their Admin has provided me with their public key (self-signed certificate weblogic.cer). When they invoke a wM service, weblogic gets “invalid certificate” and my wM ssl logs shows a similar message. Here are the details in wM ssl log:

ssl_debug(20): Sending certificate handshake message with server certificate…
ssl_debug(20): Sending certificate_request handshake message…
ssl_debug(20): Sending server_hello_done handshake message…
ssl_debug(20): Received alert message: Alert Warning: no certificate
ssl_debug(20): ChainVerifier: Empty peer certificate chain, NOT OK
ssl_debug(20): Sending alert: Alert Fatal: bad certificate
ssl_debug(20): Shutting down SSL layer…
ssl_debug(20): SSLException while handshaking: Client certificate rejected by ChainVerifier.

I’ve imported weblogic.cer into my IS and mapped it to the weblogicUser. The weblogicUser belongs to the approvedClients group which is mapped to the approvedClients ACL. The service weblogic is calling has an execute ACL of “approvedClients”.

I’ve also added weblogic.cer cert’s signing cert (weblogicCA.cer) into my trusted certs directory in wM. I’m not sure why we are seeing the “invalid cert” type message on both Weblogic and wM. Any ideas?

Thanks,
Rajesh

Update: It turns out the wM setup was actually fine. There was an issue on the client side (Weblogic) where they were using 2 different keystores. The one which contained the client certificate I had loaded into wM was being overwritten by the other keystore.

The Weblogic Admin still hasn’t figured out how to implement this, but I have suggested merging his 2 keystores into one. I believe that should do the trick.

Maybe this will help?
To set up this trust, the clients must trust the root of the server’s certificate. This means, clients have to possess the certificate of the certification authority that issued the server certificate in their Trusted Root Certification Authorities store. You can observe this store via the Certificates snap-in.

The process is mandatory if you are using a certificate not issued by a third part vendor.

Important
To install the server root certificate, do the following on the client.

To install the root Certificate on the client

  • Open the Certificates snap-in console. If you have not previously added in the Certificates snap-in console, you can achieve this by doing the following:
    [LIST]
  • Click Start, select Run, type mmc, and then tap OK.
  • On the File menu, choose Add/Remove Snap-in.
  • In the Add or Remove Snap-ins dialog box, in the Available snap-ins file, choose Certificates, and then click Add.
  • In the Certificates snap-in dialog box, select Computer account, and at that time click Next.
  • In the Select Computer dialog box, click Local computer: (the computer this console is running on), followed by selecting Finish.
  • In the Add or Remove snap-ins dialog box, click OK.
    [/LIST]
  • In the Certificates snap-in console, in the console tree, double click to show more items on Certificates (Local Computer), repeat previous step with Trusted Root Certification Authorities, right-click Certificates, and focus on All Tasks, followed by selecting Import.
  • Once you get to the Welcome to the Certificate Import Wizard page, select Next.
  • On the File to Import page, in the File name box, indicate the title of the server root certificate, then select Next.
  • On the Password page, if you created a pass phrase for the private key linked with the certificate previously, enter the pass phrase.
  • On the Certificates Store page, allow the default selection (Place all certificates in the following store – Trusted Root Certification Authorities), followed by choosing Next.
  • On the Completing the Certificate Import Wizard page, verify that the certificate settings appear as followed:
    [LIST]
  • Certificate Store Selected by User: Trusted Root Certification Authorities
  • Content: Certificate
  • File Name: FilePath<Root_Certificate_Name.cer>, where <Root_Certificate_Name> is the name of the server root certificate.
    [/LIST]
  • Select Finish.
  • Once the certificate upload has successfully concluded, a confirmation message will show up proving the import was successful. Select OK.
  • With Certificates chosen in the console hierarchy, in the detail panel, confirm that the root certificate of the server has become visible in the file of certificates on the client.

This process can be modified on client computers to use website certificates, remote desktop certificates, and Exchange certificates.

Shawn Zernik
www.internetworkconsulting.net

After a lot of tries following steps worked for me:

  1. Key: openssl genrsa -des3 -out .key 1024
  2. CSR: openssl req -config openssl.cfg -new -days 3650 -key .key -out .csr
  3. Signed Cert: openssl x509 -days 3650 -signkey .key -in .csr -req -out .crt
  4. Cert to DER format: openssl.exe x509 -in .crt -outform DER -out .der
  5. Key to DER format: openssl rsa -inform PEM -outform DER -in .key -out .der
  6. Imported cert and key to windows “Trusted Root Certification Authorities” (local Computer) keystore
  7. Doubleclicked the cert file and saved a “windows” DER copy to use it as client certificate

Then, finally, the combination of the services setKeyAndChain and http worked.

Sorry, forget my last posting. - The partner did not check for a client certificate when I tested. After he enabled certificate check again I again got the error “java.io.IOException: iaik.security.ssl.SSLException: Peer sent alert: Alert Fatal: certificate unknown”