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.

649 lines
19 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: scstore.cpp
  7. //
  8. // Contents: Smart Card Store Provider implementation
  9. //
  10. // History: 03-Dec-97 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <global.hxx>
  14. #include <dbgdef.h>
  15. //+---------------------------------------------------------------------------
  16. //
  17. // Member: CSmartCardStore::CSmartCardStore, public
  18. //
  19. // Synopsis: Constructor
  20. //
  21. //----------------------------------------------------------------------------
  22. CSmartCardStore::CSmartCardStore ()
  23. : m_dwOpenFlags( 0 ),
  24. m_pwszCardName( NULL ),
  25. m_pwszProvider( NULL ),
  26. m_dwProviderType( 0 ),
  27. m_pwszContainer( NULL ),
  28. m_hCacheStore( NULL )
  29. {
  30. Pki_InitializeCriticalSection( &m_StoreLock );
  31. }
  32. //+---------------------------------------------------------------------------
  33. //
  34. // Member: CSmartCardStore::~CSmartCardStore, public
  35. //
  36. // Synopsis: Destructor
  37. //
  38. //----------------------------------------------------------------------------
  39. CSmartCardStore::~CSmartCardStore ()
  40. {
  41. DeleteCriticalSection( &m_StoreLock );
  42. }
  43. //+---------------------------------------------------------------------------
  44. //
  45. // Member: CSmartCardStore::OpenStore, public
  46. //
  47. // Synopsis: open store
  48. //
  49. //----------------------------------------------------------------------------
  50. BOOL
  51. CSmartCardStore::OpenStore (
  52. LPCSTR pszStoreProv,
  53. DWORD dwMsgAndCertEncodingType,
  54. HCRYPTPROV hCryptProv,
  55. DWORD dwFlags,
  56. const void* pvPara,
  57. HCERTSTORE hCertStore,
  58. PCERT_STORE_PROV_INFO pStoreProvInfo
  59. )
  60. {
  61. BOOL fResult;
  62. assert( m_dwOpenFlags == 0 );
  63. assert( m_pwszCardName == NULL );
  64. assert( m_pwszProvider == NULL );
  65. assert( m_pwszContainer == NULL );
  66. assert( m_hCacheStore == NULL );
  67. if ( ( pvPara == NULL ) ||
  68. ( dwFlags & (CERT_STORE_DELETE_FLAG |
  69. CERT_STORE_UNSAFE_PHYSICAL_FLAG) ) )
  70. {
  71. SetLastError( (DWORD) E_INVALIDARG );
  72. return( FALSE );
  73. }
  74. if ( SCStoreParseOpenFilter(
  75. (LPWSTR)pvPara,
  76. &m_pwszCardName,
  77. &m_pwszProvider,
  78. &m_dwProviderType,
  79. &m_pwszContainer
  80. ) == FALSE )
  81. {
  82. return( FALSE );
  83. }
  84. m_dwOpenFlags = dwFlags;
  85. m_hCacheStore = hCertStore;
  86. fResult = FillCacheStore( FALSE );
  87. if ( fResult == TRUE )
  88. {
  89. pStoreProvInfo->cStoreProvFunc = SMART_CARD_PROV_FUNC_COUNT;
  90. pStoreProvInfo->rgpvStoreProvFunc = (void **)rgpvSmartCardProvFunc;
  91. pStoreProvInfo->hStoreProv = (HCERTSTOREPROV)this;
  92. }
  93. else
  94. {
  95. CloseStore( 0 );
  96. }
  97. return( fResult );
  98. }
  99. //+---------------------------------------------------------------------------
  100. //
  101. // Member: CSmartCardStore::CloseStore, public
  102. //
  103. // Synopsis: close store
  104. //
  105. //----------------------------------------------------------------------------
  106. VOID
  107. CSmartCardStore::CloseStore (DWORD dwFlags)
  108. {
  109. EnterCriticalSection( &m_StoreLock );
  110. delete m_pwszCardName;
  111. m_pwszCardName = NULL;
  112. delete m_pwszProvider;
  113. m_pwszProvider = NULL;
  114. delete m_pwszContainer;
  115. m_pwszContainer = NULL;
  116. LeaveCriticalSection( &m_StoreLock );
  117. }
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Member: CSmartCardStore::DeleteCert, public
  121. //
  122. // Synopsis: delete cert
  123. //
  124. //----------------------------------------------------------------------------
  125. BOOL
  126. CSmartCardStore::DeleteCert (PCCERT_CONTEXT pCertContext, DWORD dwFlags)
  127. {
  128. return( ModifyCertOnCard( pCertContext, TRUE ) );
  129. }
  130. //+---------------------------------------------------------------------------
  131. //
  132. // Member: CSmartCardStore::SetCertProperty, public
  133. //
  134. // Synopsis: set certificate property
  135. //
  136. //----------------------------------------------------------------------------
  137. BOOL
  138. CSmartCardStore::SetCertProperty (
  139. PCCERT_CONTEXT pCertContext,
  140. DWORD dwPropId,
  141. DWORD dwFlags,
  142. const void* pvPara
  143. )
  144. {
  145. // NOTENOTE: Properties are NOT persisted
  146. return( TRUE );
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Member: CSmartCardStore::WriteCert, public
  151. //
  152. // Synopsis: write certificate
  153. //
  154. //----------------------------------------------------------------------------
  155. BOOL
  156. CSmartCardStore::WriteCert (PCCERT_CONTEXT pCertContext, DWORD dwFlags)
  157. {
  158. return( ModifyCertOnCard( pCertContext, FALSE ) );
  159. }
  160. //+---------------------------------------------------------------------------
  161. //
  162. // Member: CSmartCardStore::StoreControl, public
  163. //
  164. // Synopsis: store control
  165. //
  166. //----------------------------------------------------------------------------
  167. BOOL
  168. CSmartCardStore::StoreControl (
  169. DWORD dwFlags,
  170. DWORD dwCtrlType,
  171. LPVOID pvCtrlPara
  172. )
  173. {
  174. switch ( dwCtrlType )
  175. {
  176. case CERT_STORE_CTRL_RESYNC:
  177. return( Resync() );
  178. }
  179. SetLastError( (DWORD) ERROR_NOT_SUPPORTED );
  180. return( FALSE );
  181. }
  182. //+---------------------------------------------------------------------------
  183. //
  184. // Member: CSmartCardStore::Resync, public
  185. //
  186. // Synopsis: resync store
  187. //
  188. //----------------------------------------------------------------------------
  189. BOOL
  190. CSmartCardStore::Resync ()
  191. {
  192. BOOL fResult;
  193. EnterCriticalSection( &m_StoreLock );
  194. fResult = FillCacheStore( TRUE );
  195. LeaveCriticalSection( &m_StoreLock );
  196. return( fResult );
  197. }
  198. //+---------------------------------------------------------------------------
  199. //
  200. // Member: CSmartCardStore::FillCacheStore, public
  201. //
  202. // Synopsis: fill the cache store
  203. //
  204. //----------------------------------------------------------------------------
  205. BOOL
  206. CSmartCardStore::FillCacheStore (BOOL fClearCache)
  207. {
  208. BOOL fResult = TRUE;
  209. PCCERT_CONTEXT pCertContext;
  210. PCCRL_CONTEXT pCrlContext;
  211. PCCTL_CONTEXT pCtlContext;
  212. DWORD dwFlags = 0;
  213. SMART_CARD_CERT_FIND_DATA sccfind;
  214. HCERTSTORE hMyStore;
  215. if ( fClearCache == TRUE )
  216. {
  217. while ( pCertContext = CertEnumCertificatesInStore( m_hCacheStore, NULL ) )
  218. {
  219. CertDeleteCertificateFromStore( pCertContext );
  220. }
  221. while ( pCrlContext = CertGetCRLFromStore( m_hCacheStore, NULL, NULL, &dwFlags ) )
  222. {
  223. CertDeleteCRLFromStore( pCrlContext );
  224. }
  225. while ( pCtlContext = CertEnumCTLsInStore( m_hCacheStore, NULL ) )
  226. {
  227. CertDeleteCTLFromStore( pCtlContext );
  228. }
  229. }
  230. hMyStore = CertOpenSystemStoreW( NULL, L"MY" );
  231. if ( hMyStore == NULL )
  232. {
  233. return( FALSE );
  234. }
  235. sccfind.cbSize = sizeof( sccfind );
  236. sccfind.pwszProvider = m_pwszProvider;
  237. sccfind.dwProviderType = m_dwProviderType;
  238. sccfind.pwszContainer = m_pwszContainer;
  239. sccfind.dwKeySpec = 0;
  240. pCertContext = NULL;
  241. while ( ( fResult == TRUE ) &&
  242. ( ( pCertContext = I_CryptFindSmartCardCertInStore(
  243. hMyStore,
  244. pCertContext,
  245. &sccfind,
  246. NULL
  247. ) ) != NULL ) )
  248. {
  249. fResult = CertAddCertificateContextToStore(
  250. m_hCacheStore,
  251. pCertContext,
  252. CERT_STORE_ADD_ALWAYS,
  253. NULL
  254. );
  255. }
  256. CertCloseStore( hMyStore, 0 );
  257. return( fResult );
  258. }
  259. //+---------------------------------------------------------------------------
  260. //
  261. // Member: CSmartCardStore::ModifyCertOnCard, public
  262. //
  263. // Synopsis: modify the cert corresponding to the public key in the given
  264. // cert context
  265. //
  266. //----------------------------------------------------------------------------
  267. BOOL
  268. CSmartCardStore::ModifyCertOnCard (PCCERT_CONTEXT pCertContext, BOOL fDelete)
  269. {
  270. BOOL fResult;
  271. HCRYPTPROV hContainer = NULL;
  272. HCRYPTKEY hKeyPair = 0;
  273. fResult = CryptAcquireContextU(
  274. &hContainer,
  275. m_pwszContainer,
  276. m_pwszProvider,
  277. m_dwProviderType,
  278. 0
  279. );
  280. if ( fResult == TRUE )
  281. {
  282. fResult = SCStoreAcquireHandleForCertKeyPair(
  283. hContainer,
  284. pCertContext,
  285. &hKeyPair
  286. );
  287. }
  288. if ( fResult == TRUE )
  289. {
  290. fResult = SCStoreWriteCertToCard(
  291. ( fDelete == FALSE ) ? pCertContext : NULL,
  292. hKeyPair
  293. );
  294. CryptDestroyKey( hKeyPair );
  295. }
  296. if ( hContainer != NULL )
  297. {
  298. CryptReleaseContext( hContainer, 0 );
  299. }
  300. return( fResult );
  301. }
  302. //+---------------------------------------------------------------------------
  303. //
  304. // Function: SmartCardProvOpenStore
  305. //
  306. // Synopsis: provider open store entry point
  307. //
  308. //----------------------------------------------------------------------------
  309. BOOL WINAPI SmartCardProvOpenStore (
  310. IN LPCSTR pszStoreProv,
  311. IN DWORD dwMsgAndCertEncodingType,
  312. IN HCRYPTPROV hCryptProv,
  313. IN DWORD dwFlags,
  314. IN const void* pvPara,
  315. IN HCERTSTORE hCertStore,
  316. IN OUT PCERT_STORE_PROV_INFO pStoreProvInfo
  317. )
  318. {
  319. BOOL fResult;
  320. CSmartCardStore* pSCStore;
  321. pSCStore = new CSmartCardStore;
  322. if ( pSCStore == NULL )
  323. {
  324. SetLastError( (DWORD) E_OUTOFMEMORY );
  325. return( FALSE );
  326. }
  327. fResult = pSCStore->OpenStore(
  328. pszStoreProv,
  329. dwMsgAndCertEncodingType,
  330. hCryptProv,
  331. dwFlags,
  332. pvPara,
  333. hCertStore,
  334. pStoreProvInfo
  335. );
  336. if ( fResult == FALSE )
  337. {
  338. delete pSCStore;
  339. }
  340. return( fResult );
  341. }
  342. //+---------------------------------------------------------------------------
  343. //
  344. // Function: SmartCardProvCloseStore
  345. //
  346. // Synopsis: provider close store entry point
  347. //
  348. //----------------------------------------------------------------------------
  349. void WINAPI SmartCardProvCloseStore (
  350. IN HCERTSTOREPROV hStoreProv,
  351. IN DWORD dwFlags
  352. )
  353. {
  354. ( (CSmartCardStore *)hStoreProv )->CloseStore( dwFlags );
  355. delete (CSmartCardStore *)hStoreProv;
  356. }
  357. //+---------------------------------------------------------------------------
  358. //
  359. // Function: SmartCardProvDeleteCert
  360. //
  361. // Synopsis: provider delete cert entry point
  362. //
  363. //----------------------------------------------------------------------------
  364. BOOL WINAPI SmartCardProvDeleteCert (
  365. IN HCERTSTOREPROV hStoreProv,
  366. IN PCCERT_CONTEXT pCertContext,
  367. IN DWORD dwFlags
  368. )
  369. {
  370. return( ( (CSmartCardStore *)hStoreProv )->DeleteCert(
  371. pCertContext,
  372. dwFlags
  373. ) );
  374. }
  375. //+---------------------------------------------------------------------------
  376. //
  377. // Function: SmartCardProvSetCertProperty
  378. //
  379. // Synopsis: provider set cert property entry point
  380. //
  381. //----------------------------------------------------------------------------
  382. BOOL WINAPI SmartCardProvSetCertProperty (
  383. IN HCERTSTOREPROV hStoreProv,
  384. IN PCCERT_CONTEXT pCertContext,
  385. IN DWORD dwPropId,
  386. IN DWORD dwFlags,
  387. IN const void* pvData
  388. )
  389. {
  390. return( ( (CSmartCardStore *)hStoreProv )->SetCertProperty(
  391. pCertContext,
  392. dwPropId,
  393. dwFlags,
  394. pvData
  395. ) );
  396. }
  397. //+---------------------------------------------------------------------------
  398. //
  399. // Function: SmartCardProvWriteCert
  400. //
  401. // Synopsis: provider write cert entry point
  402. //
  403. //----------------------------------------------------------------------------
  404. BOOL WINAPI SmartCardProvWriteCert (
  405. IN HCERTSTOREPROV hStoreProv,
  406. IN PCCERT_CONTEXT pCertContext,
  407. IN DWORD dwFlags
  408. )
  409. {
  410. return( ( (CSmartCardStore *)hStoreProv )->WriteCert(
  411. pCertContext,
  412. dwFlags
  413. ) );
  414. }
  415. //+---------------------------------------------------------------------------
  416. //
  417. // Function: SmartCardProvStoreControl
  418. //
  419. // Synopsis: provider store control entry point
  420. //
  421. //----------------------------------------------------------------------------
  422. BOOL WINAPI SmartCardProvStoreControl (
  423. IN HCERTSTOREPROV hStoreProv,
  424. IN DWORD dwFlags,
  425. IN DWORD dwCtrlType,
  426. IN LPVOID pvCtrlPara
  427. )
  428. {
  429. return( ( (CSmartCardStore *)hStoreProv )->StoreControl(
  430. dwFlags,
  431. dwCtrlType,
  432. pvCtrlPara
  433. ) );
  434. }
  435. //+---------------------------------------------------------------------------
  436. //
  437. // Function: SCStoreParseOpenFilter
  438. //
  439. // Synopsis: parse open filter
  440. //
  441. //----------------------------------------------------------------------------
  442. BOOL WINAPI
  443. SCStoreParseOpenFilter (
  444. IN LPWSTR pwszOpenFilter,
  445. OUT LPWSTR* ppwszCardName,
  446. OUT LPWSTR* ppwszProvider,
  447. OUT DWORD* pdwProviderType,
  448. OUT LPWSTR* ppwszContainer
  449. )
  450. {
  451. LPWSTR pwsz;
  452. DWORD cw = wcslen( pwszOpenFilter ) + 1;
  453. DWORD cParse = 1;
  454. DWORD cCount;
  455. DWORD aParse[PARSE_ELEM];
  456. LPWSTR pwszCardName;
  457. LPWSTR pwszProvider;
  458. LPSTR pszProviderType;
  459. DWORD dwProviderType;
  460. LPWSTR pwszContainer;
  461. pwsz = new WCHAR [ cw ];
  462. if ( pwsz == NULL )
  463. {
  464. SetLastError( (DWORD) E_OUTOFMEMORY );
  465. return( FALSE );
  466. }
  467. wcscpy( pwsz, pwszOpenFilter );
  468. memset( aParse, 0, sizeof( aParse ) );
  469. for ( cCount = 0; ( cCount < cw ) && ( cParse < PARSE_ELEM ); cCount++ )
  470. {
  471. if ( pwsz[cCount] == L'\\' )
  472. {
  473. aParse[cParse++] = cCount + 1;
  474. pwsz[cCount] = L'\0';
  475. }
  476. }
  477. if ( cParse < PARSE_ELEM - 1 )
  478. {
  479. delete pwsz;
  480. SetLastError( (DWORD) E_INVALIDARG );
  481. return( FALSE );
  482. }
  483. pwszCardName = new WCHAR [wcslen( &pwsz[aParse[0]] ) + 1];
  484. pwszProvider = new WCHAR [wcslen( &pwsz[aParse[1]] ) + 1];
  485. cw = wcslen( &pwsz[aParse[2]] ) + 1;
  486. pszProviderType = new CHAR [cw];
  487. pwszContainer = new WCHAR [wcslen( &pwsz[aParse[3]] ) + 1];
  488. if ( ( pwszCardName == NULL ) || ( pwszProvider == NULL ) ||
  489. ( pszProviderType == NULL ) || ( pwszContainer == NULL ) )
  490. {
  491. delete pwszCardName;
  492. delete pwszProvider;
  493. delete pszProviderType;
  494. delete pwszContainer;
  495. delete pwsz;
  496. SetLastError( (DWORD) E_OUTOFMEMORY );
  497. return( FALSE );
  498. }
  499. wcscpy( pwszCardName, &pwsz[aParse[0]] );
  500. wcscpy( pwszProvider, &pwsz[aParse[1]] );
  501. WideCharToMultiByte(
  502. CP_ACP,
  503. 0,
  504. &pwsz[aParse[2]],
  505. cw,
  506. pszProviderType,
  507. cw,
  508. NULL,
  509. NULL
  510. );
  511. dwProviderType = atol( pszProviderType );
  512. wcscpy( pwszContainer, &pwsz[aParse[3]] );
  513. *ppwszCardName = pwszCardName;
  514. *ppwszProvider = pwszProvider;
  515. *pdwProviderType = dwProviderType;
  516. *ppwszContainer = pwszContainer;
  517. delete pszProviderType;
  518. delete pwsz;
  519. return( TRUE );
  520. }
  521. //+---------------------------------------------------------------------------
  522. //
  523. // Function: SCStoreAcquireHandleForCertKeyPair
  524. //
  525. // Synopsis: get the provider handle corresponding to the key pair
  526. // identified by the public key given in the cert context
  527. //
  528. //----------------------------------------------------------------------------
  529. BOOL WINAPI
  530. SCStoreAcquireHandleForCertKeyPair (
  531. IN HCRYPTPROV hContainer,
  532. IN PCCERT_CONTEXT pCertContext,
  533. OUT HCRYPTKEY* phKeyPair
  534. )
  535. {
  536. BOOL fResult;
  537. DWORD dwKeySpec = AT_SIGNATURE;
  538. fResult = I_CertCompareCertAndProviderPublicKey(
  539. pCertContext,
  540. hContainer,
  541. dwKeySpec
  542. );
  543. if ( fResult == FALSE )
  544. {
  545. dwKeySpec = AT_KEYEXCHANGE;
  546. fResult = I_CertCompareCertAndProviderPublicKey(
  547. pCertContext,
  548. hContainer,
  549. dwKeySpec
  550. );
  551. }
  552. if ( fResult == TRUE )
  553. {
  554. fResult = CryptGetUserKey( hContainer, dwKeySpec, phKeyPair );
  555. }
  556. return( fResult );
  557. }
  558. //+---------------------------------------------------------------------------
  559. //
  560. // Function: SCStoreWriteCertToCard
  561. //
  562. // Synopsis: write the cert to the card
  563. //
  564. //----------------------------------------------------------------------------
  565. BOOL WINAPI
  566. SCStoreWriteCertToCard (
  567. IN OPTIONAL PCCERT_CONTEXT pCertContext,
  568. IN HCRYPTKEY hKeyPair
  569. )
  570. {
  571. LPBYTE pbEncoded = NULL;
  572. if ( pCertContext != NULL )
  573. {
  574. pbEncoded = pCertContext->pbCertEncoded;
  575. }
  576. return( CryptSetKeyParam( hKeyPair, KP_CERTIFICATE, pbEncoded, 0 ) );
  577. }