4
votes

I am trying to send a SOAP request by CFHTTP with a client certificate. My test requests in SOAP UI are successful but when I try to send requests by CFHTTP I get the following error:

I/O Exception: Received fatal alert: handshake_failure

My CFHTTP tag is like this:

<cfhttp
    url="https://..."
    method="post"
    clientcert="C:\..."
    clientcertpassword="password"
    result="httpResponse"
    >

I have tried to check the logs for more ideas of where the failure could be happening. I can only get the following:

http.log

"Information","ajp-bio-8014-exec-10","09/26/16","07:07:59",,"Starting HTTP request {URL='https://...', method='post'}"

coldfusion-out.log

Sep 26, 2016 07:07:59 AM Information [ajp-bio-8014-exec-10] - Starting HTTP request {URL='https://...', method='post'}

I have imported the certificates with keytool and when I list the certificates in cacerts I see them there.

Any other ideas where I can look to troubleshoot this issue?

Edited to add:

My certificate is in .p12 format and has a password. I have tested the .p12 file with the password in SOAP UI and it works.

I have installed CF10-Certman and confirmed the certificates are there from CF Administrator as well.

I've added these lines to my jvm.config:

-Djavax.net.ssl.keyStore=C:\\ColdFusion11\\jre\\lib\\security\\cacerts 
-Djavax.net.ssl.keyStorePassword=password 
-Djavax.net.ssl=debug
-Djavax.net.debug=all

I tried the keystore path with \ and / ("C:/Coldfusion11/...")

Additional coldfusion-out.log output:

Sep 26, 2016 11:10:06 AM Information [ajp-bio-8014-exec-2] - Starting HTTP request {URL='https://...', method='post'}
...
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
...
Allow unsafe renegotiation: true
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1458128991 bytes = { 40, ... }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: url ]
***
ajp-bio-8014-exec-2, WRITE: TLSv1 Handshake, length = 195
ajp-bio-8014-exec-2, READ: TLSv1.1 Alert, length = 2
ajp-bio-8014-exec-2, RECV TLSv1 ALERT:  fatal, handshake_failure
ajp-bio-8014-exec-2, called closeSocket()
ajp-bio-8014-exec-2, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Finalizer, called close()
Finalizer, called closeInternal(true)

The CipherSuite in SOAPUI is TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

UPDATE

I removed the clientcert and clientcertpassword from the cfhttp tag and now I am seeing this in coldfusion-out.log:

ajp-bio-8014-exec-1, WRITE: TLSv1.1 Handshake, length = 64
ajp-bio-8014-exec-1, setSoTimeout(360000) called
ajp-bio-8014-exec-1, WRITE: TLSv1.1 Application Data, length = 1680
ajp-bio-8014-exec-1, READ: TLSv1.1 Alert, length = 48
ajp-bio-8014-exec-1, RECV TLSv1.1 ALERT:  warning, close_notify
ajp-bio-8014-exec-1, called closeInternal(false)
ajp-bio-8014-exec-1, SEND TLSv1.1 ALERT:  warning, description = close_notify
ajp-bio-8014-exec-1, WRITE: TLSv1.1 Alert, length = 48
ajp-bio-8014-exec-1, called closeSocket(false)
ajp-bio-8014-exec-1, called close()
ajp-bio-8014-exec-1, called closeInternal(true)

I have reached out to the server administrator to see if they are seeing the request on their end.

UPDATE

Adding the clientcert back in fixed it!

1
For refference please read this and this - Leo the lion
@Leothelion I have read both of these posts. I have tried the suggestions mentioned. I will add my jvm.config to my original post. - kelseyelayne
Are you sure that is the correct keystore file in use by ColdFusion? Have you ever updated Java on that server? The ColdFusion administrator system information page will tell you the path in use under the "Java Home" label. Also have a look at this. - Miguel-F
@Miguel-F I show in CF Administrator the Java home is "C:\ColdFusion11\jre" and I added the certificates to cacerts located in C:\ColdFusion11\jre\lib\security - kelseyelayne
Then that should be the correct keystore for your installation. Check that link I referenced for other possibilities - Miguel-F

1 Answers

2
votes

I am not sure what exactly fixed this issue overall but if you review my original post including updates the following things seemed to have contributed:

1) Not including clientcert caused ColdFusion to check cacerts for the server certificates

2) Re-adding clientcert caused ColdFusion to complete the handshake

The JVM.config settings also helped in debugging and ensuring the correct protocol was used.