Leaked source code of windows server 2003
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.

741 lines
21 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 (pas[cs] = StoreProviderGetStore(hProv, WVT_STOREID_LM_MY))
  170. {
  171. cs++;
  172. }
  173. if ((pahStores) && (cs > *pchStores))
  174. {
  175. *pchStores = cs;
  176. goto ErrorMoreData;
  177. }
  178. *pchStores = cs;
  179. fRet = TRUE;
  180. if (!(pahStores))
  181. {
  182. goto ErrorMoreData;
  183. }
  184. DWORD i;
  185. for (i = 0; i < cs; i++)
  186. {
  187. pahStores[i] = pas[i];
  188. }
  189. CommonReturn:
  190. return(fRet);
  191. ErrorReturn:
  192. while (cs > 0)
  193. {
  194. CertCloseStore(pas[cs - 1], 0);
  195. cs--;
  196. }
  197. goto CommonReturn;
  198. SET_ERROR_VAR_EX(DBG_SS, ErrorMoreData, ERROR_MORE_DATA);
  199. SET_ERROR_VAR_EX(DBG_SS, ErrorNoRootStore, TRUST_E_SYSTEM_ERROR);
  200. SET_ERROR_VAR_EX(DBG_SS, ErrorInvalidParam, ERROR_INVALID_PARAMETER);
  201. }
  202. BOOL WINAPI TrustIsCertificateSelfSigned(PCCERT_CONTEXT pContext,
  203. DWORD dwEncoding,
  204. DWORD dwFlags)
  205. {
  206. if (!(pContext) ||
  207. (dwFlags != 0))
  208. {
  209. SetLastError(ERROR_INVALID_PARAMETER);
  210. return(FALSE);
  211. }
  212. if (!(CertCompareCertificateName(dwEncoding,
  213. &pContext->pCertInfo->Issuer,
  214. &pContext->pCertInfo->Subject)))
  215. {
  216. return(FALSE);
  217. }
  218. DWORD dwFlag;
  219. dwFlag = CERT_STORE_SIGNATURE_FLAG;
  220. if (!(CertVerifySubjectCertificateContext(pContext, pContext, &dwFlag)) ||
  221. (dwFlag & CERT_STORE_SIGNATURE_FLAG))
  222. {
  223. return(FALSE);
  224. }
  225. return(TRUE);
  226. }
  227. #define sz_CRYPTNET_DLL "cryptnet.dll"
  228. #define sz_CryptGetObjectUrl "CryptGetObjectUrl"
  229. #define sz_CryptRetrieveObjectByUrlW "CryptRetrieveObjectByUrlW"
  230. typedef BOOL (WINAPI *PFN_CRYPT_GET_OBJECT_URL)(
  231. IN LPCSTR pszUrlOid,
  232. IN LPVOID pvPara,
  233. IN DWORD dwFlags,
  234. OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray,
  235. IN OUT DWORD* pcbUrlArray,
  236. OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo,
  237. IN OUT OPTIONAL DWORD* pcbUrlInfo,
  238. IN OPTIONAL LPVOID pvReserved
  239. );
  240. typedef BOOL (WINAPI *PFN_CRYPT_RETRIEVE_OBJECT_BY_URLW)(
  241. IN LPCWSTR pszUrl,
  242. IN LPCSTR pszObjectOid,
  243. IN DWORD dwRetrievalFlags,
  244. IN DWORD dwTimeout,
  245. OUT LPVOID* ppvObject,
  246. IN HCRYPTASYNC hAsyncRetrieve,
  247. IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
  248. IN OPTIONAL LPVOID pvVerify,
  249. IN OPTIONAL LPVOID pvReserved
  250. );
  251. PCCERT_CONTEXT _GetExternalIssuerCert(PCCERT_CONTEXT pContext,
  252. DWORD dwEncoding,
  253. DWORD *pdwRetError,
  254. DWORD *pdwConfidence,
  255. FILETIME *psftVerifyAsOf)
  256. {
  257. *pdwConfidence = 0;
  258. #if (USE_IEv4CRYPT32)
  259. return(NULL);
  260. #else
  261. DWORD cbUrlArray;
  262. CRYPT_URL_ARRAY *pUrlArray;
  263. PCCERT_CONTEXT pIssuer;
  264. PCCERT_CONTEXT pCertBestMatch;
  265. DWORD dwHighestConfidence;
  266. DWORD dwConfidence;
  267. DWORD dwStatus;
  268. DWORD dwError;
  269. DWORD i;
  270. pCertBestMatch = NULL;
  271. pIssuer = NULL;
  272. pUrlArray = NULL;
  273. cbUrlArray = 0;
  274. dwHighestConfidence = 0;
  275. HMODULE hDll = NULL;
  276. PFN_CRYPT_GET_OBJECT_URL pfnCryptGetObjectUrl;
  277. PFN_CRYPT_RETRIEVE_OBJECT_BY_URLW pfnCryptRetrieveObjectByUrlW;
  278. if (NULL == (hDll = LoadLibraryA(sz_CRYPTNET_DLL)))
  279. goto LoadCryptNetDllError;
  280. if (NULL == (pfnCryptGetObjectUrl =
  281. (PFN_CRYPT_GET_OBJECT_URL) GetProcAddress(hDll,
  282. sz_CryptGetObjectUrl)))
  283. goto CryptGetObjectUrlProcAddressError;
  284. if (NULL == (pfnCryptRetrieveObjectByUrlW =
  285. (PFN_CRYPT_RETRIEVE_OBJECT_BY_URLW) GetProcAddress(hDll,
  286. sz_CryptRetrieveObjectByUrlW)))
  287. goto CryptRetrieveObjectByUrlWProcAddressError;
  288. if (!(pfnCryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER, (void *)pContext, 0, NULL, &cbUrlArray, NULL, NULL, NULL)) ||
  289. (cbUrlArray < 1))
  290. {
  291. goto GetObjectUrlFailed;
  292. }
  293. if (!(pUrlArray = (CRYPT_URL_ARRAY *) new BYTE[cbUrlArray]))
  294. {
  295. goto MemoryError;
  296. }
  297. memset(pUrlArray, 0x00, cbUrlArray);
  298. if (!(pfnCryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER, (void *)pContext, 0, pUrlArray, &cbUrlArray, NULL, NULL, NULL)))
  299. {
  300. goto GetObjectUrlFailed;
  301. }
  302. for (i = 0; i < pUrlArray->cUrl; i++)
  303. {
  304. if (pIssuer)
  305. {
  306. CertFreeCertificateContext(pIssuer);
  307. pIssuer = NULL;
  308. }
  309. if (pfnCryptRetrieveObjectByUrlW(pUrlArray->rgwszUrl[i], CONTEXT_OID_CERTIFICATE, 0, 0, (void **)&pIssuer,
  310. NULL, NULL, NULL, NULL))
  311. {
  312. if (!(CertCompareCertificateName(X509_ASN_ENCODING, &pContext->pCertInfo->Issuer,
  313. &pIssuer->pCertInfo->Subject)))
  314. {
  315. continue;
  316. }
  317. dwStatus = CERT_STORE_SIGNATURE_FLAG;
  318. if (!(CertVerifySubjectCertificateContext(pContext, pIssuer, &dwStatus)))
  319. {
  320. continue;
  321. }
  322. dwError = 0;
  323. _SetConfidenceOnIssuer(dwEncoding, pContext, pIssuer, dwStatus, psftVerifyAsOf,
  324. &dwConfidence, &dwError);
  325. if (dwError != 0)
  326. {
  327. continue;
  328. }
  329. if (dwConfidence > dwHighestConfidence)
  330. {
  331. if (pCertBestMatch)
  332. {
  333. CertFreeCertificateContext(pCertBestMatch);
  334. }
  335. dwHighestConfidence = dwConfidence;
  336. pCertBestMatch = CertDuplicateCertificateContext(pIssuer);
  337. }
  338. if (dwConfidence >= CERT_CONFIDENCE_HIGHEST)
  339. {
  340. goto CommonReturn;
  341. }
  342. }
  343. }
  344. goto RetrieveObjectFailed;
  345. CommonReturn:
  346. if (hDll)
  347. FreeLibrary(hDll);
  348. if (pIssuer)
  349. {
  350. CertFreeCertificateContext(pIssuer);
  351. }
  352. if (pUrlArray)
  353. {
  354. delete pUrlArray;
  355. }
  356. *pdwConfidence = dwHighestConfidence;
  357. return(pCertBestMatch);
  358. ErrorReturn:
  359. if (pCertBestMatch)
  360. {
  361. CertFreeCertificateContext(pCertBestMatch);
  362. pCertBestMatch = NULL;
  363. }
  364. goto CommonReturn;
  365. TRACE_ERROR_EX(DBG_SS, LoadCryptNetDllError)
  366. TRACE_ERROR_EX(DBG_SS, CryptGetObjectUrlProcAddressError)
  367. TRACE_ERROR_EX(DBG_SS, CryptRetrieveObjectByUrlWProcAddressError)
  368. TRACE_ERROR_EX(DBG_SS, GetObjectUrlFailed);
  369. TRACE_ERROR_EX(DBG_SS, RetrieveObjectFailed);
  370. SET_ERROR_VAR_EX(DBG_SS, MemoryError, ERROR_NOT_ENOUGH_MEMORY);
  371. #endif // USE_IEv4CRYPT32
  372. }
  373. BOOL WINAPI TrustDecode(DWORD dwModuleId, BYTE **ppbRet, DWORD *pcbRet, DWORD cbHint,
  374. DWORD dwEncoding, const char *pcszOID, const BYTE *pbEncoded, DWORD cbEncoded,
  375. DWORD dwDecodeFlags)
  376. {
  377. if (!(*ppbRet = new BYTE[cbHint]))
  378. {
  379. goto MemoryError;
  380. }
  381. *pcbRet = cbHint;
  382. if (!(CryptDecodeObject(dwEncoding, pcszOID, pbEncoded, cbEncoded, dwDecodeFlags,
  383. *ppbRet, pcbRet)))
  384. {
  385. if (GetLastError() != ERROR_MORE_DATA)
  386. {
  387. goto DecodeError;
  388. }
  389. }
  390. if (cbHint < *pcbRet)
  391. {
  392. DBG_PRINTF((DBG_SS, "****** TrustDecode(0x%08.8lX): recalling due to bad size: hint: %lu actual: %lu\r\n",
  393. dwModuleId, cbHint, *pcbRet));
  394. DELETE_OBJECT(*ppbRet);
  395. return(TrustDecode(dwModuleId, ppbRet, pcbRet, *pcbRet, dwEncoding, pcszOID,
  396. pbEncoded, cbEncoded, dwDecodeFlags));
  397. }
  398. # if DBG
  399. if ((cbHint / 3) > *pcbRet)
  400. {
  401. DBG_PRINTF((DBG_SS, "TrustDecode(0x%08.8lX): hint too big. hint: %lu actual: %lu\r\n",
  402. dwModuleId, cbHint, *pcbRet));
  403. }
  404. # endif
  405. return(TRUE);
  406. ErrorReturn:
  407. DELETE_OBJECT(*ppbRet);
  408. return(FALSE);
  409. TRACE_ERROR_EX(DBG_SS, DecodeError);
  410. SET_ERROR_VAR_EX(DBG_SS, MemoryError, ERROR_NOT_ENOUGH_MEMORY);
  411. }
  412. BOOL WINAPI TrustFreeDecode(DWORD dwModuleId, BYTE **pbAllocated)
  413. {
  414. DELETE_OBJECT(*pbAllocated);
  415. return(TRUE);
  416. }
  417. void _SetConfidenceOnIssuer(DWORD dwEncoding, PCCERT_CONTEXT pChildCert, PCCERT_CONTEXT pTestIssuerCert,
  418. DWORD dwVerificationFlag, FILETIME *psftVerifyAsOf, DWORD *pdwConfidence,
  419. DWORD *pdwError)
  420. {
  421. *pdwConfidence = 0;
  422. if (!(dwVerificationFlag & CERT_STORE_SIGNATURE_FLAG))
  423. {
  424. *pdwConfidence |= CERT_CONFIDENCE_SIG;
  425. }
  426. if (CertVerifyTimeValidity(psftVerifyAsOf, pTestIssuerCert->pCertInfo) == 0)
  427. {
  428. *pdwConfidence |= CERT_CONFIDENCE_TIME;
  429. }
  430. if (CertVerifyValidityNesting(pChildCert->pCertInfo, pTestIssuerCert->pCertInfo))
  431. {
  432. *pdwConfidence |= CERT_CONFIDENCE_TIMENEST;
  433. }
  434. if (_CompareAuthKeyId(dwEncoding, pChildCert, pTestIssuerCert))
  435. {
  436. *pdwConfidence |= CERT_CONFIDENCE_AUTHIDEXT;
  437. }
  438. else if (_CompareAuthKeyId2(dwEncoding, pChildCert, pTestIssuerCert))
  439. {
  440. *pdwConfidence |= CERT_CONFIDENCE_AUTHIDEXT;
  441. }
  442. if (_SetCertErrorAndHygiene(pChildCert, pTestIssuerCert, *pdwConfidence, pdwError))
  443. {
  444. *pdwConfidence |= CERT_CONFIDENCE_HYGIENE;
  445. }
  446. }
  447. BOOL _SetCertErrorAndHygiene(PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pIssuerContext,
  448. DWORD dwCurrentConfidence, DWORD *pdwError)
  449. {
  450. *pdwError = ERROR_SUCCESS;
  451. if (!(dwCurrentConfidence & CERT_CONFIDENCE_SIG))
  452. {
  453. *pdwError = TRUST_E_CERT_SIGNATURE;
  454. return(FALSE);
  455. }
  456. if ((dwCurrentConfidence & CERT_CONFIDENCE_SIG) &&
  457. (dwCurrentConfidence & CERT_CONFIDENCE_TIME) &&
  458. (dwCurrentConfidence & CERT_CONFIDENCE_TIMENEST) &&
  459. (dwCurrentConfidence & CERT_CONFIDENCE_AUTHIDEXT))
  460. {
  461. return(TRUE);
  462. }
  463. if (dwCurrentConfidence & CERT_CONFIDENCE_AUTHIDEXT)
  464. {
  465. return(TRUE);
  466. }
  467. return(FALSE);
  468. }
  469. BOOL _CompareAuthKeyId2(DWORD dwEncoding, PCCERT_CONTEXT pChildContext, PCCERT_CONTEXT pParentContext)
  470. {
  471. DWORD i;
  472. PCERT_EXTENSION pExt;
  473. DWORD cbIdInfo;
  474. PCERT_AUTHORITY_KEY_ID2_INFO pIdInfo;
  475. BOOL fRet;
  476. pIdInfo = NULL;
  477. if (pChildContext->pCertInfo->cExtension < 1)
  478. {
  479. goto NoExtensions;
  480. }
  481. if (!(pExt = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2, pChildContext->pCertInfo->cExtension,
  482. pChildContext->pCertInfo->rgExtension)))
  483. {
  484. goto NoExtensions;
  485. }
  486. if (!(TrustDecode(WVT_MODID_WINTRUST, (BYTE **)&pIdInfo, &cbIdInfo, 103,
  487. dwEncoding, X509_AUTHORITY_KEY_ID2, pExt->Value.pbData, pExt->Value.cbData,
  488. CRYPT_DECODE_NOCOPY_FLAG)))
  489. {
  490. goto DecodeFailed;
  491. }
  492. for (i = 0; i < pIdInfo->AuthorityCertIssuer.cAltEntry; i++)
  493. {
  494. if (pIdInfo->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice ==
  495. CERT_ALT_NAME_DIRECTORY_NAME)
  496. {
  497. break;
  498. }
  499. }
  500. if (i == pIdInfo->AuthorityCertIssuer.cAltEntry)
  501. {
  502. goto NoAltDirectoryName;
  503. }
  504. if (!(CertCompareCertificateName(dwEncoding,
  505. &pIdInfo->AuthorityCertIssuer.rgAltEntry[i].DirectoryName,
  506. &pParentContext->pCertInfo->Issuer)))
  507. {
  508. goto IncorrectIssuer;
  509. }
  510. //
  511. // issuer certificate's serial number must match
  512. //
  513. if (!(CertCompareIntegerBlob(&pIdInfo->AuthorityCertSerialNumber,
  514. &pParentContext->pCertInfo->SerialNumber)))
  515. {
  516. goto IncorrectIssuer;
  517. }
  518. fRet = TRUE;
  519. CommonReturn:
  520. if (pIdInfo)
  521. {
  522. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pIdInfo);
  523. }
  524. return(fRet);
  525. ErrorReturn:
  526. fRet = FALSE;
  527. goto CommonReturn;
  528. TRACE_ERROR_EX(DBG_SS, NoExtensions);
  529. TRACE_ERROR_EX(DBG_SS, DecodeFailed);
  530. TRACE_ERROR_EX(DBG_SS, IncorrectIssuer);
  531. TRACE_ERROR_EX(DBG_SS, NoAltDirectoryName);
  532. }
  533. BOOL _CompareAuthKeyId(DWORD dwEncoding, PCCERT_CONTEXT pChildContext, PCCERT_CONTEXT pParentContext)
  534. {
  535. PCERT_EXTENSION pExt;
  536. PCERT_AUTHORITY_KEY_ID_INFO pChildKeyIdInfo;
  537. DWORD cbKeyIdInfo;
  538. BOOL fRet;
  539. pChildKeyIdInfo = NULL;
  540. pExt = NULL;
  541. if (pChildContext->pCertInfo->cExtension < 1)
  542. {
  543. goto NoExtensions;
  544. }
  545. pChildKeyIdInfo = NULL;
  546. if (!(pExt = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER,
  547. pChildContext->pCertInfo->cExtension,
  548. pChildContext->pCertInfo->rgExtension)))
  549. {
  550. goto NoExtensions;
  551. }
  552. if (!(TrustDecode(WVT_MODID_WINTRUST, (BYTE **)&pChildKeyIdInfo, &cbKeyIdInfo, 104,
  553. dwEncoding, X509_AUTHORITY_KEY_ID, pExt->Value.pbData, pExt->Value.cbData,
  554. CRYPT_DECODE_NOCOPY_FLAG)))
  555. {
  556. goto DecodeFailed;
  557. }
  558. if ((pChildKeyIdInfo->CertIssuer.cbData < 1) ||
  559. (pChildKeyIdInfo->CertSerialNumber.cbData < 1))
  560. {
  561. goto NoKeyId;
  562. }
  563. //
  564. // issuer certificate's issuer name must match
  565. //
  566. if (!(CertCompareCertificateName(dwEncoding, &pChildKeyIdInfo->CertIssuer,
  567. &pParentContext->pCertInfo->Issuer)))
  568. {
  569. goto IncorrectIssuer;
  570. }
  571. //
  572. // issuer certificate's serial number must match
  573. //
  574. if (!(CertCompareIntegerBlob(&pChildKeyIdInfo->CertSerialNumber,
  575. &pParentContext->pCertInfo->SerialNumber)))
  576. {
  577. goto IncorrectIssuer;
  578. }
  579. fRet = TRUE;
  580. CommonReturn:
  581. if (pChildKeyIdInfo)
  582. {
  583. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pChildKeyIdInfo);
  584. }
  585. return(fRet);
  586. ErrorReturn:
  587. fRet = FALSE;
  588. goto CommonReturn;
  589. TRACE_ERROR_EX(DBG_SS, NoExtensions);
  590. TRACE_ERROR_EX(DBG_SS, DecodeFailed);
  591. TRACE_ERROR_EX(DBG_SS, NoKeyId);
  592. TRACE_ERROR_EX(DBG_SS, IncorrectIssuer);
  593. }