How to call a Web Service from CF7 using Client Certificate based ("Bilateral") authentication (Win)
If you have to call a web service from ColdFusion 7 - and the destination web service enforces bilateral SSL authentication (i.e. the caller has to supply a client certificate to prove who they are, as well as the destination supplying a server certificate to prove who it is...) - then the options, in descending order of preference are:
- Check / ask really nicely / beg / etc. to see if there is a way of calling the web service without passing a client SSL certificate
- Use CF8 (or later) - I believe that you will still need to do the SOAP generation by hand, as cfobject / cfinvoke do not appear to allow a client certificate to be set - but you can use cfhttp and specify the clientcert and clientcertpassword attributes - which avoids having to use the WinHttp.WinHttpRequest COM object as shown below.
- Use the WinHttp.WinHttpRequest COM object as shown below...
ColdFusion (when running on windows) allows (and has allowed for several versions) COM objects to be called from within CF code, using the CFOBJECT tag or CreateObject() function.
Built into the following versions of windows, is the WinHTTP 5.1 COM object:
WinHTTP 5.1 is available only with Windows Server 2003, Windows XP with Service Pack 1 (SP1), and Windows 2000 Professional with Service Pack 3 (SP3). (I suspect that it may also be available in Windows 2008)
This provides similar functionality to CFHTTP - but at a lower level. In particular it allows a client certificate to be specified, using the SetClientCetificate function.
This is not as simple as it seems - where as in CF8 using CFHTTP you just have to specify the physical location of the client certificate file - the WinHttp object requires that the client certificate is first imported into a certificate store - and then the reference to the certificate provided to the SetClientCetificate function:
ClientCertificate [in] Specifies the location, certificate store, and subject of a client certificate
To cut a very long (well around 5 hours) story short, this is how I finally got it to work:

