1 /* 2 * Copyright 2008 Maarten Lankhorst 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #define NONAMELESSUNION 20 21 #include <stdarg.h> 22 #ifdef __REACTOS__ 23 #include <wchar.h> 24 #endif 25 26 #include "windef.h" 27 #include "winbase.h" 28 #include "winnls.h" 29 #include "winreg.h" 30 #include "wincrypt.h" 31 #include "wintrust.h" 32 #include "winuser.h" 33 #include "objbase.h" 34 #include "cryptdlg.h" 35 #include "cryptuiapi.h" 36 #include "cryptres.h" 37 #include "wine/debug.h" 38 39 WINE_DEFAULT_DEBUG_CHANNEL(cryptdlg); 40 41 static HINSTANCE hInstance; 42 43 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 44 { 45 TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); 46 47 switch (fdwReason) 48 { 49 case DLL_WINE_PREATTACH: 50 return FALSE; /* prefer native version */ 51 case DLL_PROCESS_ATTACH: 52 DisableThreadLibraryCalls(hinstDLL); 53 hInstance = hinstDLL; 54 break; 55 } 56 return TRUE; 57 } 58 59 /*********************************************************************** 60 * GetFriendlyNameOfCertA (CRYPTDLG.@) 61 */ 62 DWORD WINAPI GetFriendlyNameOfCertA(PCCERT_CONTEXT pccert, LPSTR pchBuffer, 63 DWORD cchBuffer) 64 { 65 return CertGetNameStringA(pccert, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, 66 pchBuffer, cchBuffer); 67 } 68 69 /*********************************************************************** 70 * GetFriendlyNameOfCertW (CRYPTDLG.@) 71 */ 72 DWORD WINAPI GetFriendlyNameOfCertW(PCCERT_CONTEXT pccert, LPWSTR pchBuffer, 73 DWORD cchBuffer) 74 { 75 return CertGetNameStringW(pccert, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, 76 pchBuffer, cchBuffer); 77 } 78 79 /*********************************************************************** 80 * CertTrustInit (CRYPTDLG.@) 81 */ 82 HRESULT WINAPI CertTrustInit(CRYPT_PROVIDER_DATA *pProvData) 83 { 84 HRESULT ret = S_FALSE; 85 86 TRACE("(%p)\n", pProvData); 87 88 if (pProvData->padwTrustStepErrors && 89 !pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT]) 90 ret = S_OK; 91 TRACE("returning %08x\n", ret); 92 return ret; 93 } 94 95 /*********************************************************************** 96 * CertTrustCertPolicy (CRYPTDLG.@) 97 */ 98 BOOL WINAPI CertTrustCertPolicy(CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSignerChain, DWORD idxCounterSigner) 99 { 100 FIXME("(%p, %d, %s, %d)\n", pProvData, idxSigner, fCounterSignerChain ? "TRUE" : "FALSE", idxCounterSigner); 101 return FALSE; 102 } 103 104 /*********************************************************************** 105 * CertTrustCleanup (CRYPTDLG.@) 106 */ 107 HRESULT WINAPI CertTrustCleanup(CRYPT_PROVIDER_DATA *pProvData) 108 { 109 FIXME("(%p)\n", pProvData); 110 return E_NOTIMPL; 111 } 112 113 static BOOL CRYPTDLG_CheckOnlineCRL(void) 114 { 115 static const WCHAR policyFlagsKey[] = { 'S','o','f','t','w','a','r','e', 116 '\\','M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g', 117 'r','a','p','h','y','\\','{','7','8','0','1','e','b','d','0','-','c','f', 118 '4','b','-','1','1','d','0','-','8','5','1','f','-','0','0','6','0','9', 119 '7','9','3','8','7','e','a','}',0 }; 120 static const WCHAR policyFlags[] = { 'P','o','l','i','c','y','F','l','a', 121 'g','s',0 }; 122 HKEY key; 123 BOOL ret = FALSE; 124 125 if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, policyFlagsKey, 0, KEY_READ, &key)) 126 { 127 DWORD type, flags, size = sizeof(flags); 128 129 if (!RegQueryValueExW(key, policyFlags, NULL, &type, (BYTE *)&flags, 130 &size) && type == REG_DWORD) 131 { 132 /* The flag values aren't defined in any header I'm aware of, but 133 * this value is well documented on the net. 134 */ 135 if (flags & 0x00010000) 136 ret = TRUE; 137 } 138 RegCloseKey(key); 139 } 140 return ret; 141 } 142 143 /* Returns TRUE if pCert is not in the Disallowed system store, or FALSE if it 144 * is. 145 */ 146 static BOOL CRYPTDLG_IsCertAllowed(PCCERT_CONTEXT pCert) 147 { 148 BOOL ret; 149 BYTE hash[20]; 150 DWORD size = sizeof(hash); 151 152 if ((ret = CertGetCertificateContextProperty(pCert, 153 CERT_SIGNATURE_HASH_PROP_ID, hash, &size))) 154 { 155 static const WCHAR disallowedW[] = 156 { 'D','i','s','a','l','l','o','w','e','d',0 }; 157 HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 158 X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, disallowedW); 159 160 if (disallowed) 161 { 162 PCCERT_CONTEXT found = CertFindCertificateInStore(disallowed, 163 X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH, hash, NULL); 164 165 if (found) 166 { 167 ret = FALSE; 168 CertFreeCertificateContext(found); 169 } 170 CertCloseStore(disallowed, 0); 171 } 172 } 173 return ret; 174 } 175 176 static DWORD CRYPTDLG_TrustStatusToConfidence(DWORD errorStatus) 177 { 178 DWORD confidence = 0; 179 180 confidence = 0; 181 if (!(errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID)) 182 confidence |= CERT_CONFIDENCE_SIG; 183 if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_VALID)) 184 confidence |= CERT_CONFIDENCE_TIME; 185 if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED)) 186 confidence |= CERT_CONFIDENCE_TIMENEST; 187 return confidence; 188 } 189 190 static BOOL CRYPTDLG_CopyChain(CRYPT_PROVIDER_DATA *data, 191 PCCERT_CHAIN_CONTEXT chain) 192 { 193 BOOL ret; 194 CRYPT_PROVIDER_SGNR signer; 195 PCERT_SIMPLE_CHAIN simpleChain = chain->rgpChain[0]; 196 DWORD i; 197 198 memset(&signer, 0, sizeof(signer)); 199 signer.cbStruct = sizeof(signer); 200 ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer); 201 if (ret) 202 { 203 CRYPT_PROVIDER_SGNR *sgnr = WTHelperGetProvSignerFromChain(data, 0, 204 FALSE, 0); 205 206 if (sgnr) 207 { 208 sgnr->dwError = simpleChain->TrustStatus.dwErrorStatus; 209 sgnr->pChainContext = CertDuplicateCertificateChain(chain); 210 } 211 else 212 ret = FALSE; 213 for (i = 0; ret && i < simpleChain->cElement; i++) 214 { 215 ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0, 216 simpleChain->rgpElement[i]->pCertContext); 217 if (ret) 218 { 219 CRYPT_PROVIDER_CERT *cert; 220 221 if ((cert = WTHelperGetProvCertFromChain(sgnr, i))) 222 { 223 CERT_CHAIN_ELEMENT *element = simpleChain->rgpElement[i]; 224 225 cert->dwConfidence = CRYPTDLG_TrustStatusToConfidence( 226 element->TrustStatus.dwErrorStatus); 227 cert->dwError = element->TrustStatus.dwErrorStatus; 228 cert->pChainElement = element; 229 } 230 else 231 ret = FALSE; 232 } 233 } 234 } 235 return ret; 236 } 237 238 static CERT_VERIFY_CERTIFICATE_TRUST *CRYPTDLG_GetVerifyData( 239 CRYPT_PROVIDER_DATA *data) 240 { 241 CERT_VERIFY_CERTIFICATE_TRUST *pCert = NULL; 242 243 /* This should always be true, but just in case the calling function is 244 * called directly: 245 */ 246 if (data->pWintrustData->dwUnionChoice == WTD_CHOICE_BLOB && 247 data->pWintrustData->u.pBlob && data->pWintrustData->u.pBlob->cbMemObject == 248 sizeof(CERT_VERIFY_CERTIFICATE_TRUST) && 249 data->pWintrustData->u.pBlob->pbMemObject) 250 pCert = (CERT_VERIFY_CERTIFICATE_TRUST *) 251 data->pWintrustData->u.pBlob->pbMemObject; 252 return pCert; 253 } 254 255 static HCERTCHAINENGINE CRYPTDLG_MakeEngine(CERT_VERIFY_CERTIFICATE_TRUST *cert) 256 { 257 HCERTCHAINENGINE engine = NULL; 258 HCERTSTORE root = NULL, trust = NULL; 259 DWORD i; 260 261 if (cert->cRootStores) 262 { 263 root = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 264 CERT_STORE_CREATE_NEW_FLAG, NULL); 265 if (root) 266 { 267 for (i = 0; i < cert->cRootStores; i++) 268 CertAddStoreToCollection(root, cert->rghstoreRoots[i], 0, 0); 269 } 270 } 271 if (cert->cTrustStores) 272 { 273 trust = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 274 CERT_STORE_CREATE_NEW_FLAG, NULL); 275 if (trust) 276 { 277 for (i = 0; i < cert->cTrustStores; i++) 278 CertAddStoreToCollection(trust, cert->rghstoreTrust[i], 0, 0); 279 } 280 } 281 if (cert->cRootStores || cert->cStores || cert->cTrustStores) 282 { 283 CERT_CHAIN_ENGINE_CONFIG config; 284 285 memset(&config, 0, sizeof(config)); 286 config.cbSize = sizeof(config); 287 config.hRestrictedRoot = root; 288 config.hRestrictedTrust = trust; 289 config.cAdditionalStore = cert->cStores; 290 config.rghAdditionalStore = cert->rghstoreCAs; 291 config.hRestrictedRoot = root; 292 CertCreateCertificateChainEngine(&config, &engine); 293 CertCloseStore(root, 0); 294 CertCloseStore(trust, 0); 295 } 296 return engine; 297 } 298 299 /*********************************************************************** 300 * CertTrustFinalPolicy (CRYPTDLG.@) 301 */ 302 HRESULT WINAPI CertTrustFinalPolicy(CRYPT_PROVIDER_DATA *data) 303 { 304 BOOL ret; 305 DWORD err = S_OK; 306 CERT_VERIFY_CERTIFICATE_TRUST *pCert = CRYPTDLG_GetVerifyData(data); 307 308 TRACE("(%p)\n", data); 309 310 if (data->pWintrustData->dwUIChoice != WTD_UI_NONE) 311 FIXME("unimplemented for UI choice %d\n", 312 data->pWintrustData->dwUIChoice); 313 if (pCert) 314 { 315 DWORD flags = 0; 316 CERT_CHAIN_PARA chainPara; 317 HCERTCHAINENGINE engine; 318 319 memset(&chainPara, 0, sizeof(chainPara)); 320 chainPara.cbSize = sizeof(chainPara); 321 if (CRYPTDLG_CheckOnlineCRL()) 322 flags |= CERT_CHAIN_REVOCATION_CHECK_END_CERT; 323 engine = CRYPTDLG_MakeEngine(pCert); 324 GetSystemTimeAsFileTime(&data->sftSystemTime); 325 ret = CRYPTDLG_IsCertAllowed(pCert->pccert); 326 if (ret) 327 { 328 PCCERT_CHAIN_CONTEXT chain; 329 330 ret = CertGetCertificateChain(engine, pCert->pccert, 331 &data->sftSystemTime, NULL, &chainPara, flags, NULL, &chain); 332 if (ret) 333 { 334 if (chain->cChain != 1) 335 { 336 FIXME("unimplemented for more than 1 simple chain\n"); 337 err = TRUST_E_SUBJECT_FORM_UNKNOWN; 338 ret = FALSE; 339 } 340 else if ((ret = CRYPTDLG_CopyChain(data, chain))) 341 { 342 if (CertVerifyTimeValidity(&data->sftSystemTime, 343 pCert->pccert->pCertInfo)) 344 { 345 ret = FALSE; 346 err = CERT_E_EXPIRED; 347 } 348 } 349 else 350 err = TRUST_E_SYSTEM_ERROR; 351 CertFreeCertificateChain(chain); 352 } 353 else 354 err = TRUST_E_SUBJECT_NOT_TRUSTED; 355 } 356 CertFreeCertificateChainEngine(engine); 357 } 358 else 359 { 360 ret = FALSE; 361 err = TRUST_E_NOSIGNATURE; 362 } 363 /* Oddly, native doesn't set the error in the trust step error location, 364 * probably because this action is more advisory than anything else. 365 * Instead it stores it as the final error, but the function "succeeds" in 366 * any case. 367 */ 368 if (!ret) 369 data->dwFinalError = err; 370 TRACE("returning %d (%08x)\n", S_OK, data->dwFinalError); 371 return S_OK; 372 } 373 374 /*********************************************************************** 375 * CertViewPropertiesA (CRYPTDLG.@) 376 */ 377 BOOL WINAPI CertViewPropertiesA(CERT_VIEWPROPERTIES_STRUCT_A *info) 378 { 379 CERT_VIEWPROPERTIES_STRUCT_W infoW; 380 LPWSTR title = NULL; 381 BOOL ret; 382 383 TRACE("(%p)\n", info); 384 385 memcpy(&infoW, info, sizeof(infoW)); 386 if (info->szTitle) 387 { 388 int len = MultiByteToWideChar(CP_ACP, 0, info->szTitle, -1, NULL, 0); 389 390 title = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 391 if (title) 392 { 393 MultiByteToWideChar(CP_ACP, 0, info->szTitle, -1, title, len); 394 infoW.szTitle = title; 395 } 396 else 397 { 398 ret = FALSE; 399 goto error; 400 } 401 } 402 ret = CertViewPropertiesW(&infoW); 403 HeapFree(GetProcessHeap(), 0, title); 404 error: 405 return ret; 406 } 407 408 /*********************************************************************** 409 * CertViewPropertiesW (CRYPTDLG.@) 410 */ 411 BOOL WINAPI CertViewPropertiesW(CERT_VIEWPROPERTIES_STRUCT_W *info) 412 { 413 static GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY; 414 CERT_VERIFY_CERTIFICATE_TRUST trust; 415 WINTRUST_BLOB_INFO blob; 416 WINTRUST_DATA wtd; 417 LONG err; 418 BOOL ret; 419 420 TRACE("(%p)\n", info); 421 422 memset(&trust, 0, sizeof(trust)); 423 trust.cbSize = sizeof(trust); 424 trust.pccert = info->pCertContext; 425 trust.cRootStores = info->cRootStores; 426 trust.rghstoreRoots = info->rghstoreRoots; 427 trust.cStores = info->cStores; 428 trust.rghstoreCAs = info->rghstoreCAs; 429 trust.cTrustStores = info->cTrustStores; 430 trust.rghstoreTrust = info->rghstoreTrust; 431 memset(&blob, 0, sizeof(blob)); 432 blob.cbStruct = sizeof(blob); 433 blob.cbMemObject = sizeof(trust); 434 blob.pbMemObject = (BYTE *)&trust; 435 memset(&wtd, 0, sizeof(wtd)); 436 wtd.cbStruct = sizeof(wtd); 437 wtd.dwUIChoice = WTD_UI_NONE; 438 wtd.dwUnionChoice = WTD_CHOICE_BLOB; 439 wtd.u.pBlob = &blob; 440 wtd.dwStateAction = WTD_STATEACTION_VERIFY; 441 err = WinVerifyTrust(NULL, &cert_action_verify, &wtd); 442 if (err == ERROR_SUCCESS) 443 { 444 CRYPTUI_VIEWCERTIFICATE_STRUCTW uiInfo; 445 BOOL propsChanged = FALSE; 446 447 memset(&uiInfo, 0, sizeof(uiInfo)); 448 uiInfo.dwSize = sizeof(uiInfo); 449 uiInfo.hwndParent = info->hwndParent; 450 uiInfo.dwFlags = 451 CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_ENABLE_EDITPROPERTIES; 452 uiInfo.szTitle = info->szTitle; 453 uiInfo.pCertContext = info->pCertContext; 454 uiInfo.cPurposes = info->cArrayPurposes; 455 uiInfo.rgszPurposes = (LPCSTR *)info->arrayPurposes; 456 uiInfo.u.hWVTStateData = wtd.hWVTStateData; 457 uiInfo.fpCryptProviderDataTrustedUsage = TRUE; 458 uiInfo.cPropSheetPages = info->cArrayPropSheetPages; 459 uiInfo.rgPropSheetPages = info->arrayPropSheetPages; 460 uiInfo.nStartPage = info->nStartPage; 461 ret = CryptUIDlgViewCertificateW(&uiInfo, &propsChanged); 462 wtd.dwStateAction = WTD_STATEACTION_CLOSE; 463 WinVerifyTrust(NULL, &cert_action_verify, &wtd); 464 } 465 else 466 ret = FALSE; 467 return ret; 468 } 469 470 static BOOL CRYPT_FormatHexString(const BYTE *pbEncoded, DWORD cbEncoded, 471 WCHAR *str, DWORD *pcchStr) 472 { 473 BOOL ret; 474 DWORD charsNeeded; 475 476 if (cbEncoded) 477 charsNeeded = (cbEncoded * 3); 478 else 479 charsNeeded = 1; 480 if (!str) 481 { 482 *pcchStr = charsNeeded; 483 ret = TRUE; 484 } 485 else if (*pcchStr < charsNeeded) 486 { 487 *pcchStr = charsNeeded; 488 SetLastError(ERROR_MORE_DATA); 489 ret = FALSE; 490 } 491 else 492 { 493 static const WCHAR fmt[] = { '%','0','2','x',' ',0 }; 494 static const WCHAR endFmt[] = { '%','0','2','x',0 }; 495 DWORD i; 496 LPWSTR ptr = str; 497 498 *pcchStr = charsNeeded; 499 if (cbEncoded) 500 { 501 for (i = 0; i < cbEncoded; i++) 502 { 503 if (i < cbEncoded - 1) 504 ptr += swprintf(ptr, fmt, pbEncoded[i]); 505 else 506 ptr += swprintf(ptr, endFmt, pbEncoded[i]); 507 } 508 } 509 else 510 *ptr = 0; 511 ret = TRUE; 512 } 513 return ret; 514 } 515 516 static const WCHAR indent[] = { ' ',' ',' ',' ',' ',0 }; 517 static const WCHAR colonCrlf[] = { ':','\r','\n',0 }; 518 static const WCHAR colonSpace[] = { ':',' ',0 }; 519 static const WCHAR crlf[] = { '\r','\n',0 }; 520 static const WCHAR commaSep[] = { ',',' ',0 }; 521 522 static BOOL CRYPT_FormatCPS(DWORD dwCertEncodingType, 523 DWORD dwFormatStrType, const BYTE *pbEncoded, DWORD cbEncoded, 524 WCHAR *str, DWORD *pcchStr) 525 { 526 BOOL ret; 527 DWORD size, charsNeeded = 1; 528 CERT_NAME_VALUE *cpsValue; 529 530 if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_UNICODE_ANY_STRING, 531 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &cpsValue, &size))) 532 { 533 LPCWSTR sep; 534 DWORD sepLen; 535 536 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 537 sep = crlf; 538 else 539 sep = commaSep; 540 541 sepLen = lstrlenW(sep); 542 543 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 544 { 545 charsNeeded += 3 * lstrlenW(indent); 546 if (str && *pcchStr >= charsNeeded) 547 { 548 lstrcpyW(str, indent); 549 str += lstrlenW(indent); 550 lstrcpyW(str, indent); 551 str += lstrlenW(indent); 552 lstrcpyW(str, indent); 553 str += lstrlenW(indent); 554 } 555 } 556 charsNeeded += cpsValue->Value.cbData / sizeof(WCHAR); 557 if (str && *pcchStr >= charsNeeded) 558 { 559 lstrcpyW(str, (LPWSTR)cpsValue->Value.pbData); 560 str += cpsValue->Value.cbData / sizeof(WCHAR); 561 } 562 charsNeeded += sepLen; 563 if (str && *pcchStr >= charsNeeded) 564 { 565 lstrcpyW(str, sep); 566 str += sepLen; 567 } 568 LocalFree(cpsValue); 569 if (!str) 570 *pcchStr = charsNeeded; 571 else if (*pcchStr < charsNeeded) 572 { 573 *pcchStr = charsNeeded; 574 SetLastError(ERROR_MORE_DATA); 575 ret = FALSE; 576 } 577 else 578 *pcchStr = charsNeeded; 579 } 580 return ret; 581 } 582 583 static BOOL CRYPT_FormatUserNotice(DWORD dwCertEncodingType, 584 DWORD dwFormatStrType, const BYTE *pbEncoded, DWORD cbEncoded, 585 WCHAR *str, DWORD *pcchStr) 586 { 587 BOOL ret; 588 DWORD size, charsNeeded = 1; 589 CERT_POLICY_QUALIFIER_USER_NOTICE *notice; 590 591 if ((ret = CryptDecodeObjectEx(dwCertEncodingType, 592 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, pbEncoded, cbEncoded, 593 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size))) 594 { 595 static const WCHAR numFmt[] = { '%','d',0 }; 596 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE *pNoticeRef = 597 notice->pNoticeReference; 598 LPCWSTR headingSep, sep; 599 DWORD headingSepLen, sepLen; 600 LPWSTR noticeRef, organization, noticeNum, noticeText; 601 DWORD noticeRefLen, organizationLen, noticeNumLen, noticeTextLen; 602 WCHAR noticeNumStr[11]; 603 604 noticeRefLen = LoadStringW(hInstance, IDS_NOTICE_REF, 605 (LPWSTR)¬iceRef, 0); 606 organizationLen = LoadStringW(hInstance, IDS_ORGANIZATION, 607 (LPWSTR)&organization, 0); 608 noticeNumLen = LoadStringW(hInstance, IDS_NOTICE_NUM, 609 (LPWSTR)¬iceNum, 0); 610 noticeTextLen = LoadStringW(hInstance, IDS_NOTICE_TEXT, 611 (LPWSTR)¬iceText, 0); 612 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 613 { 614 headingSep = colonCrlf; 615 sep = crlf; 616 } 617 else 618 { 619 headingSep = colonSpace; 620 sep = commaSep; 621 } 622 sepLen = lstrlenW(sep); 623 headingSepLen = lstrlenW(headingSep); 624 625 if (pNoticeRef) 626 { 627 DWORD k; 628 LPCSTR src; 629 630 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 631 { 632 charsNeeded += 3 * lstrlenW(indent); 633 if (str && *pcchStr >= charsNeeded) 634 { 635 lstrcpyW(str, indent); 636 str += lstrlenW(indent); 637 lstrcpyW(str, indent); 638 str += lstrlenW(indent); 639 lstrcpyW(str, indent); 640 str += lstrlenW(indent); 641 } 642 } 643 charsNeeded += noticeRefLen; 644 if (str && *pcchStr >= charsNeeded) 645 { 646 memcpy(str, noticeRef, noticeRefLen * sizeof(WCHAR)); 647 str += noticeRefLen; 648 } 649 charsNeeded += headingSepLen; 650 if (str && *pcchStr >= charsNeeded) 651 { 652 lstrcpyW(str, headingSep); 653 str += headingSepLen; 654 } 655 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 656 { 657 charsNeeded += 4 * lstrlenW(indent); 658 if (str && *pcchStr >= charsNeeded) 659 { 660 lstrcpyW(str, indent); 661 str += lstrlenW(indent); 662 lstrcpyW(str, indent); 663 str += lstrlenW(indent); 664 lstrcpyW(str, indent); 665 str += lstrlenW(indent); 666 lstrcpyW(str, indent); 667 str += lstrlenW(indent); 668 } 669 } 670 charsNeeded += organizationLen; 671 if (str && *pcchStr >= charsNeeded) 672 { 673 memcpy(str, organization, organizationLen * sizeof(WCHAR)); 674 str += organizationLen; 675 } 676 charsNeeded += strlen(pNoticeRef->pszOrganization); 677 if (str && *pcchStr >= charsNeeded) 678 for (src = pNoticeRef->pszOrganization; src && *src; 679 src++, str++) 680 *str = *src; 681 charsNeeded += sepLen; 682 if (str && *pcchStr >= charsNeeded) 683 { 684 lstrcpyW(str, sep); 685 str += sepLen; 686 } 687 for (k = 0; k < pNoticeRef->cNoticeNumbers; k++) 688 { 689 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 690 { 691 charsNeeded += 4 * lstrlenW(indent); 692 if (str && *pcchStr >= charsNeeded) 693 { 694 lstrcpyW(str, indent); 695 str += lstrlenW(indent); 696 lstrcpyW(str, indent); 697 str += lstrlenW(indent); 698 lstrcpyW(str, indent); 699 str += lstrlenW(indent); 700 lstrcpyW(str, indent); 701 str += lstrlenW(indent); 702 } 703 } 704 charsNeeded += noticeNumLen; 705 if (str && *pcchStr >= charsNeeded) 706 { 707 memcpy(str, noticeNum, noticeNumLen * sizeof(WCHAR)); 708 str += noticeNumLen; 709 } 710 swprintf(noticeNumStr, numFmt, k + 1); 711 charsNeeded += lstrlenW(noticeNumStr); 712 if (str && *pcchStr >= charsNeeded) 713 { 714 lstrcpyW(str, noticeNumStr); 715 str += lstrlenW(noticeNumStr); 716 } 717 charsNeeded += sepLen; 718 if (str && *pcchStr >= charsNeeded) 719 { 720 lstrcpyW(str, sep); 721 str += sepLen; 722 } 723 } 724 } 725 if (notice->pszDisplayText) 726 { 727 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 728 { 729 charsNeeded += 3 * lstrlenW(indent); 730 if (str && *pcchStr >= charsNeeded) 731 { 732 lstrcpyW(str, indent); 733 str += lstrlenW(indent); 734 lstrcpyW(str, indent); 735 str += lstrlenW(indent); 736 lstrcpyW(str, indent); 737 str += lstrlenW(indent); 738 } 739 } 740 charsNeeded += noticeTextLen; 741 if (str && *pcchStr >= charsNeeded) 742 { 743 memcpy(str, noticeText, noticeTextLen * sizeof(WCHAR)); 744 str += noticeTextLen; 745 } 746 charsNeeded += lstrlenW(notice->pszDisplayText); 747 if (str && *pcchStr >= charsNeeded) 748 { 749 lstrcpyW(str, notice->pszDisplayText); 750 str += lstrlenW(notice->pszDisplayText); 751 } 752 charsNeeded += sepLen; 753 if (str && *pcchStr >= charsNeeded) 754 { 755 lstrcpyW(str, sep); 756 str += sepLen; 757 } 758 } 759 LocalFree(notice); 760 if (!str) 761 *pcchStr = charsNeeded; 762 else if (*pcchStr < charsNeeded) 763 { 764 *pcchStr = charsNeeded; 765 SetLastError(ERROR_MORE_DATA); 766 ret = FALSE; 767 } 768 else 769 *pcchStr = charsNeeded; 770 } 771 return ret; 772 } 773 774 /*********************************************************************** 775 * FormatVerisignExtension (CRYPTDLG.@) 776 */ 777 BOOL WINAPI FormatVerisignExtension(DWORD dwCertEncodingType, 778 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct, 779 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, 780 DWORD *pcbFormat) 781 { 782 CERT_POLICIES_INFO *policies; 783 DWORD size; 784 BOOL ret = FALSE; 785 786 if (!cbEncoded) 787 { 788 SetLastError(E_INVALIDARG); 789 return FALSE; 790 } 791 if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_POLICIES, 792 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size))) 793 { 794 static const WCHAR numFmt[] = { '%','d',0 }; 795 DWORD charsNeeded = 1; /* space for NULL terminator */ 796 LPCWSTR headingSep, sep; 797 DWORD headingSepLen, sepLen; 798 WCHAR policyNum[11], policyQualifierNum[11]; 799 LPWSTR certPolicy, policyId, policyQualifierInfo, policyQualifierId; 800 LPWSTR cps, userNotice, qualifier; 801 DWORD certPolicyLen, policyIdLen, policyQualifierInfoLen; 802 DWORD policyQualifierIdLen, cpsLen, userNoticeLen, qualifierLen; 803 DWORD i; 804 LPWSTR str = pbFormat; 805 806 certPolicyLen = LoadStringW(hInstance, IDS_CERT_POLICY, 807 (LPWSTR)&certPolicy, 0); 808 policyIdLen = LoadStringW(hInstance, IDS_POLICY_ID, (LPWSTR)&policyId, 809 0); 810 policyQualifierInfoLen = LoadStringW(hInstance, 811 IDS_POLICY_QUALIFIER_INFO, (LPWSTR)&policyQualifierInfo, 0); 812 policyQualifierIdLen = LoadStringW(hInstance, IDS_POLICY_QUALIFIER_ID, 813 (LPWSTR)&policyQualifierId, 0); 814 cpsLen = LoadStringW(hInstance, IDS_CPS, (LPWSTR)&cps, 0); 815 userNoticeLen = LoadStringW(hInstance, IDS_USER_NOTICE, 816 (LPWSTR)&userNotice, 0); 817 qualifierLen = LoadStringW(hInstance, IDS_QUALIFIER, 818 (LPWSTR)&qualifier, 0); 819 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 820 { 821 headingSep = colonCrlf; 822 sep = crlf; 823 } 824 else 825 { 826 headingSep = colonSpace; 827 sep = commaSep; 828 } 829 sepLen = lstrlenW(sep); 830 headingSepLen = lstrlenW(headingSep); 831 832 for (i = 0; ret && i < policies->cPolicyInfo; i++) 833 { 834 CERT_POLICY_INFO *policy = &policies->rgPolicyInfo[i]; 835 DWORD j; 836 LPCSTR src; 837 838 charsNeeded += 1; /* '['*/ 839 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 840 *str++ = '['; 841 swprintf(policyNum, numFmt, i + 1); 842 charsNeeded += lstrlenW(policyNum); 843 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 844 { 845 lstrcpyW(str, policyNum); 846 str += lstrlenW(policyNum); 847 } 848 charsNeeded += 1; /* ']'*/ 849 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 850 *str++ = ']'; 851 charsNeeded += certPolicyLen; 852 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 853 { 854 memcpy(str, certPolicy, certPolicyLen * sizeof(WCHAR)); 855 str += certPolicyLen; 856 } 857 charsNeeded += headingSepLen; 858 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 859 { 860 lstrcpyW(str, headingSep); 861 str += headingSepLen; 862 } 863 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 864 { 865 charsNeeded += lstrlenW(indent); 866 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 867 { 868 lstrcpyW(str, indent); 869 str += lstrlenW(indent); 870 } 871 } 872 charsNeeded += policyIdLen; 873 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 874 { 875 memcpy(str, policyId, policyIdLen * sizeof(WCHAR)); 876 str += policyIdLen; 877 } 878 charsNeeded += strlen(policy->pszPolicyIdentifier); 879 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 880 { 881 for (src = policy->pszPolicyIdentifier; src && *src; 882 src++, str++) 883 *str = *src; 884 } 885 charsNeeded += sepLen; 886 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 887 { 888 lstrcpyW(str, sep); 889 str += sepLen; 890 } 891 for (j = 0; j < policy->cPolicyQualifier; j++) 892 { 893 CERT_POLICY_QUALIFIER_INFO *qualifierInfo = 894 &policy->rgPolicyQualifier[j]; 895 DWORD sizeRemaining; 896 897 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 898 { 899 charsNeeded += lstrlenW(indent); 900 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 901 { 902 lstrcpyW(str, indent); 903 str += lstrlenW(indent); 904 } 905 } 906 charsNeeded += 1; /* '['*/ 907 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 908 *str++ = '['; 909 charsNeeded += lstrlenW(policyNum); 910 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 911 { 912 lstrcpyW(str, policyNum); 913 str += lstrlenW(policyNum); 914 } 915 charsNeeded += 1; /* ','*/ 916 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 917 *str++ = ','; 918 swprintf(policyQualifierNum, numFmt, j + 1); 919 charsNeeded += lstrlenW(policyQualifierNum); 920 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 921 { 922 lstrcpyW(str, policyQualifierNum); 923 str += lstrlenW(policyQualifierNum); 924 } 925 charsNeeded += 1; /* ']'*/ 926 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 927 *str++ = ']'; 928 charsNeeded += policyQualifierInfoLen; 929 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 930 { 931 memcpy(str, policyQualifierInfo, 932 policyQualifierInfoLen * sizeof(WCHAR)); 933 str += policyQualifierInfoLen; 934 } 935 charsNeeded += headingSepLen; 936 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 937 { 938 lstrcpyW(str, headingSep); 939 str += headingSepLen; 940 } 941 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 942 { 943 charsNeeded += 2 * lstrlenW(indent); 944 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 945 { 946 lstrcpyW(str, indent); 947 str += lstrlenW(indent); 948 lstrcpyW(str, indent); 949 str += lstrlenW(indent); 950 } 951 } 952 charsNeeded += policyQualifierIdLen; 953 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 954 { 955 memcpy(str, policyQualifierId, 956 policyQualifierIdLen * sizeof(WCHAR)); 957 str += policyQualifierIdLen; 958 } 959 if (!strcmp(qualifierInfo->pszPolicyQualifierId, 960 szOID_PKIX_POLICY_QUALIFIER_CPS)) 961 { 962 charsNeeded += cpsLen; 963 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 964 { 965 memcpy(str, cps, cpsLen * sizeof(WCHAR)); 966 str += cpsLen; 967 } 968 } 969 else if (!strcmp(qualifierInfo->pszPolicyQualifierId, 970 szOID_PKIX_POLICY_QUALIFIER_USERNOTICE)) 971 { 972 charsNeeded += userNoticeLen; 973 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 974 { 975 memcpy(str, userNotice, userNoticeLen * sizeof(WCHAR)); 976 str += userNoticeLen; 977 } 978 } 979 else 980 { 981 charsNeeded += strlen(qualifierInfo->pszPolicyQualifierId); 982 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 983 { 984 for (src = qualifierInfo->pszPolicyQualifierId; 985 src && *src; src++, str++) 986 *str = *src; 987 } 988 } 989 charsNeeded += sepLen; 990 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 991 { 992 lstrcpyW(str, sep); 993 str += sepLen; 994 } 995 if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) 996 { 997 charsNeeded += 2 * lstrlenW(indent); 998 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 999 { 1000 lstrcpyW(str, indent); 1001 str += lstrlenW(indent); 1002 lstrcpyW(str, indent); 1003 str += lstrlenW(indent); 1004 } 1005 } 1006 charsNeeded += qualifierLen; 1007 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 1008 { 1009 memcpy(str, qualifier, qualifierLen * sizeof(WCHAR)); 1010 str += qualifierLen; 1011 } 1012 charsNeeded += headingSepLen; 1013 if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR)) 1014 { 1015 lstrcpyW(str, headingSep); 1016 str += headingSepLen; 1017 } 1018 /* This if block is deliberately redundant with the same if 1019 * block above, in order to keep the code more readable (the 1020 * code flow follows the order in which the strings are output.) 1021 */ 1022 if (!strcmp(qualifierInfo->pszPolicyQualifierId, 1023 szOID_PKIX_POLICY_QUALIFIER_CPS)) 1024 { 1025 if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR)) 1026 { 1027 /* Insufficient space, determine how much is needed. */ 1028 ret = CRYPT_FormatCPS(dwCertEncodingType, 1029 dwFormatStrType, qualifierInfo->Qualifier.pbData, 1030 qualifierInfo->Qualifier.cbData, NULL, &size); 1031 if (ret) 1032 charsNeeded += size - 1; 1033 } 1034 else 1035 { 1036 sizeRemaining = *pcbFormat / sizeof(WCHAR); 1037 sizeRemaining -= str - (LPWSTR)pbFormat; 1038 ret = CRYPT_FormatCPS(dwCertEncodingType, 1039 dwFormatStrType, qualifierInfo->Qualifier.pbData, 1040 qualifierInfo->Qualifier.cbData, str, &sizeRemaining); 1041 if (ret || GetLastError() == ERROR_MORE_DATA) 1042 { 1043 charsNeeded += sizeRemaining - 1; 1044 str += sizeRemaining - 1; 1045 } 1046 } 1047 } 1048 else if (!strcmp(qualifierInfo->pszPolicyQualifierId, 1049 szOID_PKIX_POLICY_QUALIFIER_USERNOTICE)) 1050 { 1051 if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR)) 1052 { 1053 /* Insufficient space, determine how much is needed. */ 1054 ret = CRYPT_FormatUserNotice(dwCertEncodingType, 1055 dwFormatStrType, qualifierInfo->Qualifier.pbData, 1056 qualifierInfo->Qualifier.cbData, NULL, &size); 1057 if (ret) 1058 charsNeeded += size - 1; 1059 } 1060 else 1061 { 1062 sizeRemaining = *pcbFormat / sizeof(WCHAR); 1063 sizeRemaining -= str - (LPWSTR)pbFormat; 1064 ret = CRYPT_FormatUserNotice(dwCertEncodingType, 1065 dwFormatStrType, qualifierInfo->Qualifier.pbData, 1066 qualifierInfo->Qualifier.cbData, str, &sizeRemaining); 1067 if (ret || GetLastError() == ERROR_MORE_DATA) 1068 { 1069 charsNeeded += sizeRemaining - 1; 1070 str += sizeRemaining - 1; 1071 } 1072 } 1073 } 1074 else 1075 { 1076 if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR)) 1077 { 1078 /* Insufficient space, determine how much is needed. */ 1079 ret = CRYPT_FormatHexString( 1080 qualifierInfo->Qualifier.pbData, 1081 qualifierInfo->Qualifier.cbData, NULL, &size); 1082 if (ret) 1083 charsNeeded += size - 1; 1084 } 1085 else 1086 { 1087 sizeRemaining = *pcbFormat / sizeof(WCHAR); 1088 sizeRemaining -= str - (LPWSTR)pbFormat; 1089 ret = CRYPT_FormatHexString( 1090 qualifierInfo->Qualifier.pbData, 1091 qualifierInfo->Qualifier.cbData, str, &sizeRemaining); 1092 if (ret || GetLastError() == ERROR_MORE_DATA) 1093 { 1094 charsNeeded += sizeRemaining - 1; 1095 str += sizeRemaining - 1; 1096 } 1097 } 1098 } 1099 } 1100 } 1101 LocalFree(policies); 1102 if (ret) 1103 { 1104 if (!pbFormat) 1105 *pcbFormat = charsNeeded * sizeof(WCHAR); 1106 else if (*pcbFormat < charsNeeded * sizeof(WCHAR)) 1107 { 1108 *pcbFormat = charsNeeded * sizeof(WCHAR); 1109 SetLastError(ERROR_MORE_DATA); 1110 ret = FALSE; 1111 } 1112 else 1113 *pcbFormat = charsNeeded * sizeof(WCHAR); 1114 } 1115 } 1116 return ret; 1117 } 1118 1119 #define szOID_MICROSOFT_Encryption_Key_Preference "1.3.6.1.4.1.311.16.4" 1120 1121 /*********************************************************************** 1122 * DllRegisterServer (CRYPTDLG.@) 1123 */ 1124 HRESULT WINAPI DllRegisterServer(void) 1125 { 1126 static WCHAR cryptdlg[] = { 'c','r','y','p','t','d','l','g','.', 1127 'd','l','l',0 }; 1128 static WCHAR wintrust[] = { 'w','i','n','t','r','u','s','t','.', 1129 'd','l','l',0 }; 1130 static WCHAR certTrustInit[] = { 'C','e','r','t','T','r','u','s','t', 1131 'I','n','i','t',0 }; 1132 static WCHAR wintrustCertificateTrust[] = { 'W','i','n','t','r','u','s','t', 1133 'C','e','r','t','i','f','i','c','a','t','e','T','r','u','s','t',0 }; 1134 static WCHAR certTrustCertPolicy[] = { 'C','e','r','t','T','r','u','s','t', 1135 'C','e','r','t','P','o','l','i','c','y',0 }; 1136 static WCHAR certTrustFinalPolicy[] = { 'C','e','r','t','T','r','u','s','t', 1137 'F','i','n','a','l','P','o','l','i','c','y',0 }; 1138 static WCHAR certTrustCleanup[] = { 'C','e','r','t','T','r','u','s','t', 1139 'C','l','e','a','n','u','p',0 }; 1140 static const WCHAR cryptDlg[] = { 'c','r','y','p','t','d','l','g','.', 1141 'd','l','l',0 }; 1142 CRYPT_REGISTER_ACTIONID reg; 1143 GUID guid = CERT_CERTIFICATE_ACTION_VERIFY; 1144 HRESULT hr = S_OK; 1145 1146 memset(®, 0, sizeof(reg)); 1147 reg.cbStruct = sizeof(reg); 1148 reg.sInitProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY); 1149 reg.sInitProvider.pwszDLLName = cryptdlg; 1150 reg.sInitProvider.pwszFunctionName = certTrustInit; 1151 reg.sCertificateProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY); 1152 reg.sCertificateProvider.pwszDLLName = wintrust; 1153 reg.sCertificateProvider.pwszFunctionName = wintrustCertificateTrust; 1154 reg.sCertificatePolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY); 1155 reg.sCertificatePolicyProvider.pwszDLLName = cryptdlg; 1156 reg.sCertificatePolicyProvider.pwszFunctionName = certTrustCertPolicy; 1157 reg.sFinalPolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY); 1158 reg.sFinalPolicyProvider.pwszDLLName = cryptdlg; 1159 reg.sFinalPolicyProvider.pwszFunctionName = certTrustFinalPolicy; 1160 reg.sCleanupProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY); 1161 reg.sCleanupProvider.pwszDLLName = cryptdlg; 1162 reg.sCleanupProvider.pwszFunctionName = certTrustCleanup; 1163 if (!WintrustAddActionID(&guid, WT_ADD_ACTION_ID_RET_RESULT_FLAG, ®)) 1164 hr = GetLastError(); 1165 CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC, 1166 "1.3.6.1.4.1.311.16.1.1", cryptDlg, "EncodeAttrSequence"); 1167 CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC, 1168 szOID_MICROSOFT_Encryption_Key_Preference, cryptDlg, "EncodeRecipientID"); 1169 CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC, 1170 "1.3.6.1.4.1.311.16.1.1", cryptDlg, "DecodeAttrSequence"); 1171 CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC, 1172 szOID_MICROSOFT_Encryption_Key_Preference, cryptDlg, "DecodeRecipientID"); 1173 CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC, 1174 szOID_PKIX_KP_EMAIL_PROTECTION, cryptDlg, "FormatPKIXEmailProtection"); 1175 CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC, 1176 szOID_CERT_POLICIES, cryptDlg, "FormatVerisignExtension"); 1177 return hr; 1178 } 1179 1180 /*********************************************************************** 1181 * DllUnregisterServer (CRYPTDLG.@) 1182 */ 1183 HRESULT WINAPI DllUnregisterServer(void) 1184 { 1185 GUID guid = CERT_CERTIFICATE_ACTION_VERIFY; 1186 1187 WintrustRemoveActionID(&guid); 1188 CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC, 1189 "1.3.6.1.4.1.311.16.1.1"); 1190 CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC, 1191 szOID_MICROSOFT_Encryption_Key_Preference); 1192 CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC, 1193 "1.3.6.1.4.1.311.16.1.1"); 1194 CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC, 1195 szOID_MICROSOFT_Encryption_Key_Preference); 1196 CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC, 1197 szOID_PKIX_KP_EMAIL_PROTECTION); 1198 CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC, 1199 szOID_CERT_POLICIES); 1200 return S_OK; 1201 } 1202