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.

393 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: scrdcert.cpp
  7. //
  8. // Contents: Smart Card Certificate API
  9. //
  10. // History: 11-24-1997 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <global.hxx>
  14. #include <dbgdef.h>
  15. //+---------------------------------------------------------------------------
  16. //
  17. // Function: I_CryptRegisterSmartCardStore
  18. //
  19. // Synopsis: register smart card store
  20. //
  21. //----------------------------------------------------------------------------
  22. BOOL WINAPI
  23. I_CryptRegisterSmartCardStore (
  24. IN LPCWSTR pwszCardName,
  25. IN OPTIONAL LPCWSTR pwszProvider,
  26. IN OPTIONAL DWORD dwProviderType,
  27. IN OPTIONAL LPCWSTR pwszContainer,
  28. IN DWORD dwFlags
  29. )
  30. {
  31. BOOL fResult;
  32. DWORD cw;
  33. CHAR szProviderType[MAX_PROVIDER_TYPE_STRLEN];
  34. WCHAR wszProviderType[MAX_PROVIDER_TYPE_STRLEN];
  35. LPWSTR pwszOpenFilter;
  36. DWORD dwRegisterFlags = 0;
  37. CERT_SYSTEM_STORE_INFO cssi;
  38. CERT_PHYSICAL_STORE_INFO cpsi;
  39. cw = wcslen( pwszCardName ) + 1;
  40. if ( pwszProvider == NULL )
  41. {
  42. pwszProvider = MS_BASE_PROVIDER;
  43. }
  44. cw += wcslen( pwszProvider ) + 1;
  45. cw += MAX_PROVIDER_TYPE_STRLEN + 1;
  46. if ( pwszContainer == NULL )
  47. {
  48. pwszContainer = pwszCardName;
  49. }
  50. cw += wcslen( pwszContainer ) + 1;
  51. pwszOpenFilter = new WCHAR [cw];
  52. if ( pwszOpenFilter == NULL )
  53. {
  54. SetLastError( (DWORD) E_OUTOFMEMORY );
  55. return( FALSE );
  56. }
  57. _ultoa( dwProviderType, szProviderType, 10 );
  58. MultiByteToWideChar(
  59. CP_ACP,
  60. 0,
  61. szProviderType,
  62. MAX_PROVIDER_TYPE_STRLEN,
  63. wszProviderType,
  64. MAX_PROVIDER_TYPE_STRLEN
  65. );
  66. wcscpy( pwszOpenFilter, pwszCardName );
  67. wcscat( pwszOpenFilter, L"\\" );
  68. wcscat( pwszOpenFilter, pwszProvider );
  69. wcscat( pwszOpenFilter, L"\\" );
  70. wcscat( pwszOpenFilter, wszProviderType );
  71. wcscat( pwszOpenFilter, L"\\" );
  72. wcscat( pwszOpenFilter, pwszContainer );
  73. memset( &cssi, 0, sizeof( cssi ) );
  74. cssi.cbSize = sizeof( cssi );
  75. // What about the localized name property?
  76. CertRegisterSystemStore(
  77. SMART_CARD_SYSTEM_STORE,
  78. CERT_SYSTEM_STORE_CURRENT_USER,
  79. &cssi,
  80. NULL
  81. );
  82. memset( &cpsi, 0, sizeof( cpsi ) );
  83. cpsi.cbSize = sizeof( cpsi );
  84. cpsi.pszOpenStoreProvider = sz_CERT_STORE_PROV_SMART_CARD;
  85. cpsi.OpenParameters.cbData = cw * sizeof( WCHAR );
  86. cpsi.OpenParameters.pbData = (LPBYTE)pwszOpenFilter;
  87. cpsi.dwFlags = CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG;
  88. cpsi.dwFlags |= CERT_PHYSICAL_STORE_REMOTE_OPEN_DISABLE_FLAG;
  89. if ( !( dwFlags & SMART_CARD_STORE_REPLACE_EXISTING ) )
  90. {
  91. dwRegisterFlags |= CERT_STORE_CREATE_NEW_FLAG;
  92. }
  93. fResult = CertRegisterPhysicalStore(
  94. SMART_CARD_SYSTEM_STORE,
  95. dwRegisterFlags | CERT_SYSTEM_STORE_CURRENT_USER,
  96. pwszCardName,
  97. &cpsi,
  98. NULL
  99. );
  100. delete pwszOpenFilter;
  101. return( fResult );
  102. }
  103. //+---------------------------------------------------------------------------
  104. //
  105. // Function: I_CryptUnregisterSmartCardStore
  106. //
  107. // Synopsis: unregister a smart card store
  108. //
  109. //----------------------------------------------------------------------------
  110. BOOL WINAPI
  111. I_CryptUnregisterSmartCardStore (
  112. IN LPCWSTR pwszCardName
  113. )
  114. {
  115. return( CertUnregisterPhysicalStore(
  116. SMART_CARD_SYSTEM_STORE,
  117. CERT_SYSTEM_STORE_CURRENT_USER,
  118. pwszCardName
  119. ) );
  120. }
  121. //+---------------------------------------------------------------------------
  122. //
  123. // Function: I_CryptFindSmartCardCertInStore
  124. //
  125. // Synopsis: find a smart card certificate matching the given criteria
  126. //
  127. //----------------------------------------------------------------------------
  128. PCCERT_CONTEXT WINAPI
  129. I_CryptFindSmartCardCertInStore (
  130. IN HCERTSTORE hStore,
  131. IN PCCERT_CONTEXT pPrevCert,
  132. IN OPTIONAL PSMART_CARD_CERT_FIND_DATA pFindData,
  133. IN OUT OPTIONAL PCRYPT_DATA_BLOB* ppSmartCardData
  134. )
  135. {
  136. BOOL fResult;
  137. BOOL fFound = FALSE;
  138. PCCERT_CONTEXT pCertContext = pPrevCert;
  139. DWORD cb;
  140. PCRYPT_DATA_BLOB pSmartCardData = NULL;
  141. DWORD dwPropId = CERT_SMART_CARD_DATA_PROP_ID;
  142. assert( hStore != NULL );
  143. while ( fFound == FALSE )
  144. {
  145. pCertContext = CertFindCertificateInStore(
  146. hStore,
  147. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  148. 0,
  149. CERT_FIND_PROPERTY,
  150. (const void *)&dwPropId,
  151. pCertContext
  152. );
  153. if ( ( ppSmartCardData != NULL ) && ( *ppSmartCardData != NULL ) )
  154. {
  155. LocalFree( (HLOCAL)*ppSmartCardData );
  156. *ppSmartCardData = NULL;
  157. }
  158. if ( pCertContext != NULL )
  159. {
  160. if ( pFindData != NULL )
  161. {
  162. PCRYPT_KEY_PROV_INFO pKeyProvInfo = NULL;
  163. fResult = CertGetCertificateContextProperty(
  164. pCertContext,
  165. CERT_KEY_PROV_INFO_PROP_ID,
  166. NULL,
  167. &cb
  168. );
  169. if ( fResult == TRUE )
  170. {
  171. pKeyProvInfo = (PCRYPT_KEY_PROV_INFO)new BYTE [cb];
  172. if ( pKeyProvInfo != NULL )
  173. {
  174. fResult = CertGetCertificateContextProperty(
  175. pCertContext,
  176. CERT_KEY_PROV_INFO_PROP_ID,
  177. pKeyProvInfo,
  178. &cb
  179. );
  180. }
  181. else
  182. {
  183. fResult = FALSE;
  184. }
  185. }
  186. if ( fResult == TRUE )
  187. {
  188. fFound = TRUE;
  189. if ( ( pFindData->pwszProvider != NULL ) &&
  190. ( _wcsicmp(
  191. pKeyProvInfo->pwszProvName,
  192. pFindData->pwszProvider
  193. ) != 0 ) )
  194. {
  195. fFound = FALSE;
  196. }
  197. if ( ( pFindData->dwProviderType != 0 ) &&
  198. ( pKeyProvInfo->dwProvType !=
  199. pFindData->dwProviderType ) )
  200. {
  201. fFound = FALSE;
  202. }
  203. if ( ( pFindData->pwszContainer != NULL ) &&
  204. ( _wcsicmp(
  205. pKeyProvInfo->pwszContainerName,
  206. pFindData->pwszContainer
  207. ) != 0 ) )
  208. {
  209. fFound = FALSE;
  210. }
  211. if ( ( pFindData->dwKeySpec != 0 ) &&
  212. ( pKeyProvInfo->dwKeySpec !=
  213. pFindData->dwKeySpec ) )
  214. {
  215. fFound = FALSE;
  216. }
  217. }
  218. delete (LPBYTE)pKeyProvInfo;
  219. }
  220. else
  221. {
  222. fFound = TRUE;
  223. }
  224. }
  225. else
  226. {
  227. fFound = TRUE;
  228. }
  229. }
  230. assert( fFound == TRUE );
  231. if ( ( ppSmartCardData != NULL ) && ( pCertContext != NULL ) )
  232. {
  233. fResult = CertGetCertificateContextProperty(
  234. pCertContext,
  235. CERT_SMART_CARD_DATA_PROP_ID,
  236. NULL,
  237. &cb
  238. );
  239. if ( fResult == TRUE )
  240. {
  241. pSmartCardData = (PCRYPT_DATA_BLOB)LocalAlloc(
  242. GPTR,
  243. cb + sizeof( CRYPT_DATA_BLOB )
  244. );
  245. if ( pSmartCardData != NULL )
  246. {
  247. pSmartCardData->cbData = cb;
  248. pSmartCardData->pbData = (LPBYTE)pSmartCardData + sizeof( CRYPT_DATA_BLOB );
  249. fResult = CertGetCertificateContextProperty(
  250. pCertContext,
  251. CERT_SMART_CARD_DATA_PROP_ID,
  252. pSmartCardData->pbData,
  253. &cb
  254. );
  255. }
  256. else
  257. {
  258. fResult = FALSE;
  259. }
  260. }
  261. if ( fResult == TRUE )
  262. {
  263. *ppSmartCardData = pSmartCardData;
  264. }
  265. else
  266. {
  267. if ( pSmartCardData != NULL )
  268. {
  269. LocalFree( (HLOCAL)pSmartCardData );
  270. }
  271. CertFreeCertificateContext( pCertContext );
  272. pCertContext = NULL;
  273. }
  274. }
  275. return( pCertContext );
  276. }
  277. //+---------------------------------------------------------------------------
  278. //
  279. // Function: I_CryptAddSmartCardCertToStore
  280. //
  281. // Synopsis: add a smart card certificate to the specified store
  282. //
  283. //----------------------------------------------------------------------------
  284. BOOL WINAPI
  285. I_CryptAddSmartCardCertToStore (
  286. IN HCERTSTORE hStore,
  287. IN PCRYPT_DATA_BLOB pEncodedCert,
  288. IN OPTIONAL LPWSTR pwszCertFriendlyName,
  289. IN PCRYPT_DATA_BLOB pSmartCardData,
  290. IN PCRYPT_KEY_PROV_INFO pKeyProvInfo
  291. )
  292. {
  293. BOOL fResult = TRUE;
  294. PCCERT_CONTEXT pCertContext;
  295. CRYPT_DATA_BLOB DataBlob;
  296. pCertContext = CertCreateCertificateContext(
  297. X509_ASN_ENCODING,
  298. pEncodedCert->pbData,
  299. pEncodedCert->cbData
  300. );
  301. if ( pCertContext == NULL )
  302. {
  303. return( FALSE );
  304. }
  305. if ( pwszCertFriendlyName != NULL )
  306. {
  307. DataBlob.cbData = ( wcslen( pwszCertFriendlyName ) + 1 ) * sizeof( WCHAR );
  308. DataBlob.pbData = (LPBYTE)pwszCertFriendlyName;
  309. fResult = CertSetCertificateContextProperty(
  310. pCertContext,
  311. CERT_FRIENDLY_NAME_PROP_ID,
  312. 0,
  313. (const void *)&DataBlob
  314. );
  315. }
  316. if ( fResult == TRUE )
  317. {
  318. fResult = CertSetCertificateContextProperty(
  319. pCertContext,
  320. CERT_SMART_CARD_DATA_PROP_ID,
  321. 0,
  322. (const void *)pSmartCardData
  323. );
  324. }
  325. if ( fResult == TRUE )
  326. {
  327. fResult = CertSetCertificateContextProperty(
  328. pCertContext,
  329. CERT_KEY_PROV_INFO_PROP_ID,
  330. 0,
  331. (const void *)pKeyProvInfo
  332. );
  333. }
  334. if ( fResult == TRUE )
  335. {
  336. fResult = CertAddCertificateContextToStore(
  337. hStore,
  338. pCertContext,
  339. CERT_STORE_ADD_REPLACE_EXISTING,
  340. NULL
  341. );
  342. }
  343. CertFreeCertificateContext( pCertContext );
  344. return( fResult );
  345. }