Set client certificate is IIS

From: Chris Wenzlick (chris@slik.co.nz)
Date: 04/02/03


From: "Chris Wenzlick" <chris@slik.co.nz>
Date: Tue, 1 Apr 2003 15:50:09 -0800


Hope someone can help!

I have a problem with setting/sending a certificate from
IIS 4 OR 5.

Our application needs to submit an XML document as a HTTP
POST request to another web site that requires a client
certficate.
We have written a DCOM component in C++/MFC/ATL that works
fine when called from VB.
However when we run the component from ASP VBScript it
fails with an CInternetException 12157.
The basic logic (less error checking code) is:

SubmitHttpPost(...)
{
CHttpConnection *pConn = inetSession.GetHttpConnection
(strServerName, nPort, NULL, NULL);

DWORD dwFlags = INTERNET_FLAG_DONT_CACHE |
INTERNET_FLAG_NO_AUTO_REDIRECT |
INTERNET_FLAG_KEEP_CONNECTION;
if (dwServiceType == AFX_INET_SERVICE_HTTPS)
        dwFlags |= INTERNET_FLAG_SECURE;
                
CHttpFile *pFile = pConn->OpenRequest
(CHttpConnection::HTTP_VERB_POST,
        strObject, NULL, inetSession.GetContext(), NULL,
NULL, dwFlags);

strBody = _T("Content-Disposition: form-data;
name=\"p_xml_file\"\r\n");
CHECKOK( pFile->AddRequestHeaders(strBody) );

CComBSTR xmlText;
CHECKHR( pDoc->get_xml(&xmlText) );

strBody = _T("p_xml_file=");
strBody += _bstr_t(xmlText);

const DWORD nDataLen = strBody.GetLength();
LPCSTR pData = strBody.GetBuffer(0);

try
        {
        ok = pFile->SendRequest(NULL, 0, (VOID *)pData,
nDataLen);
        } catch(CInternetException *e)
                {
                if (e->m_dwError ==
ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED) // 12044
                        {
                        e->Delete();
                        HCERTSTORE hStore = OpenCertFile
(CERT_STORE_FILE);
                        PCCERT_CONTEXT pCertCtx = FindCert
(hStore, CERT_SUBJECT);
                        ok = pFile->SetOption
(INTERNET_OPTION_CLIENT_CERT_CONTEXT, (LPVOID)pCertCtx,
sizeof(CERT_CONTEXT));
                        ok = pFile->SendRequest(NULL, 0,
(VOID *)pData, nDataLen);
// ** FAILS here with CInternetException =
ERROR_INTERNET_SECURITY_CHANNEL_ERROR (12157)
                        }
                }
}

This example uses a serialized certficate store because
the HKEY_CURRENT_USER store does not seem to be available
in IIS as IUSR_machinename?

Has anyone else experienced this problem? Any suggestions
gratefully appreciated.

Thanks
PS: I have a small standalone VC++ project that easily
reproduces this behaviour if required.