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.

1306 lines
38 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: drvprov.cpp
  8. //
  9. // Contents: Microsoft Internet Security Authenticode Policy Provider
  10. //
  11. // Functions: DriverInitializePolicy
  12. // DriverCleanupPolicy
  13. // DriverFinalPolicy
  14. // DriverRegisterServer
  15. // DriverUnregisterServer
  16. //
  17. // *** local functions ***
  18. // _ValidCatAttr
  19. // _CheckVersionAttributeNEW
  20. // _CheckVersionNEW
  21. // _GetVersionNumbers
  22. //
  23. // History: 29-Sep-1997 pberkman created
  24. //
  25. //--------------------------------------------------------------------------
  26. #include "global.hxx"
  27. BOOL _GetVersionNumbers(
  28. WCHAR *pwszMM,
  29. DWORD *pdwMajor,
  30. DWORD *pdwMinor,
  31. DWORD *pdwBuild,
  32. WCHAR *pwcFlagMinor,
  33. WCHAR *pwcFlagBuild);
  34. BOOL _ValidCatAttr(CRYPTCATATTRIBUTE *pAttr);
  35. BOOL _CheckVersionAttributeNEW(DRIVER_VER_INFO *pVerInfo, CRYPTCATATTRIBUTE *pAttr);
  36. DWORD _CheckVersionNEW(OSVERSIONINFO *pVersion, WCHAR *pwszAttr, BOOL fUseBuildNumber);
  37. static LPSTR rgDriverUsages[] = {szOID_WHQL_CRYPTO, szOID_NT5_CRYPTO, szOID_OEM_WHQL_CRYPTO};
  38. static CERT_USAGE_MATCH RequestUsage = {USAGE_MATCH_TYPE_OR, {sizeof(rgDriverUsages)/sizeof(LPSTR), rgDriverUsages}};
  39. typedef struct _DRVPROV_PRIVATE_DATA
  40. {
  41. DWORD cbStruct;
  42. CRYPT_PROVIDER_FUNCTIONS sAuthenticodePfns;
  43. } DRVPROV_PRIVATE_DATA, *PDRVPROV_PRIVATE_DATA;
  44. #define VER_CHECK_EQ 1
  45. #define VER_CHECK_GT 2
  46. #define VER_CHECK_LT 3
  47. #define VER_CHECK_FAIL 4
  48. HRESULT WINAPI DriverInitializePolicy(CRYPT_PROVIDER_DATA *pProvData)
  49. {
  50. if (!(pProvData->padwTrustStepErrors) ||
  51. (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] != ERROR_SUCCESS))
  52. {
  53. return (S_FALSE);
  54. }
  55. if (!(_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, pRequestUsage)))
  56. {
  57. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = ERROR_INVALID_PARAMETER;
  58. return (S_FALSE);
  59. }
  60. GUID gAuthenticode = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  61. GUID gDriverProv = DRIVER_ACTION_VERIFY;
  62. CRYPT_PROVIDER_PRIVDATA sPrivData;
  63. CRYPT_PROVIDER_PRIVDATA *pPrivData;
  64. DRVPROV_PRIVATE_DATA *pDriverData;
  65. HRESULT hr;
  66. hr = S_OK;
  67. pPrivData = WTHelperGetProvPrivateDataFromChain(pProvData, &gDriverProv);
  68. if (!(pPrivData))
  69. {
  70. memset(&sPrivData, 0x00, sizeof(CRYPT_PROVIDER_PRIVDATA));
  71. sPrivData.cbStruct = sizeof(CRYPT_PROVIDER_PRIVDATA);
  72. memcpy(&sPrivData.gProviderID, &gDriverProv, sizeof(GUID));
  73. //
  74. // add my data to the chain!
  75. //
  76. if (!pProvData->psPfns->pfnAddPrivData2Chain(pProvData, &sPrivData))
  77. {
  78. return (S_FALSE);
  79. }
  80. //
  81. // get the new reference
  82. //
  83. pPrivData = WTHelperGetProvPrivateDataFromChain(pProvData, &gDriverProv);
  84. }
  85. //
  86. // allocate space for my struct
  87. //
  88. if (!(pPrivData->pvProvData = pProvData->psPfns->pfnAlloc(sizeof(DRVPROV_PRIVATE_DATA))))
  89. {
  90. pProvData->dwError = GetLastError();
  91. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = TRUST_E_SYSTEM_ERROR;
  92. return (S_FALSE);
  93. }
  94. memset(pPrivData->pvProvData, 0x00, sizeof(DRVPROV_PRIVATE_DATA));
  95. pPrivData->cbProvData = sizeof(DRVPROV_PRIVATE_DATA);
  96. pDriverData = (DRVPROV_PRIVATE_DATA *)pPrivData->pvProvData;
  97. pDriverData->cbStruct = sizeof(DRVPROV_PRIVATE_DATA);
  98. //
  99. // fill in the Authenticode Functions
  100. //
  101. pDriverData->sAuthenticodePfns.cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
  102. if (!(WintrustLoadFunctionPointers(&gAuthenticode, &pDriverData->sAuthenticodePfns)))
  103. {
  104. pProvData->psPfns->pfnFree(sPrivData.pvProvData);
  105. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = TRUST_E_PROVIDER_UNKNOWN;
  106. return (S_FALSE);
  107. }
  108. if (pDriverData->sAuthenticodePfns.pfnInitialize)
  109. {
  110. hr = pDriverData->sAuthenticodePfns.pfnInitialize(pProvData);
  111. }
  112. //
  113. // assign our usage
  114. //
  115. pProvData->pRequestUsage = &RequestUsage;
  116. // for backwards compatibility
  117. pProvData->pszUsageOID = szOID_WHQL_CRYPTO;
  118. //
  119. // do NOT allow test certs EVER!
  120. //
  121. // changed July 27, 2000
  122. //
  123. pProvData->dwRegPolicySettings &= ~(WTPF_TRUSTTEST | WTPF_TESTCANBEVALID);
  124. //
  125. // do NOT require the publisher to be in the trusted database
  126. //
  127. // (changed July 27, 2000)
  128. //
  129. pProvData->dwRegPolicySettings &= ~WTPF_ALLOWONLYPERTRUST;
  130. return (hr);
  131. }
  132. HRESULT WINAPI DriverCleanupPolicy(CRYPT_PROVIDER_DATA *pProvData)
  133. {
  134. GUID gDriverProv = DRIVER_ACTION_VERIFY;
  135. CRYPT_PROVIDER_PRIVDATA *pMyData;
  136. DRVPROV_PRIVATE_DATA *pDriverData;
  137. HRESULT hr;
  138. if (!(pProvData->padwTrustStepErrors) ||
  139. (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] != ERROR_SUCCESS))
  140. {
  141. return (S_FALSE);
  142. }
  143. hr = S_OK;
  144. pMyData = WTHelperGetProvPrivateDataFromChain(pProvData, &gDriverProv);
  145. if (pMyData)
  146. {
  147. pDriverData = (DRVPROV_PRIVATE_DATA *)pMyData->pvProvData;
  148. if (pDriverData != NULL)
  149. {
  150. //
  151. // remove the data we allocated except for the "MyData"
  152. // which WVT will clean up for us!
  153. //
  154. if (pDriverData->sAuthenticodePfns.pfnCleanupPolicy)
  155. {
  156. hr = pDriverData->sAuthenticodePfns.pfnCleanupPolicy(pProvData);
  157. }
  158. }
  159. pProvData->psPfns->pfnFree(pMyData->pvProvData);
  160. pMyData->pvProvData = NULL;
  161. pMyData->cbProvData = 0;
  162. }
  163. return (hr);
  164. }
  165. //+-------------------------------------------------------------------------
  166. // Allocates and returns the specified cryptographic message parameter.
  167. //--------------------------------------------------------------------------
  168. static void *AllocAndGetMsgParam(
  169. IN HCRYPTMSG hMsg,
  170. IN DWORD dwParamType,
  171. IN DWORD dwIndex,
  172. OUT DWORD *pcbData
  173. )
  174. {
  175. void *pvData;
  176. DWORD cbData;
  177. if (!CryptMsgGetParam(
  178. hMsg,
  179. dwParamType,
  180. dwIndex,
  181. NULL, // pvData
  182. &cbData) || 0 == cbData)
  183. goto GetParamError;
  184. if (NULL == (pvData = malloc(cbData)))
  185. goto OutOfMemory;
  186. if (!CryptMsgGetParam(
  187. hMsg,
  188. dwParamType,
  189. dwIndex,
  190. pvData,
  191. &cbData)) {
  192. free(pvData);
  193. goto GetParamError;
  194. }
  195. CommonReturn:
  196. *pcbData = cbData;
  197. return pvData;
  198. ErrorReturn:
  199. pvData = NULL;
  200. cbData = 0;
  201. goto CommonReturn;
  202. TRACE_ERROR(OutOfMemory)
  203. TRACE_ERROR(GetParamError)
  204. }
  205. //+-------------------------------------------------------------------------
  206. // Alloc and NOCOPY Decode
  207. //--------------------------------------------------------------------------
  208. static void *AllocAndDecodeObject(
  209. IN LPCSTR lpszStructType,
  210. IN const BYTE *pbEncoded,
  211. IN DWORD cbEncoded
  212. )
  213. {
  214. DWORD cbStructInfo;
  215. void *pvStructInfo;
  216. CryptDecodeObject(
  217. X509_ASN_ENCODING,
  218. lpszStructType,
  219. pbEncoded,
  220. cbEncoded,
  221. CRYPT_DECODE_NOCOPY_FLAG,
  222. NULL, // pvStructInfo
  223. &cbStructInfo
  224. );
  225. if (cbStructInfo == 0)
  226. goto ErrorReturn;
  227. if (NULL == (pvStructInfo = malloc(cbStructInfo)))
  228. goto ErrorReturn;
  229. if (!CryptDecodeObject(
  230. X509_ASN_ENCODING,
  231. lpszStructType,
  232. pbEncoded,
  233. cbEncoded,
  234. CRYPT_DECODE_NOCOPY_FLAG,
  235. pvStructInfo,
  236. &cbStructInfo
  237. )) {
  238. free(pvStructInfo);
  239. goto ErrorReturn;
  240. }
  241. CommonReturn:
  242. return pvStructInfo;
  243. ErrorReturn:
  244. pvStructInfo = NULL;
  245. goto CommonReturn;
  246. }
  247. static void CopyBytesToMaxPathString(
  248. IN const BYTE *pbData,
  249. IN DWORD cbData,
  250. OUT WCHAR wszDst[MAX_PATH]
  251. )
  252. {
  253. DWORD cchDst;
  254. if (pbData) {
  255. cchDst = cbData / sizeof(WCHAR);
  256. if (cchDst > MAX_PATH - 1)
  257. cchDst = MAX_PATH - 1;
  258. } else
  259. cchDst = 0;
  260. if (cchDst)
  261. memcpy(wszDst, pbData, cchDst * sizeof(WCHAR));
  262. wszDst[cchDst] = L'\0';
  263. }
  264. void UpdateDriverVersion(
  265. IN CRYPT_PROVIDER_DATA *pProvData,
  266. OUT WCHAR wszVersion[MAX_PATH]
  267. )
  268. {
  269. HCRYPTMSG hMsg = pProvData->hMsg;
  270. BYTE *pbContent = NULL;
  271. DWORD cbContent;
  272. PCTL_INFO pCtlInfo = NULL;
  273. PCERT_EXTENSION pExt; // not allocated
  274. PCAT_NAMEVALUE pNameValue = NULL;
  275. if (NULL == hMsg)
  276. goto NoMessage;
  277. // Get the inner content.
  278. if (NULL == (pbContent = (BYTE *) AllocAndGetMsgParam(
  279. hMsg,
  280. CMSG_CONTENT_PARAM,
  281. 0, // dwIndex
  282. &cbContent))) goto GetContentError;
  283. if (NULL == (pCtlInfo = (PCTL_INFO) AllocAndDecodeObject(
  284. PKCS_CTL,
  285. pbContent,
  286. cbContent
  287. )))
  288. goto DecodeCtlError;
  289. if (NULL == (pExt = CertFindExtension(
  290. CAT_NAMEVALUE_OBJID,
  291. pCtlInfo->cExtension,
  292. pCtlInfo->rgExtension
  293. )))
  294. goto NoVersionExt;
  295. if (NULL == (pNameValue = (PCAT_NAMEVALUE) AllocAndDecodeObject(
  296. CAT_NAMEVALUE_STRUCT,
  297. pExt->Value.pbData,
  298. pExt->Value.cbData
  299. )))
  300. goto DecodeNameValueError;
  301. CopyBytesToMaxPathString(pNameValue->Value.pbData,
  302. pNameValue->Value.cbData, wszVersion);
  303. CommonReturn:
  304. if (pNameValue)
  305. free(pNameValue);
  306. if (pCtlInfo)
  307. free(pCtlInfo);
  308. if (pbContent)
  309. free(pbContent);
  310. return;
  311. ErrorReturn:
  312. wszVersion[0] = L'\0';
  313. goto CommonReturn;
  314. TRACE_ERROR(NoMessage)
  315. TRACE_ERROR(GetContentError)
  316. TRACE_ERROR(DecodeCtlError)
  317. TRACE_ERROR(NoVersionExt)
  318. TRACE_ERROR(DecodeNameValueError)
  319. }
  320. BOOL _ValidCatAttr(CRYPTCATATTRIBUTE *pAttr)
  321. {
  322. if (!(pAttr) || (pAttr->cbValue < 1) || !(pAttr->pbValue))
  323. {
  324. return(FALSE);
  325. }
  326. return TRUE;
  327. }
  328. HRESULT WINAPI DriverFinalPolicy(CRYPT_PROVIDER_DATA *pProvData)
  329. {
  330. GUID gDriverProv = DRIVER_ACTION_VERIFY;
  331. HRESULT hr;
  332. CRYPT_PROVIDER_PRIVDATA *pMyData;
  333. CRYPTCATATTRIBUTE *pCatAttr;
  334. CRYPTCATATTRIBUTE *pMemAttr;
  335. DRIVER_VER_INFO *pVerInfo;
  336. DWORD dwExceptionCode;
  337. BOOL fUseCurrentOSVer = FALSE;
  338. hr = ERROR_SUCCESS;
  339. if (!(_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, pszUsageOID)) ||
  340. !(pProvData->pWintrustData) ||
  341. !(_ISINSTRUCT(WINTRUST_DATA, pProvData->pWintrustData->cbStruct, hWVTStateData)))
  342. {
  343. goto ErrorInvalidParam;
  344. }
  345. //
  346. // Initialize the fUseCurrentOSVer variable
  347. //
  348. if (_ISINSTRUCT(WINTRUST_DATA, pProvData->pWintrustData->cbStruct, dwProvFlags))
  349. {
  350. fUseCurrentOSVer =
  351. (pProvData->pWintrustData->dwProvFlags & WTD_USE_DEFAULT_OSVER_CHECK) != 0;
  352. }
  353. //
  354. //
  355. //
  356. pVerInfo = (DRIVER_VER_INFO *)pProvData->pWintrustData->pPolicyCallbackData;
  357. if (pVerInfo)
  358. {
  359. CRYPT_PROVIDER_SGNR *pSgnr;
  360. CRYPT_PROVIDER_CERT *pCert;
  361. // KeithV
  362. // Today we do not support ranges of versions, so the version
  363. // number must be the same. Also must be none zero
  364. // Removed this check so that ranges can now be used - 9-10-99 (reidk)
  365. /*if ((_ISINSTRUCT(DRIVER_VER_INFO, pVerInfo->cbStruct, sOSVersionLow)) &&
  366. (_ISINSTRUCT(DRIVER_VER_INFO, pVerInfo->cbStruct, sOSVersionHigh)))
  367. {
  368. if(memcmp(&pVerInfo->sOSVersionLow,
  369. &pVerInfo->sOSVersionHigh,
  370. sizeof(DRIVER_VER_MAJORMINOR)) )
  371. {
  372. goto ErrorInvalidParam;
  373. }
  374. }*/
  375. if (!(_ISINSTRUCT(DRIVER_VER_INFO, pVerInfo->cbStruct, pcSignerCertContext)))
  376. {
  377. goto ErrorInvalidParam;
  378. }
  379. pVerInfo->wszVersion[0] = NULL;
  380. if (!(pSgnr = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0)))
  381. {
  382. goto ErrorNoSigner;
  383. }
  384. if (!(pCert = WTHelperGetProvCertFromChain(pSgnr, 0)))
  385. {
  386. goto ErrorNoCert;
  387. }
  388. if (pCert->pCert)
  389. {
  390. CertGetNameStringW(
  391. pCert->pCert,
  392. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  393. 0, // dwFlags
  394. NULL, // pvTypePara
  395. pVerInfo->wszSignedBy,
  396. MAX_PATH
  397. );
  398. pVerInfo->pcSignerCertContext = CertDuplicateCertificateContext(pCert->pCert);
  399. if (pVerInfo->dwReserved1 == 0x1 && pVerInfo->dwReserved2 == 0) {
  400. HCRYPTMSG hMsg = pProvData->hMsg;
  401. // Return the message's store
  402. if (hMsg) {
  403. HCERTSTORE hStore;
  404. hStore = CertOpenStore(
  405. CERT_STORE_PROV_MSG,
  406. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  407. 0, // hCryptProv
  408. 0, // dwFlags
  409. (const void *) hMsg
  410. );
  411. pVerInfo->dwReserved2 = (ULONG_PTR) hStore;
  412. }
  413. }
  414. }
  415. }
  416. if (pProvData->padwTrustStepErrors)
  417. {
  418. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] = ERROR_SUCCESS;
  419. }
  420. if ((hr = checkGetErrorBasedOnStepErrors(pProvData)) != ERROR_SUCCESS)
  421. {
  422. goto StepError;
  423. }
  424. pCatAttr = NULL;
  425. pMemAttr = NULL;
  426. if ((pProvData->pPDSip) &&
  427. (_ISINSTRUCT(PROVDATA_SIP, pProvData->pPDSip->cbStruct, psIndirectData)) &&
  428. (pProvData->pPDSip->psSipSubjectInfo) &&
  429. (pProvData->pPDSip->psSipSubjectInfo->dwUnionChoice == MSSIP_ADDINFO_CATMEMBER) &&
  430. (pProvData->pPDSip->psSipSubjectInfo->psCatMember) &&
  431. (pProvData->pPDSip->psSipSubjectInfo->psCatMember->pStore) &&
  432. (pProvData->pPDSip->psSipSubjectInfo->psCatMember->pMember) &&
  433. (pProvData->pWintrustData->dwUnionChoice == WTD_CHOICE_CATALOG))
  434. {
  435. // The following APIs are in DELAYLOAD'ed mscat32.dll. If the
  436. // DELAYLOAD fails an exception is raised.
  437. __try {
  438. HANDLE hCatStore;
  439. hCatStore = CryptCATHandleFromStore(pProvData->pPDSip->psSipSubjectInfo->psCatMember->pStore);
  440. //
  441. // first look at the members attr
  442. //
  443. pMemAttr = CryptCATGetAttrInfo(hCatStore,
  444. pProvData->pPDSip->psSipSubjectInfo->psCatMember->pMember,
  445. L"OSAttr");
  446. pCatAttr = CryptCATGetCatAttrInfo(hCatStore, L"OSAttr");
  447. //
  448. // This statement is to honor old _weird_ semantics where if there is a
  449. // pointer to a pVerInfo struct and both the dwPlatformId/dwVersion fields
  450. // of it are zero then don't do a version check. (probably for sigverif, or maybe
  451. // even un-intentional, but keep old semantics regardless)
  452. //
  453. if ((pVerInfo == NULL) ||
  454. (pVerInfo->dwPlatform != 0) ||
  455. (pVerInfo->dwVersion != 0) ||
  456. fUseCurrentOSVer)
  457. {
  458. if (_ValidCatAttr(pMemAttr))
  459. {
  460. if (!(_CheckVersionAttributeNEW(
  461. fUseCurrentOSVer ? NULL : pVerInfo,
  462. pMemAttr)))
  463. {
  464. goto OSAttrVersionError;
  465. }
  466. }
  467. else
  468. {
  469. if (!_ValidCatAttr(pCatAttr) && !_ValidCatAttr(pMemAttr))
  470. {
  471. goto ValidOSAttrNotFound;
  472. }
  473. if (!(_CheckVersionAttributeNEW(
  474. fUseCurrentOSVer ? NULL : pVerInfo,
  475. pCatAttr)))
  476. {
  477. goto OSAttrVersionError;
  478. }
  479. }
  480. }
  481. } __except(EXCEPTION_EXECUTE_HANDLER) {
  482. dwExceptionCode = GetExceptionCode();
  483. goto CryptCATException;
  484. }
  485. }
  486. else if ((pProvData->pWintrustData) &&
  487. (pProvData->pWintrustData->dwUnionChoice == WTD_CHOICE_CATALOG))
  488. {
  489. goto ErrorInvalidParam;
  490. }
  491. //
  492. // fill our name for SigVerif...
  493. //
  494. if (pVerInfo)
  495. {
  496. if (!(pVerInfo->wszVersion[0]))
  497. {
  498. if ((pMemAttr) && (pMemAttr->cbValue > 0) && (pMemAttr->pbValue))
  499. {
  500. CopyBytesToMaxPathString(pMemAttr->pbValue, pMemAttr->cbValue,
  501. pVerInfo->wszVersion);
  502. }
  503. else if ((pCatAttr) && (pCatAttr->cbValue > 0) && (pCatAttr->pbValue))
  504. {
  505. CopyBytesToMaxPathString(pCatAttr->pbValue, pCatAttr->cbValue,
  506. pVerInfo->wszVersion);
  507. }
  508. else
  509. {
  510. UpdateDriverVersion(pProvData, pVerInfo->wszVersion);
  511. }
  512. }
  513. }
  514. //
  515. // retrieve my data from the provider struct
  516. //
  517. pMyData = WTHelperGetProvPrivateDataFromChain(pProvData, &gDriverProv);
  518. if (pMyData)
  519. {
  520. DRVPROV_PRIVATE_DATA *pDriverData;
  521. pDriverData = (DRVPROV_PRIVATE_DATA *)pMyData->pvProvData;
  522. //
  523. // call the standard final policy
  524. //
  525. if (pDriverData)
  526. {
  527. if (pDriverData->sAuthenticodePfns.pfnFinalPolicy)
  528. {
  529. DWORD dwOldUIFlags;
  530. dwOldUIFlags = pProvData->pWintrustData->dwUIChoice;
  531. pProvData->pWintrustData->dwUIChoice = WTD_UI_NONE;
  532. hr = pDriverData->sAuthenticodePfns.pfnFinalPolicy(pProvData);
  533. pProvData->pWintrustData->dwUIChoice = dwOldUIFlags;
  534. }
  535. }
  536. }
  537. CommonReturn:
  538. if (hr != ERROR_INVALID_PARAMETER)
  539. {
  540. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] = hr;
  541. }
  542. return (hr);
  543. ErrorReturn:
  544. hr = GetLastError();
  545. goto CommonReturn;
  546. SET_ERROR_VAR_EX(DBG_SS, ErrorInvalidParam, ERROR_INVALID_PARAMETER);
  547. SET_ERROR_VAR_EX(DBG_SS, ErrorNoSigner, TRUST_E_NOSIGNATURE);
  548. SET_ERROR_VAR_EX(DBG_SS, ErrorNoCert, TRUST_E_NO_SIGNER_CERT);
  549. SET_ERROR_VAR_EX(DBG_SS, ValidOSAttrNotFound,ERROR_APP_WRONG_OS);
  550. SET_ERROR_VAR_EX(DBG_SS, OSAttrVersionError,ERROR_APP_WRONG_OS);
  551. SET_ERROR_VAR_EX(DBG_SS, StepError, hr);
  552. SET_ERROR_VAR_EX(DBG_SS, CryptCATException, dwExceptionCode);
  553. }
  554. #define OSATTR_ALL L'X'
  555. #define OSATTR_GTEQ L'>'
  556. #define OSATTR_LTEQ L'-'
  557. #define OSATTR_LTEQ2 L'<'
  558. #define OSATTR_OSSEP L':'
  559. #define OSATTR_VERSEP L'.'
  560. #define OSATTR_SEP L','
  561. #define OSATTR_RANGE_SEP L';'
  562. //
  563. // NEW
  564. //
  565. BOOL _CheckVersionAttributeNEW(DRIVER_VER_INFO *pVerInfo, CRYPTCATATTRIBUTE *pAttr)
  566. {
  567. OSVERSIONINFO sVersion;
  568. OSVERSIONINFO sVersionSave;
  569. WCHAR *pwszCurrent;
  570. WCHAR *pwszEnd = NULL;
  571. WCHAR *pwszRangeSeperator = NULL;
  572. BOOL fCheckRange = FALSE;
  573. BOOL fUseBuildNumber = FALSE;
  574. DWORD dwLowCheck;
  575. DWORD dwHighCheck;
  576. //
  577. // If no version info was passed in, get the current
  578. // OS version to that verification can be done against it
  579. //
  580. memset(&sVersion, 0x00, sizeof(OSVERSIONINFO));
  581. if ((NULL == pVerInfo) || (pVerInfo->dwPlatform == 0))
  582. {
  583. sVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  584. if (!GetVersionEx(&sVersion))
  585. {
  586. return FALSE;
  587. }
  588. fUseBuildNumber = TRUE;
  589. }
  590. else
  591. {
  592. //
  593. // Analyze the pVerInfo struct and deduce whether we are checking a range,
  594. // and/or whether the dwBuildNumber* fields exist and are being used.
  595. //
  596. if (_ISINSTRUCT(DRIVER_VER_INFO, pVerInfo->cbStruct, sOSVersionHigh))
  597. {
  598. //
  599. // If version are different then a range is being used
  600. //
  601. if (memcmp( &(pVerInfo->sOSVersionLow),
  602. &(pVerInfo->sOSVersionHigh),
  603. sizeof(DRIVER_VER_MAJORMINOR)) != 0)
  604. {
  605. fCheckRange = TRUE;
  606. }
  607. //
  608. // Just set these here since the first check is the same regardless
  609. // of whetther we are doing range checking or not.
  610. //
  611. sVersion.dwPlatformId = pVerInfo->dwPlatform;
  612. sVersion.dwMajorVersion = pVerInfo->sOSVersionLow.dwMajor;
  613. sVersion.dwMinorVersion = pVerInfo->sOSVersionLow.dwMinor;
  614. //
  615. // Check to see if the dwBuildNumber* members exists, and
  616. // if they are being used (not 0).
  617. //
  618. if ((_ISINSTRUCT(DRIVER_VER_INFO, pVerInfo->cbStruct, dwBuildNumberHigh)) &&
  619. pVerInfo->dwBuildNumberLow != 0)
  620. {
  621. fUseBuildNumber = TRUE;
  622. fCheckRange |= (pVerInfo->dwBuildNumberLow == pVerInfo->dwBuildNumberHigh) ?
  623. FALSE : TRUE;
  624. //
  625. // Just set this in case we aren't doing range checking
  626. //
  627. sVersion.dwBuildNumber = pVerInfo->dwBuildNumberLow;
  628. }
  629. }
  630. else
  631. {
  632. sVersion.dwPlatformId = pVerInfo->dwPlatform;
  633. sVersion.dwMajorVersion = pVerInfo->dwVersion;
  634. sVersion.dwMinorVersion = 0;
  635. }
  636. }
  637. //
  638. // Save this in case multiple OSAttr elements need to be checked against
  639. // a range
  640. //
  641. memcpy(&sVersionSave, &sVersion, sizeof(OSVERSIONINFO));
  642. //
  643. // Loop for each version in the attribute, and check to see if
  644. // it satifies our criteria
  645. //
  646. pwszCurrent = (WCHAR *)pAttr->pbValue;
  647. while ((pwszCurrent != NULL) && (*pwszCurrent))
  648. {
  649. //
  650. // Find version seperator, insert '/0' if needed, and keep
  651. // track of location for next time through the loop
  652. //
  653. pwszEnd = wcschr(pwszCurrent, OSATTR_SEP);
  654. if (pwszEnd)
  655. {
  656. *pwszEnd = L'\0';
  657. }
  658. //
  659. // Check to see if this version string is a range
  660. //
  661. pwszRangeSeperator = wcschr(pwszCurrent, OSATTR_RANGE_SEP);
  662. if (pwszRangeSeperator != NULL)
  663. {
  664. //
  665. // The version string in the cat file is a range
  666. //
  667. *pwszRangeSeperator = L'\0';
  668. pwszRangeSeperator++;
  669. dwLowCheck = _CheckVersionNEW(&sVersion, pwszCurrent, fUseBuildNumber);
  670. //
  671. // The only difference between checking a single OS version against a range,
  672. // and checking a range of OS versions agains a range is the value used for the
  673. // upper limit.
  674. //
  675. if (fCheckRange)
  676. {
  677. sVersion.dwPlatformId = pVerInfo->dwPlatform;
  678. sVersion.dwMajorVersion = pVerInfo->sOSVersionHigh.dwMajor;
  679. sVersion.dwMinorVersion = pVerInfo->sOSVersionHigh.dwMinor;
  680. sVersion.dwBuildNumber = (fUseBuildNumber) ? pVerInfo->dwBuildNumberHigh : 0;
  681. }
  682. dwHighCheck = _CheckVersionNEW(&sVersion, pwszRangeSeperator, fUseBuildNumber);
  683. if (((dwLowCheck == VER_CHECK_EQ) || (dwLowCheck == VER_CHECK_GT)) &&
  684. ((dwHighCheck == VER_CHECK_EQ) || (dwHighCheck == VER_CHECK_LT)))
  685. {
  686. if (pVerInfo)
  687. {
  688. CopyBytesToMaxPathString(
  689. pAttr->pbValue,
  690. pAttr->cbValue,
  691. pVerInfo->wszVersion);
  692. }
  693. *(--pwszRangeSeperator) = OSATTR_RANGE_SEP;
  694. if (pwszEnd != NULL)
  695. {
  696. *pwszEnd = OSATTR_SEP;
  697. }
  698. return (TRUE);
  699. }
  700. *(--pwszRangeSeperator) = OSATTR_RANGE_SEP;
  701. //
  702. // copy back the low OSVER to get ready for the next pass
  703. //
  704. memcpy(&sVersion, &sVersionSave, sizeof(OSVERSIONINFO));
  705. }
  706. else
  707. {
  708. if (!fCheckRange)
  709. {
  710. if (_CheckVersionNEW(&sVersion, pwszCurrent, fUseBuildNumber) == VER_CHECK_EQ)
  711. {
  712. if (pVerInfo)
  713. {
  714. CopyBytesToMaxPathString(
  715. pAttr->pbValue,
  716. pAttr->cbValue,
  717. pVerInfo->wszVersion);
  718. }
  719. if (pwszEnd != NULL)
  720. {
  721. *pwszEnd = OSATTR_SEP;
  722. }
  723. return (TRUE);
  724. }
  725. }
  726. else
  727. {
  728. dwLowCheck = _CheckVersionNEW(&sVersion, pwszCurrent, fUseBuildNumber);
  729. sVersion.dwPlatformId = pVerInfo->dwPlatform;
  730. sVersion.dwMajorVersion = pVerInfo->sOSVersionHigh.dwMajor;
  731. sVersion.dwMinorVersion = pVerInfo->sOSVersionHigh.dwMinor;
  732. sVersion.dwBuildNumber = (fUseBuildNumber) ? pVerInfo->dwBuildNumberHigh : 0;
  733. dwHighCheck = _CheckVersionNEW(&sVersion, pwszCurrent, fUseBuildNumber);
  734. if (((dwLowCheck == VER_CHECK_EQ) || (dwLowCheck == VER_CHECK_LT)) &&
  735. ((dwHighCheck == VER_CHECK_EQ) || (dwHighCheck == VER_CHECK_GT)))
  736. {
  737. if (pVerInfo)
  738. {
  739. CopyBytesToMaxPathString(
  740. pAttr->pbValue,
  741. pAttr->cbValue,
  742. pVerInfo->wszVersion);
  743. }
  744. if (pwszEnd != NULL)
  745. {
  746. *pwszEnd = OSATTR_SEP;
  747. }
  748. return (TRUE);
  749. }
  750. //
  751. // copy back the low OSVER to get ready for the next pass
  752. //
  753. memcpy(&sVersion, &sVersionSave, sizeof(OSVERSIONINFO));
  754. }
  755. }
  756. //
  757. // If there aren't anymore version in the attribute, then break,
  758. // which means the version check failed
  759. //
  760. if (!(pwszEnd))
  761. {
  762. break;
  763. }
  764. //
  765. // Set up for next iteration
  766. //
  767. *pwszEnd = OSATTR_SEP;
  768. pwszCurrent = pwszEnd;
  769. pwszCurrent++;
  770. }
  771. return (FALSE);
  772. }
  773. //
  774. // Comparison is done such that pVersion is VER_CHECK_LT, VER_CHECK_GT, or
  775. // VER_CHECK_EQ to pwszAttr
  776. //
  777. DWORD _CheckVersionNEW(OSVERSIONINFO *pVersion, WCHAR *pwszAttr, BOOL fUseBuildNumber)
  778. {
  779. WCHAR *pwszCurrent;
  780. WCHAR *pwszEnd;
  781. DWORD dwPlatform;
  782. DWORD dwMajor;
  783. DWORD dwMinor;
  784. DWORD dwBuild;
  785. WCHAR wcFlagMinor;
  786. WCHAR wcFlagBuild;
  787. pwszCurrent = pwszAttr;
  788. //
  789. // format: os:major.minor, os:major.minor, ...
  790. // 2:4.x = NT 4 (all)
  791. // 2:4.> = NT 4 (all) and beyond
  792. // 2:4.- = NT 4 (all) and before
  793. // 2:4.< = NT 4 (all) and before
  794. // 2:4.1.x = NT 4.1 (all)
  795. // 2:4.1.> = NT 4.1 (all) and beyond
  796. // 2:4.1.- = NT 4.1 (all) and before
  797. // 2:4.1.< = NT 4.1 (all) and before
  798. // 2:4.1 = NT 4.1 only
  799. // 2:4.1.1 = NT 4.1 build # 1 only
  800. //
  801. if (!(pwszEnd = wcschr(pwszAttr, OSATTR_OSSEP)))
  802. {
  803. return(VER_CHECK_FAIL);
  804. }
  805. *pwszEnd = NULL;
  806. //
  807. // Check platform first
  808. //
  809. dwPlatform = (DWORD) _wtol(pwszCurrent);
  810. *pwszEnd = OSATTR_OSSEP;
  811. //
  812. // MUST be same platform
  813. //
  814. if (dwPlatform != pVersion->dwPlatformId)
  815. {
  816. return(VER_CHECK_FAIL);
  817. }
  818. pwszCurrent = pwszEnd;
  819. pwszCurrent++;
  820. if (!(_GetVersionNumbers(pwszCurrent, &dwMajor, &dwMinor, &dwBuild, &wcFlagMinor, &wcFlagBuild)))
  821. {
  822. return(VER_CHECK_FAIL);
  823. }
  824. //
  825. // The only way we can check against a build# is if the OSAttr has some build# node...
  826. // which is not the case for an OSAttr like 2.4.x
  827. //
  828. if ((fUseBuildNumber && (dwBuild != 0)) ||
  829. (wcFlagBuild != L'\0'))
  830. {
  831. switch (wcFlagBuild)
  832. {
  833. case OSATTR_ALL:
  834. // 2:4.1.x = NT 4.1 (all)
  835. if ((pVersion->dwMajorVersion == dwMajor) && (pVersion->dwMinorVersion == dwMinor))
  836. {
  837. return(VER_CHECK_EQ);
  838. }
  839. else if ((pVersion->dwMajorVersion < dwMajor) ||
  840. ((pVersion->dwMajorVersion == dwMajor) && (pVersion->dwMinorVersion < dwMinor)))
  841. {
  842. return(VER_CHECK_LT);
  843. }
  844. else
  845. {
  846. return(VER_CHECK_GT);
  847. }
  848. break;
  849. case OSATTR_GTEQ:
  850. // 2:4.1.> = NT 4.1 (all) and beyond
  851. if ((pVersion->dwMajorVersion > dwMajor) ||
  852. ((pVersion->dwMajorVersion == dwMajor) && (pVersion->dwMinorVersion >= dwMinor)))
  853. {
  854. return(VER_CHECK_EQ);
  855. }
  856. else
  857. {
  858. return(VER_CHECK_LT);
  859. }
  860. break;
  861. case OSATTR_LTEQ:
  862. case OSATTR_LTEQ2:
  863. // 2:4.1.- = NT 4.1 (all) and before
  864. // 2:4.1.< = NT 4.1 (all) and before
  865. if ((pVersion->dwMajorVersion < dwMajor) ||
  866. ((pVersion->dwMajorVersion == dwMajor) && (pVersion->dwMinorVersion <= dwMinor)))
  867. {
  868. return(VER_CHECK_EQ);
  869. }
  870. else
  871. {
  872. return(VER_CHECK_GT);
  873. }
  874. break;
  875. default:
  876. // 2:4.1.1 = NT 4.1 build # 1 only
  877. if (pVersion->dwMajorVersion < dwMajor)
  878. {
  879. return(VER_CHECK_LT);
  880. }
  881. else if (pVersion->dwMajorVersion > dwMajor)
  882. {
  883. return(VER_CHECK_GT);
  884. }
  885. else
  886. {
  887. if (pVersion->dwMinorVersion < dwMinor)
  888. {
  889. return(VER_CHECK_LT);
  890. }
  891. else if (pVersion->dwMinorVersion > dwMinor)
  892. {
  893. return(VER_CHECK_GT);
  894. }
  895. else
  896. {
  897. if (pVersion->dwBuildNumber == dwBuild)
  898. {
  899. return(VER_CHECK_EQ);
  900. }
  901. else if (pVersion->dwBuildNumber < dwBuild)
  902. {
  903. return(VER_CHECK_LT);
  904. }
  905. else
  906. {
  907. return(VER_CHECK_GT);
  908. }
  909. }
  910. }
  911. break;
  912. }
  913. }
  914. switch (wcFlagMinor)
  915. {
  916. case OSATTR_ALL:
  917. // 2:4.x = NT 4 (all)
  918. if (pVersion->dwMajorVersion == dwMajor)
  919. {
  920. return(VER_CHECK_EQ);
  921. }
  922. else if (pVersion->dwMajorVersion < dwMajor)
  923. {
  924. return(VER_CHECK_LT);
  925. }
  926. else
  927. {
  928. return(VER_CHECK_GT);
  929. }
  930. break;
  931. case OSATTR_GTEQ:
  932. // 2:4.> = NT 4 (all) and beyond
  933. if (pVersion->dwMajorVersion >= dwMajor)
  934. {
  935. return(VER_CHECK_EQ);
  936. }
  937. else
  938. {
  939. return(VER_CHECK_LT);
  940. }
  941. break;
  942. case OSATTR_LTEQ:
  943. case OSATTR_LTEQ2:
  944. // 2:4.- = NT 4 (all) and before
  945. // 2:4.< = NT 4 (all) and before
  946. if (pVersion->dwMajorVersion <= dwMajor)
  947. {
  948. return(VER_CHECK_EQ);
  949. }
  950. else
  951. {
  952. return(VER_CHECK_GT);
  953. }
  954. break;
  955. default:
  956. // 2:4.1 = NT 4.1 only
  957. if ((pVersion->dwMajorVersion == dwMajor) && (pVersion->dwMinorVersion == dwMinor))
  958. {
  959. return(VER_CHECK_EQ);
  960. }
  961. else if (pVersion->dwMajorVersion == dwMajor)
  962. {
  963. if (pVersion->dwMinorVersion < dwMinor)
  964. {
  965. return(VER_CHECK_LT);
  966. }
  967. else
  968. {
  969. return(VER_CHECK_GT);
  970. }
  971. }
  972. else if (pVersion->dwMajorVersion < dwMajor)
  973. {
  974. return(VER_CHECK_LT);
  975. }
  976. else
  977. {
  978. return(VER_CHECK_GT);
  979. }
  980. break;
  981. }
  982. return(VER_CHECK_FAIL);
  983. }
  984. BOOL _GetVersionNumbers(
  985. WCHAR *pwszMM,
  986. DWORD *pdwMajor,
  987. DWORD *pdwMinor,
  988. DWORD *pdwBuild,
  989. WCHAR *pwcFlagMinor,
  990. WCHAR *pwcFlagBuild)
  991. {
  992. //
  993. // special characters:
  994. // - = all versions less than or equal to
  995. // < = all versions less than or equal to
  996. // > = all versions greater than or equal to
  997. // X = all sub-versions.
  998. //
  999. WCHAR *pwszEnd;
  1000. *pdwMajor = 0;
  1001. *pdwMinor = 0;
  1002. *pdwBuild = 0;
  1003. *pwcFlagMinor = L'\0';
  1004. *pwcFlagBuild = L'\0';
  1005. if (pwszEnd = wcschr(pwszMM, OSATTR_VERSEP))
  1006. {
  1007. *pwszEnd = NULL;
  1008. }
  1009. *pdwMajor = (DWORD) _wtol(pwszMM);
  1010. //
  1011. // If there is only a major ver then return now, otherwise,
  1012. // continue processiing
  1013. //
  1014. if (pwszEnd == NULL)
  1015. {
  1016. return (TRUE);
  1017. }
  1018. *pwszEnd = OSATTR_VERSEP;
  1019. pwszMM = pwszEnd;
  1020. pwszMM++;
  1021. if (*pwszMM == '/0')
  1022. {
  1023. return (TRUE);
  1024. }
  1025. //
  1026. // Get the minor ver/wildcard
  1027. //
  1028. if ((*pwszMM == OSATTR_GTEQ) ||
  1029. (*pwszMM == OSATTR_LTEQ) ||
  1030. (*pwszMM == OSATTR_LTEQ2) ||
  1031. (towupper(*pwszMM) == OSATTR_ALL))
  1032. {
  1033. *pwcFlagMinor = towupper(*pwszMM);
  1034. return(TRUE);
  1035. }
  1036. if (!(pwszEnd = wcschr(pwszMM, OSATTR_VERSEP)))
  1037. {
  1038. *pdwMinor = (DWORD) _wtol(pwszMM);
  1039. //
  1040. // This grandfathers all catalog files that had an OSAttr string of
  1041. // 2:4.1 to be 2:4.1.*
  1042. //
  1043. *pwcFlagBuild = OSATTR_ALL;
  1044. return(TRUE);
  1045. }
  1046. *pwszEnd = NULL;
  1047. *pdwMinor = (DWORD) _wtol(pwszMM);
  1048. *pwszEnd = OSATTR_VERSEP;
  1049. pwszMM = pwszEnd;
  1050. pwszMM++;
  1051. //
  1052. // Get the build#/wildcard
  1053. //
  1054. if ((*pwszMM == OSATTR_GTEQ) ||
  1055. (*pwszMM == OSATTR_LTEQ) ||
  1056. (*pwszMM == OSATTR_LTEQ2) ||
  1057. (towupper(*pwszMM) == OSATTR_ALL))
  1058. {
  1059. *pwcFlagBuild = towupper(*pwszMM);
  1060. return(TRUE);
  1061. }
  1062. *pdwBuild = (DWORD) _wtol(pwszMM);
  1063. *pwcFlagBuild = L'\0';
  1064. return(TRUE);
  1065. }
  1066. STDAPI DriverRegisterServer(void)
  1067. {
  1068. GUID gDriver = DRIVER_ACTION_VERIFY;
  1069. CRYPT_REGISTER_ACTIONID sRegAID;
  1070. memset(&sRegAID, 0x00, sizeof(CRYPT_REGISTER_ACTIONID));
  1071. sRegAID.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
  1072. // use our init policy
  1073. sRegAID.sInitProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  1074. sRegAID.sInitProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  1075. sRegAID.sInitProvider.pwszFunctionName = DRIVER_INITPROV_FUNCTION;
  1076. // use standard object policy
  1077. sRegAID.sObjectProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  1078. sRegAID.sObjectProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  1079. sRegAID.sObjectProvider.pwszFunctionName = SP_OBJTRUST_FUNCTION;
  1080. // use standard signature policy
  1081. sRegAID.sSignatureProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  1082. sRegAID.sSignatureProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  1083. sRegAID.sSignatureProvider.pwszFunctionName = SP_SIGTRUST_FUNCTION;
  1084. // use standard cert builder
  1085. sRegAID.sCertificateProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  1086. sRegAID.sCertificateProvider.pwszDLLName = WT_PROVIDER_DLL_NAME;
  1087. sRegAID.sCertificateProvider.pwszFunctionName = WT_PROVIDER_CERTTRUST_FUNCTION;
  1088. // use standard cert policy
  1089. sRegAID.sCertificatePolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  1090. sRegAID.sCertificatePolicyProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  1091. sRegAID.sCertificatePolicyProvider.pwszFunctionName = SP_CHKCERT_FUNCTION;
  1092. // use our final policy
  1093. sRegAID.sFinalPolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  1094. sRegAID.sFinalPolicyProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  1095. sRegAID.sFinalPolicyProvider.pwszFunctionName = DRIVER_FINALPOLPROV_FUNCTION;
  1096. // use our cleanup policy
  1097. sRegAID.sCleanupProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  1098. sRegAID.sCleanupProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  1099. sRegAID.sCleanupProvider.pwszFunctionName = DRIVER_CLEANUPPOLICY_FUNCTION;
  1100. //
  1101. // Register our provider GUID...
  1102. //
  1103. if (!(WintrustAddActionID(&gDriver, 0, &sRegAID)))
  1104. {
  1105. return (S_FALSE);
  1106. }
  1107. return (S_OK);
  1108. }
  1109. STDAPI DriverUnregisterServer(void)
  1110. {
  1111. GUID gDriver = DRIVER_ACTION_VERIFY;
  1112. if (!(WintrustRemoveActionID(&gDriver)))
  1113. {
  1114. return (S_FALSE);
  1115. }
  1116. return (S_OK);
  1117. }