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.

1114 lines
31 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: octxutil.cpp
  7. //
  8. // Contents: General Object Context Utility Function implemention
  9. //
  10. // History: 29-Sep-97 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <global.hxx>
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Function: ObjectContextGetOriginIdentifier
  17. //
  18. // Synopsis: get origin identifier for a CAPI2 object
  19. //
  20. //----------------------------------------------------------------------------
  21. BOOL WINAPI ObjectContextGetOriginIdentifier (
  22. IN LPCSTR pszContextOid,
  23. IN LPVOID pvContext,
  24. IN PCCERT_CONTEXT pIssuer,
  25. IN DWORD dwFlags,
  26. OUT CRYPT_ORIGIN_IDENTIFIER OriginIdentifier
  27. )
  28. {
  29. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  30. {
  31. return( CertGetOriginIdentifier(
  32. (PCCERT_CONTEXT)pvContext,
  33. pIssuer,
  34. dwFlags,
  35. OriginIdentifier
  36. ) );
  37. }
  38. else if ( pszContextOid == CONTEXT_OID_CTL )
  39. {
  40. return( CtlGetOriginIdentifier(
  41. (PCCTL_CONTEXT)pvContext,
  42. pIssuer,
  43. dwFlags,
  44. OriginIdentifier
  45. ) );
  46. }
  47. else if ( pszContextOid == CONTEXT_OID_CRL )
  48. {
  49. return( CrlGetOriginIdentifier(
  50. (PCCRL_CONTEXT)pvContext,
  51. pIssuer,
  52. dwFlags,
  53. OriginIdentifier
  54. ) );
  55. }
  56. SetLastError( (DWORD) E_INVALIDARG );
  57. return( FALSE );
  58. }
  59. //+---------------------------------------------------------------------------
  60. //
  61. // Function: ObjectContextIsValidForSubject
  62. //
  63. // Synopsis: returns TRUE if the object context is valid for the specified
  64. // subject
  65. //
  66. //----------------------------------------------------------------------------
  67. BOOL WINAPI
  68. ObjectContextIsValidForSubject (
  69. IN LPCSTR pszContextOid,
  70. IN LPVOID pvContext,
  71. IN LPVOID pvSubject,
  72. IN OPTIONAL LPVOID pvExtraInfo
  73. )
  74. {
  75. if ( pszContextOid == CONTEXT_OID_CRL && pvSubject != NULL )
  76. {
  77. BOOL fResult;
  78. PCCRL_CONTEXT pCrl = (PCCRL_CONTEXT) pvContext;
  79. fResult = CertIsValidCRLForCertificate(
  80. (PCCERT_CONTEXT) pvSubject,
  81. pCrl,
  82. 0, // dwFlags
  83. NULL // pvReserved
  84. );
  85. if (fResult && pvExtraInfo)
  86. {
  87. int iDeltaCrlIndicator = 0;
  88. // Since we are using a reserved parameter, guard against someone
  89. // passing in a nonNULL pointer when they shouldn't
  90. __try
  91. {
  92. iDeltaCrlIndicator =
  93. ((PCRL_IS_VALID_EXTRA_INFO) pvExtraInfo)->iDeltaCrlIndicator;
  94. }
  95. __except(EXCEPTION_EXECUTE_HANDLER)
  96. {
  97. iDeltaCrlIndicator = 0;
  98. }
  99. if (0 < iDeltaCrlIndicator)
  100. {
  101. PCERT_EXTENSION pCrlNumberExt;
  102. int iCrlNumber = 0;
  103. DWORD cbInt = sizeof(iCrlNumber);
  104. if (NULL == (pCrlNumberExt = CertFindExtension(
  105. szOID_CRL_NUMBER,
  106. pCrl->pCrlInfo->cExtension,
  107. pCrl->pCrlInfo->rgExtension))
  108. ||
  109. !CryptDecodeObject(
  110. pCrl->dwCertEncodingType,
  111. X509_INTEGER,
  112. pCrlNumberExt->Value.pbData,
  113. pCrlNumberExt->Value.cbData,
  114. 0, // dwFlags
  115. &iCrlNumber,
  116. &cbInt)
  117. ||
  118. iCrlNumber < iDeltaCrlIndicator)
  119. {
  120. fResult = FALSE;
  121. }
  122. }
  123. }
  124. return fResult;
  125. }
  126. else
  127. {
  128. return TRUE;
  129. }
  130. }
  131. //+---------------------------------------------------------------------------
  132. //
  133. // Function: ObjectContextFindExtension
  134. //
  135. // Synopsis: get the specified extension from the object
  136. //
  137. //----------------------------------------------------------------------------
  138. PCERT_EXTENSION WINAPI
  139. ObjectContextFindExtension (
  140. IN LPCSTR pszContextOid,
  141. IN LPVOID pvContext,
  142. IN LPCSTR pszExtOid
  143. )
  144. {
  145. DWORD cExt;
  146. PCERT_EXTENSION rgExt;
  147. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  148. {
  149. PCCERT_CONTEXT pCertContext = (PCCERT_CONTEXT)pvContext;
  150. cExt = pCertContext->pCertInfo->cExtension;
  151. rgExt = pCertContext->pCertInfo->rgExtension;
  152. }
  153. else if ( pszContextOid == CONTEXT_OID_CTL )
  154. {
  155. PCCTL_CONTEXT pCtlContext = (PCCTL_CONTEXT)pvContext;
  156. cExt = pCtlContext->pCtlInfo->cExtension;
  157. rgExt = pCtlContext->pCtlInfo->rgExtension;
  158. }
  159. else if ( pszContextOid == CONTEXT_OID_CRL )
  160. {
  161. PCCRL_CONTEXT pCrlContext = (PCCRL_CONTEXT)pvContext;
  162. cExt = pCrlContext->pCrlInfo->cExtension;
  163. rgExt = pCrlContext->pCrlInfo->rgExtension;
  164. }
  165. else
  166. {
  167. return( NULL );
  168. }
  169. return( CertFindExtension( pszExtOid, cExt, rgExt ) );
  170. }
  171. //+---------------------------------------------------------------------------
  172. //
  173. // Function: ObjectContextGetProperty
  174. //
  175. // Synopsis: get the specified property from the object
  176. //
  177. //----------------------------------------------------------------------------
  178. BOOL WINAPI
  179. ObjectContextGetProperty (
  180. IN LPCSTR pszContextOid,
  181. IN LPVOID pvContext,
  182. IN DWORD dwPropId,
  183. IN LPVOID pvData,
  184. IN DWORD* pcbData
  185. )
  186. {
  187. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  188. {
  189. return( CertGetCertificateContextProperty(
  190. (PCCERT_CONTEXT)pvContext,
  191. dwPropId,
  192. pvData,
  193. pcbData
  194. ) );
  195. }
  196. else if ( pszContextOid == CONTEXT_OID_CTL )
  197. {
  198. return( CertGetCTLContextProperty(
  199. (PCCTL_CONTEXT)pvContext,
  200. dwPropId,
  201. pvData,
  202. pcbData
  203. ) );
  204. }
  205. else if ( pszContextOid == CONTEXT_OID_CRL )
  206. {
  207. return( CertGetCRLContextProperty(
  208. (PCCRL_CONTEXT)pvContext,
  209. dwPropId,
  210. pvData,
  211. pcbData
  212. ) );
  213. }
  214. SetLastError( (DWORD) E_INVALIDARG );
  215. return( FALSE );
  216. }
  217. //+---------------------------------------------------------------------------
  218. //
  219. // Function: ObjectContextGetAttribute
  220. //
  221. // Synopsis: find an attribute
  222. //
  223. //----------------------------------------------------------------------------
  224. BOOL WINAPI
  225. ObjectContextGetAttribute (
  226. IN LPCSTR pszContextOid,
  227. IN LPVOID pvContext,
  228. IN DWORD Index,
  229. IN DWORD dwFlags,
  230. IN LPCSTR pszAttrOid,
  231. OUT PCRYPT_ATTRIBUTE pAttribute,
  232. IN OUT DWORD* pcbAttribute
  233. )
  234. {
  235. BOOL fResult;
  236. PCRYPT_ATTRIBUTES pAttributes;
  237. DWORD cbData;
  238. DWORD cCount;
  239. HCRYPTMSG hCryptMsg;
  240. DWORD dwParamType;
  241. BOOL fFound = FALSE;
  242. if ( Index == -1 )
  243. {
  244. SetLastError( (DWORD) E_INVALIDARG );
  245. return( FALSE );
  246. }
  247. if ( dwFlags == CRYPT_GET_URL_FROM_UNAUTH_ATTRIBUTE )
  248. {
  249. dwParamType = CMSG_SIGNER_UNAUTH_ATTR_PARAM;
  250. }
  251. else if ( dwFlags == CRYPT_GET_URL_FROM_AUTH_ATTRIBUTE )
  252. {
  253. dwParamType = CMSG_SIGNER_AUTH_ATTR_PARAM;
  254. }
  255. else
  256. {
  257. SetLastError( (DWORD) E_INVALIDARG );
  258. return( FALSE );
  259. }
  260. if ( pszContextOid == CONTEXT_OID_CTL )
  261. {
  262. hCryptMsg = ((PCCTL_CONTEXT)pvContext)->hCryptMsg;
  263. }
  264. else if ( pszContextOid == CONTEXT_OID_PKCS7 )
  265. {
  266. hCryptMsg = (HCRYPTMSG)pvContext;
  267. }
  268. else
  269. {
  270. SetLastError( (DWORD) E_INVALIDARG );
  271. return( FALSE );
  272. }
  273. if ( CryptMsgGetParam(
  274. hCryptMsg,
  275. dwParamType,
  276. Index,
  277. NULL,
  278. &cbData
  279. ) == FALSE )
  280. {
  281. return( FALSE );
  282. }
  283. pAttributes = (PCRYPT_ATTRIBUTES)new BYTE [cbData];
  284. if ( pAttributes == NULL )
  285. {
  286. SetLastError( (DWORD) E_OUTOFMEMORY );
  287. return( FALSE );
  288. }
  289. if ( CryptMsgGetParam(
  290. hCryptMsg,
  291. dwParamType,
  292. Index,
  293. pAttributes,
  294. &cbData
  295. ) == FALSE )
  296. {
  297. delete [] (BYTE *)pAttributes;
  298. return( FALSE );
  299. }
  300. fResult = TRUE;
  301. for ( cCount = 0; cCount < pAttributes->cAttr; cCount++ )
  302. {
  303. if ( strcmp( pAttributes->rgAttr[cCount].pszObjId, pszAttrOid ) == 0 )
  304. {
  305. DWORD cbAttribute;
  306. DWORD cbOid;
  307. cbAttribute = sizeof( CRYPT_ATTRIBUTE ) + sizeof( CRYPT_ATTR_BLOB );
  308. cbOid = strlen( pszAttrOid ) + 1;
  309. cbData = pAttributes->rgAttr[cCount].rgValue[0].cbData;
  310. cbAttribute += cbOid + cbData;
  311. if ( pAttribute == NULL )
  312. {
  313. if ( pcbAttribute == NULL )
  314. {
  315. SetLastError( (DWORD) E_INVALIDARG );
  316. fResult = FALSE;
  317. }
  318. else
  319. {
  320. *pcbAttribute = cbAttribute;
  321. fFound = TRUE;
  322. break;
  323. }
  324. }
  325. else if ( *pcbAttribute < cbAttribute )
  326. {
  327. SetLastError( (DWORD) ERROR_MORE_DATA );
  328. fResult = FALSE;
  329. }
  330. if ( fResult == TRUE )
  331. {
  332. pAttribute->pszObjId = (LPSTR)((LPBYTE)pAttribute +
  333. sizeof( CRYPT_ATTRIBUTE ) +
  334. sizeof( CRYPT_ATTR_BLOB ));
  335. strcpy( pAttribute->pszObjId, pszAttrOid );
  336. pAttribute->cValue = 1;
  337. pAttribute->rgValue = (PCRYPT_ATTR_BLOB)((LPBYTE)pAttribute +
  338. sizeof( CRYPT_ATTRIBUTE ));
  339. pAttribute->rgValue[0].cbData = cbData;
  340. pAttribute->rgValue[0].pbData = (LPBYTE)pAttribute->pszObjId +
  341. cbOid;
  342. memcpy(
  343. pAttribute->rgValue[0].pbData,
  344. pAttributes->rgAttr[cCount].rgValue[0].pbData,
  345. cbData
  346. );
  347. }
  348. fFound = TRUE;
  349. break;
  350. }
  351. }
  352. delete [] (BYTE *)pAttributes;
  353. if ( fResult == TRUE )
  354. {
  355. fResult = fFound;
  356. }
  357. return( fResult );
  358. }
  359. //+---------------------------------------------------------------------------
  360. //
  361. // Function: ObjectContextDuplicate
  362. //
  363. // Synopsis: duplicate the context
  364. //
  365. //----------------------------------------------------------------------------
  366. LPVOID WINAPI
  367. ObjectContextDuplicate (
  368. IN LPCSTR pszContextOid,
  369. IN LPVOID pvContext
  370. )
  371. {
  372. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  373. {
  374. return( (LPVOID)CertDuplicateCertificateContext(
  375. (PCCERT_CONTEXT)pvContext
  376. ) );
  377. }
  378. else if ( pszContextOid == CONTEXT_OID_CTL )
  379. {
  380. return( (LPVOID)CertDuplicateCTLContext( (PCCTL_CONTEXT)pvContext ) );
  381. }
  382. else if ( pszContextOid == CONTEXT_OID_CRL )
  383. {
  384. return( (LPVOID)CertDuplicateCRLContext( (PCCRL_CONTEXT)pvContext ) );
  385. }
  386. SetLastError( (DWORD) E_INVALIDARG );
  387. return( NULL );
  388. }
  389. //+---------------------------------------------------------------------------
  390. //
  391. // Function: ObjectContextAdd
  392. //
  393. // Synopsis: object context create
  394. //
  395. //----------------------------------------------------------------------------
  396. BOOL WINAPI
  397. ObjectContextCreate (
  398. IN LPCSTR pszContextOid,
  399. IN LPVOID pvContext,
  400. OUT LPVOID* ppvContext
  401. )
  402. {
  403. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  404. {
  405. return( CertAddCertificateContextToStore(
  406. NULL,
  407. (PCCERT_CONTEXT)pvContext,
  408. CERT_STORE_ADD_ALWAYS,
  409. (PCCERT_CONTEXT *)ppvContext
  410. ) );
  411. }
  412. else if ( pszContextOid == CONTEXT_OID_CTL )
  413. {
  414. return( CertAddCTLContextToStore(
  415. NULL,
  416. (PCCTL_CONTEXT)pvContext,
  417. CERT_STORE_ADD_ALWAYS,
  418. (PCCTL_CONTEXT *)ppvContext
  419. ) );
  420. }
  421. else if ( pszContextOid == CONTEXT_OID_CRL )
  422. {
  423. return( CertAddCRLContextToStore(
  424. NULL,
  425. (PCCRL_CONTEXT)pvContext,
  426. CERT_STORE_ADD_ALWAYS,
  427. (PCCRL_CONTEXT *)ppvContext
  428. ) );
  429. }
  430. SetLastError( (DWORD) E_INVALIDARG );
  431. return( FALSE );
  432. }
  433. //+---------------------------------------------------------------------------
  434. //
  435. // Function: ObjectContextGetCreateAndExpireTimes
  436. //
  437. // Synopsis: get create and expire times
  438. //
  439. //----------------------------------------------------------------------------
  440. BOOL WINAPI
  441. ObjectContextGetCreateAndExpireTimes (
  442. IN LPCSTR pszContextOid,
  443. IN LPVOID pvContext,
  444. OUT LPFILETIME pftCreateTime,
  445. OUT LPFILETIME pftExpireTime
  446. )
  447. {
  448. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  449. {
  450. *pftCreateTime = ((PCCERT_CONTEXT)pvContext)->pCertInfo->NotBefore;
  451. *pftExpireTime = ((PCCERT_CONTEXT)pvContext)->pCertInfo->NotAfter;
  452. return( TRUE );
  453. }
  454. else if ( pszContextOid == CONTEXT_OID_CTL )
  455. {
  456. *pftCreateTime = ((PCCTL_CONTEXT)pvContext)->pCtlInfo->ThisUpdate;
  457. *pftExpireTime = ((PCCTL_CONTEXT)pvContext)->pCtlInfo->NextUpdate;
  458. return( TRUE );
  459. }
  460. else if ( pszContextOid == CONTEXT_OID_CRL )
  461. {
  462. *pftCreateTime = ((PCCRL_CONTEXT)pvContext)->pCrlInfo->ThisUpdate;
  463. *pftExpireTime = ((PCCRL_CONTEXT)pvContext)->pCrlInfo->NextUpdate;
  464. return( TRUE );
  465. }
  466. SetLastError( (DWORD) E_INVALIDARG );
  467. return( FALSE );
  468. }
  469. //+---------------------------------------------------------------------------
  470. //
  471. // Function: ObjectContextGetNextUpdateUrl
  472. //
  473. // Synopsis: get the renewal URL
  474. //
  475. //----------------------------------------------------------------------------
  476. BOOL WINAPI
  477. ObjectContextGetNextUpdateUrl (
  478. IN LPCSTR pszContextOid,
  479. IN LPVOID pvContext,
  480. IN PCCERT_CONTEXT pIssuer,
  481. IN LPWSTR pwszUrlHint,
  482. OUT PCRYPT_URL_ARRAY* ppUrlArray,
  483. OUT DWORD* pcbUrlArray,
  484. OUT DWORD* pPreferredUrlIndex,
  485. OUT BOOL* pfHintInArray
  486. )
  487. {
  488. BOOL fResult;
  489. DWORD cbUrlArray;
  490. PCRYPT_URL_ARRAY pUrlArray = NULL;
  491. DWORD PreferredUrlIndex;
  492. DWORD cCount;
  493. DWORD cSigner;
  494. DWORD cbData;
  495. BOOL fHintInArray = FALSE;
  496. PCCTL_CONTEXT pCtlContext = (PCCTL_CONTEXT)pvContext;
  497. PCERT_INFO pCertInfo;
  498. BOOL fFoundIssuer = FALSE;
  499. LPVOID apv[2];
  500. if ( pszContextOid != CONTEXT_OID_CTL )
  501. {
  502. SetLastError( (DWORD) E_INVALIDARG );
  503. return( FALSE );
  504. }
  505. cbData = sizeof( DWORD );
  506. if ( CryptMsgGetParam(
  507. pCtlContext->hCryptMsg,
  508. CMSG_SIGNER_COUNT_PARAM,
  509. 0,
  510. &cSigner,
  511. &cbData
  512. ) == FALSE )
  513. {
  514. return( FALSE );
  515. }
  516. for ( cCount = 0;
  517. ( cCount < cSigner ) && ( fFoundIssuer == FALSE );
  518. cCount++ )
  519. {
  520. if ( CryptMsgGetParam(
  521. pCtlContext->hCryptMsg,
  522. CMSG_SIGNER_CERT_INFO_PARAM,
  523. cCount,
  524. NULL,
  525. &cbData
  526. ) == FALSE )
  527. {
  528. printf("GetLastError() = %lx\n", GetLastError());
  529. return( FALSE );
  530. }
  531. pCertInfo = (PCERT_INFO)new BYTE [cbData];
  532. if ( pCertInfo == NULL )
  533. {
  534. SetLastError( (DWORD) E_OUTOFMEMORY );
  535. return( FALSE );
  536. }
  537. if ( CryptMsgGetParam(
  538. pCtlContext->hCryptMsg,
  539. CMSG_SIGNER_CERT_INFO_PARAM,
  540. cCount,
  541. (LPVOID)pCertInfo,
  542. &cbData
  543. ) == FALSE )
  544. {
  545. delete [] (BYTE *)pCertInfo;
  546. return( FALSE );
  547. }
  548. if ( ( pIssuer->pCertInfo->Issuer.cbData ==
  549. pCertInfo->Issuer.cbData ) &&
  550. ( pIssuer->pCertInfo->SerialNumber.cbData ==
  551. pCertInfo->SerialNumber.cbData ) &&
  552. ( memcmp(
  553. pIssuer->pCertInfo->Issuer.pbData,
  554. pCertInfo->Issuer.pbData,
  555. pCertInfo->Issuer.cbData
  556. ) == 0 ) &&
  557. ( memcmp(
  558. pIssuer->pCertInfo->SerialNumber.pbData,
  559. pCertInfo->SerialNumber.pbData,
  560. pCertInfo->SerialNumber.cbData
  561. ) == 0 ) )
  562. {
  563. fFoundIssuer = TRUE;
  564. }
  565. delete [] (BYTE *)pCertInfo;
  566. }
  567. if ( fFoundIssuer == FALSE )
  568. {
  569. SetLastError( (DWORD) CRYPT_E_NOT_FOUND );
  570. return( FALSE );
  571. }
  572. apv[0] = pvContext;
  573. apv[1] = (LPVOID)(UINT_PTR)(cCount - 1);
  574. fResult = CryptGetObjectUrl(
  575. URL_OID_CTL_NEXT_UPDATE,
  576. apv,
  577. 0,
  578. NULL,
  579. &cbUrlArray,
  580. NULL,
  581. NULL,
  582. NULL
  583. );
  584. if ( fResult == TRUE )
  585. {
  586. pUrlArray = (PCRYPT_URL_ARRAY)new BYTE [ cbUrlArray ];
  587. if ( pUrlArray != NULL )
  588. {
  589. fResult = CryptGetObjectUrl(
  590. URL_OID_CTL_NEXT_UPDATE,
  591. apv,
  592. 0,
  593. pUrlArray,
  594. &cbUrlArray,
  595. NULL,
  596. NULL,
  597. NULL
  598. );
  599. }
  600. else
  601. {
  602. SetLastError( (DWORD) E_OUTOFMEMORY );
  603. fResult = FALSE;
  604. }
  605. }
  606. if ( fResult == TRUE )
  607. {
  608. GetUrlArrayIndex(
  609. pUrlArray,
  610. pwszUrlHint,
  611. 0,
  612. &PreferredUrlIndex,
  613. &fHintInArray
  614. );
  615. *ppUrlArray = pUrlArray;
  616. *pcbUrlArray = cbUrlArray;
  617. if ( pPreferredUrlIndex != NULL )
  618. {
  619. *pPreferredUrlIndex = PreferredUrlIndex;
  620. }
  621. if ( pfHintInArray != NULL )
  622. {
  623. *pfHintInArray = fHintInArray;
  624. }
  625. }
  626. else if ( pUrlArray != NULL )
  627. {
  628. delete [] (BYTE *) pUrlArray;
  629. }
  630. return( fResult );
  631. }
  632. //+---------------------------------------------------------------------------
  633. //
  634. // Function: ObjectContextFree
  635. //
  636. // Synopsis: free context
  637. //
  638. //----------------------------------------------------------------------------
  639. VOID WINAPI
  640. ObjectContextFree (
  641. IN LPCSTR pszContextOid,
  642. IN LPVOID pvContext
  643. )
  644. {
  645. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  646. {
  647. CertFreeCertificateContext( (PCCERT_CONTEXT)pvContext );
  648. }
  649. else if ( pszContextOid == CONTEXT_OID_CTL )
  650. {
  651. CertFreeCTLContext( (PCCTL_CONTEXT)pvContext );
  652. }
  653. else if ( pszContextOid == CONTEXT_OID_CRL )
  654. {
  655. CertFreeCRLContext( (PCCRL_CONTEXT)pvContext );
  656. }
  657. }
  658. //+---------------------------------------------------------------------------
  659. //
  660. // Function: ObjectContextVerifySignature
  661. //
  662. // Synopsis: verify the object signature
  663. //
  664. //----------------------------------------------------------------------------
  665. BOOL WINAPI
  666. ObjectContextVerifySignature (
  667. IN LPCSTR pszContextOid,
  668. IN LPVOID pvContext,
  669. IN PCCERT_CONTEXT pSigner
  670. )
  671. {
  672. if ( ( pszContextOid == CONTEXT_OID_CERTIFICATE ) ||
  673. ( pszContextOid == CONTEXT_OID_CRL ) )
  674. {
  675. #ifdef CMS_PKCS7
  676. DWORD dwSubjectType = 0;
  677. #else
  678. DWORD cbEncoded;
  679. LPBYTE pbEncoded;
  680. #endif // CMS_PKCS7
  681. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  682. {
  683. #ifdef CMS_PKCS7
  684. dwSubjectType = CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT;
  685. #else
  686. cbEncoded = ((PCCERT_CONTEXT)pvContext)->cbCertEncoded;
  687. pbEncoded = ((PCCERT_CONTEXT)pvContext)->pbCertEncoded;
  688. #endif // CMS_PKCS7
  689. }
  690. else if ( pszContextOid == CONTEXT_OID_CRL )
  691. {
  692. #ifdef CMS_PKCS7
  693. dwSubjectType = CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL;
  694. #else
  695. cbEncoded = ((PCCRL_CONTEXT)pvContext)->cbCrlEncoded;
  696. pbEncoded = ((PCCRL_CONTEXT)pvContext)->pbCrlEncoded;
  697. #endif // CMS_PKCS7
  698. }
  699. #ifdef CMS_PKCS7
  700. return( CryptVerifyCertificateSignatureEx(
  701. NULL, // hCryptProv
  702. X509_ASN_ENCODING,
  703. dwSubjectType,
  704. pvContext,
  705. CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT,
  706. (void *) pSigner,
  707. 0, // dwFlags
  708. NULL // pvReserved
  709. ) );
  710. #else
  711. return( CryptVerifyCertificateSignature(
  712. NULL,
  713. X509_ASN_ENCODING,
  714. pbEncoded,
  715. cbEncoded,
  716. &pSigner->pCertInfo->SubjectPublicKeyInfo
  717. ) );
  718. #endif // CMS_PKCS7
  719. }
  720. else if ( pszContextOid == CONTEXT_OID_CTL )
  721. {
  722. #ifdef CMS_PKCS7
  723. CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA CtrlPara;
  724. memset(&CtrlPara, 0, sizeof(CtrlPara));
  725. CtrlPara.cbSize = sizeof(CtrlPara);
  726. // CtrlPara.hCryptProv =
  727. // Assumption: CTL only has one signer
  728. CtrlPara.dwSignerIndex = 0;
  729. CtrlPara.dwSignerType = CMSG_VERIFY_SIGNER_CERT;
  730. CtrlPara.pvSigner = (void *) pSigner;
  731. if (CryptMsgControl(
  732. ((PCCTL_CONTEXT)pvContext)->hCryptMsg,
  733. 0,
  734. CMSG_CTRL_VERIFY_SIGNATURE_EX,
  735. &CtrlPara
  736. ))
  737. return TRUE;
  738. // Otherwise, fall through in case it wasn't signer 0.
  739. #endif // CMS_PKCS7
  740. return( CryptMsgControl(
  741. ((PCCTL_CONTEXT)pvContext)->hCryptMsg,
  742. 0,
  743. CMSG_CTRL_VERIFY_SIGNATURE,
  744. pSigner->pCertInfo
  745. ) );
  746. }
  747. SetLastError( (DWORD) E_INVALIDARG );
  748. return( FALSE );
  749. }
  750. //+---------------------------------------------------------------------------
  751. //
  752. // Function: ObjectContextEnumObjectsInStore
  753. //
  754. // Synopsis: enumerate objects in a store
  755. //
  756. //----------------------------------------------------------------------------
  757. LPVOID WINAPI
  758. ObjectContextEnumObjectsInStore (
  759. IN HCERTSTORE hStore,
  760. IN LPCSTR pszContextOid,
  761. IN LPVOID pvContext,
  762. OUT OPTIONAL LPCSTR* ppszContextOid
  763. )
  764. {
  765. if ( ppszContextOid )
  766. {
  767. *ppszContextOid = pszContextOid;
  768. }
  769. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  770. {
  771. pvContext = (LPVOID)CertEnumCertificatesInStore(
  772. hStore,
  773. (PCCERT_CONTEXT)pvContext
  774. );
  775. if ( pvContext != NULL )
  776. {
  777. return( pvContext );
  778. }
  779. if (ppszContextOid == NULL)
  780. {
  781. return( NULL );
  782. }
  783. *ppszContextOid = pszContextOid = CONTEXT_OID_CTL;
  784. }
  785. if ( pszContextOid == CONTEXT_OID_CTL )
  786. {
  787. pvContext = (LPVOID)CertEnumCTLsInStore(
  788. hStore,
  789. (PCCTL_CONTEXT)pvContext
  790. );
  791. if ( pvContext != NULL )
  792. {
  793. return( pvContext );
  794. }
  795. if (ppszContextOid == NULL)
  796. {
  797. return( NULL );
  798. }
  799. *ppszContextOid = pszContextOid = CONTEXT_OID_CRL;
  800. }
  801. if ( pszContextOid == CONTEXT_OID_CRL )
  802. {
  803. pvContext = (LPVOID)CertEnumCRLsInStore(
  804. hStore,
  805. (PCCRL_CONTEXT)pvContext
  806. );
  807. if ( pvContext != NULL )
  808. {
  809. return( pvContext );
  810. }
  811. }
  812. return( NULL );
  813. }
  814. //+---------------------------------------------------------------------------
  815. //
  816. // Function: ObjectContextGetEncodedBits
  817. //
  818. // Synopsis: get encoded bits out of the context
  819. //
  820. //----------------------------------------------------------------------------
  821. VOID WINAPI
  822. ObjectContextGetEncodedBits (
  823. IN LPCSTR pszContextOid,
  824. IN LPVOID pvContext,
  825. OUT DWORD* pcbEncoded,
  826. OUT LPBYTE* ppbEncoded
  827. )
  828. {
  829. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  830. {
  831. *pcbEncoded = ((PCCERT_CONTEXT)pvContext)->cbCertEncoded;
  832. *ppbEncoded = ((PCCERT_CONTEXT)pvContext)->pbCertEncoded;
  833. }
  834. else if ( pszContextOid == CONTEXT_OID_CTL )
  835. {
  836. *pcbEncoded = ((PCCTL_CONTEXT)pvContext)->cbCtlEncoded;
  837. *ppbEncoded = ((PCCTL_CONTEXT)pvContext)->pbCtlEncoded;
  838. }
  839. else if ( pszContextOid == CONTEXT_OID_CRL )
  840. {
  841. *pcbEncoded = ((PCCRL_CONTEXT)pvContext)->cbCrlEncoded;
  842. *ppbEncoded = ((PCCRL_CONTEXT)pvContext)->pbCrlEncoded;
  843. }
  844. else
  845. {
  846. assert( !"Bad context" );
  847. *pcbEncoded = 0;
  848. *ppbEncoded = NULL;
  849. }
  850. }
  851. //+---------------------------------------------------------------------------
  852. //
  853. // Function: ObjectContextFindCorrespondingObject
  854. //
  855. // Synopsis: find corresponding object
  856. //
  857. //----------------------------------------------------------------------------
  858. LPVOID WINAPI
  859. ObjectContextFindCorrespondingObject (
  860. IN HCERTSTORE hStore,
  861. IN LPCSTR pszContextOid,
  862. IN LPVOID pvContext
  863. )
  864. {
  865. DWORD cbHash = MAX_HASH_SIZE;
  866. BYTE aHash[MAX_HASH_SIZE];
  867. CRYPT_HASH_BLOB HashBlob;
  868. if ( pszContextOid == CONTEXT_OID_CERTIFICATE )
  869. {
  870. if ( CertGetCertificateContextProperty(
  871. (PCCERT_CONTEXT)pvContext,
  872. CERT_HASH_PROP_ID,
  873. aHash,
  874. &cbHash
  875. ) == FALSE )
  876. {
  877. return( NULL );
  878. }
  879. HashBlob.cbData = cbHash;
  880. HashBlob.pbData = aHash;
  881. return( (LPVOID)CertFindCertificateInStore(
  882. hStore,
  883. X509_ASN_ENCODING,
  884. 0,
  885. CERT_FIND_HASH,
  886. &HashBlob,
  887. NULL
  888. ) );
  889. }
  890. else if ( pszContextOid == CONTEXT_OID_CTL )
  891. {
  892. if ( CertGetCTLContextProperty(
  893. (PCCTL_CONTEXT)pvContext,
  894. CERT_SHA1_HASH_PROP_ID,
  895. aHash,
  896. &cbHash
  897. ) == FALSE )
  898. {
  899. return( NULL );
  900. }
  901. HashBlob.cbData = cbHash;
  902. HashBlob.pbData = aHash;
  903. return( (LPVOID)CertFindCTLInStore(
  904. hStore,
  905. X509_ASN_ENCODING,
  906. 0,
  907. CTL_FIND_SHA1_HASH,
  908. &HashBlob,
  909. NULL
  910. ) );
  911. }
  912. else if ( pszContextOid == CONTEXT_OID_CRL )
  913. {
  914. DWORD cbFindHash = MAX_HASH_SIZE;
  915. BYTE aFindHash[MAX_HASH_SIZE];
  916. PCCRL_CONTEXT pFindCrl = NULL;
  917. DWORD dwFlags = 0;
  918. if ( CertGetCRLContextProperty(
  919. (PCCRL_CONTEXT)pvContext,
  920. CERT_HASH_PROP_ID,
  921. aHash,
  922. &cbHash
  923. ) == FALSE )
  924. {
  925. return( NULL );
  926. }
  927. while ( ( pFindCrl = CertGetCRLFromStore(
  928. hStore,
  929. NULL,
  930. pFindCrl,
  931. &dwFlags
  932. ) ) != NULL )
  933. {
  934. if ( CertGetCRLContextProperty(
  935. pFindCrl,
  936. CERT_HASH_PROP_ID,
  937. aFindHash,
  938. &cbFindHash
  939. ) == TRUE )
  940. {
  941. if ( cbHash == cbFindHash )
  942. {
  943. if ( memcmp( aHash, aFindHash, cbHash ) == 0 )
  944. {
  945. return( (LPVOID)pFindCrl );
  946. }
  947. }
  948. }
  949. }
  950. }
  951. return( NULL );
  952. }
  953. //+---------------------------------------------------------------------------
  954. //
  955. // Function: ObjectContextDeleteAllObjectsFromStore
  956. //
  957. // Synopsis: delete all objects from the specified store
  958. //
  959. //----------------------------------------------------------------------------
  960. BOOL WINAPI
  961. ObjectContextDeleteAllObjectsFromStore (
  962. IN HCERTSTORE hStore
  963. )
  964. {
  965. PCCERT_CONTEXT pCertContext;
  966. PCCRL_CONTEXT pCrlContext;
  967. PCCTL_CONTEXT pCtlContext;
  968. DWORD dwFlags = 0;
  969. while ( pCertContext = CertEnumCertificatesInStore( hStore, NULL ) )
  970. {
  971. CertDeleteCertificateFromStore( pCertContext );
  972. }
  973. while ( pCrlContext = CertGetCRLFromStore( hStore, NULL, NULL, &dwFlags ) )
  974. {
  975. CertDeleteCRLFromStore( pCrlContext );
  976. }
  977. while ( pCtlContext = CertEnumCTLsInStore( hStore, NULL ) )
  978. {
  979. CertDeleteCTLFromStore( pCtlContext );
  980. }
  981. return( TRUE );
  982. }
  983. //+---------------------------------------------------------------------------
  984. //
  985. // Function: MapOidToPropertyId
  986. //
  987. // Synopsis: maps an OID to a property id
  988. //
  989. //----------------------------------------------------------------------------
  990. BOOL WINAPI
  991. MapOidToPropertyId (
  992. IN LPCSTR pszOid,
  993. OUT DWORD* pPropId
  994. )
  995. {
  996. if ( (DWORD_PTR)pszOid <= 0xFFFF )
  997. {
  998. // NOTE: Switch on pszOid and map
  999. return( FALSE );
  1000. }
  1001. else if ( 0 == strcmp(pszOid, szOID_CROSS_CERT_DIST_POINTS) )
  1002. {
  1003. *pPropId = CERT_CROSS_CERT_DIST_POINTS_PROP_ID;
  1004. }
  1005. else if ( 0 == strcmp(pszOid, szOID_NEXT_UPDATE_LOCATION) )
  1006. {
  1007. *pPropId = CERT_NEXT_UPDATE_LOCATION_PROP_ID;
  1008. }
  1009. else
  1010. {
  1011. // NOTE: Compare pszOid and map
  1012. return( FALSE );
  1013. }
  1014. return( TRUE );
  1015. }