HRESULT CCertExitSample::_NotifyNewCert( /* [in] */ LONG Context) { HRESULT hr; VARIANT varCert; ICertServerExit *pServer = NULL; VariantInit(&varCert); // only call write fxns if server policy allows if (m_dwExitPublishFlags & EXITPUB_FILE) { hr = CoCreateInstance( CLSID_CCertServerExit, NULL, // pUnkOuter CLSCTX_INPROC_SERVER, IID_ICertServerExit, (VOID **) &pServer); _JumpIfError(hr, error, "Exit:CoCreateInstance"); hr = pServer->SetContext(Context); _JumpIfError(hr, error, "Exit:SetContext"); hr = exitGetProperty( pServer, FALSE, // fRequest, wszPROPRAWCERTIFICATE, PROPTYPE_BINARY, &varCert); _JumpIfErrorStr( hr, error, "Exit:exitGetProperty", wszPROPRAWCERTIFICATE); if (VT_BSTR != varCert.vt) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); _JumpError(hr, error, "Exit:BAD cert var type"); } hr = _WriteCertToFile( pServer, (BYTE const *) varCert.bstrVal, SysStringByteLen(varCert.bstrVal)); _JumpIfError(hr, error, "_WriteCertToFile"); } hr = S_OK; error: VariantClear(&varCert); if (NULL != pServer) { pServer->Release(); } return(hr); }
HRESULT ceSanitizedNameToDSName( __in WCHAR const *pwszSanitizedName, __deref_out WCHAR **ppwszNameOut) { HRESULT hr; size_t cwc; size_t cwcCopy; WCHAR wszDSName[cwcCHOPBASE + cwcCHOPHASHMAX + 1]; *ppwszNameOut = NULL; cwc = wcslen(pwszSanitizedName); cwcCopy = cwc; if (cwcCHOPBASE < cwcCopy) { cwcCopy = cwcCHOPBASE; } CopyMemory(wszDSName, pwszSanitizedName, cwcCopy * sizeof(WCHAR)); wszDSName[cwcCopy] = L'\0'; if (cwcCHOPBASE < cwc) { // Hash the rest of the name into a USHORT USHORT usHash = 0; size_t i; WCHAR *pwsz; // Truncate an incomplete sanitized Unicode character pwsz = wcsrchr(wszDSName, L'!'); if (NULL != pwsz && wcslen(pwsz) < 5) { cwcCopy -= wcslen(pwsz); *pwsz = L'\0'; } for (i = cwcCopy; i < cwc; i++) { USHORT usLowBit = (0x8000 & usHash)? 1 : 0; usHash = ((usHash << 1) | usLowBit) + pwszSanitizedName[i]; } hr = StringCchPrintf(&wszDSName[cwcCopy], sizeof(wszDSName)/sizeof(WCHAR) - cwcCopy, L"-%05hu", usHash); _JumpIfError(hr, error, "StringCchPrintf"); assert(wcslen(wszDSName) < ARRAYSIZE(wszDSName)); } hr = ceDupString(wszDSName, ppwszNameOut); _JumpIfError(hr, error, "ceDupString"); error: return(hr); }
HRESULT CRequestInstance::SetTemplateName( IN ICertServerPolicy *pServer, IN OPTIONAL WCHAR const *pwszTemplateName, IN OPTIONAL WCHAR const *pwszTemplateObjId) { HRESULT hr; BSTR strProp = NULL; BSTR strTemplateName = NULL; if (NULL != pwszTemplateName) { m_strTemplateName = SysAllocString(pwszTemplateName); if (IsNullBStr(m_strTemplateName)) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Policy:SysAllocString"); } strTemplateName = m_strTemplateName; } if (NULL != pwszTemplateObjId) { m_strTemplateObjId = SysAllocString(pwszTemplateObjId); if (IsNullBStr(m_strTemplateObjId)) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Policy:SysAllocString"); } strTemplateName = m_strTemplateObjId; } if (!IsNullBStr(strTemplateName)) { VARIANT var; strProp = SysAllocString(wszPROPCERTIFICATETEMPLATE); if (IsNullBStr(strProp)) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Policy:SysAllocString"); } var.vt = VT_BSTR; var.bstrVal = strTemplateName; hr = pServer->SetCertificateProperty(strProp, PROPTYPE_STRING, &var); _JumpIfError(hr, error, "Policy:SetCertificateProperty"); } hr = S_OK; error: SysFreeString(strProp); return(hr); }
HRESULT ceMakeExprDate( IN OUT DATE *pDate, IN LONG lDelta, IN enum ENUM_PERIOD enumPeriod) { HRESULT hr; FILETIME ft; hr = ceDateToFileTime(pDate, &ft); _JumpIfError(hr, error, "ceDateToFileTime"); ceMakeExprDateTime(&ft, lDelta, enumPeriod); hr = ceFileTimeToDate(&ft, pDate); _JumpIfError(hr, error, "ceFileTimeToDate"); error: return(hr); }
HRESULT ceIsConfigLocal( IN WCHAR const *pwszConfig, OPTIONAL OUT WCHAR **ppwszMachine, OUT BOOL *pfLocal) { HRESULT hr; WCHAR *pwszDnsName = NULL; WCHAR *pwszOldName = NULL; *pfLocal = FALSE; if (NULL != ppwszMachine) { *ppwszMachine = NULL; } hr = ceGetComputerNames(&pwszDnsName, &pwszOldName); _JumpIfError(hr, error, "ceGetComputerNames"); hr = _IsConfigLocal( pwszConfig, pwszDnsName, pwszOldName, ppwszMachine, pfLocal); _JumpIfError(hr, error, "_IsConfigLocal"); error: if (NULL != pwszDnsName) { LocalFree(pwszDnsName); } if (NULL != pwszOldName) { LocalFree(pwszOldName); } return(hr); }
HRESULT GetServerCallbackInterface( OUT ICertServerExit** ppServer, IN LONG Context) { HRESULT hr; if (NULL == ppServer) { hr = E_POINTER; _JumpError(hr, error, "Exit:NULL pointer"); } hr = CoCreateInstance( CLSID_CCertServerExit, NULL, // pUnkOuter CLSCTX_INPROC_SERVER, IID_ICertServerExit, (VOID **) ppServer); _JumpIfError(hr, error, "Exit:CoCreateInstance"); if (*ppServer == NULL) { hr = E_UNEXPECTED; _JumpError(hr, error, "Exit:NULL *ppServer"); } // only set context if nonzero if (0 != Context) { hr = (*ppServer)->SetContext(Context); _JumpIfError(hr, error, "Exit: SetContext"); } error: return(hr); }
STDMETHODIMP CCertExitSample::GetManageModule( /* [out, retval] */ ICertManageModule **ppManageModule) { HRESULT hr; *ppManageModule = NULL; hr = CoCreateInstance( CLSID_CCertManageExitModuleSample, NULL, // pUnkOuter CLSCTX_INPROC_SERVER, IID_ICertManageModule, (VOID **) ppManageModule); _JumpIfError(hr, error, "CoCreateInstance"); error: return(hr); }
HRESULT ceGetComputerNames( OUT WCHAR **ppwszDnsName, OUT WCHAR **ppwszOldName) { HRESULT hr; DWORD cwc; WCHAR *pwszOldName = NULL; *ppwszOldName = NULL; *ppwszDnsName = NULL; cwc = MAX_COMPUTERNAME_LENGTH + 1; pwszOldName = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR)); if (NULL == pwszOldName) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } if (!GetComputerName(pwszOldName, &cwc)) { hr = ceHLastError(); _JumpError(hr, error, "GetComputerName"); } hr = ceGetMachineDnsName(ppwszDnsName); _JumpIfError(hr, error, "ceGetMachineDnsName"); *ppwszOldName = pwszOldName; pwszOldName = NULL; error: if (NULL != pwszOldName) { LocalFree(pwszOldName); } return(hr); }
HRESULT ceDispatchSetErrorInfoSub( IN HRESULT hrError, OPTIONAL IN WCHAR const *pwszIDispatchMethod, OPTIONAL IN WCHAR const *pwszDescription, OPTIONAL IN WCHAR const *pwszSource, OPTIONAL IN IID const *piid, OPTIONAL IN WCHAR const *pwszHelpFile, IN DWORD dwHelpFileContext) { HRESULT hr; WCHAR const *pwszError = NULL; ICreateErrorInfo *pCreateErrorInfo = NULL; IErrorInfo *pErrorInfo = NULL; if (NULL != pwszIDispatchMethod) { pwszError = ceGetErrorMessageText(hrError, TRUE); } hr = CreateErrorInfo(&pCreateErrorInfo); _JumpIfError(hr, error, "CreateErrorInfo"); if (NULL != piid) { hr = pCreateErrorInfo->SetGUID(*piid); _PrintIfError(hr, "SetGUID"); } if (NULL != pwszSource) { hr = pCreateErrorInfo->SetSource(const_cast<WCHAR *>(pwszSource)); _PrintIfError(hr, "SetSource"); } if (NULL != pwszDescription) { hr = pCreateErrorInfo->SetDescription( const_cast<WCHAR *>(pwszDescription)); _PrintIfError(hr, "SetDescription"); } if (NULL != pwszHelpFile) { hr = pCreateErrorInfo->SetHelpFile(const_cast<WCHAR *>(pwszHelpFile)); _PrintIfError(hr, "SetHelpFile"); hr = pCreateErrorInfo->SetHelpContext(dwHelpFileContext); _PrintIfError(hr, "SetHelpContext"); } hr = pCreateErrorInfo->QueryInterface( IID_IErrorInfo, (VOID **) &pErrorInfo); _JumpIfError(hr, error, "QueryInterface"); SetErrorInfo(0, pErrorInfo); hr = S_OK; error: if (NULL != pwszError) { LocalFree(const_cast<WCHAR *>(pwszError)); } if (NULL != pErrorInfo) { pErrorInfo->Release(); } if (NULL != pCreateErrorInfo) { pCreateErrorInfo->Release(); } return(hr); }
int ceWtoI( IN WCHAR const *string, OUT BOOL *pfValid) { HRESULT hr; WCHAR szBuf[16]; WCHAR *szTmp = szBuf; int cTmp = ARRAYSIZE(szBuf); int i = 0; WCHAR const *pwsz; BOOL fSawDigit = FALSE; if (pfValid == NULL) { hr = E_POINTER; _JumpError(hr, error, "NULLPARAM"); } *pfValid = FALSE; assert(NULL != pfValid); cTmp = FoldString( MAP_FOLDDIGITS, string, -1, szTmp, cTmp); if (cTmp == 0) { hr = ceHLastError(); if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) { hr = S_OK; cTmp = FoldString( MAP_FOLDDIGITS, string, -1, NULL, 0); szTmp = (WCHAR*)LocalAlloc(LMEM_FIXED, cTmp*sizeof(WCHAR)); if (NULL == szTmp) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } cTmp = FoldString( MAP_FOLDDIGITS, string, -1, szTmp, cTmp); if (cTmp == 0) hr = ceHLastError(); } _JumpIfError(hr, error, "FoldString"); } pwsz = szTmp; while (iswspace(*pwsz)) { pwsz++; } while (iswdigit(*pwsz)) { fSawDigit = TRUE; pwsz++; } while (iswspace(*pwsz)) { pwsz++; } if (L'\0' == *pwsz) { *pfValid = fSawDigit; } i = _wtoi(szTmp); error: if (szTmp && (szTmp != szBuf)) LocalFree(szTmp); return i; }
HRESULT ceFormatCertsrvStringArray( IN BOOL fURL, IN LPCWSTR pwszServerName_p1_2, IN LPCWSTR pwszSanitizedName_p3_7, IN DWORD iCert_p4, IN LPCWSTR pwszDomainDN_p5, IN LPCWSTR pwszConfigDN_p6, IN DWORD iCRL_p8, IN BOOL fDeltaCRL_p9, IN BOOL fDSAttrib_p10_11, IN DWORD cStrings, IN LPCWSTR *apwszStringsIn, OUT LPWSTR *apwszStringsOut) { HRESULT hr = S_OK; LPCWSTR apwszInsertionArray[100]; // 100 'cause this is the max number of insertion numbers allowed by FormatMessage LPWSTR pwszCurrent = NULL; BSTR strShortMachineName = NULL; DWORD i; WCHAR *pwszSanitizedDSName = NULL; WCHAR wszCertSuffix[cwcFILENAMESUFFIXMAX]; WCHAR wszCRLSuffix[cwcFILENAMESUFFIXMAX]; WCHAR wszDeltaCRLSuffix[cwcFILENAMESUFFIXMAX]; WCHAR const *pwszT; ZeroMemory(apwszStringsOut, cStrings * sizeof(apwszStringsOut[0])); ZeroMemory(apwszInsertionArray, sizeof(apwszInsertionArray)); // Format the template into a real name // Initialize the insertion string array. // Machine DNS name (%1) assert(L'1' == wszFCSAPARM_SERVERDNSNAME[1]); apwszInsertionArray[1 - 1] = pwszServerName_p1_2; // Short Machine Name (%2) assert(L'2' == wszFCSAPARM_SERVERSHORTNAME[1]); strShortMachineName = SysAllocString(pwszServerName_p1_2); if (strShortMachineName == NULL) { hr = E_OUTOFMEMORY; _JumpIfError(hr, error, "SysAllocString"); } pwszCurrent = wcschr(strShortMachineName, L'.'); if(pwszCurrent) { *pwszCurrent = 0; } apwszInsertionArray[2 - 1] = strShortMachineName; // sanitized name (%3) assert(L'3' == wszFCSAPARM_SANITIZEDCANAME[1]); apwszInsertionArray[3 - 1] = pwszSanitizedName_p3_7; // Cert filename suffix (%4) assert(L'4' == wszFCSAPARM_CERTFILENAMESUFFIX[1]); wszCertSuffix[0] = L'\0'; if (0 != iCert_p4) { wsprintf(wszCertSuffix, L"(%u)", iCert_p4); } apwszInsertionArray[4 - 1] = wszCertSuffix; assert(L'5' == wszFCSAPARM_DOMAINDN[1]); apwszInsertionArray[5 - 1] = pwszDomainDN_p5; assert(L'6' == wszFCSAPARM_CONFIGDN[1]); apwszInsertionArray[6 - 1] = pwszConfigDN_p6; // Don't pass pwszSanitizedName_p3_7 to SysAllocStringLen with the extended // length to avoid faulting past end of pwszSanitizedName_p3_7. assert(L'7' == wszFCSAPARM_SANITIZEDCANAMEHASH[1]); hr = ceSanitizedNameToDSName(pwszSanitizedName_p3_7, &pwszSanitizedDSName); _JumpIfError(hr, error, "ceSanitizedNameToDSName"); apwszInsertionArray[7 - 1] = pwszSanitizedDSName; // CRL filename suffix (%8) assert(L'8' == wszFCSAPARM_CRLFILENAMESUFFIX[1]); wszCRLSuffix[0] = L'\0'; if (0 != iCRL_p8) { wsprintf(wszCRLSuffix, L"(%u)", iCRL_p8); } apwszInsertionArray[8 - 1] = wszCRLSuffix; assert(L'9' == wszFCSAPARM_CRLDELTAFILENAMESUFFIX[1]); wszDeltaCRLSuffix[0] = L'\0'; if (fDeltaCRL_p9) { wcscpy(wszDeltaCRLSuffix, L"+"); } apwszInsertionArray[9 - 1] = wszDeltaCRLSuffix; assert(L'1' == wszFCSAPARM_DSCRLATTRIBUTE[1]); assert(L'0' == wszFCSAPARM_DSCRLATTRIBUTE[2]); pwszT = L""; if (fDSAttrib_p10_11) { pwszT = fDeltaCRL_p9? wszDSSEARCHDELTACRLATTRIBUTE : wszDSSEARCHBASECRLATTRIBUTE; } apwszInsertionArray[10 - 1] = pwszT; assert(L'1' == wszFCSAPARM_DSCACERTATTRIBUTE[1]); assert(L'1' == wszFCSAPARM_DSCACERTATTRIBUTE[2]); pwszT = L""; if (fDSAttrib_p10_11) { pwszT = wszDSSEARCHCACERTATTRIBUTE; } apwszInsertionArray[11 - 1] = pwszT; for (i = 0; i < cStrings; i++) { if (0 == FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, (VOID *) apwszStringsIn[i], 0, // dwMessageID 0, // dwLanguageID (LPWSTR) &apwszStringsOut[i], (DWORD)wcslen(apwszStringsIn[i]), (va_list *) apwszInsertionArray)) { hr = ceHLastError(); _JumpError(hr, error, "FormatMessage"); } if (fURL) { WCHAR *pwsz; hr = ceInternetCanonicalizeUrl(apwszStringsOut[i], &pwsz); _JumpIfError(hr, error, "ceInternetCanonicalizeUrl"); LocalFree(apwszStringsOut[i]); apwszStringsOut[i] = pwsz; } } error: if (S_OK != hr) { for (i = 0; i < cStrings; i++) { if (NULL != apwszStringsOut[i]) { LocalFree(apwszStringsOut[i]); apwszStringsOut[i] = NULL; } } } if(strShortMachineName) { SysFreeString(strShortMachineName); } if (NULL != pwszSanitizedDSName) { LocalFree(pwszSanitizedDSName); } return (hr); }
HRESULT ceInternetCanonicalizeUrl( __in WCHAR const *pwszIn, __deref_out WCHAR **ppwszOut) { HRESULT hr; WCHAR *pwsz = NULL; assert(NULL != pwszIn); if (0 == _wcsnicmp(L"file:", pwszIn, 5)) { hr = ceDupString(pwszIn, &pwsz); _JumpIfError(hr, error, "ceDupString"); } else { // Calculate required buffer size by passing a very small buffer // The call will fail, and tell us how big the buffer should be. WCHAR wszPlaceHolder[1]; DWORD cwc = ARRAYSIZE(wszPlaceHolder); BOOL bResult; bResult = InternetCanonicalizeUrl( pwszIn, // lpszUrl wszPlaceHolder, // lpszBuffer &cwc, // lpdwBufferLength 0); // dwFlags assert(!bResult); // This will always fail hr = ceHLastError(); if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) != hr) { // unexpected error _JumpError(hr, error, "InternetCanonicalizeUrl"); } // NOTE: InternetCanonicalizeUrl counts characters, not bytes as doc'd // cwc includes trailing L'0' pwsz = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR)); if (NULL == pwsz) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } // canonicalize if (!InternetCanonicalizeUrl( pwszIn, // lpszUrl pwsz, // lpszBuffer &cwc, // lpdwBufferLength 0)) // dwFlags { hr = ceHLastError(); _JumpError(hr, error, "InternetCanonicalizeUrl"); } } *ppwszOut = pwsz; pwsz = NULL; hr = S_OK; error: if (NULL != pwsz) { LocalFree(pwsz); } return(hr); }
HRESULT CCertExitSample::_NotifyCRLIssued( /* [in] */ LONG Context) { HRESULT hr; ICertServerExit *pServer = NULL; DWORD i; VARIANT varBaseCRL; VARIANT varDeltaCRL; BOOL fDeltaCRLsDisabled; VariantInit(&varBaseCRL); VariantInit(&varDeltaCRL); hr = CoCreateInstance( CLSID_CCertServerExit, NULL, // pUnkOuter CLSCTX_INPROC_SERVER, IID_ICertServerExit, (VOID **) &pServer); _JumpIfError(hr, error, "Exit:CoCreateInstance"); hr = pServer->SetContext(Context); _JumpIfError(hr, error, "Exit:SetContext"); hr = exitGetProperty( pServer, FALSE, // fRequest, wszPROPDELTACRLSDISABLED, PROPTYPE_LONG, &varBaseCRL); _JumpIfErrorStr( hr, error, "Exit:exitGetProperty", wszPROPDELTACRLSDISABLED); fDeltaCRLsDisabled = varBaseCRL.lVal; // How many CRLs are there? // Loop for each CRL for (i = 0; i < m_cCACert; i++) { // array size for wsprintf("%s.%u") #define MAX_CRL_PROP ( \ max( max( ARRAYSIZE(wszPROPCRLSTATE), \ ARRAYSIZE(wszPROPRAWCRL) ), \ ARRAYSIZE(wszPROPRAWDELTACRL) ) + 1 + cwcDWORDSPRINTF) WCHAR wszCRLPROP[MAX_CRL_PROP]; // Verify the CRL State says we should update this CRL wsprintf(wszCRLPROP, wszPROPCRLSTATE L".%u", i); hr = exitGetProperty( pServer, FALSE, // fRequest, wszCRLPROP, PROPTYPE_LONG, &varBaseCRL); _JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszCRLPROP); if (CA_DISP_VALID != varBaseCRL.lVal) { continue; } // Grab the raw base CRL wsprintf(wszCRLPROP, wszPROPRAWCRL L".%u", i); hr = exitGetProperty( pServer, FALSE, // fRequest, wszCRLPROP, PROPTYPE_BINARY, &varBaseCRL); _JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszCRLPROP); // Grab the raw delta CRL (which may not exist) wsprintf(wszCRLPROP, wszPROPRAWDELTACRL L".%u", i); hr = exitGetProperty( pServer, FALSE, // fRequest, wszCRLPROP, PROPTYPE_BINARY, &varDeltaCRL); _PrintIfErrorStr2( hr, "Exit:exitGetProperty", wszCRLPROP, fDeltaCRLsDisabled? HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) : S_OK); if (S_OK != hr && !fDeltaCRLsDisabled) { goto error; } // Publish the CRL(s) ... } hr = S_OK; error: if (NULL != pServer) { pServer->Release(); } VariantClear(&varBaseCRL); VariantClear(&varDeltaCRL); return(hr); }
HRESULT CCertExitSample::_WriteCertToFile( IN ICertServerExit *pServer, IN BYTE const *pbCert, IN DWORD cbCert) { HRESULT hr; BSTR strCertFile = NULL; DWORD cbWritten; HANDLE hFile = INVALID_HANDLE_VALUE; WCHAR wszDir[MAX_PATH]; WCHAR *pwszPath = NULL; WCHAR wszFile[cwcDWORDSPRINTF+5]; //format "requestid.cer" VARIANT varRequestID; VariantInit(&varRequestID); // Old functionality asked requester to pass in a CertFile attribute with // the output request file name. After the security review we decided // to not allow file name from user but to build it at server. Still, we // don't want to start publishing all certificates, so we'll maintain the // CertFile property; if present, we'll just ignore its content, if not // present we won't publish. hr = exitGetRequestAttribute(pServer, wszPROPEXITCERTFILE, &strCertFile); if (S_OK != hr) { DBGPRINT(( fDebug, "Exit:exitGetRequestAttribute(%ws): %x%hs\n", wszPROPEXITCERTFILE, hr, CERTSRV_E_PROPERTY_EMPTY == hr? " EMPTY VALUE" : "")); if (CERTSRV_E_PROPERTY_EMPTY == hr) { hr = S_OK; } goto error; } // build file name as "requestid.cer" hr = exitGetProperty( pServer, TRUE, // fRequest, wszPROPREQUESTREQUESTID, PROPTYPE_LONG, &varRequestID); _JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPREQUESTREQUESTID); wsprintf(wszFile, L"%d.cer", V_I4(&varRequestID)); hr = _ExpandEnvironmentVariables( L"%SystemRoot%\\System32\\" wszCERTENROLLSHAREPATH L"\\", wszDir, ARRAYSIZE(wszDir)); _JumpIfError(hr, error, "_ExpandEnvironmentVariables"); hr = ceBuildPathAndExt(wszDir, wszFile, NULL, &pwszPath); _JumpIfError(hr, error, "ceBuildPathAndExt"); // open file & write binary cert out. hFile = CreateFile( pwszPath, GENERIC_WRITE, 0, // dwShareMode NULL, // lpSecurityAttributes CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); // hTemplateFile if (INVALID_HANDLE_VALUE == hFile) { hr = ceHLastError(); _JumpErrorStr(hr, error, "Exit:CreateFile", pwszPath); } if (!WriteFile(hFile, pbCert, cbCert, &cbWritten, NULL)) { hr = ceHLastError(); _JumpErrorStr(hr, error, "Exit:WriteFile", pwszPath); } if (cbWritten != cbCert) { hr = STG_E_WRITEFAULT; DBGPRINT(( fDebug, "Exit:WriteFile(%ws): attempted %x, actual %x bytes: %x\n", pwszPath, cbCert, cbWritten, hr)); goto error; } error: if (INVALID_HANDLE_VALUE != hFile) { CloseHandle(hFile); } if (NULL != pwszPath) { LocalFree(pwszPath); } if (NULL != strCertFile) { SysFreeString(strCertFile); } return(hr); }
STDMETHODIMP CCertExitSample::Initialize( /* [in] */ BSTR const strConfig, /* [retval][out] */ LONG __RPC_FAR *pEventMask) { HRESULT hr = S_OK; DWORD cbbuf; DWORD dwType; ENUM_CATYPES CAType; ICertServerExit* pServer = NULL; VARIANT varValue; WCHAR sz[MAX_PATH]; VariantInit(&varValue); assert(wcslen(wsz_SAMPLE_DESCRIPTION) < ARRAYSIZE(sz)); wcsncpy(sz, wsz_SAMPLE_DESCRIPTION, ARRAYSIZE(sz)); sz[ARRAYSIZE(sz) - 1] = L'\0'; m_strDescription = SysAllocString(sz); if (NULL == m_strDescription) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Exit:SysAllocString"); } m_strCAName = SysAllocString(strConfig); if (NULL == m_strCAName) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Exit:SysAllocString"); } *pEventMask = ceEXITEVENTS; DBGPRINT((fDebug, "Exit:Initialize(%ws) ==> %x\n", m_strCAName, *pEventMask)); // get server callbacks hr = GetServerCallbackInterface(&pServer, 0); _JumpIfError(hr, error, "Exit:GetServerCallbackInterface"); // get storage location hr = exitGetProperty( pServer, FALSE, // fRequest wszPROPMODULEREGLOC, PROPTYPE_STRING, &varValue); _JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPMODULEREGLOC); m_pwszRegStorageLoc = (LPWSTR)LocalAlloc(LMEM_FIXED, (wcslen(varValue.bstrVal)+1) *sizeof(WCHAR)); if (NULL == m_pwszRegStorageLoc) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Exit:LocalAlloc"); } wcscpy(m_pwszRegStorageLoc, varValue.bstrVal); VariantClear(&varValue); // get CA type hr = exitGetProperty( pServer, FALSE, // fRequest wszPROPCATYPE, PROPTYPE_LONG, &varValue); _JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPCATYPE); CAType = (ENUM_CATYPES) varValue.lVal; VariantClear(&varValue); hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_pwszRegStorageLoc, 0, // dwReserved KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_QUERY_VALUE, &m_hExitKey); if (S_OK != hr) { if ((HRESULT) ERROR_FILE_NOT_FOUND == hr) { hr = S_OK; goto error; } _JumpError(hr, error, "Exit:RegOpenKeyEx"); } hr = exitGetProperty( pServer, FALSE, // fRequest wszPROPCERTCOUNT, PROPTYPE_LONG, &varValue); _JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPCERTCOUNT); m_cCACert = varValue.lVal; cbbuf = sizeof(m_dwExitPublishFlags); hr = RegQueryValueEx( m_hExitKey, wszREGCERTPUBLISHFLAGS, NULL, // lpdwReserved &dwType, (BYTE *) &m_dwExitPublishFlags, &cbbuf); if (S_OK != hr) { m_dwExitPublishFlags = 0; } hr = S_OK; error: VariantClear(&varValue); if (NULL != pServer) { pServer->Release(); } return(ceHError(hr)); }
HRESULT CRequestInstance::Initialize( IN CCertPolicySample *pPolicy, IN ICertServerPolicy *pServer, OUT BOOL *pfEnableEnrolleeExtensions) { HRESULT hr; HRESULT hrTemplate = S_OK; CERT_TEMPLATE_EXT *pTemplate = NULL; CERT_NAME_VALUE *pName = NULL; BSTR strTemplateObjId = NULL; // from V2 template extension BSTR strTemplateName = NULL; // from V1 template extension BSTR strTemplateRA = NULL; // from request attributes WCHAR const *pwszTemplateName; WCHAR const *pwszTemplateObjId; WCHAR const *pwszV1TemplateClass; VARIANT varValue; DWORD cbType; DWORD i; BOOL fConflict; BOOL f; BOOL fTemplateMissing; BOOL fRAObjId = FALSE; VariantInit(&varValue); *pfEnableEnrolleeExtensions = TRUE ; m_pPolicy = pPolicy; m_fCA = FALSE; // Retrieve the template ObjId from the V2 cert template info extension m_dwTemplateMajorVersion = 0; m_dwTemplateMinorVersion = 0; hr = polGetCertificateExtension( pServer, TEXT(szOID_CERTIFICATE_TEMPLATE), PROPTYPE_BINARY, &varValue); _PrintIfErrorStr2( hr, "Policy:polGetCertificateExtension", TEXT(szOID_CERTIFICATE_TEMPLATE), CERTSRV_E_PROPERTY_EMPTY); if (S_OK == hr) { // There was a cert type indicator. // varValue points to an encoded string if (VT_BSTR != varValue.vt) { hr = E_INVALIDARG; _JumpError(hr, error, "Policy:varValue.vt"); } if (!ceDecodeObject( X509_ASN_ENCODING, X509_CERTIFICATE_TEMPLATE, (BYTE *) varValue.bstrVal, SysStringByteLen(varValue.bstrVal), FALSE, (VOID **) &pTemplate, &cbType)) { hr = ceHLastError(); _JumpError(hr, error, "Policy:ceDecodeObject"); } if (!ceConvertSzToBstr(&strTemplateObjId, pTemplate->pszObjId, -1)) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Policy:ceConvertSzToBstr"); } m_dwTemplateMajorVersion = pTemplate->dwMajorVersion; m_dwTemplateMinorVersion = pTemplate->dwMinorVersion; DBGPRINT(( fDebug, pTemplate->fMinorVersion? "Extension Template Info: %ws V%u.%u\n" : "Extension Template Info: %ws V%u%\n", strTemplateObjId, m_dwTemplateMajorVersion, m_dwTemplateMinorVersion)); } VariantClear(&varValue); // Retrieve template Name from the V1 cert template name extension hr = polGetCertificateExtension( pServer, TEXT(szOID_ENROLL_CERTTYPE_EXTENSION), PROPTYPE_BINARY, &varValue); _PrintIfErrorStr2( hr, "Policy:polGetCertificateExtension", TEXT(szOID_ENROLL_CERTTYPE_EXTENSION), CERTSRV_E_PROPERTY_EMPTY); if (S_OK == hr) { // There was a cert type indicator. // varValue points to an encoded string if (VT_BSTR != varValue.vt) { hr = E_INVALIDARG; _JumpError(hr, error, "Policy:varValue.vt"); } if (!ceDecodeObject( X509_ASN_ENCODING, X509_UNICODE_ANY_STRING, (BYTE *) varValue.bstrVal, SysStringByteLen(varValue.bstrVal), FALSE, (VOID **) &pName, &cbType)) { hr = ceHLastError(); _JumpError(hr, error, "Policy:ceDecodeObject"); } strTemplateName = SysAllocString((WCHAR *) pName->Value.pbData); if (IsNullBStr(strTemplateName)) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Policy:SysAllocString"); } DBGPRINT((fDebug, "Extension Template: %ws\n", strTemplateName)); } fConflict = FALSE; fTemplateMissing = FALSE; // Retrieve the template from the request attributes hr = polGetRequestAttribute(pServer, wszPROPCERTTEMPLATE, &strTemplateRA); if (S_OK != hr) { _PrintErrorStr2( hr, "Policy:polGetRequestAttribute", wszPROPCERTTEMPLATE, CERTSRV_E_PROPERTY_EMPTY); hr = S_OK; } else { DBGPRINT((fDebug, "Attribute Template: %ws\n", strTemplateRA)); if (!IsNullBStr(strTemplateObjId) && !_TemplateNamesMatch(strTemplateObjId, strTemplateRA, &f)) { fConflict = TRUE; if (f) { fTemplateMissing = TRUE; } } if (!IsNullBStr(strTemplateName) && !_TemplateNamesMatch(strTemplateName, strTemplateRA, &f)) { fConflict = TRUE; if (f) { fTemplateMissing = TRUE; } } hr = ceVerifyObjId(strTemplateRA); fRAObjId = S_OK == hr; } if (!IsNullBStr(strTemplateObjId) && !IsNullBStr(strTemplateName) && !_TemplateNamesMatch(strTemplateObjId, strTemplateName, &f)) { fConflict = TRUE; if (f) { fTemplateMissing = TRUE; } } pwszTemplateName = strTemplateName; pwszTemplateObjId = strTemplateObjId; if (fRAObjId) { if (NULL == pwszTemplateObjId) { pwszTemplateObjId = strTemplateRA; } } else { if (NULL == pwszTemplateName) { pwszTemplateName = strTemplateRA; } } if (fConflict) { hrTemplate = CERTSRV_E_TEMPLATE_CONFLICT; if (!IsNullBStr(strTemplateObjId)) { _PrintErrorStr( hrTemplate, "Policy:Extension Template ObjId", strTemplateObjId); } if (!IsNullBStr(strTemplateName)) { _PrintErrorStr( hrTemplate, "Policy:Extension Template Name", strTemplateName); } if (!IsNullBStr(strTemplateRA)) { _PrintErrorStr( hrTemplate, "Policy:Attribute Template", strTemplateRA); } } { if (NULL != pwszTemplateName) { for (i = 0; i < ARRAYSIZE(s_apwszCATypes); i++) { if (0 == celstrcmpiL(s_apwszCATypes[i], pwszTemplateName)) { m_fCA = TRUE; break; } } } } hr = SetTemplateName(pServer, pwszTemplateName, pwszTemplateObjId); _JumpIfError(hr, error, "Policy:SetTemplateName"); pwszV1TemplateClass = pwszTemplateName; hr = pPolicy->AddV1TemplateNameExtension(pServer, pwszV1TemplateClass); _JumpIfError(hr, error, "AddTemplateNameExtension"); error: if (S_OK != hrTemplate) { hr = hrTemplate; // override secondary errors } VariantClear(&varValue); if (NULL != pName) { LocalFree(pName); } if (NULL != pTemplate) { LocalFree(pTemplate); } SysFreeString(strTemplateObjId); SysFreeString(strTemplateName); SysFreeString(strTemplateRA); return(hr); }