I am working on a web service project which requires that clients connecting to my service authenticate themselves via X.509 certificates as part of a Mutual Authentication TLS negotiation. In addition to linking the client certificate to a specific PKI trust chain, my requirements dictate that I must verify specific values within the certificate. Specifically, the subject DN must contain one OU with a predetermined value, and the certificate must contain one subjectAltName with a different predetermined value in URI format.
I am using Apache httpd 2.4.6 on a CentOS 7 system, and am able to satisfy most of these requirements fairly easily with standard Apache configuration directives leveraging common mod_ssl variables, with one notable exception: I cannot seem to find a variable that allows me to access a subjectAltName value in URI format. Looking at the mod_ssl documentation found here:
https://httpd.apache.org/docs/2.4/mod/mod_ssl.html
I can see variables for the following subjectAltName formats:
SSL_CLIENT_SAN_Email_n - Client certificate's subjectAltName extension entries of type rfc822Name
SSL_CLIENT_SAN_DNS_n - Client certificate's subjectAltName extension entries of type dNSName
SSL_CLIENT_SAN_OTHER_msUPN_n - Client certificate's subjectAltName extension entries of type otherName, Microsoft User Principal Name form (OID 1.3.6.1.4.1.311.20.2.3)
Given that URI is a distinct and valid format for subjectAltName values as defined in RFC 5280 (X.509/PKI) section 4.2.1.6, I'm at a loss for why mod_ssl would not provide access to subjectAltNames in this format. Is there a variable that provides this functionality which I am simply not seeing in the documentation?
Further reviewing the mod_ssl source code, it is clear that extracting SAN values in URI format for use in variables is simply not currently supported, as noted by this comment:
/*
* Not implemented right now:
* GEN_X400 (x400Address)
* GEN_DIRNAME (directoryName)
* GEN_EDIPARTY (ediPartyName)
* GEN_URI (uniformResourceIdentifier)
* GEN_IPADD (iPAddress)
* GEN_RID (registeredID)
*/
in https://github.com/apache/httpd/blob/5f32ea94af5f1e7ea68d6fca58f0ac2478cc18c5/modules/ssl/ssl_util_ssl.c
As such, the answer to my question is apparently that there is not presently a variable I can use for this purpose, and fulfilling this requirement will necessitate a workaround (or an implementation of GEN_URI pushed to mod_ssl).
I am just playing arround with WCF and certificates. I have installed a certificate on my computer, referenced it in my WCF service config like this:
<serviceCertificate findValue="testcert"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
I then start the service. All is fine. Then I create a simple client console program in visual studio, by adding the service as a service reference. I can infact contact the service, so all is working correctly! When I look in my app.config for my client, I have this identity:
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAAuFTG2BUHH8JSm1VyxrCgEzaOQfAgAAAAAQAAALIEAAAwggSuMIIClqADAgECAhBqosPak3lGkETZ3xl9oaC0MA0GCSqGSIb3DQEBBQUAMBMxETAPBgNVBAMTCHRlc3RjZXJ0MB4XDTE1MDUwMjIyMDAwMFoXDTI1MDUwOTIyMDAwMFowEzERMA8GA1UEAxMIdGVzdGNlcnQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCoRWN7519nqQ7uFwgKtUWdTyKUhz+OdF9XtQF431/A1nhVsQsZ+J2k2Ola63eyTIEdR4y6jUx7KfQ1TMOtKSKB6iobP+JT8jibS1Ll47s6Ym2iEGLI6myftsuTezjObrnFO3tifCIMeKtMKdu1XYkpWr/DQogBElI6ZjkpaxIN+R+kw0cBwUm1o29/3V3VdHY9rlh4j8YJPMY903WCU/p7kCjiCfHWrWEkicer1rC6OC0TPLQVP0FSt6dCo1ptvHHk+aIUOU/lExCpT/FYjGUw5l8KeLz+V2xJ+Uy/kjuaAfSqE9wel/yDhDq599xbiBCViyAFSOfl11IcmOpA+H2LLuqvYZaFfem0MrTNJbr79Xjp/ywaQYf0jcK/D7t+6ouPmv4hibkeeELO1Cy3LQIYc3MNkvAkoiIXTxve2TmmN8CThQPfX3jrFm+sHvUEja4HnP5sbMuk9yNEvS+pJZj6hcmRyHzj9GIRRB5rCYfg/6pe0ttIs0Y4vaVzO232i4ffL1S9OzSLf7OYHfKvPc7YeEuouqPSAjIzB9BbEh678AtIUmatOiSBPpHYsPgz5QN+0kNSCgXnVkV+XN+JEOjxmHxGaPQHP3bvXAXZ94Y8jeSzLH5SyDxakAEJuujTL3wSRbNAy+ORexSC3YGmuQixaOHuTZ40BCQKxrDo/+NX6wIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQCcPb5B8Q3X3XqIrrNbzl4Eb4mLzmHrRP/W64LssGLr9O0MoJYw+RdOWyIbEtvg7nq0p0qBSi7lBq1ete/RSNiT3WMjIRPCgwZkq/yadolGgtRBq3FVHR7royjLu1DwOBtAhMQuBHopK6Dt88E4z8Bh/vyMruMs7VSH6cFbA0+iII02TLkC4+cgt5ZTxdet2JwyGsHNdk9c8pfq50Wht3kFzZPMYrowYH/c0fxkaIqWUN+W2sabBj/lzpo3kd6q0bBqamek9Bmk6IgikQrgx/ktAF3ul1u+2ybltQ7gJZIIuZphDSPmRRm+/sB2Wf6XGSG1ZUhrxsofQ7HVhlksTIfDQ7CtB8IlTmtesorJNfXw9ymKDWzvDRfNEVChDj/OGu3GHX6qwq7PeCsstxQeQRVQgB4Mo+ghCeTjH20xCxOzzZZVP0IRe/WvxNzxJxcnzYCgF7F9ztQBJoqUBqLVKdXYnLFRymFPpnc6OOTIi/+yD/4oNV9qMfFX14K+rVmq+HkDW1p3ipteDz2xzodiiYTk27yILHb3yJ2GgvuLmv4zKgUc3KTkxQeN4fmDOgqFP9VFXGWqgiPrbuFiBB+VNFDwbqgQtnz/tmZ6PDCNuMFJYALYSnKzU9/IWWScivzVeyrZuWPALX8nW3gAtOOgTaSKg9/3jAAqIWqTvkO0sviG6A==" /></identity>
I have read somewhere that this value, is the base64 encoded value of the public key, that is served by the wsdl of the service. Is this correct? If I look at the wsdl, the public key here is,
<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>
MIIErjCCApagAwIBAgIQaqLD2pN5RpBE2d8ZfaGgtDANBgkqhkiG9w0BAQUFADATMREwDwYDVQQDEwh0ZXN0Y2VydDAeFw0xNTA1MDIyMjAwMDBaFw0yNTA1MDkyMjAwMDBaMBMxETAPBgNVBAMTCHRlc3RjZXJ0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqEVje+dfZ6kO7hcICrVFnU8ilIc/jnRfV7UBeN9fwNZ4VbELGfidpNjpWut3skyBHUeMuo1Meyn0NUzDrSkigeoqGz/iU/I4m0tS5eO7OmJtohBiyOpsn7bLk3s4zm65xTt7YnwiDHirTCnbtV2JKVq/w0KIARJSOmY5KWsSDfkfpMNHAcFJtaNvf91d1XR2Pa5YeI/GCTzGPdN1glP6e5Ao4gnx1q1hJInHq9awujgtEzy0FT9BUrenQqNabbxx5PmiFDlP5RMQqU/xWIxlMOZfCni8/ldsSflMv5I7mgH0qhPcHpf8g4Q6uffcW4gQlYsgBUjn5ddSHJjqQPh9iy7qr2GWhX3ptDK0zSW6+/V46f8sGkGH9I3Cvw+7fuqLj5r+IYm5HnhCztQsty0CGHNzDZLwJKIiF08b3tk5pjfAk4UD31946xZvrB71BI2uB5z+bGzLpPcjRL0vqSWY+oXJkch84/RiEUQeawmH4P+qXtLbSLNGOL2lcztt9ouH3y9UvTs0i3+zmB3yrz3O2HhLqLqj0gIyMwfQWxIeu/ALSFJmrTokgT6R2LD4M+UDftJDUgoF51ZFflzfiRDo8Zh8Rmj0Bz9271wF2feGPI3ksyx+Usg8WpABCbro0y98EkWzQMvjkXsUgt2BprkIsWjh7k2eNAQkCsaw6P/jV+sCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAnD2+QfEN1916iK6zW85eBG+Ji85h60T/1uuC7LBi6/TtDKCWMPkXTlsiGxLb4O56tKdKgUou5QatXrXv0UjYk91jIyETwoMGZKv8mnaJRoLUQatxVR0e66Moy7tQ8DgbQITELgR6KSug7fPBOM/AYf78jK7jLO1Uh+nBWwNPoiCNNky5AuPnILeWU8XXrdicMhrBzXZPXPKX6udFobd5Bc2TzGK6MGB/3NH8ZGiKllDfltrGmwY/5c6aN5HeqtGwampnpPQZpOiIIpEK4Mf5LQBd7pdbvtsm5bUO4CWSCLmaYQ0j5kUZvv7Adln+lxkhtWVIa8bKH0Ox1YZZLEyHw0OwrQfCJU5rXrKKyTX18Pcpig1s7w0XzRFQoQ4/zhrtxh1+qsKuz3grLLcUHkEVUIAeDKPoIQnk4x9tMQsTs82WVT9CEXv1r8Tc8ScXJ82AoBexfc7UASaKlAai1SnV2JyxUcphT6Z3OjjkyIv/sg/+KDVfajHxV9eCvq1Zqvh5A1tad4qbXg89sc6HYomE5Nu8iCx298idhoL7i5r+MyoFHNyk5MUHjeH5gzoKhT/VRVxlqoIj627hYgQflTRQ8G6oELZ8/7ZmejwwjbjBSWAC2Epys1PfyFlknIr81Xsq2bljwC1/J1t4ALTjoE2kioPf94wAKiFqk75DtLL4hug=
</X509Certificate>
</X509Data>
</KeyInfo>
</Identity>
And it matches the public key, when I export the key (base64 encoded export) from the certificate store. All fine. But what I dont get how the value from the wsdl and export corresponds to value in the client app.config file? If I base64 encode the exported value (or the value from the wsdl), i dont get the encoded value.
So my questions is: how is the value, in the client app.config file encoded? Have I missed something? Is it even the public key that is present in the client app.config at all?
Both of the values are for a certificate with the thumbprint B854C6D815071FC2529B5572C6B0A013368E41F0 and subject CN=testcert
One of them is the base64 encoding of the the bytes of what your would get if you used this method (https://msdn.microsoft.com/en-us/library/dxz81eb9(v=vs.110).aspx) and passed the Cert X509ContentType and the other is using the SerializedCert X509ContentType.
I don't know why one is used over the other but they represent the same thing (though from the link I posted, it appears the SerializedCert contains properties that were included in the Windows certificate store as well as the certificate itself)
I am working on a WCF client which must talk to an Oracle WebLogic service. The service enforces mutual certificate authentication.
We are not, however, able to satisfy the policy and the server logs an error stating:
"WSM-00081: The X.509 certificate is not signed."
I have been wondering what the exact meaning of this is. The Oracle documentation states:
WSM-00081: The X.509 certificate is not signed.
Cause: The X509 token used was not signed according to requirements of certificate authentication scenario.
Action: Sign the X509 token (depending upon the reference mechanism used) for certificate authentication.
Level: 1
Type: ERROR
Impact: Security
(http://docs.oracle.com/cd/E25054_01/core.1111/e10113/chapter_wsm_messages.htm)
After some research, we found out that we can disable the check in the service policy configuration file by setting is-signed="false:
<orasp:x509-token orasp:enc-key-ref-mech="direct" orasp:is-encrypted="false"
orasp:is-signed="false"
orasp:rcpt-enc-key-ref-mech="direct"
orasp:rcpt-sign-key-ref-mech="direct"
orasp:sign-key-ref-mech="direct"/>
My two theories:
The certificate needs to be signed by a CA
We checked using an a certificate signed by a CA, but this made no difference
However, we might have made som errors when configurating this. Should we try it over?
We somehow need to sign the included BinarySecurityToken's, which are included in the request.
However, I have no idea how I can do this
Have I completely misunderstood the subject or can any of you give some pointers to what the problem might be and how it can be solved?
You need to sign the security token as part of the request.
In the binding element of your config set the security element mode to SecurityMode.Message and the message element clientCredentialType to MessageCredentialType.Certificate:
<security mode="Message">
<message clientCredentialType="Certificate"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
Next, create an endpoint behavior to resolve the location of your client certificate:
<behavior name="endpointCredentialBehavior">
<clientCredentials>
<clientCertificate findValue="Contoso.com"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
I'm having some trouble getting a password protected PFX certificate to install through WiX.
I'm using WiX 3.5.2519.0.
I include a PFX file as follows:
<Binary Id="My.Binary"
SourceFile="$(var.ProjectDir)MyProject$(var.ConfigSuffix).pfx" />
The value of $(var.ConfigSuffix) varies based on solution configuration (e.g. " (Debug)", " (Stage)"). For "Release", it is set to an empty string.
I have various solution configurations, all but one use a non-password protected PFX certificate, "Release" uses a password protected PFX. I deal with this by conditionally defining $(var.PfxPassword) in "Release" configuration only, and then installing the certificate as follows:
<?ifdef $(var.PfxPassword) ?>
<iis:Certificate
Id="My.Certificate"
StoreName="root"
Overwrite="yes"
Name="My Web Site$(var.ConfigSuffix)"
Request="no"
BinaryKey="MyCertificate.Binary"
StoreLocation="localMachine"
PFXPassword="$(var.PfxPassword)" />
<?else?>
<iis:Certificate
Id="My.Certificate"
StoreName="root"
Overwrite="yes"
Name="My Web Site$(var.ConfigSuffix)"
Request="no"
BinaryKey="MyCertificate.Binary"
StoreLocation="localMachine" />
<?endif?>
I have also tried replacing "$(var.PfxPassword)" with "[PFXPASSWORD]" (having defined this elsewhere), and the actual password in plain text. In every case, installation fails with the following log snippet:
Action start 12:29:02: InstallCertificates.
InstallCertificates: Error 0x80070056: Failed to open PFX file.
InstallCertificates: Error 0x80070056: Failed to get SHA1 hash of certificate.
InstallCertificates: Error 0x80070056: Failed to resolve certificate: LinnRecords.Certificate
CustomAction InstallCertificates returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 12:29:02: InstallCertificates. Return value 3.
I believe error 0x80070056 indicates an incorrect password, however I have used the Get-PfxCertificate in PowerShell to verify that the password I am using is correct.
For all configurations where the PFX file does not use a password, the installation works without issue.
Looking at a similar problem elsewhere on the internet, it looks like return code 3 is a "File not found" problem. Are you sure the correct pfx file is being included?
I'm currently working with a payment processor. I can browse to the payment URL from our server, so it's not a firewall issue, but when I try to use CFHTTP I get a I/O Exception: peer not authenticated. I've downloaded and installed their latest security cert into cacerts keystore and restarted CF and am still getting the same error. Not only have I installed the providers cert, but also the 2 other Verisign certificate authority certs in the certificate chain. The cert is one of the newer Class 3 Extended Validation certs.
Has anybody come across this before and found a solution?
A colleague of mine found the following after experiencing the same issue when connecting to a 3rd party.
http://www.coldfusionjedi.com/index.cfm/2011/1/12/Diagnosing-a-CFHTTP-issue--peer-not-authenticated
https://www.raymondcamden.com/2011/01/12/Diagnosing-a-CFHTTP-issue-peer-not-authenticated/
We used the solution provided in the comment by Pete Freitag further down the page. It works, but I think should be used with caution, as it involves dynamically removing and adding back in a particular property of the JsafeJCE provider.
For the sake of archiving, here is the original content of Pete Freitag's comment:
I've narrowed this down a bit further, and removing the
KeyAgreement.DiffieHellman from the RSA JsafeJCE provider (which
causes the default sun implementation to be used instead) seams to
work, and probably has less of an effect on your server than removing
the entire provider would. Here's how you do it:
<cfset objSecurity = createObject("java", "java.security.Security") />
<cfset storeProvider = objSecurity.getProvider("JsafeJCE") />
<cfset dhKeyAgreement = storeProvider.getProperty("KeyAgreement.DiffieHellman")>
<!--- dhKeyAgreement=com.rsa.jsafe.provider.JSA_DHKeyAgree --->
<cfset storeProvider.remove("KeyAgreement.DiffieHellman")>
Do your http call, but pack the key agreement if you want:
<cfset storeProvider.put("KeyAgreement.DiffieHellman", dhKeyAgreement)>
I figured this out by using the SSLSocketFactory to create a https
connection, which provided a bit more details in the stack trace, than
when using cfhttp:
yadayadayada Caused by: java.security.InvalidKeyException: Cannot
build a secret key of algorithm TlsPremasterSecret at
com.rsa.jsafe.provider.JS_KeyAgree.engineGenerateSecret(Unknown
Source) at javax.crypto.KeyAgreement.generateSecret(DashoA13*..) at
com.sun.net.ssl.internal.ssl.DHCrypt.getAgreedSecret(DHCrypt.java:166)
Would be great if the exception thrown from ColdFusion was a bit less
generic.
specific to coldfusion 8 with an webserver with modern ssl ciphers:
I use coldfusion 8 on JDK 1.6.45 and had problems with <cfdocument ...> giving me just red crosses instead of images, and also with cfhttp not able to connect to the local webserver with ssl.
my test script to reproduce with coldfusion 8 was
<CFHTTP URL="https://www.onlineumfragen.com" METHOD="get" ></CFHTTP>
<CFDUMP VAR="#CFHTTP#">
this gave me the quite generic error of " I/O Exception: peer not authenticated."
I then tried to add certificates of the server including root and intermediate certificates to the java keystore and also the coldfusion keystore, but nothing helped.
then I debugged the problem with
java SSLPoke www.onlineumfragen.com 443
and got
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
and
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive)
at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:107)
... 10 more
I then had the idea that the webserver (apache in my case) had very modern ciphers for ssl and is quite restrictive (qualys score a+) and uses strong Diffie-Hellman groups with more than 1024 bits. obviously, coldfusion and java jdk 1.6.45 can not manage this.
Next step in the odyssee was to think of installing an alternative security provider for java, and I decided for bouncy castle.
see also http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/
I then downloaded the
bcprov-ext-jdk15on-156.jar
from http://www.bouncycastle.org/latest_releases.html and installed it under
C:\jdk6_45\jre\lib\ext or where ever your jdk is, in original install of coldfusion 8 it would be under C:\JRun4\jre\lib\ext but I use a newer jdk (1.6.45) located outside the coldfusion directory. it is very important to put the bcprov-ext-jdk15on-156.jar in the \ext directory (this cost me about two hours and some hair ;-)
then I edited the file C:\jdk6_45\jre\lib\security\java.security (with wordpad not with editor.exe!) and put in one line for the new provider. afterwards the list looked like
#
# List of providers and their preference orders (see above):
#
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI
(see the new one in position 1)
then restart coldfusion service completely.
you can then
java SSLPoke www.onlineumfragen.com 443 (or of course your url!)
and enjoy the feeling...
and of course
<cfhttp and <cfdocument worked like a charm and like before we "hardened" our ssl ciphers in apache!
what a night and what a day. Hopefully this will help (partially or fully) to someone out there. if you have questions, just mail me at info ... (domain above).
Did you add it to the correct keystore? Remember that ColdFusion uses it's own Java instance. I spent several hours on this once before remembering that fact. The one you want is at somewhere like /ColdFusion8/runtime/jre/lib/security/
Try with this in CMD
C:\ColdFusion9\runtime\jre\bin>
keytool -import -keystore ../lib/security/cacerts
-alias uniquename -file certificatename.cer
Note: We must choose the correct keystore present inside the security folder,as there are other keystore file present inside bin.If we will import the certificate to those key stores it will not work.
What I just found out was referenced at this article: http://kb2.adobe.com/cps/400/kb400977.html and a few other places after a lot of digging.
If you are looking at this article you have most likely inserted your "server.crt" certificate in the proper root locations and you have probably inserted it into the cacerts file in /ColdFusion9/runtime/jre/lib/security using the command
\ColdFusion9\runtime\jre\bin\keytool -import -v -alias someServer-cert -file someServerCertFile.crt -keystore cacerts -storepass changeit
(if you haven't done this, do it now).
The thing I was running into was that I am setting up ssl on my localhost so after doing these steps I was still getting the same error.
As it turns out, you need to also insert your "server.crt" into the "trustStore" file commonly located in /ColdFusion9/runtime/jre/lib using the command
\ColdFusion9\runtime\jre\bin\keytool -import -v -alias someServer-cert -file someServerCertFile.cer -keystore trustStore -storepass changeit
Hopefully this will save someone time.
I am using JRun. After trying a lot of different things I came across a snippet of information that was applicable in my setup. I had configured an (1)HTTPS SSLService with my own truststore file. This caused the piece of information in the following link to become important.
http://helpx.adobe.com/coldfusion/kb/import-certificates-certificate-stores-coldfusion.html
Note: If you are using JRun as the underlying J2EE server (either the
Server Configuration or the Multiserver/J2EE with JRun Configuration)
and have enabled SSL for the internal JRun Web server (JWS), you will
need to import the certificate to the truststore defined in the
jrun.xml file for the Secure JWS rather than the JRE key store. By
default, the file is called "trustStore" and is typically located
under jrun_root/lib for the Multiserver/J2EE with JRun configuration
or cf_root/runtime/lib for the ColdFusion Server configuration. You
use the same Java keytool to manage the trustStore.
Here is the excerpt from my jrun.xml file:
<service class="jrun.servlet.http.SSLService" name="SSLService">
<attribute name="port">8301</attribute>
<attribute name="keyStore">/app/jrun4/cert/cfusion.jks</attribute>
<attribute name="trustStore">/app/jrun4/cert/truststore.jks</attribute>
<attribute name="name">SSLService</attribute>
<attribute name="bindAddress">*</attribute>
<attribute name="socketFactoryName">jrun.servlet.http.JRunSSLServerSocketFactory</attribute>
<attribute name="interface">*</attribute>
<attribute name="keyStorePassword">cfadmin</attribute>
<attribute name="deactivated">false</attribute>
</service>
Once I imported the certificate into this truststore (/app/jrun4/cert/truststore.jks) it worked after restarting ColdFusion.
(1) http://helpx.adobe.com/legacy/kb/ssl-jrun-web-server-connector.html
Adding the cert to the keystore did not work for me on CF9 Enterprise.
Ended up using the CFX tag, CFX_HTTP5.
I realize this is a very old discussion, but since it still comes up near the top of a search for the "peer not authenticated" error in CF, I wanted to share that for most people, the simple solution is to update the JVM that CF uses. (More in a moment on how to do that.)
The cause of the problem is generally that the service BEING CALLED has made a change that requires a later version of TLS or SSL (and perhaps a change to supported algorithms). Later JVMs offer that, while earlier ones did not. Since CF runs atop the JVM, it's the calls out of CF (va cfhttp, cfldap, cfmail, etc) that "suddenly" start to fail.
And sure, sometimes a cert update is the answer (and even then, you have to do it carefully), but it's not always needed. And updating the JVM also gives other benefits, in terms of bug fixes, etc.
The only challenge is knowing what JVM your version of CF will support. (But even people still running on an old CF version have found that updating the JVM CF uses has solved this problem and not caused any others.)
I discuss all this in a 2019 post:
https://coldfusion.adobe.com/2019/06/error-calling-cf-via-https-solved-updating-jvm/
Hope that may help someone.