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.

524 lines
15 KiB

  1. // CspProfile.cpp -- CSP Profile class implementation
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 1998. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. #if defined(_UNICODE)
  8. #if !defined(UNICODE)
  9. #define UNICODE
  10. #endif //!UNICODE
  11. #endif //_UNICODE
  12. #if defined(UNICODE)
  13. #if !defined(_UNICODE)
  14. #define _UNICODE
  15. #endif //!_UNICODE
  16. #endif //UNICODE
  17. #include "stdafx.h"
  18. #include <stddef.h>
  19. #include <basetsd.h>
  20. #include <wincrypt.h>
  21. #include <scuOsExc.h>
  22. #include <slbModVer.h>
  23. #include "StResource.h"
  24. #include "MasterLock.h"
  25. #include "Guard.h"
  26. #include "Blob.h"
  27. #include "CspProfile.h"
  28. using namespace std;
  29. using namespace ProviderProfile;
  30. namespace
  31. {
  32. BYTE g_abCF4kATRString[] = { 0x3b, 0xe2, 0x00, 0x00, 0x40, 0x20,
  33. 0x49, 0x00 };
  34. BYTE g_abCF4kATRMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  35. 0xff, 0x00 };
  36. BYTE g_abCF8kATRString[] = { 0x3b, 0x85, 0x40, 0x20, 0x68,
  37. 0x01, 0x01, 0x00, 0x00 };
  38. BYTE g_abCF8kATRMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff,
  39. 0xff, 0xff, 0x00, 0x00 };
  40. BYTE g_abCF8kV2ATRString[] = { 0x3b, 0x95, 0x15, 0x40, 0x00,
  41. 0x68, 0x01, 0x02, 0x00, 0x00 };
  42. BYTE g_abCF8kV2ATRMask[] = { 0xff, 0xff, 0xff, 0xff, 0x00,
  43. 0xff, 0xff, 0xff, 0x00, 0x00 };
  44. // BYTE g_abCF16kATRString[] = { 0x3B, 0x95, 0x15, 0x40, 0xFF, 0x63,
  45. // 0x01, 0x01, 0x00, 0x00 };
  46. // BYTE g_abCF16kATRMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  47. // 0xFF, 0xFF, 0x00, 0x00 };
  48. BYTE g_abCFe_gateATRString[] = { 0x3B, 0x95, 0x00, 0x40, 0xFF,
  49. 0x62, 0x01, 0x01, 0x00, 0x00 };
  50. BYTE g_abCFe_gateATRMask[] = { 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
  51. 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
  52. BYTE g_abCA16kATRString[] = { 0x3b, 0x16, 0x94, 0x81, 0x10,
  53. 0x06, 0x01, 0x00, 0x00 };
  54. BYTE g_abCA16kATRMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff,
  55. 0xff, 0xff, 0x00, 0x00 };
  56. BYTE g_abCACampusATRString[] = { 0x3b, 0x23, 0x00, 0x35, 0x13, 0x80 };
  57. BYTE g_abCACampusATRMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  58. BYTE g_abCFActivCardATRString[] = { 0x3b, 0x05, 0x68, 0x01, 0x01,
  59. 0x02, 0x05 };
  60. BYTE g_abCFActivCardATRMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff,
  61. 0xff, 0xff };
  62. GUID g_guidPrimaryProvider = { 0x19B7E2E8, 0xFEBD, 0x11d0,
  63. { 0x88, 0x27, 0x00, 0xA0, 0xC9,
  64. 0x55, 0xFC, 0x7E } };
  65. } // namespace
  66. ATR::ATR()
  67. : m_al(0)
  68. {}
  69. ATR::ATR(Length al,
  70. BYTE const abATR[],
  71. BYTE const abMask[])
  72. : m_al(al)
  73. {
  74. memcpy(m_atrstring, abATR, al);
  75. memcpy(m_atrsMask, abMask, al);
  76. }
  77. BYTE const *
  78. ATR::String() const
  79. {
  80. return m_atrstring;
  81. }
  82. BYTE const *
  83. ATR::Mask() const
  84. {
  85. return m_atrsMask;
  86. }
  87. ATR::Length
  88. ATR::ATRLength() const
  89. {
  90. return m_al;
  91. }
  92. size_t
  93. ATR::Size() const
  94. {
  95. return m_al * sizeof *m_atrstring;
  96. }
  97. ATR &
  98. ATR::operator=(ATR const &rhs)
  99. {
  100. if (*this != rhs)
  101. {
  102. m_al = rhs.m_al;
  103. memcpy(m_atrstring, rhs.m_atrstring,
  104. sizeof m_atrstring / sizeof *m_atrstring);
  105. memcpy(m_atrsMask, rhs.m_atrsMask,
  106. sizeof m_atrsMask / sizeof *m_atrsMask);
  107. }
  108. return *this;
  109. }
  110. bool
  111. ATR::operator==(ATR const &rhs)
  112. {
  113. return !(*this != rhs);
  114. }
  115. bool
  116. ATR::operator!=(ATR const &rhs)
  117. {
  118. return (m_al != rhs.m_al) ||
  119. memcmp(m_atrstring, rhs.m_atrstring, m_al) ||
  120. memcmp(m_atrsMask, rhs.m_atrsMask, m_al);
  121. }
  122. CardProfile::CardProfile()
  123. : m_atr(),
  124. m_sFriendlyName(),
  125. m_sRegistryName(),
  126. m_csFriendlyName(),
  127. m_csRegistryName(),
  128. m_gPrimaryProvider(),
  129. m_attr(Attribute::attrNone)
  130. {}
  131. CardProfile::CardProfile(ProviderProfile::ATR const &ratr,
  132. string const &rsFriendlyName,
  133. string const &rsRegistryName,
  134. GUID const &rgPrimaryProvider,
  135. Attribute attr)
  136. : m_atr(ratr),
  137. m_sFriendlyName(rsFriendlyName),
  138. m_sRegistryName(rsRegistryName),
  139. m_csFriendlyName(StringResource::UnicodeFromAscii(rsFriendlyName)),
  140. m_csRegistryName(StringResource::UnicodeFromAscii(rsRegistryName)),
  141. m_gPrimaryProvider(rgPrimaryProvider),
  142. m_attr(attr)
  143. {}
  144. CardProfile::CardProfile(ProviderProfile::ATR const &ratr,
  145. CString const &rcsFriendlyName,
  146. CString const &rcsRegistryName,
  147. GUID const &rgPrimaryProvider,
  148. Attribute attr)
  149. : m_atr(ratr),
  150. m_csFriendlyName(rcsFriendlyName),
  151. m_csRegistryName(rcsRegistryName),
  152. m_sFriendlyName(StringResource::AsciiFromUnicode((LPCTSTR)rcsFriendlyName)),
  153. m_sRegistryName(StringResource::AsciiFromUnicode((LPCTSTR)rcsRegistryName)),
  154. m_gPrimaryProvider(rgPrimaryProvider),
  155. m_attr(attr)
  156. {}
  157. CardProfile::~CardProfile()
  158. {}
  159. ATR const &
  160. CardProfile::ATR() const
  161. {
  162. return m_atr;
  163. }
  164. string
  165. CardProfile::FriendlyName() const
  166. {
  167. return m_sFriendlyName;
  168. }
  169. CString
  170. CardProfile::csFriendlyName() const
  171. {
  172. return m_csFriendlyName;
  173. }
  174. GUID const &
  175. CardProfile::PrimaryProvider() const
  176. {
  177. return m_gPrimaryProvider;
  178. }
  179. string
  180. CardProfile::RegistryName() const
  181. {
  182. return m_sRegistryName;
  183. }
  184. CString
  185. CardProfile::csRegistryName() const
  186. {
  187. return m_csRegistryName;
  188. }
  189. bool
  190. CardProfile::AtrMatches(ATR::Length cAtr,
  191. BYTE const *pbRhsAtr) const
  192. {
  193. bool fIsAMatch = false;
  194. ATR::Length const cAtrLength = m_atr.ATRLength();
  195. if (cAtrLength == cAtr)
  196. {
  197. BYTE const *pbLhsAtr = m_atr.String();
  198. BYTE const *pbLhsMask = m_atr.Mask();
  199. for (ATR::Length i = 0; cAtrLength != i; ++i)
  200. {
  201. if ((pbLhsMask[i] & pbLhsAtr[i]) != (pbLhsMask[i] & pbRhsAtr[i]))
  202. break; // no sense continuing
  203. }
  204. if (cAtrLength == i)
  205. fIsAMatch = true;
  206. }
  207. return fIsAMatch;
  208. }
  209. bool
  210. CardProfile::HasAttribute(Attribute attr) const
  211. {
  212. return m_attr & attr ? true : false;
  213. }
  214. bool
  215. CardProfile::operator==(CardProfile const &rhs)
  216. {
  217. return !(*this != rhs);
  218. }
  219. bool
  220. CardProfile::operator!=(CardProfile const &rhs)
  221. {
  222. return (m_atr != rhs.m_atr) ||
  223. (m_sFriendlyName != rhs.m_sFriendlyName) ||
  224. (memcmp(&m_gPrimaryProvider, &rhs.m_gPrimaryProvider,
  225. sizeof m_gPrimaryProvider)) ||
  226. (m_attr != m_attr);
  227. }
  228. CspProfile::CspProfile(DWORD Type,
  229. vector<CardProfile> const &rvcp)
  230. : m_hDllInstance(0),
  231. m_dwType(Type),
  232. m_vi(),
  233. m_vcp(rvcp),
  234. m_hResInstance(0),
  235. m_RsrcExtensionDLL(),
  236. m_apExtDll()
  237. {
  238. static const TCHAR szBaseRsrc[] = TEXT("slbRcCsp.dll");
  239. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  240. m_hDllInstance = AfxGetInstanceHandle();
  241. if (!m_hDllInstance)
  242. throw scu::OsException(GetLastError());
  243. // Try loading slbRcCsp.dll from the same directory as this CSP.
  244. DWORD dwLen;
  245. TCHAR szFileName[MAX_PATH + sizeof TCHAR];
  246. dwLen = GetModuleFileName(m_hDllInstance, szFileName,
  247. MAX_PATH );
  248. if (0 == dwLen)
  249. throw scu::OsException(GetLastError());
  250. szFileName[dwLen] = 0;
  251. string sPathDelimiters(AsCCharP(TEXT(":\\")), _tcslen(TEXT(":\\")));
  252. string sDllName(AsCCharP(szFileName), _tcslen(szFileName));
  253. string::size_type cDelimiterPosition(sDllName.find_last_of(sPathDelimiters));
  254. if (string::npos != cDelimiterPosition)
  255. {
  256. string sModuleName = sDllName.substr(0, cDelimiterPosition + 1) +
  257. string(AsCCharP(szBaseRsrc), _tcslen(szBaseRsrc));
  258. CString csModuleName = StringResource::UnicodeFromAscii(sModuleName);
  259. m_hResInstance = LoadLibraryEx((LPCTSTR)csModuleName, NULL,
  260. LOAD_LIBRARY_AS_DATAFILE);
  261. }
  262. // If not found, then load using the normal search path strategy.
  263. if (!m_hResInstance)
  264. m_hResInstance = LoadLibraryEx(szBaseRsrc, NULL,
  265. LOAD_LIBRARY_AS_DATAFILE);
  266. ZeroMemory(&m_RsrcExtensionDLL, sizeof m_RsrcExtensionDLL);
  267. if (!m_hResInstance)
  268. {
  269. AfxInitExtensionModule(m_RsrcExtensionDLL, m_hResInstance);
  270. m_apExtDll =
  271. auto_ptr<CDynLinkLibrary>(new CDynLinkLibrary(m_RsrcExtensionDLL));
  272. }
  273. CModuleVersion cmv;
  274. if (!cmv.GetFileVersionInfo((HMODULE)m_hDllInstance))
  275. throw scu::OsException(GetLastError());
  276. m_vi.m_dwMajor = HIWORD(cmv.dwProductVersionMS);
  277. m_vi.m_dwMinor = LOWORD(cmv.dwProductVersionMS);
  278. }
  279. CspProfile::~CspProfile()
  280. {
  281. try
  282. {
  283. if (m_apExtDll.get())
  284. AfxTermExtensionModule(m_RsrcExtensionDLL);
  285. }
  286. catch (...)
  287. {
  288. }
  289. try
  290. {
  291. if (m_hResInstance)
  292. {
  293. FreeLibrary(m_hResInstance);
  294. m_hResInstance = NULL;
  295. }
  296. }
  297. catch (...)
  298. {
  299. }
  300. }
  301. const CString
  302. CspProfile::Name() const
  303. {
  304. return StringResource(IDS_CSP_NAME).AsCString();
  305. }
  306. HINSTANCE
  307. CspProfile::DllInstance() const
  308. {
  309. if (!m_hDllInstance)
  310. throw scu::OsException(static_cast<HRESULT>(HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE)));
  311. return m_hDllInstance;
  312. }
  313. HINSTANCE
  314. CspProfile::Resources() const
  315. {
  316. return (NULL == m_hResInstance) ? m_hDllInstance : m_hResInstance;
  317. }
  318. DWORD
  319. CspProfile::Type() const
  320. {
  321. return m_dwType;
  322. }
  323. VersionInfo
  324. CspProfile::Version() const
  325. {
  326. return m_vi;
  327. }
  328. vector<CardProfile> const &
  329. CspProfile::Cards() const
  330. {
  331. return m_vcp;
  332. }
  333. // Return the one and only Profile object for this CSP
  334. CspProfile const &
  335. CspProfile::Instance()
  336. {
  337. Guard<Lockable> guard(TheMasterLock());
  338. if (!m_pInstance)
  339. {
  340. //We use CString to be able to do Unicode string manipulations
  341. CString csCardNamePrefix(TEXT("Schlumberger "),
  342. _tcslen(TEXT("Schlumberger ")));
  343. ATR atrCF4k(sizeof g_abCF4kATRString / sizeof g_abCF4kATRString[0],
  344. g_abCF4kATRString, g_abCF4kATRMask);
  345. ATR atrCF8k(sizeof g_abCF8kATRString / sizeof g_abCF8kATRString[0],
  346. g_abCF8kATRString, g_abCF8kATRMask);
  347. ATR atrCF8kV2(sizeof g_abCF8kV2ATRString / sizeof g_abCF8kV2ATRString[0],
  348. g_abCF8kV2ATRString, g_abCF8kV2ATRMask);
  349. // ATR atrCF16k(sizeof g_abCF16kATRString / sizeof g_abCF16kATRString[0],
  350. // g_abCF16kATRString, g_abCF16kATRMask);
  351. ATR atrCFe_gate(sizeof g_abCFe_gateATRString / sizeof g_abCFe_gateATRString[0],
  352. g_abCFe_gateATRString, g_abCFe_gateATRMask);
  353. ATR atrCA16k(sizeof g_abCA16kATRString / sizeof g_abCA16kATRString[0],
  354. g_abCA16kATRString, g_abCA16kATRMask);
  355. ATR atrCACampus(sizeof g_abCACampusATRString /
  356. sizeof g_abCACampusATRString[0],
  357. g_abCACampusATRString, g_abCACampusATRMask);
  358. ATR atrCFActivCard(sizeof g_abCFActivCardATRString /
  359. sizeof g_abCFActivCardATRString[0],
  360. g_abCFActivCardATRString, g_abCFActivCardATRMask);
  361. CString csCF4kFriendlyName(TEXT("Cryptoflex 4K"),
  362. _tcslen(TEXT("Cryptoflex 4K")));
  363. CardProfile cpCF4k(atrCF4k,
  364. csCF4kFriendlyName,
  365. csCardNamePrefix + csCF4kFriendlyName,
  366. g_guidPrimaryProvider);
  367. CString csCF8kFriendlyName(TEXT("Cryptoflex 8K"),
  368. _tcslen(TEXT("Cryptoflex 8K")));
  369. CardProfile cpCF8k(atrCF8k,
  370. csCF8kFriendlyName,
  371. csCardNamePrefix + csCF8kFriendlyName,
  372. g_guidPrimaryProvider,
  373. CardProfile::attrMsbKeyDefect);
  374. CString csCF8kV2FriendlyName(TEXT("Cryptoflex 8K v2"),
  375. _tcslen(TEXT("Cryptoflex 8K v2")));
  376. CardProfile cpCF8kV2(atrCF8kV2,
  377. csCF8kV2FriendlyName,
  378. csCardNamePrefix + csCF8kV2FriendlyName,
  379. g_guidPrimaryProvider);
  380. // string CF16kFriendlyName(TEXT("Cryptoflex 16K"));
  381. // CardProfile cpCF16k(atrCF16k,
  382. // CF16kFriendlyName,
  383. // CardNamePrefix + CF16kFriendlyName,
  384. // g_guidPrimaryProvider);
  385. CString csCFe_gateFriendlyName(TEXT("Cryptoflex e-gate"),
  386. _tcslen(TEXT("Cryptoflex e-gate")));
  387. CardProfile cpCFe_gate(atrCFe_gate,
  388. csCFe_gateFriendlyName,
  389. csCardNamePrefix + csCFe_gateFriendlyName,
  390. g_guidPrimaryProvider);
  391. CString csCA16kFriendlyName(TEXT("Cyberflex Access 16K"),
  392. _tcslen(TEXT("Cyberflex Access 16K")));
  393. CardProfile cpCA16k(atrCA16k,
  394. csCA16kFriendlyName,
  395. csCardNamePrefix + csCA16kFriendlyName,
  396. g_guidPrimaryProvider);
  397. CString csCACampusFriendlyName(TEXT("Cyberflex Access Campus"),
  398. _tcslen(TEXT("Cyberflex Access Campus")));
  399. CardProfile cpCACampus(atrCACampus,
  400. csCACampusFriendlyName,
  401. csCardNamePrefix + csCACampusFriendlyName,
  402. g_guidPrimaryProvider);
  403. CString csCFActivCardFriendlyName(TEXT("Cryptoflex ActivCard"),
  404. _tcslen(TEXT("Cryptoflex ActivCard")));
  405. CardProfile cpCFActivCard(atrCFActivCard,
  406. csCFActivCardFriendlyName,
  407. csCardNamePrefix + csCFActivCardFriendlyName,
  408. g_guidPrimaryProvider);
  409. vector<CardProfile> vcp;
  410. vcp.push_back(cpCF4k);
  411. vcp.push_back(cpCF8k);
  412. vcp.push_back(cpCF8kV2);
  413. // vcp.push_back(cpCF16k);
  414. vcp.push_back(cpCFe_gate);
  415. vcp.push_back(cpCA16k);
  416. vcp.push_back(cpCACampus);
  417. vcp.push_back(cpCFActivCard);
  418. m_pInstance = new CspProfile(PROV_RSA_FULL, vcp);
  419. }
  420. return *m_pInstance;
  421. }
  422. void
  423. CspProfile::Release()
  424. {
  425. if (m_pInstance)
  426. {
  427. Guard<Lockable> guard(TheMasterLock());
  428. if (m_pInstance)
  429. {
  430. // in case delete throws, this is VC++ you know...
  431. CspProfile *pTmp = m_pInstance;
  432. m_pInstance = 0;
  433. delete m_pInstance;
  434. }
  435. }
  436. }
  437. CspProfile *CspProfile::m_pInstance = 0;