SSL using certificates retrieved with Sun MSCAPI provider

We are having a problem with establishing a mutually (client) authenticated SSL connection between Java clients and a server. The aspect of our solution that differs from much of the information we can find on Java and SSL connections is that we are using certificates that are in the Microsoft certificate store and retrieved using the Sun MSCAPI provider.

We have written a custom KeyManager and a custom TrustManager, each of which use certificates out of the Microsoft certificate store (again, accessed using Sun MSCAPI provider) rather than certificates in a JKS. All of the certificates we are using are part of a PKI (not self-signed).

We are successfully using the certificates in other cryptographic operations in Java, such as creating and verifying digital signatures, using normal java.security classes. Although the error messages I will post below may seem to indicate that there is an issue with the certificate ("bad certificate" - see below), I really don't think it is a problem with the certificates as we are using them in many other places successfully - both in Java and COTS applications...we are only having a problem with Java SSL. The certificate chain that we create in the KeyManager includes all certs in the chain from the certificate to it's root (root is last in the array).

We have tried connecting the Java client to a variety of servers, including a simple java server, and all seem to have the same problem with it not being able to create a mutually authenticated ssl connection. When we disable client authentication on the servers (ss.setNeedClientAuth(false) in the simple java one), a server-side SSL connection is successfully established (not an option for our application - just fyi).

The error on the server side from our simple java server is:

*** CertificateVerify

Thread-0, SEND TLSv1 ALERT: fatal, description = bad_certificate

Thread-0, WRITE: TLSv1 Alert, length = 2

Thread-0, called closeSocket()

Thread-0, handling exception: javax.net.ssl.SSLHandshakeException: certificate verify message signature error

The error on the client side is:

***

[write] MD5 and SHA1 hashes: len = 16

0000: 14 00 00 0C 11 B4 2E 4905 CF AA D1 3E 20 10 B5 .......I....> ..

main, WRITE: TLSv1 Handshake, length = 32

main, READ: TLSv1 Alert, length = 2

main, RECV TLSv1 ALERT: fatal, bad_certificate

Does anyone have any experience with using certificates retrieved via the MS CAPI provider in SSL connections or any suggestions as to how to fix this problem? Is there something that needs to be set different from the default for the SSL context? We have tried changing the default settings, but haven't found a configuration that makes it work.

Thanks for any help.

[2821 byte] By [dj242a] at [2007-11-27 3:54:59]
# 1
Are the certificates current or have they by any chance expired?
ejpa at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 2
> Are the certificates current or have they by any> chance expired?I'm involved with this project also, and the certificates are current, have not expired, or been revoked.
lobsterboya at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 3

The certificates are current. Additionally, they work in many other applications in which we are using them, all of which are doing full validation on them (expired, revoked, etc.) and using them successfully.

We are also able to use them successfully in other non-Java test clients for client authenticated SSL.

Some additional information - I have tried changing the order of the providers so that SunMSCAPI is first. These changes were made on both the client and server side. This did not seem to have any effect on the problem (same error messages). Is making the SunMSCAPI provider the first the appropriate thing to do when we are using it for all of our certificate storage?

I have not found any examples or documentation on using keystores other than JKS for client authenticated SSL. Is there some configuration that needs to be done with the providers or algorithms in order to make this work?

One last thing. When connecting the simple Java client to a test openssl server (openssl s_server) with client auth required, the following error message is output by openssl:

ERROR

3996:error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01:.\crypto\rsa\rsa_pk1.c:100:

3996:error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed:.\crypto\rsa\rsa_eay.c:699:

3996:error:1408807A:SSL routines:SSL3_GET_CERT_VERIFY:bad rsa signature:.\ssl\s3_srvr.c:2315:

dj242a at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 4
Well there you are, openssl and JSSE both think it's a bad certificate. All I can suggest is try to get a better one, or re-examine your certificate import/export processes.
ejpa at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 5

