0

I'm trying to get client certificate verification working with ColdFusion10 http requests. Currently, all I'm getting back is a 403.7. I believe ColdFusion isn't picking up my client certificate. Below is the steps I've currently taken to install and get it set up.

What I've done:

  • Created a self-signed SSL certificate and installed it to my default website on IIS 7.5.
  • Installed the SSL cert into CF store.
    • Tested HTTPS request, everything works fine.
  • Followed this guide for CA and Client Certs. https://ondrej.wordpress.com/2010/01/24/iis-7-and-client-certificates/
  • Installed the CA cert to server and client (through MMC). Installed client cert (.pfx) on client.
    • Tested in local browser, everything is working as it should up to this point.
  • Created another client cert for CF10 (.cer, .pvk, .pfx).
  • Added the CA cert into CF store.
    • Tested, HTTPS rejected with 403.7.
  • Added CA cert, client .pfx and .cer through MMC under CF10.
    • Tested, rejected again with 403.7 still.

I've seen that there has been issues with CFHTTP and client certs before, but I haven't found an solution yet. If anyone can help me with this, it would be great.

EDIT: After doing what Miguel-F suggested, I skimmed through the log files and found that my CA was imported inside the ColdFusion trust store, but my client certificate wasn't there. I assume this is the reason for the 403.7.

However, I can't add my client certificate(.pfx) to the trust store using certman or keytool through cmd. I created the .pfx by merging my .cer and .pvk together, so I have both of those also.

How can I add my .pfx to the trust store so that Coldfusion picks it up and validates my https?

EDIT #2: After following this to add my .pfx to the keystore, I can now see my client cert along with my CA being added as 'trusted cert' during the https request.

However, I'm still getting the 403.7 - Forbidden error.

Edit #3: The handshake in ssl debug info after adding my .pfx (see edit #2) is:

'Is initial handshake: true'
'catalina-exec-3, WRITE: TLSv1 Handshake, length = 181' (Several of these in 1 request)

Edit #4 (More Debug Info):

The last section above where it returns 403 in the debug info looks like HTML content for the error page returned by the server. Just above that however is this:

catalina-exec-3, READ: TLSv1 Application Data, length = 5808
Padded plaintext after DECRYPTION:  len = 5808
0000: 48 54 54 50 2F 31 2E 31   20 34 30 33 20 46 6F 72  HTTP/1.1 403 For (Example of the HTML error content)

Edit #5: I can see my client cert being added as a trusted cert during the start of the request... It's just not using it.

adding as trusted cert:
Subject: CN=George CF10
Issuer:  CN=MyPersonalCA
Algorithm: RSA; Serial number: 0x-431b7d9911f9856cb0adf94d50bb1479
Valid from Fri Apr 01 00:00:00 BST 2016 until Wed Apr 01 00:00:00 BST 2020

Edit #6: After adding setClientCert(path to my .pfx) and setClientCertPassword(client cert password) to my https request, I'm seeing this error:

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.).

