|
|
#include "stdafx.h"
#include "CertObj.h"
#include "common.h"
//////////////////////////////////////////////////////////////////
CString ReturnGoodMetabasePath(CString csInstanceName) { CString key_path_lm = _T(""); CString key_path = _T(""); // csInstanceName will come in looking like
// w3svc/1
// or /lm/w3svc/1
//
// we want to it to go out as /lm/w3svc/1
key_path_lm = SZ_MBN_SEP_STR SZ_MBN_MACHINE SZ_MBN_SEP_STR;// SZ_MBN_WEB SZ_MBN_SEP_STR;
if (csInstanceName.GetLength() >= 4) { if (csInstanceName.Left(4) == key_path_lm) { key_path = csInstanceName; } else { key_path_lm = SZ_MBN_MACHINE SZ_MBN_SEP_STR; if (csInstanceName.Left(3) == key_path_lm) { key_path = csInstanceName; } else { key_path = key_path_lm; key_path += csInstanceName; } } } else { key_path = key_path_lm; key_path += csInstanceName; }
return key_path; }
HRESULT ShutdownSSL(CString& server_name) { CComAuthInfo auth; CString str = server_name; str += _T("/root"); CMetaKey key(&auth, str, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE); DWORD dwSslAccess;
if (!key.Succeeded()) { return key.QueryResult(); }
if (SUCCEEDED(key.QueryValue(MD_SSL_ACCESS_PERM, dwSslAccess)) && dwSslAccess > 0) { key.SetValue(MD_SSL_ACCESS_PERM, 0); }
// Now we need to remove SSL setting from any virtual directory below
CError err; CStringListEx data_paths; DWORD dwMDIdentifier, dwMDAttributes, dwMDUserType,dwMDDataType;
VERIFY(CMetaKey::GetMDFieldDef(MD_SSL_ACCESS_PERM, dwMDIdentifier, dwMDAttributes, dwMDUserType,dwMDDataType));
err = key.GetDataPaths( data_paths,dwMDIdentifier,dwMDDataType); if (err.Succeeded() && !data_paths.empty()) { CStringListEx::iterator it = data_paths.begin(); while (it != data_paths.end()) { CString& str = (*it++); if (SUCCEEDED(key.QueryValue(MD_SSL_ACCESS_PERM, dwSslAccess, NULL, str)) && dwSslAccess > 0) { key.SetValue(MD_SSL_ACCESS_PERM, 0, NULL, str); } } } return key.QueryResult(); }
BOOL AddChainToStore(HCERTSTORE hCertStore,PCCERT_CONTEXT pCertContext,DWORD cStores,HCERTSTORE * rghStores,BOOL fDontAddRootCert,CERT_TRUST_STATUS * pChainTrustStatus) { DWORD i; CERT_CHAIN_ENGINE_CONFIG CertChainEngineConfig; HCERTCHAINENGINE hCertChainEngine = NULL; PCCERT_CHAIN_CONTEXT pCertChainContext = NULL; CERT_CHAIN_PARA CertChainPara; BOOL fRet = TRUE; PCCERT_CONTEXT pTempCertContext = NULL;
//
// create a new chain engine, then build the chain
//
memset(&CertChainEngineConfig, 0, sizeof(CertChainEngineConfig)); CertChainEngineConfig.cbSize = sizeof(CertChainEngineConfig); CertChainEngineConfig.cAdditionalStore = cStores; CertChainEngineConfig.rghAdditionalStore = rghStores; CertChainEngineConfig.dwFlags = CERT_CHAIN_USE_LOCAL_MACHINE_STORE;
if (!CertCreateCertificateChainEngine(&CertChainEngineConfig, &hCertChainEngine)) { goto AddChainToStore_Error; }
memset(&CertChainPara, 0, sizeof(CertChainPara)); CertChainPara.cbSize = sizeof(CertChainPara);
if (!CertGetCertificateChain(hCertChainEngine,pCertContext,NULL,NULL,&CertChainPara,0,NULL,&pCertChainContext)) { goto AddChainToStore_Error; }
//
// make sure there is atleast 1 simple chain
//
if (pCertChainContext->cChain != 0) { i = 0; while (i < pCertChainContext->rgpChain[0]->cElement) { //
// if we are supposed to skip the root cert,
// and we are on the root cert, then continue
//
if (fDontAddRootCert && (pCertChainContext->rgpChain[0]->rgpElement[i]->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED)) { i++; continue; }
CertAddCertificateContextToStore(hCertStore,pCertChainContext->rgpChain[0]->rgpElement[i]->pCertContext,CERT_STORE_ADD_REPLACE_EXISTING,&pTempCertContext); //
// remove any private key property the certcontext may have on it.
//
if (pTempCertContext) { CertSetCertificateContextProperty(pTempCertContext, CERT_KEY_PROV_INFO_PROP_ID, 0, NULL); CertFreeCertificateContext(pTempCertContext); }
i++; } } else { goto AddChainToStore_Error; }
//
// if the caller wants the status, then set it
//
if (pChainTrustStatus != NULL) { pChainTrustStatus->dwErrorStatus = pCertChainContext->TrustStatus.dwErrorStatus; pChainTrustStatus->dwInfoStatus = pCertChainContext->TrustStatus.dwInfoStatus; }
AddChainToStore_Exit: if (pCertChainContext != NULL) { CertFreeCertificateChain(pCertChainContext); }
if (hCertChainEngine != NULL) { CertFreeCertificateChainEngine(hCertChainEngine); } return fRet;
AddChainToStore_Error: fRet = FALSE; goto AddChainToStore_Exit; }
// This function is borrowed from trustapi.cpp
BOOL TrustIsCertificateSelfSigned(PCCERT_CONTEXT pContext,DWORD dwEncoding, DWORD dwFlags) { if (!(pContext) || (dwFlags != 0)) { SetLastError(ERROR_INVALID_PARAMETER); return(FALSE); }
if (!(CertCompareCertificateName(dwEncoding,&pContext->pCertInfo->Issuer,&pContext->pCertInfo->Subject))) { return(FALSE); }
DWORD dwFlag;
dwFlag = CERT_STORE_SIGNATURE_FLAG;
if (!(CertVerifySubjectCertificateContext(pContext, pContext, &dwFlag)) || (dwFlag & CERT_STORE_SIGNATURE_FLAG)) { return(FALSE); }
return(TRUE); }
HRESULT UninstallCert(CString csInstanceName) { CComAuthInfo auth; CString key_path = ReturnGoodMetabasePath(csInstanceName); CMetaKey key(&auth, key_path, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE); if (key.Succeeded()) { CString store_name; key.QueryValue(MD_SSL_CERT_STORE_NAME, store_name); if (SUCCEEDED(key.DeleteValue(MD_SSL_CERT_HASH))) { key.DeleteValue(MD_SSL_CERT_STORE_NAME); } } return key.QueryResult(); }
CERT_CONTEXT * GetInstalledCert(HRESULT * phResult, CString csKeyPath) { // ATLASSERT(GetEnroll() != NULL);
ATLASSERT(phResult != NULL); CERT_CONTEXT * pCert = NULL; *phResult = S_OK; CComAuthInfo auth; CString key_path = ReturnGoodMetabasePath(csKeyPath);
CMetaKey key(&auth, key_path, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE); if (key.Succeeded()) { CString store_name; CBlob hash; if (SUCCEEDED(*phResult = key.QueryValue(MD_SSL_CERT_STORE_NAME, store_name)) && SUCCEEDED(*phResult = key.QueryValue(MD_SSL_CERT_HASH, hash))) { // Open MY store. We assume that store type and flags
// cannot be changed between installation and unistallation
// of the sertificate.
HCERTSTORE hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,NULL,CERT_SYSTEM_STORE_LOCAL_MACHINE,store_name); ASSERT(hStore != NULL); if (hStore != NULL) { // Now we need to find cert by hash
CRYPT_HASH_BLOB crypt_hash; crypt_hash.cbData = hash.GetSize(); crypt_hash.pbData = hash.GetData(); pCert = (CERT_CONTEXT *)CertFindCertificateInStore(hStore,X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,0,CERT_FIND_HASH,(LPVOID)&crypt_hash,NULL); if (pCert == NULL) { *phResult = HRESULT_FROM_WIN32(GetLastError()); } VERIFY(CertCloseStore(hStore, 0)); } else { *phResult = HRESULT_FROM_WIN32(GetLastError()); } } } else { *phResult = key.QueryResult(); } return pCert; }
CERT_CONTEXT * GetInstalledCert(HRESULT * phResult,DWORD cbHashBlob, char * pHashBlob) { ATLASSERT(phResult != NULL); CERT_CONTEXT * pCert = NULL; *phResult = S_OK; CString store_name = _T("MY");
HCERTSTORE hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,NULL,CERT_SYSTEM_STORE_LOCAL_MACHINE,store_name); ASSERT(hStore != NULL); if (hStore != NULL) { // Now we need to find cert by hash
CRYPT_HASH_BLOB crypt_hash; crypt_hash.cbData = cbHashBlob; crypt_hash.pbData = (BYTE *) pHashBlob; pCert = (CERT_CONTEXT *)CertFindCertificateInStore(hStore,X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,0,CERT_FIND_HASH,(LPVOID)&crypt_hash,NULL); if (pCert == NULL) { *phResult = HRESULT_FROM_WIN32(GetLastError()); } VERIFY(CertCloseStore(hStore, 0)); } else { *phResult = HRESULT_FROM_WIN32(GetLastError()); }
return pCert; }
/*
InstallHashToMetabase
Function writes hash array to metabase. After that IIS could use certificate with that hash from MY store. Function expects server_name in format lm\w3svc\<number>, i.e. from root node down to virtual server */ BOOL InstallHashToMetabase(CRYPT_HASH_BLOB * pHash,BSTR InstanceName,HRESULT * phResult) { BOOL bRes = FALSE; CComAuthInfo auth; CString key_path = ReturnGoodMetabasePath(InstanceName); CMetaKey key(&auth, key_path, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE); if (key.Succeeded()) { CBlob blob; blob.SetValue(pHash->cbData, pHash->pbData, TRUE); bRes = SUCCEEDED(*phResult = key.SetValue(MD_SSL_CERT_HASH, blob)) && SUCCEEDED(*phResult = key.SetValue(MD_SSL_CERT_STORE_NAME, CString(L"MY"))); } else { *phResult = key.QueryResult(); } return bRes; }
HRESULT HereIsBinaryGimmieVtArray(DWORD cbBinaryBufferSize,char *pbBinaryBuffer,VARIANT * lpVarDestObject,BOOL bReturnBinaryAsVT_VARIANT) { HRESULT hr = S_OK; SAFEARRAY *aList = NULL; SAFEARRAYBOUND aBound; CHAR HUGEP *pArray = NULL;
aBound.lLbound = 0; aBound.cElements = cbBinaryBufferSize;
if (bReturnBinaryAsVT_VARIANT) { aList = SafeArrayCreate( VT_VARIANT, 1, &aBound ); } else { aList = SafeArrayCreate( VT_UI1, 1, &aBound ); }
aList = SafeArrayCreate( VT_UI1, 1, &aBound ); if ( aList == NULL ) { hr = E_OUTOFMEMORY; goto HereIsBinaryGimmieVtArray_Exit; }
hr = SafeArrayAccessData( aList, (void HUGEP * FAR *) &pArray ); if (FAILED(hr)) { goto HereIsBinaryGimmieVtArray_Exit; }
memcpy( pArray, pbBinaryBuffer, aBound.cElements ); SafeArrayUnaccessData( aList );
if (bReturnBinaryAsVT_VARIANT) { V_VT(lpVarDestObject) = VT_ARRAY | VT_VARIANT; } else { V_VT(lpVarDestObject) = VT_ARRAY | VT_UI1; }
V_ARRAY(lpVarDestObject) = aList;
return hr;
HereIsBinaryGimmieVtArray_Exit: if (aList) {SafeArrayDestroy( aList );}
return hr; }
HRESULT HereIsVtArrayGimmieBinary( VARIANT * lpVarSrcObject, DWORD * cbBinaryBufferSize, char **pbBinaryBuffer, BOOL bReturnBinaryAsVT_VARIANT ) { HRESULT hr = S_OK; LONG dwSLBound = 0; LONG dwSUBound = 0; CHAR HUGEP *pArray = NULL;
if (NULL == cbBinaryBufferSize || NULL == pbBinaryBuffer) { hr = E_INVALIDARG; goto HereIsVtArrayGimmieBinary_Exit; }
if (bReturnBinaryAsVT_VARIANT) { hr = VariantChangeType(lpVarSrcObject,lpVarSrcObject,0,VT_ARRAY | VT_VARIANT); } else { hr = VariantChangeType(lpVarSrcObject,lpVarSrcObject,0,VT_ARRAY | VT_UI1); }
if (FAILED(hr)) { if (hr != E_OUTOFMEMORY) { hr = OLE_E_CANTCONVERT; } goto HereIsVtArrayGimmieBinary_Exit; }
if (bReturnBinaryAsVT_VARIANT) { if( lpVarSrcObject->vt != (VT_ARRAY | VT_VARIANT)) { hr = OLE_E_CANTCONVERT; goto HereIsVtArrayGimmieBinary_Exit; } } else { if( lpVarSrcObject->vt != (VT_ARRAY | VT_UI1)) { hr = OLE_E_CANTCONVERT; goto HereIsVtArrayGimmieBinary_Exit; } }
hr = SafeArrayGetLBound(V_ARRAY(lpVarSrcObject),1,(long FAR *) &dwSLBound ); if (FAILED(hr)) {goto HereIsVtArrayGimmieBinary_Exit;}
hr = SafeArrayGetUBound(V_ARRAY(lpVarSrcObject),1,(long FAR *) &dwSUBound ); if (FAILED(hr)) {goto HereIsVtArrayGimmieBinary_Exit;}
//*pbBinaryBuffer = (LPBYTE) AllocADsMem(dwSUBound - dwSLBound + 1);
*pbBinaryBuffer = (char *) ::CoTaskMemAlloc(dwSUBound - dwSLBound + 1); if (*pbBinaryBuffer == NULL) { hr = E_OUTOFMEMORY; goto HereIsVtArrayGimmieBinary_Exit; }
*cbBinaryBufferSize = dwSUBound - dwSLBound + 1;
hr = SafeArrayAccessData( V_ARRAY(lpVarSrcObject),(void HUGEP * FAR *) &pArray ); if (FAILED(hr)) {goto HereIsVtArrayGimmieBinary_Exit;}
memcpy(*pbBinaryBuffer,pArray,dwSUBound-dwSLBound+1); SafeArrayUnaccessData( V_ARRAY(lpVarSrcObject) );
HereIsVtArrayGimmieBinary_Exit: return hr; }
BOOL IsCertExportable(PCCERT_CONTEXT pCertContext) { HCRYPTPROV hCryptProv = NULL; DWORD dwKeySpec = 0; BOOL fCallerFreeProv = FALSE; BOOL fReturn = FALSE; HCRYPTKEY hKey = NULL; DWORD dwPermissions = 0; DWORD dwSize = 0;
if (!pCertContext) { fReturn = FALSE; goto IsCertExportable_Exit; }
//
// first get the private key context
//
if (!CryptAcquireCertificatePrivateKey( pCertContext, CRYPT_ACQUIRE_USE_PROV_INFO_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &hCryptProv, &dwKeySpec, &fCallerFreeProv)) { fReturn = FALSE; goto IsCertExportable_Exit; }
//
// get the handle to the key
//
if (!CryptGetUserKey(hCryptProv, dwKeySpec, &hKey)) { fReturn = FALSE; goto IsCertExportable_Exit; }
//
// finally, get the permissions on the key and check if it is exportable
//
dwSize = sizeof(dwPermissions); if (!CryptGetKeyParam(hKey, KP_PERMISSIONS, (PBYTE)&dwPermissions, &dwSize, 0)) { fReturn = FALSE; goto IsCertExportable_Exit; }
fReturn = (dwPermissions & CRYPT_EXPORT) ? TRUE : FALSE;
IsCertExportable_Exit: if (hKey != NULL){CryptDestroyKey(hKey);} if (fCallerFreeProv){CryptReleaseContext(hCryptProv, 0);} return fReturn; }
BOOL FormatDateString(LPWSTR * pszReturn, FILETIME ft, BOOL fIncludeTime, BOOL fLongFormat) { int cch; int cch2; SYSTEMTIME st; FILETIME localTime; LPWSTR psz = NULL; if (!FileTimeToLocalFileTime(&ft, &localTime)) { return FALSE; } if (!FileTimeToSystemTime(&localTime, &st)) { //
// if the conversion to local time failed, then just use the original time
//
if (!FileTimeToSystemTime(&ft, &st)) { return FALSE; } }
cch = (GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &st, NULL, NULL, 0) + GetDateFormat(LOCALE_SYSTEM_DEFAULT, fLongFormat ? DATE_LONGDATE : 0, &st, NULL, NULL, 0) + 5);
if (NULL == (psz = (LPWSTR) malloc((cch+5) * sizeof(WCHAR)))) { return FALSE; } cch2 = GetDateFormat(LOCALE_SYSTEM_DEFAULT, fLongFormat ? DATE_LONGDATE : 0, &st, NULL, psz, cch); if (fIncludeTime) { psz[cch2-1] = ' '; GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS, &st, NULL, &psz[cch2], cch-cch2); }
if (psz) { *pszReturn = psz; return TRUE; } else { return FALSE; } }
const WCHAR RgwchHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; BOOL FormatMemBufToString(LPWSTR *ppString, LPBYTE pbData, DWORD cbData) { DWORD i = 0; LPBYTE pb; DWORD numCharsInserted = 0;
//
// calculate the size needed
//
pb = pbData; while (pb <= &(pbData[cbData-1])) { if (numCharsInserted == 4) { i += sizeof(WCHAR); numCharsInserted = 0; } else { i += 2 * sizeof(WCHAR); pb++; numCharsInserted += 2; } }
if (NULL == (*ppString = (LPWSTR) malloc(i+sizeof(WCHAR)))) { return FALSE; }
//
// copy to the buffer
//
i = 0; numCharsInserted = 0; pb = pbData; while (pb <= &(pbData[cbData-1])) { if (numCharsInserted == 4) { (*ppString)[i++] = L' '; numCharsInserted = 0; } else { (*ppString)[i++] = RgwchHex[(*pb & 0xf0) >> 4]; (*ppString)[i++] = RgwchHex[*pb & 0x0f]; pb++; numCharsInserted += 2; } } (*ppString)[i] = 0; return TRUE; }
BOOL MyGetOIDInfo(LPWSTR string, DWORD stringSize, LPSTR pszObjId) { /*
PCCRYPT_OID_INFO pOIDInfo; pOIDInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, pszObjId, 0); if (pOIDInfo != NULL) { if ((DWORD)wcslen(pOIDInfo->pwszName)+1 <= stringSize) { wcscpy(string, pOIDInfo->pwszName); } else { return FALSE; } } else { */ return (MultiByteToWideChar(CP_ACP, 0, pszObjId, -1, string, stringSize) != 0); /*
} return TRUE; */ }
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
#define STRING_ALLOCATION_SIZE 128
BOOL GetCertDescription(PCCERT_CONTEXT pCert, LPWSTR *ppString, DWORD * cbReturn, BOOL fMultiline) { CERT_NAME_INFO *pNameInfo; DWORD cbNameInfo; WCHAR szText[256]; LPWSTR pwszText; int i,j; DWORD numChars = 1; // 1 for the terminating 0
DWORD numAllocations = 1; void *pTemp;
//
// decode the dnname into a CERT_NAME_INFO struct
//
if (!CryptDecodeObject( X509_ASN_ENCODING, X509_UNICODE_NAME, pCert->pCertInfo->Subject.pbData, pCert->pCertInfo->Subject.cbData, 0, NULL, &cbNameInfo)) { return FALSE; } if (NULL == (pNameInfo = (CERT_NAME_INFO *) malloc(cbNameInfo))) { return FALSE; } if (!CryptDecodeObject( X509_ASN_ENCODING, X509_UNICODE_NAME, pCert->pCertInfo->Subject.pbData, pCert->pCertInfo->Subject.cbData, 0, pNameInfo, &cbNameInfo)) { free (pNameInfo); return FALSE; }
//
// allocate an initial buffer for the DN name string, then if it grows larger
// than the initial amount just grow as needed
//
*ppString = (LPWSTR) malloc(STRING_ALLOCATION_SIZE * sizeof(WCHAR)); if (*ppString == NULL) { free (pNameInfo); return FALSE; }
(*ppString)[0] = 0;
//
// loop for each rdn and add it to the string
//
for (i=pNameInfo->cRDN-1; i>=0; i--) { // if this is not the first iteration, then add a eol or a ", "
if (i != (int)pNameInfo->cRDN-1) { if (numChars+2 >= (numAllocations * STRING_ALLOCATION_SIZE)) { pTemp = realloc(*ppString, ++numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR)); if (pTemp == NULL) { free (pNameInfo); free (*ppString); return FALSE; } *ppString = (LPWSTR) pTemp; } if (fMultiline) wcscat(*ppString, L"\n"); else wcscat(*ppString, L", ");
numChars += 2; }
for (j=pNameInfo->rgRDN[i].cRDNAttr-1; j>=0; j--) { // if this is not the first iteration, then add a eol or a ", "
if (j != (int)pNameInfo->rgRDN[i].cRDNAttr-1) { if (numChars+2 >= (numAllocations * STRING_ALLOCATION_SIZE)) { pTemp = realloc(*ppString, ++numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR)); if (pTemp == NULL) { free (pNameInfo); free (*ppString); return FALSE; } *ppString = (LPWSTR) pTemp; } if (fMultiline) wcscat(*ppString, L"\n"); else wcscat(*ppString, L", ");
numChars += 2; } //
// add the field name to the string if it is Multiline display
//
if (fMultiline) { if (!MyGetOIDInfo(szText, ARRAYSIZE(szText), pNameInfo->rgRDN[i].rgRDNAttr[j].pszObjId)) { free (pNameInfo); return FALSE; }
if ((numChars + wcslen(szText) + 3) >= (numAllocations * STRING_ALLOCATION_SIZE)) { // increment the number of allocation blocks until it is large enough
while ((numChars + wcslen(szText) + 3) >= (++numAllocations * STRING_ALLOCATION_SIZE));
pTemp = realloc(*ppString, numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR)); if (pTemp == NULL) { free (pNameInfo); free (*ppString); return FALSE; } *ppString = (LPWSTR) pTemp; }
numChars += wcslen(szText) + 1; wcscat(*ppString, szText); wcscat(*ppString, L"="); // delimiter
}
//
// add the value to the string
//
if (CERT_RDN_ENCODED_BLOB == pNameInfo->rgRDN[i].rgRDNAttr[j].dwValueType || CERT_RDN_OCTET_STRING == pNameInfo->rgRDN[i].rgRDNAttr[j].dwValueType) { // translate the buffer to a text string and display it that way
if (FormatMemBufToString( &pwszText, pNameInfo->rgRDN[i].rgRDNAttr[j].Value.pbData, pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData)) { if ((numChars + wcslen(pwszText)) >= (numAllocations * STRING_ALLOCATION_SIZE)) { // increment the number of allocation blocks until it is large enough
while ((numChars + wcslen(pwszText)) >= (++numAllocations * STRING_ALLOCATION_SIZE));
pTemp = realloc(*ppString, numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR)); if (pTemp == NULL) { free (pwszText); free (pNameInfo); free (*ppString); return FALSE; } *ppString = (LPWSTR) pTemp; } wcscat(*ppString, pwszText); numChars += wcslen(pwszText);
free (pwszText); } } else { // buffer is already a string so just copy it
if ((numChars + (pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData/sizeof(WCHAR))) >= (numAllocations * STRING_ALLOCATION_SIZE)) { // increment the number of allocation blocks until it is large enough
while ((numChars + (pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData/sizeof(WCHAR))) >= (++numAllocations * STRING_ALLOCATION_SIZE));
pTemp = realloc(*ppString, numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR)); if (pTemp == NULL) { free (pNameInfo); free (*ppString); return FALSE; } *ppString = (LPWSTR) pTemp; }
wcscat(*ppString, (LPWSTR) pNameInfo->rgRDN[i].rgRDNAttr[j].Value.pbData); numChars += (pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData/sizeof(WCHAR)); } } }
{
// issued to
LPWSTR pwName = NULL; DWORD cchName = CertGetNameString(pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0); if (cchName > 1 && (NULL != ( pwName = (LPWSTR) malloc (cchName * sizeof(WCHAR) )))) { BOOL bRes = FALSE; bRes = (1 != CertGetNameString(pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, pwName, cchName)); if (bRes) { wcscat(*ppString, (LPWSTR) L"\n"); numChars += 2; // append it on to the string.
//#define CERT_INFO_ISSUER_FLAG 4
wcscat(*ppString, (LPWSTR) L"4="); numChars += 2; // append it on to the string.
wcscat(*ppString, (LPWSTR) pwName); numChars += (cchName); } if (pwName) {free(pwName);pwName=NULL;} }
// expiration date
if (FormatDateString(&pwName, pCert->pCertInfo->NotAfter, FALSE, FALSE)) { wcscat(*ppString, (LPWSTR) L"\n"); numChars += 2; // append it on to the string.
//#define CERT_INFO_NOT_AFTER_FLAG 6
wcscat(*ppString, (LPWSTR) L"6="); numChars += 2; // append it on to the string.
wcscat(*ppString, (LPWSTR) pwName); numChars += wcslen(pwName); if (pwName) {free(pwName);pwName = NULL;} } }
*cbReturn = numChars; free (pNameInfo); return TRUE; }
|