Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwintrust_main.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2001 Rein Klazes 00003 * Copyright 2007 Juan Lang 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 #include "config.h" 00021 00022 #include <stdarg.h> 00023 00024 #define NONAMELESSUNION 00025 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winerror.h" 00029 #include "winreg.h" 00030 #include "guiddef.h" 00031 #include "wintrust.h" 00032 #include "softpub.h" 00033 #include "mscat.h" 00034 #include "objbase.h" 00035 #include "winuser.h" 00036 #include "cryptdlg.h" 00037 #include "cryptuiapi.h" 00038 #include "wintrust_priv.h" 00039 #include "wine/debug.h" 00040 00041 WINE_DEFAULT_DEBUG_CHANNEL(wintrust); 00042 00043 00044 /* Utility functions */ 00045 void * WINAPI WINTRUST_Alloc(DWORD cb) 00046 { 00047 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb); 00048 } 00049 00050 static void* WINTRUST_ReAlloc(void *ptr, DWORD cb) __WINE_ALLOC_SIZE(2); 00051 static void* WINTRUST_ReAlloc(void *ptr, DWORD cb) 00052 { 00053 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb); 00054 } 00055 00056 void WINAPI WINTRUST_Free(void *p) 00057 { 00058 HeapFree(GetProcessHeap(), 0, p); 00059 } 00060 00061 /*********************************************************************** 00062 * DllMain (WINTRUST.@) 00063 */ 00064 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) 00065 { 00066 switch(reason) 00067 { 00068 case DLL_PROCESS_ATTACH: 00069 DisableThreadLibraryCalls( inst ); 00070 break; 00071 } 00072 return TRUE; 00073 } 00074 00075 /*********************************************************************** 00076 * TrustIsCertificateSelfSigned (WINTRUST.@) 00077 */ 00078 BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert ) 00079 { 00080 PCERT_EXTENSION ext; 00081 DWORD size; 00082 BOOL ret; 00083 00084 TRACE("%p\n", cert); 00085 if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2, 00086 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) 00087 { 00088 CERT_AUTHORITY_KEY_ID2_INFO *info; 00089 00090 ret = CryptDecodeObjectEx(cert->dwCertEncodingType, 00091 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData, 00092 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, 00093 &info, &size); 00094 if (ret) 00095 { 00096 if (info->AuthorityCertIssuer.cAltEntry && 00097 info->AuthorityCertSerialNumber.cbData) 00098 { 00099 PCERT_ALT_NAME_ENTRY directoryName = NULL; 00100 DWORD i; 00101 00102 for (i = 0; !directoryName && 00103 i < info->AuthorityCertIssuer.cAltEntry; i++) 00104 if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice 00105 == CERT_ALT_NAME_DIRECTORY_NAME) 00106 directoryName = 00107 &info->AuthorityCertIssuer.rgAltEntry[i]; 00108 if (directoryName) 00109 { 00110 ret = CertCompareCertificateName(cert->dwCertEncodingType, 00111 &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer) 00112 && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, 00113 &cert->pCertInfo->SerialNumber); 00114 } 00115 else 00116 { 00117 FIXME("no supported name type in authority key id2\n"); 00118 ret = FALSE; 00119 } 00120 } 00121 else if (info->KeyId.cbData) 00122 { 00123 ret = CertGetCertificateContextProperty(cert, 00124 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); 00125 if (ret && size == info->KeyId.cbData) 00126 { 00127 LPBYTE buf = CryptMemAlloc(size); 00128 00129 if (buf) 00130 { 00131 CertGetCertificateContextProperty(cert, 00132 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); 00133 ret = !memcmp(buf, info->KeyId.pbData, size); 00134 CryptMemFree(buf); 00135 } 00136 else 00137 ret = FALSE; 00138 } 00139 else 00140 ret = FALSE; 00141 } 00142 LocalFree(info); 00143 } 00144 } 00145 else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER, 00146 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) 00147 { 00148 CERT_AUTHORITY_KEY_ID_INFO *info; 00149 00150 ret = CryptDecodeObjectEx(cert->dwCertEncodingType, 00151 X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData, 00152 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, 00153 &info, &size); 00154 if (ret) 00155 { 00156 if (info->CertIssuer.cbData && info->CertSerialNumber.cbData) 00157 { 00158 ret = CertCompareCertificateName(cert->dwCertEncodingType, 00159 &info->CertIssuer, &cert->pCertInfo->Issuer) && 00160 CertCompareIntegerBlob(&info->CertSerialNumber, 00161 &cert->pCertInfo->SerialNumber); 00162 } 00163 else if (info->KeyId.cbData) 00164 { 00165 ret = CertGetCertificateContextProperty(cert, 00166 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); 00167 if (ret && size == info->KeyId.cbData) 00168 { 00169 LPBYTE buf = CryptMemAlloc(size); 00170 00171 if (buf) 00172 { 00173 CertGetCertificateContextProperty(cert, 00174 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); 00175 ret = !memcmp(buf, info->KeyId.pbData, size); 00176 CryptMemFree(buf); 00177 } 00178 else 00179 ret = FALSE; 00180 } 00181 else 00182 ret = FALSE; 00183 } 00184 else 00185 ret = FALSE; 00186 LocalFree(info); 00187 } 00188 } 00189 else 00190 ret = CertCompareCertificateName(cert->dwCertEncodingType, 00191 &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer); 00192 return ret; 00193 } 00194 00195 typedef HRESULT (WINAPI *wintrust_step_func)(CRYPT_PROVIDER_DATA *data); 00196 00197 struct wintrust_step 00198 { 00199 wintrust_step_func func; 00200 DWORD error_index; 00201 }; 00202 00203 static DWORD WINTRUST_ExecuteSteps(const struct wintrust_step *steps, 00204 DWORD numSteps, CRYPT_PROVIDER_DATA *provData) 00205 { 00206 DWORD i, err = ERROR_SUCCESS; 00207 00208 for (i = 0; !err && i < numSteps; i++) 00209 { 00210 err = steps[i].func(provData); 00211 if (err) 00212 err = provData->padwTrustStepErrors[steps[i].error_index]; 00213 } 00214 return err; 00215 } 00216 00217 static CRYPT_PROVIDER_DATA *WINTRUST_AllocateProviderData(void) 00218 { 00219 CRYPT_PROVIDER_DATA *provData; 00220 00221 provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA)); 00222 if (!provData) 00223 goto oom; 00224 provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA); 00225 00226 provData->padwTrustStepErrors = 00227 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD)); 00228 if (!provData->padwTrustStepErrors) 00229 goto oom; 00230 provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS; 00231 00232 provData->u.pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP)); 00233 if (!provData->u.pPDSip) 00234 goto oom; 00235 provData->u.pPDSip->cbStruct = sizeof(PROVDATA_SIP); 00236 00237 provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS)); 00238 if (!provData->psPfns) 00239 goto oom; 00240 provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS); 00241 return provData; 00242 00243 oom: 00244 if (provData) 00245 { 00246 WINTRUST_Free(provData->padwTrustStepErrors); 00247 WINTRUST_Free(provData->u.pPDSip); 00248 WINTRUST_Free(provData->psPfns); 00249 WINTRUST_Free(provData); 00250 } 00251 return NULL; 00252 } 00253 00254 /* Adds trust steps for each function in psPfns. Assumes steps has at least 00255 * 5 entries. Returns the number of steps added. 00256 */ 00257 static DWORD WINTRUST_AddTrustStepsFromFunctions(struct wintrust_step *steps, 00258 const CRYPT_PROVIDER_FUNCTIONS *psPfns) 00259 { 00260 DWORD numSteps = 0; 00261 00262 if (psPfns->pfnInitialize) 00263 { 00264 steps[numSteps].func = psPfns->pfnInitialize; 00265 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT; 00266 } 00267 if (psPfns->pfnObjectTrust) 00268 { 00269 steps[numSteps].func = psPfns->pfnObjectTrust; 00270 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV; 00271 } 00272 if (psPfns->pfnSignatureTrust) 00273 { 00274 steps[numSteps].func = psPfns->pfnSignatureTrust; 00275 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV; 00276 } 00277 if (psPfns->pfnCertificateTrust) 00278 { 00279 steps[numSteps].func = psPfns->pfnCertificateTrust; 00280 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV; 00281 } 00282 if (psPfns->pfnFinalPolicy) 00283 { 00284 steps[numSteps].func = psPfns->pfnFinalPolicy; 00285 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV; 00286 } 00287 return numSteps; 00288 } 00289 00290 static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID, 00291 WINTRUST_DATA *data) 00292 { 00293 DWORD err = ERROR_SUCCESS, numSteps = 0; 00294 CRYPT_PROVIDER_DATA *provData; 00295 BOOL ret; 00296 struct wintrust_step verifySteps[5]; 00297 00298 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); 00299 00300 provData = WINTRUST_AllocateProviderData(); 00301 if (!provData) 00302 return ERROR_OUTOFMEMORY; 00303 00304 ret = WintrustLoadFunctionPointers(actionID, provData->psPfns); 00305 if (!ret) 00306 { 00307 err = GetLastError(); 00308 goto error; 00309 } 00310 00311 data->hWVTStateData = provData; 00312 provData->pWintrustData = data; 00313 if (hwnd == INVALID_HANDLE_VALUE) 00314 provData->hWndParent = GetDesktopWindow(); 00315 else 00316 provData->hWndParent = hwnd; 00317 provData->pgActionID = actionID; 00318 WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings); 00319 00320 numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps, 00321 provData->psPfns); 00322 err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData); 00323 goto done; 00324 00325 error: 00326 if (provData) 00327 { 00328 WINTRUST_Free(provData->padwTrustStepErrors); 00329 WINTRUST_Free(provData->u.pPDSip); 00330 WINTRUST_Free(provData->psPfns); 00331 WINTRUST_Free(provData); 00332 } 00333 done: 00334 TRACE("returning %08x\n", err); 00335 return err; 00336 } 00337 00338 static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID, 00339 WINTRUST_DATA *data) 00340 { 00341 DWORD err = ERROR_SUCCESS; 00342 CRYPT_PROVIDER_DATA *provData = data->hWVTStateData; 00343 00344 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); 00345 00346 if (provData) 00347 { 00348 if (provData->psPfns->pfnCleanupPolicy) 00349 err = provData->psPfns->pfnCleanupPolicy(provData); 00350 00351 WINTRUST_Free(provData->padwTrustStepErrors); 00352 WINTRUST_Free(provData->u.pPDSip); 00353 WINTRUST_Free(provData->psPfns); 00354 WINTRUST_Free(provData); 00355 data->hWVTStateData = NULL; 00356 } 00357 TRACE("returning %08x\n", err); 00358 return err; 00359 } 00360 00361 static LONG WINTRUST_DefaultVerifyAndClose(HWND hwnd, GUID *actionID, 00362 WINTRUST_DATA *data) 00363 { 00364 LONG err; 00365 00366 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); 00367 00368 err = WINTRUST_DefaultVerify(hwnd, actionID, data); 00369 WINTRUST_DefaultClose(hwnd, actionID, data); 00370 TRACE("returning %08x\n", err); 00371 return err; 00372 } 00373 00374 static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID, 00375 WINTRUST_DATA *data) 00376 { 00377 WINTRUST_DATA wintrust_data = { sizeof(wintrust_data), 0 }; 00378 /* Undocumented: the published software action is passed a path, 00379 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE. 00380 */ 00381 LPWIN_TRUST_SUBJECT_FILE subjectFile = data->pSIPClientData; 00382 WINTRUST_FILE_INFO fileInfo = { sizeof(fileInfo), 0 }; 00383 00384 TRACE("subjectFile->hFile: %p\n", subjectFile->hFile); 00385 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile->lpPath)); 00386 fileInfo.pcwszFilePath = subjectFile->lpPath; 00387 fileInfo.hFile = subjectFile->hFile; 00388 wintrust_data.u.pFile = &fileInfo; 00389 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE; 00390 wintrust_data.dwUIChoice = WTD_UI_NONE; 00391 00392 return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data); 00393 } 00394 00395 /* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY 00396 * action is not stored in the registry and is located in wintrust, not in 00397 * cryptdlg along with the rest of the implementation (verified by running the 00398 * action with a native wintrust.dll.) 00399 */ 00400 static HRESULT WINAPI WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA *data) 00401 { 00402 BOOL ret; 00403 00404 TRACE("(%p)\n", data); 00405 00406 if (!data->padwTrustStepErrors) 00407 return S_FALSE; 00408 00409 switch (data->pWintrustData->dwUnionChoice) 00410 { 00411 case WTD_CHOICE_BLOB: 00412 if (data->pWintrustData->u.pBlob && 00413 WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(WINTRUST_BLOB_INFO, 00414 data->pWintrustData->u.pBlob->cbStruct, pbMemObject) && 00415 data->pWintrustData->u.pBlob->cbMemObject == 00416 sizeof(CERT_VERIFY_CERTIFICATE_TRUST) && 00417 data->pWintrustData->u.pBlob->pbMemObject) 00418 { 00419 CERT_VERIFY_CERTIFICATE_TRUST *pCert = 00420 (CERT_VERIFY_CERTIFICATE_TRUST *) 00421 data->pWintrustData->u.pBlob->pbMemObject; 00422 00423 if (pCert->cbSize == sizeof(CERT_VERIFY_CERTIFICATE_TRUST) && 00424 pCert->pccert) 00425 { 00426 CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } }; 00427 DWORD i; 00428 SYSTEMTIME sysTime; 00429 00430 /* Add a signer with nothing but the time to verify, so we can 00431 * add a cert to it 00432 */ 00433 GetSystemTime(&sysTime); 00434 SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf); 00435 ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer); 00436 if (!ret) 00437 goto error; 00438 ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0, 00439 pCert->pccert); 00440 if (!ret) 00441 goto error; 00442 for (i = 0; ret && i < pCert->cRootStores; i++) 00443 ret = data->psPfns->pfnAddStore2Chain(data, 00444 pCert->rghstoreRoots[i]); 00445 for (i = 0; ret && i < pCert->cStores; i++) 00446 ret = data->psPfns->pfnAddStore2Chain(data, 00447 pCert->rghstoreCAs[i]); 00448 for (i = 0; ret && i < pCert->cTrustStores; i++) 00449 ret = data->psPfns->pfnAddStore2Chain(data, 00450 pCert->rghstoreTrust[i]); 00451 } 00452 else 00453 { 00454 SetLastError(ERROR_INVALID_PARAMETER); 00455 ret = FALSE; 00456 } 00457 } 00458 else 00459 { 00460 SetLastError(ERROR_INVALID_PARAMETER); 00461 ret = FALSE; 00462 } 00463 break; 00464 default: 00465 FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice); 00466 SetLastError(ERROR_INVALID_PARAMETER); 00467 ret = FALSE; 00468 } 00469 00470 error: 00471 if (!ret) 00472 data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = 00473 GetLastError(); 00474 TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE, 00475 data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]); 00476 return ret ? S_OK : S_FALSE; 00477 } 00478 00479 static LONG WINTRUST_CertVerify(HWND hwnd, GUID *actionID, 00480 WINTRUST_DATA *data) 00481 { 00482 DWORD err = ERROR_SUCCESS, numSteps = 0; 00483 CRYPT_PROVIDER_DATA *provData; 00484 BOOL ret; 00485 struct wintrust_step verifySteps[5]; 00486 00487 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); 00488 00489 provData = WINTRUST_AllocateProviderData(); 00490 if (!provData) 00491 return ERROR_OUTOFMEMORY; 00492 00493 ret = WintrustLoadFunctionPointers(actionID, provData->psPfns); 00494 if (!ret) 00495 { 00496 err = GetLastError(); 00497 goto error; 00498 } 00499 if (!provData->psPfns->pfnObjectTrust) 00500 provData->psPfns->pfnObjectTrust = WINTRUST_CertVerifyObjTrust; 00501 /* Not sure why, but native skips the policy check */ 00502 provData->psPfns->pfnCertCheckPolicy = NULL; 00503 00504 data->hWVTStateData = provData; 00505 provData->pWintrustData = data; 00506 if (hwnd == INVALID_HANDLE_VALUE) 00507 provData->hWndParent = GetDesktopWindow(); 00508 else 00509 provData->hWndParent = hwnd; 00510 provData->pgActionID = actionID; 00511 WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings); 00512 00513 numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps, 00514 provData->psPfns); 00515 err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData); 00516 goto done; 00517 00518 error: 00519 if (provData) 00520 { 00521 WINTRUST_Free(provData->padwTrustStepErrors); 00522 WINTRUST_Free(provData->u.pPDSip); 00523 WINTRUST_Free(provData->psPfns); 00524 WINTRUST_Free(provData); 00525 } 00526 done: 00527 TRACE("returning %08x\n", err); 00528 return err; 00529 } 00530 00531 static LONG WINTRUST_CertVerifyAndClose(HWND hwnd, GUID *actionID, 00532 WINTRUST_DATA *data) 00533 { 00534 LONG err; 00535 00536 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); 00537 00538 err = WINTRUST_CertVerify(hwnd, actionID, data); 00539 WINTRUST_DefaultClose(hwnd, actionID, data); 00540 TRACE("returning %08x\n", err); 00541 return err; 00542 } 00543 00544 static LONG WINTRUST_CertActionVerify(HWND hwnd, GUID *actionID, 00545 WINTRUST_DATA *data) 00546 { 00547 DWORD stateAction; 00548 LONG err = ERROR_SUCCESS; 00549 00550 if (WVT_ISINSTRUCT(WINTRUST_DATA, data->cbStruct, dwStateAction)) 00551 stateAction = data->dwStateAction; 00552 else 00553 { 00554 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n"); 00555 stateAction = WTD_STATEACTION_IGNORE; 00556 } 00557 switch (stateAction) 00558 { 00559 case WTD_STATEACTION_IGNORE: 00560 err = WINTRUST_CertVerifyAndClose(hwnd, actionID, data); 00561 break; 00562 case WTD_STATEACTION_VERIFY: 00563 err = WINTRUST_CertVerify(hwnd, actionID, data); 00564 break; 00565 case WTD_STATEACTION_CLOSE: 00566 err = WINTRUST_DefaultClose(hwnd, actionID, data); 00567 break; 00568 default: 00569 FIXME("unimplemented for %d\n", data->dwStateAction); 00570 } 00571 return err; 00572 } 00573 00574 static void dump_file_info(WINTRUST_FILE_INFO *pFile) 00575 { 00576 TRACE("%p\n", pFile); 00577 if (pFile) 00578 { 00579 TRACE("cbStruct: %d\n", pFile->cbStruct); 00580 TRACE("pcwszFilePath: %s\n", debugstr_w(pFile->pcwszFilePath)); 00581 TRACE("hFile: %p\n", pFile->hFile); 00582 TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile->pgKnownSubject)); 00583 } 00584 } 00585 00586 static void dump_catalog_info(WINTRUST_CATALOG_INFO *catalog) 00587 { 00588 TRACE("%p\n", catalog); 00589 if (catalog) 00590 { 00591 TRACE("cbStruct: %d\n", catalog->cbStruct); 00592 TRACE("dwCatalogVersion: %d\n", catalog->dwCatalogVersion); 00593 TRACE("pcwszCatalogFilePath: %s\n", 00594 debugstr_w(catalog->pcwszCatalogFilePath)); 00595 TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog->pcwszMemberTag)); 00596 TRACE("pcwszMemberFilePath: %s\n", 00597 debugstr_w(catalog->pcwszMemberFilePath)); 00598 TRACE("hMemberFile: %p\n", catalog->hMemberFile); 00599 TRACE("pbCalculatedFileHash: %p\n", catalog->pbCalculatedFileHash); 00600 TRACE("cbCalculatedFileHash: %d\n", catalog->cbCalculatedFileHash); 00601 TRACE("pcCatalogContext: %p\n", catalog->pcCatalogContext); 00602 } 00603 } 00604 00605 static void dump_blob_info(WINTRUST_BLOB_INFO *blob) 00606 { 00607 TRACE("%p\n", blob); 00608 if (blob) 00609 { 00610 TRACE("cbStruct: %d\n", blob->cbStruct); 00611 TRACE("gSubject: %s\n", debugstr_guid(&blob->gSubject)); 00612 TRACE("pcwszDisplayName: %s\n", debugstr_w(blob->pcwszDisplayName)); 00613 TRACE("cbMemObject: %d\n", blob->cbMemObject); 00614 TRACE("pbMemObject: %p\n", blob->pbMemObject); 00615 TRACE("cbMemSignedMsg: %d\n", blob->cbMemSignedMsg); 00616 TRACE("pbMemSignedMsg: %p\n", blob->pbMemSignedMsg); 00617 } 00618 } 00619 00620 static void dump_sgnr_info(WINTRUST_SGNR_INFO *sgnr) 00621 { 00622 TRACE("%p\n", sgnr); 00623 if (sgnr) 00624 { 00625 TRACE("cbStruct: %d\n", sgnr->cbStruct); 00626 TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr->pcwszDisplayName)); 00627 TRACE("psSignerInfo: %p\n", sgnr->psSignerInfo); 00628 TRACE("chStores: %d\n", sgnr->chStores); 00629 } 00630 } 00631 00632 static void dump_cert_info(WINTRUST_CERT_INFO *cert) 00633 { 00634 TRACE("%p\n", cert); 00635 if (cert) 00636 { 00637 TRACE("cbStruct: %d\n", cert->cbStruct); 00638 TRACE("pcwszDisplayName: %s\n", debugstr_w(cert->pcwszDisplayName)); 00639 TRACE("psCertContext: %p\n", cert->psCertContext); 00640 TRACE("chStores: %d\n", cert->chStores); 00641 TRACE("dwFlags: %08x\n", cert->dwFlags); 00642 TRACE("psftVerifyAsOf: %p\n", cert->psftVerifyAsOf); 00643 } 00644 } 00645 00646 static void dump_wintrust_data(WINTRUST_DATA *data) 00647 { 00648 TRACE("%p\n", data); 00649 if (data) 00650 { 00651 TRACE("cbStruct: %d\n", data->cbStruct); 00652 TRACE("pPolicyCallbackData: %p\n", data->pPolicyCallbackData); 00653 TRACE("pSIPClientData: %p\n", data->pSIPClientData); 00654 TRACE("dwUIChoice: %d\n", data->dwUIChoice); 00655 TRACE("fdwRevocationChecks: %08x\n", data->fdwRevocationChecks); 00656 TRACE("dwUnionChoice: %d\n", data->dwUnionChoice); 00657 switch (data->dwUnionChoice) 00658 { 00659 case WTD_CHOICE_FILE: 00660 dump_file_info(data->u.pFile); 00661 break; 00662 case WTD_CHOICE_CATALOG: 00663 dump_catalog_info(data->u.pCatalog); 00664 break; 00665 case WTD_CHOICE_BLOB: 00666 dump_blob_info(data->u.pBlob); 00667 break; 00668 case WTD_CHOICE_SIGNER: 00669 dump_sgnr_info(data->u.pSgnr); 00670 break; 00671 case WTD_CHOICE_CERT: 00672 dump_cert_info(data->u.pCert); 00673 break; 00674 } 00675 TRACE("dwStateAction: %d\n", data->dwStateAction); 00676 TRACE("hWVTStateData: %p\n", data->hWVTStateData); 00677 TRACE("pwszURLReference: %s\n", debugstr_w(data->pwszURLReference)); 00678 TRACE("dwProvFlags: %08x\n", data->dwProvFlags); 00679 TRACE("dwUIContext: %d\n", data->dwUIContext); 00680 } 00681 } 00682 00683 /*********************************************************************** 00684 * WinVerifyTrust (WINTRUST.@) 00685 * 00686 * Verifies an object by calling the specified trust provider. 00687 * 00688 * PARAMS 00689 * hwnd [I] Handle to a caller window. 00690 * ActionID [I] Pointer to a GUID that identifies the action to perform. 00691 * ActionData [I] Information used by the trust provider to verify the object. 00692 * 00693 * RETURNS 00694 * Success: Zero. 00695 * Failure: A TRUST_E_* error code. 00696 * 00697 * NOTES 00698 * Trust providers can be found at: 00699 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\ 00700 */ 00701 LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData ) 00702 { 00703 static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47, 00704 0x00,0xC0,0x4F,0xC2,0x95,0xEE } }; 00705 static const GUID published_software = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE; 00706 static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; 00707 static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY; 00708 static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY; 00709 static const GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY; 00710 LONG err = ERROR_SUCCESS; 00711 WINTRUST_DATA *actionData = ActionData; 00712 00713 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(ActionID), ActionData); 00714 dump_wintrust_data(ActionData); 00715 00716 /* Support for known old-style callers: */ 00717 if (IsEqualGUID(ActionID, &published_software)) 00718 err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData); 00719 else if (IsEqualGUID(ActionID, &cert_action_verify)) 00720 err = WINTRUST_CertActionVerify(hwnd, ActionID, ActionData); 00721 else 00722 { 00723 DWORD stateAction; 00724 00725 /* Check known actions to warn of possible problems */ 00726 if (!IsEqualGUID(ActionID, &unknown) && 00727 !IsEqualGUID(ActionID, &generic_verify_v2) && 00728 !IsEqualGUID(ActionID, &generic_cert_verify) && 00729 !IsEqualGUID(ActionID, &generic_chain_verify)) 00730 WARN("unknown action %s, default behavior may not be right\n", 00731 debugstr_guid(ActionID)); 00732 if (WVT_ISINSTRUCT(WINTRUST_DATA, actionData->cbStruct, dwStateAction)) 00733 stateAction = actionData->dwStateAction; 00734 else 00735 { 00736 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n"); 00737 stateAction = WTD_STATEACTION_IGNORE; 00738 } 00739 switch (stateAction) 00740 { 00741 case WTD_STATEACTION_IGNORE: 00742 err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData); 00743 break; 00744 case WTD_STATEACTION_VERIFY: 00745 err = WINTRUST_DefaultVerify(hwnd, ActionID, ActionData); 00746 break; 00747 case WTD_STATEACTION_CLOSE: 00748 err = WINTRUST_DefaultClose(hwnd, ActionID, ActionData); 00749 break; 00750 default: 00751 FIXME("unimplemented for %d\n", actionData->dwStateAction); 00752 } 00753 } 00754 00755 TRACE("returning %08x\n", err); 00756 return err; 00757 } 00758 00759 /*********************************************************************** 00760 * WinVerifyTrustEx (WINTRUST.@) 00761 */ 00762 HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID, 00763 WINTRUST_DATA* ActionData ) 00764 { 00765 return WinVerifyTrust(hwnd, ActionID, ActionData); 00766 } 00767 00768 /*********************************************************************** 00769 * WTHelperGetProvSignerFromChain (WINTRUST.@) 00770 */ 00771 CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain( 00772 CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner, 00773 DWORD idxCounterSigner) 00774 { 00775 CRYPT_PROVIDER_SGNR *sgnr; 00776 00777 TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner, 00778 idxCounterSigner); 00779 00780 if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners) 00781 return NULL; 00782 sgnr = &pProvData->pasSigners[idxSigner]; 00783 if (fCounterSigner) 00784 { 00785 if (idxCounterSigner >= sgnr->csCounterSigners || 00786 !sgnr->pasCounterSigners) 00787 return NULL; 00788 sgnr = &sgnr->pasCounterSigners[idxCounterSigner]; 00789 } 00790 TRACE("returning %p\n", sgnr); 00791 return sgnr; 00792 } 00793 00794 /*********************************************************************** 00795 * WTHelperGetProvCertFromChain (WINTRUST.@) 00796 */ 00797 CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain( 00798 CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert) 00799 { 00800 CRYPT_PROVIDER_CERT *cert; 00801 00802 TRACE("(%p %d)\n", pSgnr, idxCert); 00803 00804 if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain) 00805 return NULL; 00806 cert = &pSgnr->pasCertChain[idxCert]; 00807 TRACE("returning %p\n", cert); 00808 return cert; 00809 } 00810 00811 CRYPT_PROVIDER_PRIVDATA *WINAPI WTHelperGetProvPrivateDataFromChain( 00812 CRYPT_PROVIDER_DATA* pProvData, 00813 GUID* pgProviderID) 00814 { 00815 CRYPT_PROVIDER_PRIVDATA *privdata = NULL; 00816 DWORD i; 00817 00818 TRACE("(%p, %s)\n", pProvData, debugstr_guid(pgProviderID)); 00819 00820 for (i = 0; i < pProvData->csProvPrivData; i++) 00821 if (IsEqualGUID(pgProviderID, &pProvData->pasProvPrivData[i].gProviderID)) 00822 { 00823 privdata = &pProvData->pasProvPrivData[i]; 00824 break; 00825 } 00826 00827 return privdata; 00828 } 00829 00830 /*********************************************************************** 00831 * WTHelperProvDataFromStateData (WINTRUST.@) 00832 */ 00833 CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData) 00834 { 00835 TRACE("%p\n", hStateData); 00836 return hStateData; 00837 } 00838 00839 /*********************************************************************** 00840 * WTHelperGetFileName(WINTRUST.@) 00841 */ 00842 LPCWSTR WINAPI WTHelperGetFileName(WINTRUST_DATA *data) 00843 { 00844 TRACE("%p\n",data); 00845 if (data->dwUnionChoice == WTD_CHOICE_FILE) 00846 return data->u.pFile->pcwszFilePath; 00847 else 00848 return NULL; 00849 } 00850 00851 /*********************************************************************** 00852 * WTHelperGetFileHandle(WINTRUST.@) 00853 */ 00854 HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *data) 00855 { 00856 TRACE("%p\n",data); 00857 if (data->dwUnionChoice == WTD_CHOICE_FILE) 00858 return data->u.pFile->hFile; 00859 else 00860 return INVALID_HANDLE_VALUE; 00861 } 00862 00863 static BOOL WINAPI WINTRUST_enumUsages(PCCRYPT_OID_INFO pInfo, void *pvArg) 00864 { 00865 PCCRYPT_OID_INFO **usages = pvArg; 00866 DWORD cUsages; 00867 BOOL ret; 00868 00869 if (!*usages) 00870 { 00871 cUsages = 0; 00872 *usages = WINTRUST_Alloc(2 * sizeof(PCCRYPT_OID_INFO)); 00873 } 00874 else 00875 { 00876 PCCRYPT_OID_INFO *ptr; 00877 00878 /* Count the existing usages. 00879 * FIXME: make sure the new usage doesn't duplicate any in the list? 00880 */ 00881 for (cUsages = 0, ptr = *usages; *ptr; ptr++, cUsages++) 00882 ; 00883 *usages = WINTRUST_ReAlloc(*usages, 00884 (cUsages + 2) * sizeof(PCCRYPT_OID_INFO)); 00885 } 00886 if (*usages) 00887 { 00888 (*usages)[cUsages] = pInfo; 00889 (*usages)[cUsages + 1] = NULL; 00890 ret = TRUE; 00891 } 00892 else 00893 { 00894 SetLastError(ERROR_OUTOFMEMORY); 00895 ret = FALSE; 00896 } 00897 return ret; 00898 } 00899 00900 /*********************************************************************** 00901 * WTHelperGetKnownUsages(WINTRUST.@) 00902 * 00903 * Enumerates the known enhanced key usages as an array of PCCRYPT_OID_INFOs. 00904 * 00905 * PARAMS 00906 * action [In] 1 => allocate and return known usages, 2 => free previously 00907 * allocated usages. 00908 * usages [In/Out] If action == 1, *usages is set to an array of 00909 * PCCRYPT_OID_INFO *. The array is terminated with a NULL 00910 * pointer. 00911 * If action == 2, *usages is freed. 00912 * 00913 * RETURNS 00914 * TRUE on success, FALSE on failure. 00915 */ 00916 BOOL WINAPI WTHelperGetKnownUsages(DWORD action, PCCRYPT_OID_INFO **usages) 00917 { 00918 BOOL ret; 00919 00920 TRACE("(%d, %p)\n", action, usages); 00921 00922 if (!usages) 00923 { 00924 SetLastError(ERROR_INVALID_PARAMETER); 00925 return FALSE; 00926 } 00927 00928 if (action == 1) 00929 { 00930 *usages = NULL; 00931 ret = CryptEnumOIDInfo(CRYPT_ENHKEY_USAGE_OID_GROUP_ID, 0, usages, 00932 WINTRUST_enumUsages); 00933 } 00934 else if (action == 2) 00935 { 00936 WINTRUST_Free(*usages); 00937 *usages = NULL; 00938 ret = TRUE; 00939 } 00940 else 00941 { 00942 WARN("unknown action %d\n", action); 00943 SetLastError(ERROR_INVALID_PARAMETER); 00944 ret = FALSE; 00945 } 00946 return ret; 00947 } 00948 00949 static const WCHAR Software_Publishing[] = { 00950 'S','o','f','t','w','a','r','e','\\', 00951 'M','i','c','r','o','s','o','f','t','\\', 00952 'W','i','n','d','o','w','s','\\', 00953 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 00954 'W','i','n','t','r','u','s','t','\\', 00955 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\', 00956 'S','o','f','t','w','a','r','e',' ', 00957 'P','u','b','l','i','s','h','i','n','g',0 }; 00958 static const WCHAR State[] = { 'S','t','a','t','e',0 }; 00959 00960 /*********************************************************************** 00961 * WintrustGetRegPolicyFlags (WINTRUST.@) 00962 */ 00963 void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags ) 00964 { 00965 HKEY key; 00966 LONG r; 00967 00968 TRACE("%p\n", pdwPolicyFlags); 00969 00970 *pdwPolicyFlags = 0; 00971 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0, 00972 KEY_READ, NULL, &key, NULL); 00973 if (!r) 00974 { 00975 DWORD size = sizeof(DWORD); 00976 00977 r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags, 00978 &size); 00979 RegCloseKey(key); 00980 if (r) 00981 { 00982 /* Failed to query, create and return default value */ 00983 *pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS | 00984 WTPF_OFFLINEOKNBU_COM | 00985 WTPF_OFFLINEOKNBU_IND | 00986 WTPF_OFFLINEOK_COM | 00987 WTPF_OFFLINEOK_IND; 00988 WintrustSetRegPolicyFlags(*pdwPolicyFlags); 00989 } 00990 } 00991 } 00992 00993 /*********************************************************************** 00994 * WintrustSetRegPolicyFlags (WINTRUST.@) 00995 */ 00996 BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags) 00997 { 00998 HKEY key; 00999 LONG r; 01000 01001 TRACE("%x\n", dwPolicyFlags); 01002 01003 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, 01004 NULL, 0, KEY_WRITE, NULL, &key, NULL); 01005 if (!r) 01006 { 01007 r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags, 01008 sizeof(DWORD)); 01009 RegCloseKey(key); 01010 } 01011 if (r) SetLastError(r); 01012 return r == ERROR_SUCCESS; 01013 } 01014 01015 /* Utility functions */ 01016 01017 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store) 01018 { 01019 BOOL ret = FALSE; 01020 01021 TRACE("(%p, %p)\n", data, store); 01022 01023 if (data->chStores) 01024 data->pahStores = WINTRUST_ReAlloc(data->pahStores, 01025 (data->chStores + 1) * sizeof(HCERTSTORE)); 01026 else 01027 { 01028 data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE)); 01029 data->chStores = 0; 01030 } 01031 if (data->pahStores) 01032 { 01033 data->pahStores[data->chStores++] = CertDuplicateStore(store); 01034 ret = TRUE; 01035 } 01036 else 01037 SetLastError(ERROR_OUTOFMEMORY); 01038 return ret; 01039 } 01040 01041 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data, 01042 BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr) 01043 { 01044 BOOL ret = FALSE; 01045 01046 TRACE("(%p, %d, %d, %p)\n", data, fCounterSigner, idxSigner, sgnr); 01047 01048 if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR)) 01049 { 01050 SetLastError(ERROR_INVALID_PARAMETER); 01051 return FALSE; 01052 } 01053 if (fCounterSigner) 01054 { 01055 FIXME("unimplemented for counter signers\n"); 01056 SetLastError(ERROR_INVALID_PARAMETER); 01057 return FALSE; 01058 } 01059 if (data->csSigners) 01060 data->pasSigners = WINTRUST_ReAlloc(data->pasSigners, 01061 (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR)); 01062 else 01063 { 01064 data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR)); 01065 data->csSigners = 0; 01066 } 01067 if (data->pasSigners) 01068 { 01069 if (idxSigner < data->csSigners) 01070 memmove(&data->pasSigners[idxSigner], 01071 &data->pasSigners[idxSigner + 1], 01072 (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR)); 01073 ret = TRUE; 01074 if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR)) 01075 { 01076 /* The PSDK says psSigner should be allocated using pfnAlloc, but 01077 * it doesn't say anything about ownership. Since callers are 01078 * internal, assume ownership is passed, and just store the 01079 * pointer. 01080 */ 01081 memcpy(&data->pasSigners[idxSigner], sgnr, 01082 sizeof(CRYPT_PROVIDER_SGNR)); 01083 } 01084 else 01085 memset(&data->pasSigners[idxSigner], 0, 01086 sizeof(CRYPT_PROVIDER_SGNR)); 01087 data->csSigners++; 01088 } 01089 else 01090 SetLastError(ERROR_OUTOFMEMORY); 01091 return ret; 01092 } 01093 01094 BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner, 01095 BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add) 01096 { 01097 BOOL ret = FALSE; 01098 01099 TRACE("(%p, %d, %d, %d, %p)\n", data, idxSigner, fCounterSigner, 01100 idxSigner, pCert2Add); 01101 01102 if (fCounterSigner) 01103 { 01104 FIXME("unimplemented for counter signers\n"); 01105 SetLastError(ERROR_INVALID_PARAMETER); 01106 return FALSE; 01107 } 01108 if (data->pasSigners[idxSigner].csCertChain) 01109 data->pasSigners[idxSigner].pasCertChain = 01110 WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain, 01111 (data->pasSigners[idxSigner].csCertChain + 1) * 01112 sizeof(CRYPT_PROVIDER_CERT)); 01113 else 01114 { 01115 data->pasSigners[idxSigner].pasCertChain = 01116 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT)); 01117 data->pasSigners[idxSigner].csCertChain = 0; 01118 } 01119 if (data->pasSigners[idxSigner].pasCertChain) 01120 { 01121 CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[ 01122 data->pasSigners[idxSigner].csCertChain]; 01123 01124 cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT); 01125 cert->pCert = CertDuplicateCertificateContext(pCert2Add); 01126 data->pasSigners[idxSigner].csCertChain++; 01127 ret = TRUE; 01128 } 01129 else 01130 SetLastError(ERROR_OUTOFMEMORY); 01131 return ret; 01132 } 01133 01134 BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data, 01135 CRYPT_PROVIDER_PRIVDATA *pPrivData2Add) 01136 { 01137 BOOL ret = FALSE; 01138 01139 TRACE("(%p, %p)\n", data, pPrivData2Add); 01140 01141 if (pPrivData2Add->cbStruct > sizeof(CRYPT_PROVIDER_PRIVDATA)) 01142 { 01143 SetLastError(ERROR_INVALID_PARAMETER); 01144 WARN("invalid struct size\n"); 01145 return FALSE; 01146 } 01147 if (data->csProvPrivData) 01148 data->pasProvPrivData = WINTRUST_ReAlloc(data->pasProvPrivData, 01149 (data->csProvPrivData + 1) * sizeof(CRYPT_PROVIDER_SGNR)); 01150 else 01151 { 01152 data->pasProvPrivData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR)); 01153 data->csProvPrivData = 0; 01154 } 01155 if (data->pasProvPrivData) 01156 { 01157 DWORD i; 01158 01159 for (i = 0; i < data->csProvPrivData; i++) 01160 if (IsEqualGUID(&pPrivData2Add->gProviderID, &data->pasProvPrivData[i])) 01161 break; 01162 01163 data->pasProvPrivData[i] = *pPrivData2Add; 01164 if (i == data->csProvPrivData) 01165 data->csProvPrivData++; 01166 } 01167 else 01168 SetLastError(ERROR_OUTOFMEMORY); 01169 return ret; 01170 } 01171 01172 /*********************************************************************** 01173 * OpenPersonalTrustDBDialog (WINTRUST.@) 01174 * 01175 * Opens the certificate manager dialog, showing only the stores that 01176 * contain trusted software publishers. 01177 * 01178 * PARAMS 01179 * hwnd [I] handle of parent window 01180 * 01181 * RETURNS 01182 * TRUE if the dialog could be opened, FALSE if not. 01183 */ 01184 BOOL WINAPI OpenPersonalTrustDBDialog(HWND hwnd) 01185 { 01186 CRYPTUI_CERT_MGR_STRUCT uiCertMgr; 01187 01188 uiCertMgr.dwSize = sizeof(uiCertMgr); 01189 uiCertMgr.hwndParent = hwnd; 01190 uiCertMgr.dwFlags = CRYPTUI_CERT_MGR_PUBLISHER_TAB; 01191 uiCertMgr.pwszTitle = NULL; 01192 uiCertMgr.pszInitUsageOID = NULL; 01193 return CryptUIDlgCertMgr(&uiCertMgr); 01194 } 01195 01196 /*********************************************************************** 01197 * WTHelperCertCheckValidSignature 01198 */ 01199 HRESULT WINAPI WTHelperCertCheckValidSignature(CRYPT_PROVIDER_DATA *pProvData) 01200 { 01201 FIXME("Stub\n"); 01202 return S_OK; 01203 } Generated on Sun May 27 2012 04:27:03 for ReactOS by
1.7.6.1
|