Check that the certificate path and password are correct and the file is in PKCS#12 format.
Kyll
  • 7,036
  • 7
  • 41
  • 64
  • That is not the debugging information that we need. You modified the wrong file. The `jvm.config` file that ColdFusion uses is under the `C:\ColdFusion10\cfusion\bin` directory. Or you can just make the changes via the ColdFusion administrator, under the Server Settings, "Java and JVM". There is a text box on that page with the JVM Arguments. Remember, after making changes you will need to restart the ColdFusion service. When it is done correctly you will start seeing more information regarding the SSL connection attempt. – Miguel-F Oct 06 '16 at 12:56
  • Sorry about the confusion, I've got the debug info now but it's 3000 lines of info. After skimming through, there is some sensitive info in there, so was there a section you were looking for in particular I can post into the original? Or can I perhaps PM you somewhere? – George Foster Oct 06 '16 at 13:19
  • No need to post all of that here. Just scan through those logs and see what comes out to you. Hopefully there is something in there that pinpoints the issue. If you see something that you think is relevant and you are able to post it here then please do. – Miguel-F Oct 06 '16 at 13:27
  • 1
    We had to use a client certificate when we used CF8/9. We switched to CFX_HTTP5 out of frustration. It was easy to use. Just provide path to cert file. No importing/rebooting. It's also compatible w/TLS-only SNI certs. http://adiabata.com/cfx_http5.cfm – James Moberg Oct 06 '16 at 13:47
  • [See the answer here](http://stackoverflow.com/a/4714112/1636917) on how to convert a `.pfx` file to the keystore. – Miguel-F Oct 06 '16 at 14:13
  • You need to add the .cer file to the CF store. As you said you can not add a .pfx file. You can create a .cer file from a .pfx file. – Rado Oct 06 '16 at 14:28
  • @Rado: I've taken the client cert base ,cer I created my .pfx from and added it to the CF store. I'm still having the same response, 403.7. (I restarted CF) – George Foster Oct 06 '16 at 14:38
  • @GeorgeFoster is the certificate now listed in the CF key store? – Rado Oct 06 '16 at 14:40
  • @Rado: Using certman, I can see that it is in the CF key store. – George Foster Oct 06 '16 at 14:48
  • I would suggest that you use something like Wireshark to see the exact exchange and why the handshake is not happening. It might be that you need to turn off SSL3 or TLS 1.0 if they are not supported by the other side. CF will use these by default. – Rado Oct 06 '16 at 14:55
  • 1
    If you still have the ssl debug switch turned on you should see the handshake info in the log file. What does it show now that you have the certificate installed? – Miguel-F Oct 06 '16 at 15:28
  • 1
    @Miguel-F: I've added some examples of 'handshake' info to the op. – George Foster Oct 06 '16 at 16:06
  • Keep scanning through the logs. Are there any error messages before the 403 response is returned? – Miguel-F Oct 06 '16 at 16:23
  • @Miguel-F: Only what I could find just above the 403 response.It looks like the HTML server error content returned to me, but there is two lines of information above that so I've added it to OP. – George Foster Oct 07 '16 at 07:54
  • 1
    Have you tried using the `clientCert` and `clientCertPassword` attributes of the `cfhttp` tag? Note that it will require _the full path to a PKCS12 format file that contains the client certificate for the request._ [see docs here](https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-g-h/cfhttp.html) – Miguel-F Oct 07 '16 at 12:33
  • @Miguel-f: I've updated the OP with the results of adding that. I seem to remember seeing issues with CFHTTP and these parameters. – George Foster Oct 07 '16 at 13:23
  • 1
    The certificate file has to be in PKCS12 format. – Miguel-F Oct 07 '16 at 14:37
  • @Miguel-F I checked online and PKCS12 format are files with the extension .p12 or .pfx. Just for verification I tried the p12 format as well, and had the same issue. – George Foster Oct 07 '16 at 15:12
  • 1
    Take a look at this page - [CFHTTP and client certificates](http://jochem.vandieten.net/2008/02/28/cfhttp-and-client-certificates/) regarding the error message you are getting. – Miguel-F Oct 07 '16 at 15:33
  • @Miguel-F: Thanks so much, finally fixed my issue. I'll update OP. Thanks again! – George Foster Oct 10 '16 at 09:26
  • Don't answer your question in an edit. Instead, post a new answer! – Kyll Oct 10 '16 at 09:31
  • ... or if someone else provided you with the answer, ask them to promote *their* comment to an answer, as a way of saying thanks for assisting :) If you think the answer still requires more explanation, you can always post a separate answer with additional details about how you got it to work. – Leigh Oct 10 '16 at 17:38

2 Answers2

2

Too long for comment

Are you sure that you added the certificate to the correct JVM keystore? If you have upgraded Java on your ColdFusion server then it may not be in the default location. The ColdFusion administrator system information page will tell you the path in use under the "Java Home" label.

In order to turn on debugging information, add these lines to your ColdFusion server's jvm.config file located under this directory C:\ColdFusion10\cfusion\bin (by default) and restart the ColdFusion service:

-Djavax.net.ssl=debug
-Djavax.net.debug=all

This should add some more information to the coldfusion-out.log log file on your server. Post that information back here into your question for further analysis.

Adding the certificate to the Windows server using MMC is not needed and does not help your cfhttp calls from ColdFusion. It uses the Java keystore.

Response for EDIT 1 and 2

Follow the steps from this other answer on how to convert a .pfx file to the keystore.

Response for EDIT 3, 4 and 5

If you still have the ssl debug switch turned on you should see the handshake info in the log file. What does it show now that you have the certificate installed?

Have you tried using the clientCert and clientCertPassword attributes of the cfhttp tag? Note that it will require the full path to a PKCS12 format file that contains the client certificate for the request. See the docs here.

Response for EDIT 6

Take a look at this page - CFHTTP and client certificates regarding the error message you are getting: Could not decode key from BER. Excerpt from that page:

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.

Community
  • 1
  • 1
Miguel-F
  • 13,450
  • 6
  • 38
  • 63
0

Solved by following this link.

I used the new .pkcs format file inside setClientCert of the HTTP request and it is now working.

  • 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.

dbinott
  • 911
  • 1
  • 11
  • 36
  • 3
    Please quote the essential parts of the answer from the reference link(s), as the answer can become invalid if the linked page(s) change. – DavidPostill Oct 10 '16 at 10:09