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.

515 lines
13 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. LPCWSTR pcwszFileName = NULL;
  92. switch (pWintrustData->dwUnionChoice)
  93. {
  94. case WTD_CHOICE_FILE:
  95. pcwszFileName = pWintrustData->pFile->pcwszFilePath;
  96. break;
  97. case WTD_CHOICE_CATALOG:
  98. if (pWintrustData->pCatalog->pcwszCatalogFilePath &&
  99. pWintrustData->pCatalog->pcwszMemberTag)
  100. {
  101. pcwszFileName =
  102. pWintrustData->pCatalog->pcwszMemberFilePath;
  103. }
  104. break;
  105. case WTD_CHOICE_CERT:
  106. if (pWintrustData->pCert->pcwszDisplayName)
  107. pcwszFileName = pWintrustData->pCert->pcwszDisplayName;
  108. else
  109. pcwszFileName = L"Certificate";
  110. break;
  111. case WTD_CHOICE_BLOB:
  112. if (pWintrustData->pBlob->pcwszDisplayName)
  113. pcwszFileName = pWintrustData->pBlob->pcwszDisplayName;
  114. else
  115. pcwszFileName = L"Blob";
  116. break;
  117. case WTD_CHOICE_SIGNER:
  118. if (pWintrustData->pSgnr->pcwszDisplayName)
  119. pcwszFileName = pWintrustData->pSgnr->pcwszDisplayName;
  120. else
  121. pcwszFileName = L"Signer";
  122. break;
  123. }
  124. if (NULL == pcwszFileName)
  125. {
  126. pcwszFileName = L"Unspecified Name";
  127. }
  128. return (LPWSTR) pcwszFileName;
  129. }
  130. BOOL WINAPI WTHelperOpenKnownStores(CRYPT_PROVIDER_DATA *pProvData)
  131. {
  132. DWORD i;
  133. DWORD cs;
  134. HCERTSTORE *pas;
  135. if ((pProvData->pWintrustData) &&
  136. (pProvData->pWintrustData->dwUnionChoice == WTD_CHOICE_CERT) &&
  137. (_ISINSTRUCT(WINTRUST_CERT_INFO, pProvData->pWintrustData->pCert->cbStruct, dwFlags)))
  138. {
  139. HCERTSTORE hStore;
  140. if (pProvData->pWintrustData->pCert->dwFlags & WTCI_DONT_OPEN_STORES)
  141. {
  142. if (hStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL))
  143. {
  144. AddToStoreChain(hStore, &pProvData->chStores, &pProvData->pahStores);
  145. return(TRUE);
  146. }
  147. return(FALSE);
  148. }
  149. if (pProvData->pWintrustData->pCert->dwFlags & WTCI_OPEN_ONLY_ROOT)
  150. {
  151. if (hStore = StoreProviderGetStore(pProvData->hProv, WVT_STOREID_ROOT))
  152. {
  153. AddToStoreChain(hStore, &pProvData->chStores, &pProvData->pahStores);
  154. return(TRUE);
  155. }
  156. return(FALSE);
  157. }
  158. }
  159. cs = 0;
  160. TrustOpenStores(pProvData->hProv, &cs, NULL, 0);
  161. if (cs > 0)
  162. {
  163. if (!(pas = new HCERTSTORE[cs]))
  164. {
  165. pProvData->dwError = ERROR_NOT_ENOUGH_MEMORY;
  166. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = TRUST_E_SYSTEM_ERROR;
  167. return(FALSE);
  168. }
  169. if (TrustOpenStores(pProvData->hProv, &cs, pas, 0))
  170. {
  171. for (i = 0; i < cs; i++)
  172. {
  173. AddToStoreChain(pas[i], &pProvData->chStores, &pProvData->pahStores);
  174. }
  175. }
  176. else
  177. {
  178. cs = 0;
  179. }
  180. delete pas;
  181. }
  182. if (cs > 0)
  183. {
  184. return(TRUE);
  185. }
  186. return(FALSE);
  187. }
  188. BOOL WINAPI WTHelperGetAgencyInfo(PCCERT_CONTEXT pCert, DWORD *pcbAgencyInfo, SPC_SP_AGENCY_INFO *pAgencyInfo)
  189. {
  190. PCERT_EXTENSION pExt;
  191. if (!(pCert) || !(pcbAgencyInfo))
  192. {
  193. SetLastError(ERROR_INVALID_PARAMETER);
  194. return(FALSE);
  195. }
  196. *pcbAgencyInfo = 0;
  197. if (!(pExt = CertFindExtension(SPC_SP_AGENCY_INFO_OBJID, pCert->pCertInfo->cExtension,
  198. pCert->pCertInfo->rgExtension)))
  199. {
  200. return(FALSE);
  201. }
  202. CryptDecodeObject(X509_ASN_ENCODING, SPC_SP_AGENCY_INFO_STRUCT,
  203. pExt->Value.pbData, pExt->Value.cbData, 0, NULL,
  204. pcbAgencyInfo);
  205. if (*pcbAgencyInfo == 0)
  206. {
  207. return(FALSE);
  208. }
  209. if (!(pAgencyInfo))
  210. {
  211. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  212. return(FALSE);
  213. }
  214. if (!(CryptDecodeObject(X509_ASN_ENCODING, SPC_SP_AGENCY_INFO_STRUCT,
  215. pExt->Value.pbData, pExt->Value.cbData, 0, pAgencyInfo,
  216. pcbAgencyInfo)))
  217. {
  218. return(FALSE);
  219. }
  220. return(TRUE);
  221. }
  222. BOOL WINAPI WTHelperCheckCertUsage(PCCERT_CONTEXT pCertContext, LPCSTR pszRequestedUsageOID)
  223. {
  224. PCERT_ENHKEY_USAGE pUsage;
  225. DWORD cbUsage;
  226. cbUsage = 0;
  227. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
  228. if (cbUsage > 0)
  229. {
  230. if (!(pUsage = (PCERT_ENHKEY_USAGE)new BYTE[cbUsage]))
  231. {
  232. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  233. return(FALSE);
  234. }
  235. if (!(CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  236. pUsage, &cbUsage)))
  237. {
  238. delete pUsage;
  239. return(FALSE);
  240. }
  241. //
  242. // the cert has enhanced key usage extensions, check if we find ours
  243. //
  244. if (!(_FindKeyUsage(pUsage, pszRequestedUsageOID)))
  245. {
  246. SetLastError(CERT_E_WRONG_USAGE);
  247. delete pUsage;
  248. return(FALSE);
  249. }
  250. delete pUsage;
  251. }
  252. //
  253. // OK... either we have NO EXTENSION or we found our OID in the list in the EXTENSION.
  254. // now, make sure if we have properties that it has been enabled.
  255. //
  256. cbUsage = 0;
  257. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
  258. if (cbUsage > 0)
  259. {
  260. if (!(pUsage = (PCERT_ENHKEY_USAGE)new BYTE[cbUsage]))
  261. {
  262. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  263. return(FALSE);
  264. }
  265. if (!(CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  266. pUsage, &cbUsage)))
  267. {
  268. delete pUsage;
  269. return(FALSE);
  270. }
  271. //
  272. // the cert has properties, first check if we're disabled
  273. //
  274. if (_FindKeyUsage(pUsage, szOID_YESNO_TRUST_ATTR))
  275. {
  276. SetLastError(CERT_E_WRONG_USAGE);
  277. delete pUsage;
  278. return(FALSE);
  279. }
  280. if (!(_FindKeyUsage(pUsage, pszRequestedUsageOID)))
  281. {
  282. SetLastError(CERT_E_WRONG_USAGE);
  283. delete pUsage;
  284. return(FALSE);
  285. }
  286. delete pUsage;
  287. }
  288. return(TRUE);
  289. }
  290. BOOL _FindKeyUsage(PCERT_ENHKEY_USAGE pUsage, LPCSTR pszRequestedUsageOID)
  291. {
  292. int i;
  293. for (i = 0; i < (int)pUsage->cUsageIdentifier; i++)
  294. {
  295. if (strcmp(pUsage->rgpszUsageIdentifier[i], pszRequestedUsageOID) == 0)
  296. {
  297. return(TRUE); // OK found it!
  298. }
  299. }
  300. return(FALSE);
  301. }
  302. BOOL WINAPI WTHelperIsInRootStore(CRYPT_PROVIDER_DATA *pProvData, PCCERT_CONTEXT pCertContext)
  303. {
  304. if (pProvData->chStores < 1)
  305. {
  306. return(FALSE);
  307. }
  308. //
  309. // check the fast way first!
  310. //
  311. if (pCertContext->hCertStore == pProvData->pahStores[0])
  312. {
  313. //
  314. // it's in the root store!
  315. //
  316. return(TRUE);
  317. }
  318. //
  319. // can't do it the fast way -- do it the slow way!
  320. //
  321. BYTE *pbHash;
  322. DWORD cbHash;
  323. CRYPT_HASH_BLOB sBlob;
  324. PCCERT_CONTEXT pWorkContext;
  325. cbHash = 0;
  326. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
  327. {
  328. return(FALSE);
  329. }
  330. if (cbHash < 1)
  331. {
  332. return(FALSE);
  333. }
  334. if (!(pbHash = (BYTE *)WVTNew(cbHash)))
  335. {
  336. return(FALSE);
  337. }
  338. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
  339. {
  340. delete pbHash;
  341. return(FALSE);
  342. }
  343. sBlob.cbData = cbHash;
  344. sBlob.pbData = pbHash;
  345. pWorkContext = CertFindCertificateInStore(pProvData->pahStores[0], pProvData->dwEncoding, 0,
  346. CERT_FIND_SHA1_HASH, &sBlob, NULL);
  347. delete pbHash;
  348. if (pWorkContext)
  349. {
  350. CertFreeCertificateContext(pWorkContext);
  351. return(TRUE);
  352. }
  353. return(FALSE);
  354. }
  355. typedef struct _ENUM_OID_INFO_ARG {
  356. DWORD cOidInfo;
  357. PCCRYPT_OID_INFO *ppOidInfo;
  358. } ENUM_OID_INFO_ARG, *PENUM_OID_INFO_ARG;
  359. static BOOL WINAPI EnumOidInfoCallback(
  360. IN PCCRYPT_OID_INFO pOidInfo,
  361. IN void *pvArg
  362. )
  363. {
  364. PENUM_OID_INFO_ARG pEnumOidInfoArg = (PENUM_OID_INFO_ARG) pvArg;
  365. PCCRYPT_OID_INFO *ppNewOidInfo;
  366. DWORD cOidInfo = pEnumOidInfoArg->cOidInfo;
  367. // DSIE: Bug 152473.
  368. for (DWORD i = 0; i < cOidInfo; i++)
  369. {
  370. if (0 == wcscmp(pOidInfo->pwszName, pEnumOidInfoArg->ppOidInfo[i]->pwszName))
  371. {
  372. return TRUE;
  373. }
  374. }
  375. if (ppNewOidInfo = (PCCRYPT_OID_INFO *) PkiRealloc(
  376. pEnumOidInfoArg->ppOidInfo,
  377. (cOidInfo + 2) * sizeof(PCCRYPT_OID_INFO))) {
  378. ppNewOidInfo[cOidInfo] = pOidInfo;
  379. ppNewOidInfo[cOidInfo + 1] = NULL;
  380. pEnumOidInfoArg->cOidInfo = cOidInfo + 1;
  381. pEnumOidInfoArg->ppOidInfo = ppNewOidInfo;
  382. }
  383. return TRUE;
  384. }
  385. BOOL WINAPI WTHelperGetKnownUsages(DWORD fdwAction, PCCRYPT_OID_INFO **pppOidInfo)
  386. {
  387. if (!(pppOidInfo))
  388. {
  389. SetLastError(ERROR_INVALID_PARAMETER);
  390. return(FALSE);
  391. }
  392. if (fdwAction == WTH_FREE)
  393. {
  394. PkiFree(*pppOidInfo);
  395. *pppOidInfo = NULL;
  396. return(TRUE);
  397. }
  398. if (fdwAction == WTH_ALLOC)
  399. {
  400. ENUM_OID_INFO_ARG EnumOidInfoArg;
  401. memset(&EnumOidInfoArg, 0, sizeof(EnumOidInfoArg));
  402. CryptEnumOIDInfo(
  403. CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
  404. 0, // dwFlags
  405. &EnumOidInfoArg,
  406. EnumOidInfoCallback
  407. );
  408. return (NULL != (*pppOidInfo = EnumOidInfoArg.ppOidInfo));
  409. }
  410. SetLastError(ERROR_INVALID_PARAMETER);
  411. *pppOidInfo = NULL;
  412. return(FALSE);
  413. }
  414. CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
  415. {
  416. return((CRYPT_PROVIDER_DATA *)hStateData);
  417. }