I had a client with a pretty weird issue with client certificates last week and I thought I would share and maybe save somebody some time.
The client needed to consume a SOAP webservice that was protected with 2-way SSL, i.e. with both a server and a client certificate. Because of the new support for client certificates they had stepped away from the usual createObject() or cfinvoke code and moved to cfhttp, but they were getting connection errors on the ColdFusion side and HTTP 400 statuscodes in the logfiles of the webservice. That statuscode mean “Bad Request” and indeed the logfile did not show the correct resource path to the webservice but an empty path.
The first step towards solving the problem was to import the certificate chain of the server into ColdFusion. Steven Erat has an excellent article about this on his blog and sure enough the landscape changed. Instead of the HTTP 400 error the message in the cfhttp result and the webservice logfiles now was a HTTP 403 (Authentication Failed), but it did show the correct resource path. So obviously the next problem lay with the client certificates.
The client certificate appeared to be a normal client certificate with private key in PKCS#12 format, but from a different certificate chain then the server format. So I first had the client double-check that the chain was correctly installed on the server. Unfortunately it wasn’t that easy. I will spare you the details of what I tried, but in the end it turned out to be that the certificate was incorrectly encoded. These are the actual conversion steps I took to convert the certificate to a working state:
- import the certificate in the Windows Certificate store through the MMC;
- export the certificate with private key, whole chain and without strong encryption in PFX formet;
- convert the PFX encoded certificate to PEM using OpenSSL:
openssl pkcs12 -in raw.pfx -out intermediate.pem -nodes
- re-order the certificates inside the PEM file to the following order:
- Identity certificate
- Intermediate certificate
- Root certificate
- Private Key
- convert the PEM encoded certificate to PKCS#12 using OpenSSL:
openssl pkcs12 -export -out final.pkcs -in final.pem
It is probably possible to skip / merge a few of these steps (you probably just need to convert to PEM, reorder and convert back), but I really didn’t have time to explore that, I just know that this worked for me.
Several people have reported this procedure also fixes the following error which may occur after an update to ColdFusion 10:
Error while trying to get the SSL client certificate:
java.security.UnrecoverableKeyException: Could not decrypt key: Could not
decode key from BER. (Invalid encoding: expected tag not there. ).