HRESULT ceGetMachineDnsName( OUT WCHAR **ppwszDnsName) { HRESULT hr; WCHAR *pwszDnsName = NULL; DWORD cwc; COMPUTER_NAME_FORMAT NameType = ComputerNameDnsFullyQualified; *ppwszDnsName = NULL; while (TRUE) { cwc = 0; if (!GetComputerNameEx(NameType, NULL, &cwc)) { hr = ceHLastError(); if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr && ComputerNameDnsFullyQualified == NameType) { _PrintError(hr, "GetComputerNameEx(DnsFullyQualified) -- switching to NetBIOS"); NameType = ComputerNameNetBIOS; continue; } if (HRESULT_FROM_WIN32(ERROR_MORE_DATA) != hr) { _JumpError(hr, error, "GetComputerNameEx"); } break; } } pwszDnsName = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR)); if (NULL == pwszDnsName) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } if (!GetComputerNameEx(NameType, pwszDnsName, &cwc)) { hr = ceHLastError(); _JumpError(hr, error, "GetComputerNameEx"); } *ppwszDnsName = pwszDnsName; pwszDnsName = NULL; hr = S_OK; error: if (NULL != pwszDnsName) { LocalFree(pwszDnsName); } return(hr); }
HRESULT ceDateToFileTime( IN DATE const *pDate, OUT FILETIME *pft) { SYSTEMTIME st; HRESULT hr = S_OK; if (*pDate == 0.0) { GetSystemTime(&st); } else { if (!VariantTimeToSystemTime(*pDate, &st)) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); _JumpError(hr, error, "VariantTimeToSystemTime"); } } if (!SystemTimeToFileTime(&st, pft)) { hr = ceHLastError(); _JumpError(hr, error, "SystemTimeToFileTime"); } error: return(hr); }
STDMETHODIMP CCertEncodeAltName::Decode( /* [in] */ BSTR const strBinary) { HRESULT hr = S_OK; _Cleanup(); if (NULL == strBinary) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } // Decode CERT_ALT_NAME_INFO: if (!ceDecodeObject( X509_ASN_ENCODING, X509_ALTERNATE_NAME, (BYTE *) strBinary, SysStringByteLen(strBinary), FALSE, (VOID **) &m_DecodeInfo, &m_DecodeLength)) { hr = ceHLastError(); ceERRORPRINTLINE("ceDecodeObject", hr); goto error; } m_aValue = m_DecodeInfo->rgAltEntry; m_cValue = m_DecodeInfo->cAltEntry; error: if (S_OK != hr) { _Cleanup(); } return(_SetErrorInfo(hr, L"CCertEncodeAltName::Decode")); }
HRESULT ceFileTimeToDate( IN FILETIME const *pft, OUT DATE *pDate) { SYSTEMTIME st; HRESULT hr = S_OK; if (!FileTimeToSystemTime(pft, &st)) { hr = ceHLastError(); _JumpError(hr, error, "FileTimeToSystemTime"); } if (!SystemTimeToVariantTime(&st, pDate)) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); _JumpError(hr, error, "SystemTimeToVariantTime"); } 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 ceVerifyAltNameString( IN LONG NameChoice, IN BSTR strName) { HRESULT hr = S_OK; CERT_ALT_NAME_INFO AltName; CERT_ALT_NAME_ENTRY Entry; CERT_OTHER_NAME OtherName; char *pszObjectId = NULL; DWORD cbEncoded; ZeroMemory(&AltName, sizeof(AltName)); AltName.cAltEntry = 1; AltName.rgAltEntry = &Entry; ZeroMemory(&Entry, sizeof(Entry)); Entry.dwAltNameChoice = NameChoice; switch (NameChoice) { case CERT_ALT_NAME_RFC822_NAME: Entry.pwszRfc822Name = strName; break; case CERT_ALT_NAME_DNS_NAME: Entry.pwszDNSName = strName; break; case CERT_ALT_NAME_URL: Entry.pwszURL = strName; break; case CERT_ALT_NAME_REGISTERED_ID: if (!ceConvertWszToSz(&pszObjectId, strName, -1)) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("ceConvertWszToSz", hr); goto error; } Entry.pszRegisteredID = pszObjectId; break; case CERT_ALT_NAME_OTHER_NAME: Entry.pOtherName = &OtherName; OtherName.pszObjId = szOID_NT_PRINCIPAL_NAME; OtherName.Value.cbData = SysStringByteLen(strName); OtherName.Value.pbData = (BYTE *) strName; break; case CERT_ALT_NAME_DIRECTORY_NAME: Entry.DirectoryName.cbData = SysStringByteLen(strName); Entry.DirectoryName.pbData = (BYTE *) strName; break; case CERT_ALT_NAME_IP_ADDRESS: Entry.IPAddress.cbData = SysStringByteLen(strName); Entry.IPAddress.pbData = (BYTE *) strName; break; //case CERT_ALT_NAME_X400_ADDRESS: //case CERT_ALT_NAME_EDI_PARTY_NAME: default: hr = E_INVALIDARG; ceERRORPRINTLINE("NameChoice", hr); goto error; } // Encode CERT_ALT_NAME_INFO: if (!CryptEncodeObject( X509_ASN_ENCODING, X509_ALTERNATE_NAME, &AltName, NULL, &cbEncoded)) { hr = ceHLastError(); ceERRORPRINTLINE("ceEncodeObject", hr); goto error; } error: if (NULL != pszObjectId) { LocalFree(pszObjectId); } return(hr); }
HRESULT ceVerifyObjIdA( IN CHAR const *pszObjId) { HRESULT hr; BYTE *pbEncoded = NULL; DWORD cbEncoded; CRYPT_ATTRIBUTE ainfo; CRYPT_ATTRIBUTE *painfo = NULL; DWORD cbainfo; char const *psz; int i; ainfo.pszObjId = const_cast<char *>(pszObjId); ainfo.cValue = 0; ainfo.rgValue = NULL; if (!ceEncodeObject( X509_ASN_ENCODING, PKCS_ATTRIBUTE, &ainfo, 0, FALSE, &pbEncoded, &cbEncoded)) { hr = ceHLastError(); _JumpError(hr, error, "ceEncodeObject"); } if (!ceDecodeObject( X509_ASN_ENCODING, PKCS_ATTRIBUTE, pbEncoded, cbEncoded, FALSE, (VOID **) &painfo, &cbainfo)) { hr = ceHLastError(); _JumpError(hr, error, "ceDecodeObject"); } hr = E_INVALIDARG; if (0 != strcmp(ainfo.pszObjId, painfo->pszObjId)) { _JumpError(hr, error, "bad ObjId: decode mismatch"); } for (psz = painfo->pszObjId; '\0' != *psz; psz++) { // must be a digit or a dot separator if (!isdigit(*psz)) { if ('.' != *psz) { _JumpError(hr, error, "bad ObjId: bad char"); } // can't have dot at start, double dots or dot at end if (psz == painfo->pszObjId || '.' == psz[1] || '\0' == psz[1]) { _JumpError(hr, error, "bad ObjId: dot location"); } } } psz = strchr(painfo->pszObjId, '.'); if (NULL == psz) { _JumpError(hr, error, "bad ObjId: must have at least one dot"); } i = atoi(painfo->pszObjId); switch (i) { case 0: case 1: i = atoi(++psz); if (0 > i || 39 < i) { _JumpError(hr, error, "bad ObjId: 0. or 1. must be followed by 0..39"); } break; case 2: break; default: _JumpError(hr, error, "bad ObjId: must start with 0, 1 or 2"); } hr = S_OK; error: if (NULL != pbEncoded) { LocalFree(pbEncoded); } if (NULL != painfo) { LocalFree(painfo); } 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, OUT WCHAR **ppwszOut) { HRESULT hr; WCHAR *pwsz = NULL; assert(NULL != pwszIn); // 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); }
STDMETHODIMP CCertEncodeAltName::Encode( /* [out, retval] */ BSTR __RPC_FAR *pstrBinary) { HRESULT hr = S_OK; CERT_ALT_NAME_INFO AltName; BYTE *pbEncoded = NULL; DWORD cbEncoded; LONG i; if (NULL == pstrBinary) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } AltName.cAltEntry = m_cValue; AltName.rgAltEntry = m_aValue; ceFreeBstr(pstrBinary); if (!m_fConstructing || NULL == m_aValue) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } for (i = 0; i < m_cValue; i++) { // Verify all entries are initialized: if (!_VerifyName(i)) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); ceERRORPRINTLINE("uninitialized name", hr); goto error; } } // Encode CERT_ALT_NAME_INFO: if (!ceEncodeObject( X509_ASN_ENCODING, X509_ALTERNATE_NAME, &AltName, 0, FALSE, &pbEncoded, &cbEncoded)) { hr = ceHLastError(); ceERRORPRINTLINE("ceEncodeObject", hr); goto error; } if (!ceConvertWszToBstr(pstrBinary, (WCHAR const *) pbEncoded, cbEncoded)) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("ceConvertWszToBstr", hr); goto error; } error: if (NULL != pbEncoded) { LocalFree(pbEncoded); } return(_SetErrorInfo(hr, L"CCertEncodeAltName::Encode")); }
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); }
HRESULT CCertExitSample::_ExpandEnvironmentVariables( IN WCHAR const *pwszIn, OUT WCHAR *pwszOut, IN DWORD cwcOut) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW); WCHAR awcVar[MAX_PATH]; WCHAR const *pwszSrc; WCHAR *pwszDst; WCHAR *pwszDstEnd; WCHAR *pwszVar; DWORD cwc; pwszSrc = pwszIn; pwszDst = pwszOut; pwszDstEnd = &pwszOut[cwcOut]; while (L'\0' != (*pwszDst = *pwszSrc++)) { if ('%' == *pwszDst) { *pwszDst = L'\0'; pwszVar = awcVar; while (L'\0' != *pwszSrc) { if ('%' == *pwszSrc) { pwszSrc++; break; } *pwszVar++ = *pwszSrc++; if (pwszVar >= &awcVar[sizeof(awcVar)/sizeof(awcVar[0]) - 1]) { _JumpError(hr, error, "Exit:overflow 1"); } } *pwszVar = L'\0'; cwc = GetEnvironmentVariable(awcVar, pwszDst, SAFE_SUBTRACT_POINTERS(pwszDstEnd, pwszDst)); if (0 == cwc) { hr = ceHLastError(); _JumpError(hr, error, "Exit:GetEnvironmentVariable"); } if ((DWORD) (pwszDstEnd - pwszDst) <= cwc) { _JumpError(hr, error, "Exit:overflow 2"); } pwszDst += cwc; } else { pwszDst++; } if (pwszDst >= pwszDstEnd) { _JumpError(hr, error, "Exit:overflow 3"); } } hr = S_OK; error: return(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); }