Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

736 lines
20 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: trustapi.cpp
  8. //
  9. // Contents: Microsoft Internet Security Trust APIs
  10. //
  11. // Functions: TrustFindIssuerCertificate
  12. // TrustOpenStores
  13. // TrustDecode
  14. // TrustFreeDecode
  15. //
  16. // *** local functions ***
  17. // _CompareAuthKeyId
  18. // _CompareAuthKeyId2
  19. // _SetCertErrorAndHygiene
  20. // _GetExternalIssuerCert
  21. //
  22. // History: 20-Nov-1997 pberkman created
  23. //
  24. //--------------------------------------------------------------------------
  25. #include "global.hxx"
  26. BOOL _CompareAuthKeyId(DWORD dwEncoding, PCCERT_CONTEXT pChildContext,
  27. PCCERT_CONTEXT pParentContext);
  28. BOOL _CompareAuthKeyId2(DWORD dwEncoding, PCCERT_CONTEXT pChildContext,
  29. PCCERT_CONTEXT pParentContext);
  30. BOOL _SetCertErrorAndHygiene(PCCERT_CONTEXT pSubjectContext,
  31. PCCERT_CONTEXT pIssuerContext,
  32. DWORD dwCurrentConfidence, DWORD *pdwError);
  33. PCCERT_CONTEXT _GetExternalIssuerCert(PCCERT_CONTEXT pContext,
  34. DWORD dwEncoding,
  35. DWORD *pdwRetError,
  36. DWORD *pdwConfidence,
  37. FILETIME *psftVerifyAsOf);
  38. void _SetConfidenceOnIssuer(DWORD dwEncoding, PCCERT_CONTEXT pChildCert, PCCERT_CONTEXT pTestIssuerCert,
  39. DWORD dwVerificationFlag, FILETIME *psftVerifyAsOf, DWORD *pdwConfidence,
  40. DWORD *pdwError);
  41. PCCERT_CONTEXT WINAPI TrustFindIssuerCertificate(PCCERT_CONTEXT pChildContext,
  42. DWORD dwEncoding,
  43. DWORD chStores,
  44. HCERTSTORE *pahStores,
  45. FILETIME *psftVerifyAsOf,
  46. DWORD *pdwConfidence,
  47. DWORD *pdwError,
  48. DWORD dwFlags)
  49. {
  50. if (!(pChildContext) ||
  51. !(pahStores) ||
  52. !(psftVerifyAsOf) ||
  53. (dwFlags != 0))
  54. {
  55. SetLastError(ERROR_INVALID_PARAMETER);
  56. return(NULL);
  57. }
  58. PCCERT_CONTEXT pCertContext;
  59. DWORD fdwRetError;
  60. DWORD fdwWork;
  61. DWORD dwError;
  62. PCCERT_CONTEXT pCertWithHighestConfidence;
  63. DWORD dwHighestConfidence;
  64. DWORD dwConfidence;
  65. if (pdwError)
  66. {
  67. *pdwError = ERROR_SUCCESS;
  68. }
  69. dwConfidence = 0;
  70. dwHighestConfidence = 0;
  71. pCertWithHighestConfidence = NULL;
  72. fdwRetError = 0;
  73. fdwWork = 0;
  74. for (int i = 0; i < (int)chStores; i++)
  75. {
  76. fdwWork = CERT_STORE_SIGNATURE_FLAG;
  77. pCertContext = NULL;
  78. while (pCertContext = CertGetIssuerCertificateFromStore(pahStores[i],
  79. pChildContext,
  80. pCertContext,
  81. &fdwWork))
  82. {
  83. _SetConfidenceOnIssuer(dwEncoding, pChildContext, pCertContext, fdwWork,
  84. psftVerifyAsOf, &dwConfidence, &dwError);
  85. if (dwConfidence > dwHighestConfidence)
  86. {
  87. if (pCertWithHighestConfidence)
  88. {
  89. CertFreeCertificateContext(pCertWithHighestConfidence);
  90. }
  91. dwHighestConfidence = dwConfidence;
  92. pCertWithHighestConfidence = CertDuplicateCertificateContext(pCertContext);
  93. fdwRetError = dwError;
  94. }
  95. if (dwConfidence >= CERT_CONFIDENCE_HIGHEST)
  96. {
  97. if (pdwError)
  98. {
  99. *pdwError = dwError;
  100. }
  101. if (pdwConfidence)
  102. {
  103. *pdwConfidence = dwConfidence;
  104. }
  105. CertFreeCertificateContext(pCertContext);
  106. return(pCertWithHighestConfidence);
  107. }
  108. fdwWork = CERT_STORE_SIGNATURE_FLAG;
  109. }
  110. }
  111. if (!(dwHighestConfidence & CERT_CONFIDENCE_HYGIENE))
  112. {
  113. if (pCertContext = _GetExternalIssuerCert(pChildContext,
  114. dwEncoding,
  115. &fdwRetError,
  116. &dwConfidence,
  117. psftVerifyAsOf))
  118. {
  119. if (dwHighestConfidence < dwConfidence)
  120. {
  121. CertFreeCertificateContext(pCertWithHighestConfidence);
  122. pCertWithHighestConfidence = pCertContext;
  123. dwHighestConfidence = dwConfidence;
  124. }
  125. }
  126. }
  127. if (pdwError)
  128. {
  129. *pdwError = fdwRetError;
  130. }
  131. if (pdwConfidence)
  132. {
  133. *pdwConfidence = dwHighestConfidence;
  134. }
  135. return(pCertWithHighestConfidence);
  136. }
  137. BOOL WINAPI TrustOpenStores(HCRYPTPROV hProv, OUT DWORD *pchStores,
  138. HCERTSTORE *pahStores, DWORD dwFlags)
  139. {
  140. BOOL fRet;
  141. DWORD cs = 0;
  142. HCERTSTORE pas[WVT_STOREID_MAX];
  143. fRet = FALSE;
  144. if (!(pchStores) ||
  145. (dwFlags != 0))
  146. {
  147. goto ErrorInvalidParam;
  148. }
  149. //
  150. // ROOT store - ALWAYS #0 !!!!
  151. //
  152. if (!(pas[cs] = StoreProviderGetStore(hProv, WVT_STOREID_ROOT)))
  153. {
  154. goto ErrorNoRootStore;
  155. }
  156. cs++;
  157. if (pas[cs] = StoreProviderGetStore(hProv, WVT_STOREID_TRUST))
  158. {
  159. cs++;
  160. }
  161. if (pas[cs] = StoreProviderGetStore(hProv, WVT_STOREID_CA))
  162. {
  163. cs++;
  164. }
  165. if (pas[cs] = StoreProviderGetStore(hProv, WVT_STOREID_MY))
  166. {
  167. cs++;
  168. }
  169. if ((pahStores) && (cs > *pchStores))
  170. {
  171. *pchStores = cs;
  172. goto ErrorMoreData;
  173. }
  174. *pchStores = cs;
  175. fRet = TRUE;
  176. if (!(pahStores))
  177. {
  178. goto ErrorMoreData;
  179. }
  180. DWORD i;
  181. for (i = 0; i < cs; i++)
  182. {
  183. pahStores[i] = pas[i];
  184. }
  185. CommonReturn:
  186. return(fRet);
  187. ErrorReturn:
  188. while (cs > 0)
  189. {
  190. CertCloseStore(pas[cs - 1], 0);
  191. cs--;
  192. }
  193. goto CommonReturn;
  194. SET_ERROR_VAR_EX(DBG_SS, ErrorMoreData, ERROR_MORE_DATA);
  195. SET_ERROR_VAR_EX(DBG_SS, ErrorNoRootStore, TRUST_E_SYSTEM_ERROR);
  196. SET_ERROR_VAR_EX(DBG_SS, ErrorInvalidParam, ERROR_INVALID_PARAMETER);
  197. }
  198. BOOL WINAPI TrustIsCertificateSelfSigned(PCCERT_CONTEXT pContext,
  199. DWORD dwEncoding,
  200. DWORD dwFlags)
  201. {
  202. if (!(pContext) ||
  203. (dwFlags != 0))
  204. {
  205. SetLastError(ERROR_INVALID_PARAMETER);
  206. return(FALSE);
  207. }
  208. if (!(CertCompareCertificateName(dwEncoding,
  209. &pContext->pCertInfo->Issuer,
  210. &pContext->pCertInfo->Subject)))
  211. {
  212. return(FALSE);
  213. }
  214. DWORD dwFlag;
  215. dwFlag = CERT_STORE_SIGNATURE_FLAG;
  216. if (!(CertVerifySubjectCertificateContext(pContext, pContext, &dwFlag)) ||
  217. (dwFlag & CERT_STORE_SIGNATURE_FLAG))
  218. {
  219. return(FALSE);
  220. }
  221. return(TRUE);
  222. }
  223. #define sz_CRYPTNET_DLL "cryptnet.dll"
  224. #define sz_CryptGetObjectUrl "CryptGetObjectUrl"
  225. #define sz_CryptRetrieveObjectByUrlW "CryptRetrieveObjectByUrlW"
  226. typedef BOOL (WINAPI *PFN_CRYPT_GET_OBJECT_URL)(
  227. IN LPCSTR pszUrlOid,
  228. IN LPVOID pvPara,
  229. IN DWORD dwFlags,
  230. OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray,
  231. IN OUT DWORD* pcbUrlArray,
  232. OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo,
  233. IN OUT OPTIONAL DWORD* pcbUrlInfo,
  234. IN OPTIONAL LPVOID pvReserved
  235. );
  236. typedef BOOL (WINAPI *PFN_CRYPT_RETRIEVE_OBJECT_BY_URLW)(
  237. IN LPCWSTR pszUrl,
  238. IN LPCSTR pszObjectOid,
  239. IN DWORD dwRetrievalFlags,
  240. IN DWORD dwTimeout,
  241. OUT LPVOID* ppvObject,
  242. IN HCRYPTASYNC hAsyncRetrieve,
  243. IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
  244. IN OPTIONAL LPVOID pvVerify,
  245. IN OPTIONAL LPVOID pvReserved
  246. );
  247. PCCERT_CONTEXT _GetExternalIssuerCert(PCCERT_CONTEXT pContext,
  248. DWORD dwEncoding,
  249. DWORD *pdwRetError,
  250. DWORD *pdwConfidence,
  251. FILETIME *psftVerifyAsOf)
  252. {
  253. *pdwConfidence = 0;
  254. #if (USE_IEv4CRYPT32)
  255. return(NULL);
  256. #else
  257. DWORD cbUrlArray;
  258. CRYPT_URL_ARRAY *pUrlArray;
  259. PCCERT_CONTEXT pIssuer;
  260. PCCERT_CONTEXT pCertBestMatch;
  261. DWORD dwHighestConfidence;
  262. DWORD dwConfidence;
  263. DWORD dwStatus;
  264. DWORD dwError;
  265. DWORD i;
  266. pCertBestMatch = NULL;
  267. pIssuer = NULL;
  268. pUrlArray = NULL;
  269. cbUrlArray = 0;
  270. dwHighestConfidence = 0;
  271. HMODULE hDll = NULL;
  272. PFN_CRYPT_GET_OBJECT_URL pfnCryptGetObjectUrl;
  273. PFN_CRYPT_RETRIEVE_OBJECT_BY_URLW pfnCryptRetrieveObjectByUrlW;
  274. if (NULL == (hDll = LoadLibraryA(sz_CRYPTNET_DLL)))
  275. goto LoadCryptNetDllError;
  276. if (NULL == (pfnCryptGetObjectUrl =
  277. (PFN_CRYPT_GET_OBJECT_URL) GetProcAddress(hDll,
  278. sz_CryptGetObjectUrl)))
  279. goto CryptGetObjectUrlProcAddressError;
  280. if (NULL == (pfnCryptRetrieveObjectByUrlW =
  281. (PFN_CRYPT_RETRIEVE_OBJECT_BY_URLW) GetProcAddress(hDll,
  282. sz_CryptRetrieveObjectByUrlW)))
  283. goto CryptRetrieveObjectByUrlWProcAddressError;
  284. if (!(pfnCryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER, (void *)pContext, 0, NULL, &cbUrlArray, NULL, NULL, NULL)) ||
  285. (cbUrlArray < 1))
  286. {
  287. goto GetObjectUrlFailed;
  288. }
  289. if (!(pUrlArray = (CRYPT_URL_ARRAY *) new BYTE[cbUrlArray]))
  290. {
  291. goto MemoryError;
  292. }
  293. memset(pUrlArray, 0x00, cbUrlArray);
  294. if (!(pfnCryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER, (void *)pContext, 0, pUrlArray, &cbUrlArray, NULL, NULL, NULL)))
  295. {
  296. goto GetObjectUrlFailed;
  297. }
  298. for (i = 0; i < pUrlArray->cUrl; i++)
  299. {
  300. if (pIssuer)
  301. {
  302. CertFreeCertificateContext(pIssuer);
  303. pIssuer = NULL;
  304. }
  305. if (pfnCryptRetrieveObjectByUrlW(pUrlArray->rgwszUrl[i], CONTEXT_OID_CERTIFICATE, 0, 0, (void **)&pIssuer,
  306. NULL, NULL, NULL, NULL))
  307. {
  308. if (!(CertCompareCertificateName(X509_ASN_ENCODING, &pContext->pCertInfo->Issuer,
  309. &pIssuer->pCertInfo->Subject)))
  310. {
  311. continue;
  312. }
  313. dwStatus = CERT_STORE_SIGNATURE_FLAG;
  314. if (!(CertVerifySubjectCertificateContext(pContext, pIssuer, &dwStatus)))
  315. {
  316. continue;
  317. }
  318. dwError = 0;
  319. _SetConfidenceOnIssuer(dwEncoding, pContext, pIssuer, dwStatus, psftVerifyAsOf,
  320. &dwConfidence, &dwError);
  321. if (dwError != 0)
  322. {
  323. continue;
  324. }
  325. if (dwConfidence > dwHighestConfidence)
  326. {
  327. if (pCertBestMatch)
  328. {
  329. CertFreeCertificateContext(pCertBestMatch);
  330. }
  331. dwHighestConfidence = dwConfidence;
  332. pCertBestMatch = CertDuplicateCertificateContext(pIssuer);
  333. }
  334. if (dwConfidence >= CERT_CONFIDENCE_HIGHEST)
  335. {
  336. goto CommonReturn;
  337. }
  338. }
  339. }
  340. goto RetrieveObjectFailed;
  341. CommonReturn:
  342. if (hDll)
  343. FreeLibrary(hDll);
  344. if (pIssuer)
  345. {
  346. CertFreeCertificateContext(pIssuer);
  347. }
  348. if (pUrlArray)
  349. {
  350. delete pUrlArray;
  351. }
  352. *pdwConfidence = dwHighestConfidence;
  353. return(pCertBestMatch);
  354. ErrorReturn:
  355. if (pCertBestMatch)
  356. {
  357. CertFreeCertificateContext(pCertBestMatch);
  358. pCertBestMatch = NULL;
  359. }
  360. goto CommonReturn;
  361. TRACE_ERROR_EX(DBG_SS, LoadCryptNetDllError)
  362. TRACE_ERROR_EX(DBG_SS, CryptGetObjectUrlProcAddressError)
  363. TRACE_ERROR_EX(DBG_SS, CryptRetrieveObjectByUrlWProcAddressError)
  364. TRACE_ERROR_EX(DBG_SS, GetObjectUrlFailed);
  365. TRACE_ERROR_EX(DBG_SS, RetrieveObjectFailed);
  366. SET_ERROR_VAR_EX(DBG_SS, MemoryError, ERROR_NOT_ENOUGH_MEMORY);
  367. #endif // USE_IEv4CRYPT32
  368. }
  369. BOOL WINAPI TrustDecode(DWORD dwModuleId, BYTE **ppbRet, DWORD *pcbRet, DWORD cbHint,
  370. DWORD dwEncoding, const char *pcszOID, const BYTE *pbEncoded, DWORD cbEncoded,
  371. DWORD dwDecodeFlags)
  372. {
  373. if (!(*ppbRet = new BYTE[cbHint]))
  374. {
  375. goto MemoryError;
  376. }
  377. *pcbRet = cbHint;
  378. if (!(CryptDecodeObject(dwEncoding, pcszOID, pbEncoded, cbEncoded, dwDecodeFlags,
  379. *ppbRet, pcbRet)))
  380. {
  381. if (GetLastError() != ERROR_MORE_DATA)
  382. {
  383. goto DecodeError;
  384. }
  385. }
  386. if (cbHint < *pcbRet)
  387. {
  388. DBG_PRINTF((DBG_SS, "****** TrustDecode(0x%08.8lX): recalling due to bad size: hint: %lu actual: %lu\r\n",
  389. dwModuleId, cbHint, *pcbRet));
  390. DELETE_OBJECT(*ppbRet);
  391. return(TrustDecode(dwModuleId, ppbRet, pcbRet, *pcbRet, dwEncoding, pcszOID,
  392. pbEncoded, cbEncoded, dwDecodeFlags));
  393. }
  394. # if DBG
  395. if ((cbHint / 3) > *pcbRet)
  396. {
  397. DBG_PRINTF((DBG_SS, "TrustDecode(0x%08.8lX): hint too big. hint: %lu actual: %lu\r\n",
  398. dwModuleId, cbHint, *pcbRet));
  399. }
  400. # endif
  401. return(TRUE);
  402. ErrorReturn:
  403. DELETE_OBJECT(*ppbRet);
  404. return(FALSE);
  405. TRACE_ERROR_EX(DBG_SS, DecodeError);
  406. SET_ERROR_VAR_EX(DBG_SS, MemoryError, ERROR_NOT_ENOUGH_MEMORY);
  407. }
  408. BOOL WINAPI TrustFreeDecode(DWORD dwModuleId, BYTE **pbAllocated)
  409. {
  410. DELETE_OBJECT(*pbAllocated);
  411. return(TRUE);
  412. }
  413. void _SetConfidenceOnIssuer(DWORD dwEncoding, PCCERT_CONTEXT pChildCert, PCCERT_CONTEXT pTestIssuerCert,
  414. DWORD dwVerificationFlag, FILETIME *psftVerifyAsOf, DWORD *pdwConfidence,
  415. DWORD *pdwError)
  416. {
  417. *pdwConfidence = 0;
  418. if (!(dwVerificationFlag & CERT_STORE_SIGNATURE_FLAG))
  419. {
  420. *pdwConfidence |= CERT_CONFIDENCE_SIG;
  421. }
  422. if (CertVerifyTimeValidity(psftVerifyAsOf, pTestIssuerCert->pCertInfo) == 0)
  423. {
  424. *pdwConfidence |= CERT_CONFIDENCE_TIME;
  425. }
  426. if (CertVerifyValidityNesting(pChildCert->pCertInfo, pTestIssuerCert->pCertInfo))
  427. {
  428. *pdwConfidence |= CERT_CONFIDENCE_TIMENEST;
  429. }
  430. if (_CompareAuthKeyId(dwEncoding, pChildCert, pTestIssuerCert))
  431. {
  432. *pdwConfidence |= CERT_CONFIDENCE_AUTHIDEXT;
  433. }
  434. else if (_CompareAuthKeyId2(dwEncoding, pChildCert, pTestIssuerCert))
  435. {
  436. *pdwConfidence |= CERT_CONFIDENCE_AUTHIDEXT;
  437. }
  438. if (_SetCertErrorAndHygiene(pChildCert, pTestIssuerCert, *pdwConfidence, pdwError))
  439. {
  440. *pdwConfidence |= CERT_CONFIDENCE_HYGIENE;
  441. }
  442. }
  443. BOOL _SetCertErrorAndHygiene(PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pIssuerContext,
  444. DWORD dwCurrentConfidence, DWORD *pdwError)
  445. {
  446. *pdwError = ERROR_SUCCESS;
  447. if (!(dwCurrentConfidence & CERT_CONFIDENCE_SIG))
  448. {
  449. *pdwError = TRUST_E_CERT_SIGNATURE;
  450. return(FALSE);
  451. }
  452. if ((dwCurrentConfidence & CERT_CONFIDENCE_SIG) &&
  453. (dwCurrentConfidence & CERT_CONFIDENCE_TIME) &&
  454. (dwCurrentConfidence & CERT_CONFIDENCE_TIMENEST) &&
  455. (dwCurrentConfidence & CERT_CONFIDENCE_AUTHIDEXT))
  456. {
  457. return(TRUE);
  458. }
  459. if (dwCurrentConfidence & CERT_CONFIDENCE_AUTHIDEXT)
  460. {
  461. return(TRUE);
  462. }
  463. return(FALSE);
  464. }
  465. BOOL _CompareAuthKeyId2(DWORD dwEncoding, PCCERT_CONTEXT pChildContext, PCCERT_CONTEXT pParentContext)
  466. {
  467. DWORD i;
  468. PCERT_EXTENSION pExt;
  469. DWORD cbIdInfo;
  470. PCERT_AUTHORITY_KEY_ID2_INFO pIdInfo;
  471. BOOL fRet;
  472. pIdInfo = NULL;
  473. if (pChildContext->pCertInfo->cExtension < 1)
  474. {
  475. goto NoExtensions;
  476. }
  477. if (!(pExt = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2, pChildContext->pCertInfo->cExtension,
  478. pChildContext->pCertInfo->rgExtension)))
  479. {
  480. goto NoExtensions;
  481. }
  482. if (!(TrustDecode(WVT_MODID_WINTRUST, (BYTE **)&pIdInfo, &cbIdInfo, 103,
  483. dwEncoding, X509_AUTHORITY_KEY_ID2, pExt->Value.pbData, pExt->Value.cbData,
  484. CRYPT_DECODE_NOCOPY_FLAG)))
  485. {
  486. goto DecodeFailed;
  487. }
  488. for (i = 0; i < pIdInfo->AuthorityCertIssuer.cAltEntry; i++)
  489. {
  490. if (pIdInfo->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice ==
  491. CERT_ALT_NAME_DIRECTORY_NAME)
  492. {
  493. break;
  494. }
  495. }
  496. if (i == pIdInfo->AuthorityCertIssuer.cAltEntry)
  497. {
  498. goto NoAltDirectoryName;
  499. }
  500. if (!(CertCompareCertificateName(dwEncoding,
  501. &pIdInfo->AuthorityCertIssuer.rgAltEntry[i].DirectoryName,
  502. &pParentContext->pCertInfo->Issuer)))
  503. {
  504. goto IncorrectIssuer;
  505. }
  506. //
  507. // issuer certificate's serial number must match
  508. //
  509. if (!(CertCompareIntegerBlob(&pIdInfo->AuthorityCertSerialNumber,
  510. &pParentContext->pCertInfo->SerialNumber)))
  511. {
  512. goto IncorrectIssuer;
  513. }
  514. fRet = TRUE;
  515. CommonReturn:
  516. if (pIdInfo)
  517. {
  518. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pIdInfo);
  519. }
  520. return(fRet);
  521. ErrorReturn:
  522. fRet = FALSE;
  523. goto CommonReturn;
  524. TRACE_ERROR_EX(DBG_SS, NoExtensions);
  525. TRACE_ERROR_EX(DBG_SS, DecodeFailed);
  526. TRACE_ERROR_EX(DBG_SS, IncorrectIssuer);
  527. TRACE_ERROR_EX(DBG_SS, NoAltDirectoryName);
  528. }
  529. BOOL _CompareAuthKeyId(DWORD dwEncoding, PCCERT_CONTEXT pChildContext, PCCERT_CONTEXT pParentContext)
  530. {
  531. PCERT_EXTENSION pExt;
  532. PCERT_AUTHORITY_KEY_ID_INFO pChildKeyIdInfo;
  533. DWORD cbKeyIdInfo;
  534. BOOL fRet;
  535. pChildKeyIdInfo = NULL;
  536. pExt = NULL;
  537. if (pChildContext->pCertInfo->cExtension < 1)
  538. {
  539. goto NoExtensions;
  540. }
  541. pChildKeyIdInfo = NULL;
  542. if (!(pExt = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER,
  543. pChildContext->pCertInfo->cExtension,
  544. pChildContext->pCertInfo->rgExtension)))
  545. {
  546. goto NoExtensions;
  547. }
  548. if (!(TrustDecode(WVT_MODID_WINTRUST, (BYTE **)&pChildKeyIdInfo, &cbKeyIdInfo, 104,
  549. dwEncoding, X509_AUTHORITY_KEY_ID, pExt->Value.pbData, pExt->Value.cbData,
  550. CRYPT_DECODE_NOCOPY_FLAG)))
  551. {
  552. goto DecodeFailed;
  553. }
  554. if ((pChildKeyIdInfo->CertIssuer.cbData < 1) ||
  555. (pChildKeyIdInfo->CertSerialNumber.cbData < 1))
  556. {
  557. goto NoKeyId;
  558. }
  559. //
  560. // issuer certificate's issuer name must match
  561. //
  562. if (!(CertCompareCertificateName(dwEncoding, &pChildKeyIdInfo->CertIssuer,
  563. &pParentContext->pCertInfo->Issuer)))
  564. {
  565. goto IncorrectIssuer;
  566. }
  567. //
  568. // issuer certificate's serial number must match
  569. //
  570. if (!(CertCompareIntegerBlob(&pChildKeyIdInfo->CertSerialNumber,
  571. &pParentContext->pCertInfo->SerialNumber)))
  572. {
  573. goto IncorrectIssuer;
  574. }
  575. fRet = TRUE;
  576. CommonReturn:
  577. if (pChildKeyIdInfo)
  578. {
  579. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pChildKeyIdInfo);
  580. }
  581. return(fRet);
  582. ErrorReturn:
  583. fRet = FALSE;
  584. goto CommonReturn;
  585. TRACE_ERROR_EX(DBG_SS, NoExtensions);
  586. TRACE_ERROR_EX(DBG_SS, DecodeFailed);
  587. TRACE_ERROR_EX(DBG_SS, NoKeyId);
  588. TRACE_ERROR_EX(DBG_SS, IncorrectIssuer);
  589. }