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.

499 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: wthelper.cpp
  8. //
  9. // Contents: Microsoft Internet Security Trust Provider
  10. //
  11. // Functions: WTHelperGetProvPrivateDataFromChain
  12. // WTHelperGetProvSignerFromChain
  13. // WTHelperGetFileHandle
  14. // WTHelperGetFileName
  15. // WTHelperOpenKnownStores
  16. // WTHelperGetProvCertFromChain
  17. // WTHelperCheckCertUsage
  18. // WTHelperIsInRootStore
  19. // WTHelperProvDataFromStateData
  20. // WTHelperGetAgencyInfo
  21. //
  22. // *** local functions ***
  23. // _FindKeyUsage
  24. //
  25. // History: 01-Jun-1997 pberkman created
  26. //
  27. //--------------------------------------------------------------------------
  28. #include "global.hxx"
  29. #include "pkialloc.h"
  30. BOOL _FindKeyUsage(PCERT_ENHKEY_USAGE pUsage, LPCSTR pszRequestedUsageOID);
  31. CRYPT_PROVIDER_PRIVDATA * WINAPI WTHelperGetProvPrivateDataFromChain(CRYPT_PROVIDER_DATA *pProvData,
  32. GUID *pgProviderID)
  33. {
  34. if (!(pProvData) ||
  35. !(pgProviderID))
  36. {
  37. return(NULL);
  38. }
  39. for (int i = 0; i < (int)pProvData->csProvPrivData; i++)
  40. {
  41. if (memcmp(&pProvData->pasProvPrivData[i].gProviderID, pgProviderID, sizeof(GUID)) == 0)
  42. {
  43. return(&pProvData->pasProvPrivData[i]);
  44. }
  45. }
  46. return(NULL);
  47. }
  48. CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(CRYPT_PROVIDER_DATA *pProvData,
  49. DWORD idxSigner,
  50. BOOL fCounterSigner,
  51. DWORD idxCounterSigner)
  52. {
  53. if (!(pProvData) ||
  54. (idxSigner >= pProvData->csSigners))
  55. {
  56. return(NULL);
  57. }
  58. if (fCounterSigner)
  59. {
  60. if (idxCounterSigner >= pProvData->pasSigners[idxSigner].csCounterSigners)
  61. {
  62. return(NULL);
  63. }
  64. return(&pProvData->pasSigners[idxSigner].pasCounterSigners[idxCounterSigner]);
  65. }
  66. return(&pProvData->pasSigners[idxSigner]);
  67. }
  68. CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(CRYPT_PROVIDER_SGNR *pSgnr,
  69. DWORD idxCert)
  70. {
  71. if (!(pSgnr) ||
  72. (idxCert >= pSgnr->csCertChain))
  73. {
  74. return(NULL);
  75. }
  76. return(&pSgnr->pasCertChain[idxCert]);
  77. }
  78. HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *pWintrustData)
  79. {
  80. switch (pWintrustData->dwUnionChoice)
  81. {
  82. case WTD_CHOICE_FILE:
  83. return(pWintrustData->pFile->hFile);
  84. case WTD_CHOICE_CATALOG:
  85. return(pWintrustData->pCatalog->hMemberFile);
  86. }
  87. return(INVALID_HANDLE_VALUE);
  88. }
  89. WCHAR * WINAPI WTHelperGetFileName(WINTRUST_DATA *pWintrustData)
  90. {
  91. switch (pWintrustData->dwUnionChoice)
  92. {
  93. case WTD_CHOICE_FILE:
  94. return((WCHAR *)pWintrustData->pFile->pcwszFilePath);
  95. case WTD_CHOICE_CATALOG:
  96. if (!(pWintrustData->pCatalog->pcwszCatalogFilePath) ||
  97. !(pWintrustData->pCatalog->pcwszMemberTag))
  98. {
  99. return(NULL);
  100. }
  101. return((WCHAR *)pWintrustData->pCatalog->pcwszMemberFilePath);
  102. case WTD_CHOICE_CERT:
  103. if (pWintrustData->pCert->pcwszDisplayName)
  104. return (WCHAR *) pWintrustData->pCert->pcwszDisplayName;
  105. else
  106. return L"Certificate";
  107. case WTD_CHOICE_BLOB:
  108. if (pWintrustData->pBlob->pcwszDisplayName)
  109. return (WCHAR *) pWintrustData->pBlob->pcwszDisplayName;
  110. else
  111. return L"Blob";
  112. }
  113. return(NULL);
  114. }
  115. BOOL WINAPI WTHelperOpenKnownStores(CRYPT_PROVIDER_DATA *pProvData)
  116. {
  117. DWORD i;
  118. DWORD cs;
  119. HCERTSTORE *pas;
  120. if ((pProvData->pWintrustData) &&
  121. (pProvData->pWintrustData->dwUnionChoice == WTD_CHOICE_CERT) &&
  122. (_ISINSTRUCT(WINTRUST_CERT_INFO, pProvData->pWintrustData->pCert->cbStruct, dwFlags)))
  123. {
  124. HCERTSTORE hStore;
  125. if (pProvData->pWintrustData->pCert->dwFlags & WTCI_DONT_OPEN_STORES)
  126. {
  127. if (hStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL))
  128. {
  129. AddToStoreChain(hStore, &pProvData->chStores, &pProvData->pahStores);
  130. return(TRUE);
  131. }
  132. return(FALSE);
  133. }
  134. if (pProvData->pWintrustData->pCert->dwFlags & WTCI_OPEN_ONLY_ROOT)
  135. {
  136. if (hStore = StoreProviderGetStore(pProvData->hProv, WVT_STOREID_ROOT))
  137. {
  138. AddToStoreChain(hStore, &pProvData->chStores, &pProvData->pahStores);
  139. return(TRUE);
  140. }
  141. return(FALSE);
  142. }
  143. }
  144. cs = 0;
  145. TrustOpenStores(pProvData->hProv, &cs, NULL, 0);
  146. if (cs > 0)
  147. {
  148. if (!(pas = new HCERTSTORE[cs]))
  149. {
  150. pProvData->dwError = ERROR_NOT_ENOUGH_MEMORY;
  151. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = TRUST_E_SYSTEM_ERROR;
  152. return(FALSE);
  153. }
  154. if (TrustOpenStores(pProvData->hProv, &cs, pas, 0))
  155. {
  156. for (i = 0; i < cs; i++)
  157. {
  158. AddToStoreChain(pas[i], &pProvData->chStores, &pProvData->pahStores);
  159. }
  160. }
  161. else
  162. {
  163. cs = 0;
  164. }
  165. delete pas;
  166. }
  167. if (cs > 0)
  168. {
  169. return(TRUE);
  170. }
  171. return(FALSE);
  172. }
  173. BOOL WINAPI WTHelperGetAgencyInfo(PCCERT_CONTEXT pCert, DWORD *pcbAgencyInfo, SPC_SP_AGENCY_INFO *pAgencyInfo)
  174. {
  175. PCERT_EXTENSION pExt;
  176. PSPC_SP_AGENCY_INFO pInfo;
  177. DWORD cbInfo;
  178. if (!(pCert) || !(pcbAgencyInfo))
  179. {
  180. SetLastError(ERROR_INVALID_PARAMETER);
  181. return(FALSE);
  182. }
  183. *pcbAgencyInfo = 0;
  184. if (!(pExt = CertFindExtension(SPC_SP_AGENCY_INFO_OBJID, pCert->pCertInfo->cExtension,
  185. pCert->pCertInfo->rgExtension)))
  186. {
  187. return(FALSE);
  188. }
  189. CryptDecodeObject(X509_ASN_ENCODING, SPC_SP_AGENCY_INFO_STRUCT,
  190. pExt->Value.pbData, pExt->Value.cbData, 0, NULL,
  191. pcbAgencyInfo);
  192. if (*pcbAgencyInfo == 0)
  193. {
  194. return(FALSE);
  195. }
  196. if (!(pAgencyInfo))
  197. {
  198. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  199. return(FALSE);
  200. }
  201. if (!(CryptDecodeObject(X509_ASN_ENCODING, SPC_SP_AGENCY_INFO_STRUCT,
  202. pExt->Value.pbData, pExt->Value.cbData, 0, pAgencyInfo,
  203. pcbAgencyInfo)))
  204. {
  205. return(FALSE);
  206. }
  207. return(TRUE);
  208. }
  209. BOOL WINAPI WTHelperCheckCertUsage(PCCERT_CONTEXT pCertContext, LPCSTR pszRequestedUsageOID)
  210. {
  211. PCERT_ENHKEY_USAGE pUsage;
  212. DWORD cbUsage;
  213. int i;
  214. cbUsage = 0;
  215. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
  216. if (cbUsage > 0)
  217. {
  218. if (!(pUsage = (PCERT_ENHKEY_USAGE)new BYTE[cbUsage]))
  219. {
  220. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  221. return(FALSE);
  222. }
  223. if (!(CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  224. pUsage, &cbUsage)))
  225. {
  226. delete pUsage;
  227. return(FALSE);
  228. }
  229. //
  230. // the cert has enhanced key usage extensions, check if we find ours
  231. //
  232. if (!(_FindKeyUsage(pUsage, pszRequestedUsageOID)))
  233. {
  234. SetLastError(CERT_E_WRONG_USAGE);
  235. delete pUsage;
  236. return(FALSE);
  237. }
  238. delete pUsage;
  239. }
  240. //
  241. // OK... either we have NO EXTENSION or we found our OID in the list in the EXTENSION.
  242. // now, make sure if we have properties that it has been enabled.
  243. //
  244. cbUsage = 0;
  245. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
  246. if (cbUsage > 0)
  247. {
  248. if (!(pUsage = (PCERT_ENHKEY_USAGE)new BYTE[cbUsage]))
  249. {
  250. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  251. return(FALSE);
  252. }
  253. if (!(CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  254. pUsage, &cbUsage)))
  255. {
  256. delete pUsage;
  257. return(FALSE);
  258. }
  259. //
  260. // the cert has properties, first check if we're disabled
  261. //
  262. if (_FindKeyUsage(pUsage, szOID_YESNO_TRUST_ATTR))
  263. {
  264. SetLastError(CERT_E_WRONG_USAGE);
  265. delete pUsage;
  266. return(FALSE);
  267. }
  268. if (!(_FindKeyUsage(pUsage, pszRequestedUsageOID)))
  269. {
  270. SetLastError(CERT_E_WRONG_USAGE);
  271. delete pUsage;
  272. return(FALSE);
  273. }
  274. delete pUsage;
  275. }
  276. return(TRUE);
  277. }
  278. BOOL _FindKeyUsage(PCERT_ENHKEY_USAGE pUsage, LPCSTR pszRequestedUsageOID)
  279. {
  280. int i;
  281. for (i = 0; i < (int)pUsage->cUsageIdentifier; i++)
  282. {
  283. if (strcmp(pUsage->rgpszUsageIdentifier[i], pszRequestedUsageOID) == 0)
  284. {
  285. return(TRUE); // OK found it!
  286. }
  287. }
  288. return(FALSE);
  289. }
  290. BOOL WINAPI WTHelperIsInRootStore(CRYPT_PROVIDER_DATA *pProvData, PCCERT_CONTEXT pCertContext)
  291. {
  292. if (pProvData->chStores < 1)
  293. {
  294. return(FALSE);
  295. }
  296. //
  297. // check the fast way first!
  298. //
  299. if (pCertContext->hCertStore == pProvData->pahStores[0])
  300. {
  301. //
  302. // it's in the root store!
  303. //
  304. return(TRUE);
  305. }
  306. //
  307. // can't do it the fast way -- do it the slow way!
  308. //
  309. BYTE *pbHash;
  310. DWORD cbHash;
  311. CRYPT_HASH_BLOB sBlob;
  312. PCCERT_CONTEXT pWorkContext;
  313. cbHash = 0;
  314. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
  315. {
  316. return(FALSE);
  317. }
  318. if (cbHash < 1)
  319. {
  320. return(FALSE);
  321. }
  322. if (!(pbHash = (BYTE *)WVTNew(cbHash)))
  323. {
  324. return(FALSE);
  325. }
  326. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
  327. {
  328. delete pbHash;
  329. return(FALSE);
  330. }
  331. sBlob.cbData = cbHash;
  332. sBlob.pbData = pbHash;
  333. pWorkContext = CertFindCertificateInStore(pProvData->pahStores[0], pProvData->dwEncoding, 0,
  334. CERT_FIND_SHA1_HASH, &sBlob, NULL);
  335. delete pbHash;
  336. if (pWorkContext)
  337. {
  338. CertFreeCertificateContext(pWorkContext);
  339. return(TRUE);
  340. }
  341. return(FALSE);
  342. }
  343. typedef struct _ENUM_OID_INFO_ARG {
  344. DWORD cOidInfo;
  345. PCCRYPT_OID_INFO *ppOidInfo;
  346. } ENUM_OID_INFO_ARG, *PENUM_OID_INFO_ARG;
  347. static BOOL WINAPI EnumOidInfoCallback(
  348. IN PCCRYPT_OID_INFO pOidInfo,
  349. IN void *pvArg
  350. )
  351. {
  352. PENUM_OID_INFO_ARG pEnumOidInfoArg = (PENUM_OID_INFO_ARG) pvArg;
  353. PCCRYPT_OID_INFO *ppNewOidInfo;
  354. DWORD cOidInfo = pEnumOidInfoArg->cOidInfo;
  355. // DSIE: Bug 152473.
  356. for (DWORD i = 0; i < cOidInfo; i++)
  357. {
  358. if (0 == wcscmp(pOidInfo->pwszName, pEnumOidInfoArg->ppOidInfo[i]->pwszName))
  359. {
  360. return TRUE;
  361. }
  362. }
  363. if (ppNewOidInfo = (PCCRYPT_OID_INFO *) PkiRealloc(
  364. pEnumOidInfoArg->ppOidInfo,
  365. (cOidInfo + 2) * sizeof(PCCRYPT_OID_INFO))) {
  366. ppNewOidInfo[cOidInfo] = pOidInfo;
  367. ppNewOidInfo[cOidInfo + 1] = NULL;
  368. pEnumOidInfoArg->cOidInfo = cOidInfo + 1;
  369. pEnumOidInfoArg->ppOidInfo = ppNewOidInfo;
  370. }
  371. return TRUE;
  372. }
  373. BOOL WINAPI WTHelperGetKnownUsages(DWORD fdwAction, PCCRYPT_OID_INFO **pppOidInfo)
  374. {
  375. if (!(pppOidInfo))
  376. {
  377. SetLastError(ERROR_INVALID_PARAMETER);
  378. return(FALSE);
  379. }
  380. if (fdwAction == WTH_FREE)
  381. {
  382. PkiFree(*pppOidInfo);
  383. *pppOidInfo = NULL;
  384. return(TRUE);
  385. }
  386. if (fdwAction == WTH_ALLOC)
  387. {
  388. ENUM_OID_INFO_ARG EnumOidInfoArg;
  389. memset(&EnumOidInfoArg, 0, sizeof(EnumOidInfoArg));
  390. CryptEnumOIDInfo(
  391. CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
  392. 0, // dwFlags
  393. &EnumOidInfoArg,
  394. EnumOidInfoCallback
  395. );
  396. return (NULL != (*pppOidInfo = EnumOidInfoArg.ppOidInfo));
  397. }
  398. SetLastError(ERROR_INVALID_PARAMETER);
  399. *pppOidInfo = NULL;
  400. return(FALSE);
  401. }
  402. CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
  403. {
  404. return((CRYPT_PROVIDER_DATA *)hStateData);
  405. }