Set Network SSL Properties Example for C++
#include
#pragma comment(lib, "crypt32.lib")
HRESULT FindCertificateByName(LPCTSTR store, LPCTSTR certificate, CAtlArray& hash)
{
hash.RemoveAll();
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_MAXIMUM_ALLOWED_FLAG, store);
if(hCertStore)
{
PCCERT_CONTEXT pCertContext = NULL;
while (pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext))
{
CString certname;
DWORD dwBufferSize = 0;
CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dwBufferSize);
if (dwBufferSize)
{
CStringW sBuffer;
CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, sBuffer.GetBufferSetLength(dwBufferSize/sizeof(wchar_t)), &dwBufferSize);
sBuffer.ReleaseBuffer();
certname = sBuffer;
if(certname.CompareNoCase(certificate) == 0)
{
DWORD dwData = 0;
CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, NULL, &dwData);
hash.SetCount(dwData);
CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, hash.GetData(), &dwData);
return S_OK;
}
}
}
CertCloseStore(hCertStore, 0);
}
return E_FAIL;
}
HRESULT SetNetworkSSLProperties(IltmsServer* server, long port, LPCTSTR store, LPCTSTR certificate)
{
HRESULT hr;
CComPtr props;
CAtlArray hash;
// find the certificate name in the specified store
hr = FindCertificateByName(store, certificate, hash);
if(FAILED(hr))
goto error;
// retrieve a copy of the current network properties
hr = server->GetNetworkProperties(&props);
if(FAILED(hr))
goto error;
// change the properties
hr = props->put_SSLPort(6968);
if(FAILED(hr))
goto error;
hr = props->put_SSLCertificateStore(CComBSTR(store));
if(FAILED(hr))
goto error;
{
CComVariant v;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = (ULONG) hash.GetCount();
v.vt = VT_ARRAY | VT_UI1;
v.parray = SafeArrayCreate(VT_UI1, 1, rgsabound);
if(!v.parray)
{
hr = E_OUTOFMEMORY;
goto error;
}
BYTE* pdata;
hr = SafeArrayAccessData(v.parray, (void**)&pdata);
if(FAILED(hr))
goto error;
memcpy(pdata, hash.GetData(), v.parray->rgsabound[0].cElements);
SafeArrayUnaccessData(v.parray);
hr = props->put_SSLCertificateHash(v);
if(FAILED(hr))
goto error;
}
// copy the properties to the server
hr = server->SetNetworkProperties(props);
if(FAILED(hr))
goto error;
error:
return hr;
}