If there is a problem with the certificates, the problem only exists under JSSE when using Sun MSCAPI as a certificate source. As I've said, we are successfully using the same certificates in Java to create and verify digital signatures (and retrieving them via the Sun MSCAPI provider using the same method as we are using in our custom managers that JSSE calls). Using an openssl client (s_client) to connect to the openssl server mentioned above works exactly as expected - so openssl does not think it's a bad certificate (unless JSSE with retrieval from Sun MSCAPI is involved). In fact, we've successfully used the certificates to create client authenticated ssl connections between a number of clients (openssl, IE, Firefox, .NET, Java JSSE using JKS) and servers (openssl, IIS, Java JSSE using JKS), all of which work except when JSSE using Sun MSCAPI is on either end of the connection (openssl client connecting to simple Java server mentioned above also does not work).

As far as importing and exporting the certificates goes - we are not dealing with a JKS here - we are installing them into the Microsoft certificate store, and all of our other applications are using them successfully. The certificates have been issued under a mature PKI solution that has a standard way of installing the certificates into the Microsoft certificate store for use. We also, as mentioned were able to get JSSE to work with the certificates using a JKS. However, using a JKS is not an option in our production environment.

We've been working with this issue for a while now and have gone to great lengths to isolate the problem to the Sun MSCAPI / JSSE combination. Does anyone have experience with this combination or any thoughts on why we are having problems with it?

Thanks for the continued interest in this subject.

dj242a at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 6

We have created a simple test case that reproduces the problem discussed in this thread. It is a simple Java SSL server that requires client authentication and a simple Java client. The test certificates were generated using openssl using the information at this link as a guide:

http://www-128.ibm.com/developerworks/java/library/j-certgen/

The certificates mimic those that were issued by the PKI with which we are integrating in that they form a three certificate chain. This simple test case and the test certificates exactly reproduce the problem we are having with our production application that is using certificates issued by a mature PKI.

The test case fails when the Windows-MY key store is used on the client side. The test case succeeds when the exact same certificates are used directly from the user1.p12 and server1.p12 PKCS12 certificate files. The only change made when testing against Windows-MY versus PKCS12 is a configuration change to the values of the javax.net.ssl.keyStore properties (same code in both cases).

The test case includes a custom key manager that uses a certificate with alias "User1" for client and a certificate with alias "Server1" for server. You can also reproduce the problem without the custom key manager (to eliminate the possibilty that there is a problem with the customer key manager) by removing all of your certificates from your Personal store (use certmgr.msc) except "User1" and "Server1" (which are installed by the user1.p12 and server1.p12 files below), and commenting out the property in resource/security.properties.

Note that this must be run under Java 6 since it uses the SunMSCAPI provider.

Follow these steps to run the test case (the test case and logs are provided at links below):

1. Extract the test case.

2. Install from the certs folder user1.p12 and server1.p12 into the Microsoft certificate store (double click each file and follow the wizard, the password for the private keys is "test", allow Windows to automatically select the certificate store, otherwise choose defaults).

3. Build the example (actually, the binary classes are in the zip, so this is not required):

...\SimpleSSL> ant build

4. Run the server from a command prompt:

...\SimpleSSL> ant server

5. Run the client from another command prompt:

...\SimpleSSL> ant client

The test will fail with the error messages included in previous posts (see full logs at links below).

To make it succeed with the PKCS12 store, either modify resource/client-system.properties and comment out the MSCAPI section and uncomment the PKCS12 section, or rename resource/client-system.properties.thisOneWorks to resource/client-system.properties. Now run step 5 above again and it will succeed using the same certificates from the PKCS12 store.

The example is also an Eclipse project so it can easily be imported and run in Eclipse if that is your preferred development environment.

I have also exported the certificates back out of the Microsoft store into a PFX, converted them back to a P12 using Firefox, and run the test case against that P12 file to show that the certificates are not being corrupted in the Microsoft store.

Logs of problem with sunmscapi (Windows-MY) store:

http://hostfile.org/serversunmscapi.log

http://hostfile.org/clientsunmscapi.log

Logs of success with pkcs12 store:

http://hostfile.org/serverpkcs12.log

http://hostfile.org/clientpkcs12.log

Test case source code:

http://hostfile.org/SimpleSSL.zip

dj242a at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 7
Try the Bug Parade.
ejpa at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 8
I too am having the same error. I am able to successfully run my application when the key is in a PKCS12 keystore, but the application fails when trying to run with the keys in a Windows keystore.
DuckSeductora at 2007-7-12 8:59:08 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...