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.

506 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_apExtDll()
  236. {
  237. static const TCHAR szBaseRsrc[] = TEXT("slbRcCsp.dll");
  238. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  239. m_hDllInstance = AfxGetInstanceHandle();
  240. if (!m_hDllInstance)
  241. throw scu::OsException(GetLastError());
  242. // Try loading slbRcCsp.dll from the same directory as this CSP.
  243. DWORD dwLen;
  244. TCHAR szFileName[MAX_PATH + sizeof TCHAR];
  245. dwLen = GetModuleFileName(m_hDllInstance, szFileName,
  246. MAX_PATH );
  247. if (0 == dwLen)
  248. throw scu::OsException(GetLastError());
  249. szFileName[dwLen] = 0;
  250. wstring wsPathDelimiters(TEXT(":\\"));
  251. wstring wsDllName(szFileName);
  252. wstring::size_type cDelimiterPosition(wsDllName.find_last_of(wsPathDelimiters));
  253. // Security: Ensure the filename used to LoadLibraryEx contains a
  254. // path so the normal search strategy is not invoked; otherwise it
  255. // leaves a security vulnerability.
  256. if (wstring::npos != cDelimiterPosition)
  257. {
  258. wstring wsModuleName = wsDllName.substr(0, cDelimiterPosition + 1) +
  259. wstring(szBaseRsrc);
  260. m_hResInstance = LoadLibraryEx(wsModuleName.c_str(), NULL,
  261. LOAD_LIBRARY_AS_DATAFILE);
  262. if (!m_hResInstance)
  263. throw scu::OsException(GetLastError());
  264. }
  265. else
  266. throw scu::OsException(ERROR_INVALID_PARAMETER);
  267. CModuleVersion cmv;
  268. if (!cmv.GetFileVersionInfo((HMODULE)m_hDllInstance))
  269. throw scu::OsException(GetLastError());
  270. m_vi.m_dwMajor = HIWORD(cmv.dwProductVersionMS);
  271. m_vi.m_dwMinor = LOWORD(cmv.dwProductVersionMS);
  272. }
  273. CspProfile::~CspProfile()
  274. {
  275. try
  276. {
  277. if (m_hResInstance)
  278. {
  279. FreeLibrary(m_hResInstance);
  280. m_hResInstance = NULL;
  281. }
  282. }
  283. catch (...)
  284. {
  285. }
  286. }
  287. const CString
  288. CspProfile::Name() const
  289. {
  290. return StringResource(IDS_CSP_NAME).AsCString();
  291. }
  292. HINSTANCE
  293. CspProfile::DllInstance() const
  294. {
  295. if (!m_hDllInstance)
  296. throw scu::OsException(static_cast<HRESULT>(HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE)));
  297. return m_hDllInstance;
  298. }
  299. HINSTANCE
  300. CspProfile::Resources() const
  301. {
  302. return (NULL == m_hResInstance) ? m_hDllInstance : m_hResInstance;
  303. }
  304. DWORD
  305. CspProfile::Type() const
  306. {
  307. return m_dwType;
  308. }
  309. VersionInfo
  310. CspProfile::Version() const
  311. {
  312. return m_vi;
  313. }
  314. vector<CardProfile> const &
  315. CspProfile::Cards() const
  316. {
  317. return m_vcp;
  318. }
  319. // Return the one and only Profile object for this CSP
  320. CspProfile const &
  321. CspProfile::Instance()
  322. {
  323. Guard<Lockable> guard(TheMasterLock());
  324. if (!m_pInstance)
  325. {
  326. //We use CString to be able to do Unicode string manipulations
  327. CString csCardNamePrefix(TEXT("Schlumberger "),
  328. _tcslen(TEXT("Schlumberger ")));
  329. ATR atrCF4k(sizeof g_abCF4kATRString / sizeof g_abCF4kATRString[0],
  330. g_abCF4kATRString, g_abCF4kATRMask);
  331. ATR atrCF8k(sizeof g_abCF8kATRString / sizeof g_abCF8kATRString[0],
  332. g_abCF8kATRString, g_abCF8kATRMask);
  333. ATR atrCF8kV2(sizeof g_abCF8kV2ATRString / sizeof g_abCF8kV2ATRString[0],
  334. g_abCF8kV2ATRString, g_abCF8kV2ATRMask);
  335. // ATR atrCF16k(sizeof g_abCF16kATRString / sizeof g_abCF16kATRString[0],
  336. // g_abCF16kATRString, g_abCF16kATRMask);
  337. ATR atrCFe_gate(sizeof g_abCFe_gateATRString / sizeof g_abCFe_gateATRString[0],
  338. g_abCFe_gateATRString, g_abCFe_gateATRMask);
  339. ATR atrCA16k(sizeof g_abCA16kATRString / sizeof g_abCA16kATRString[0],
  340. g_abCA16kATRString, g_abCA16kATRMask);
  341. ATR atrCACampus(sizeof g_abCACampusATRString /
  342. sizeof g_abCACampusATRString[0],
  343. g_abCACampusATRString, g_abCACampusATRMask);
  344. ATR atrCFActivCard(sizeof g_abCFActivCardATRString /
  345. sizeof g_abCFActivCardATRString[0],
  346. g_abCFActivCardATRString, g_abCFActivCardATRMask);
  347. CString csCF4kFriendlyName(TEXT("Cryptoflex 4K"),
  348. _tcslen(TEXT("Cryptoflex 4K")));
  349. CardProfile cpCF4k(atrCF4k,
  350. csCF4kFriendlyName,
  351. csCardNamePrefix + csCF4kFriendlyName,
  352. g_guidPrimaryProvider);
  353. CString csCF8kFriendlyName(TEXT("Cryptoflex 8K"),
  354. _tcslen(TEXT("Cryptoflex 8K")));
  355. CardProfile cpCF8k(atrCF8k,
  356. csCF8kFriendlyName,
  357. csCardNamePrefix + csCF8kFriendlyName,
  358. g_guidPrimaryProvider,
  359. CardProfile::attrMsbKeyDefect);
  360. CString csCF8kV2FriendlyName(TEXT("Cryptoflex 8K v2"),
  361. _tcslen(TEXT("Cryptoflex 8K v2")));
  362. CardProfile cpCF8kV2(atrCF8kV2,
  363. csCF8kV2FriendlyName,
  364. csCardNamePrefix + csCF8kV2FriendlyName,
  365. g_guidPrimaryProvider);
  366. // string CF16kFriendlyName(TEXT("Cryptoflex 16K"));
  367. // CardProfile cpCF16k(atrCF16k,
  368. // CF16kFriendlyName,
  369. // CardNamePrefix + CF16kFriendlyName,
  370. // g_guidPrimaryProvider);
  371. CString csCFe_gateFriendlyName(TEXT("Cryptoflex e-gate"),
  372. _tcslen(TEXT("Cryptoflex e-gate")));
  373. CardProfile cpCFe_gate(atrCFe_gate,
  374. csCFe_gateFriendlyName,
  375. csCardNamePrefix + csCFe_gateFriendlyName,
  376. g_guidPrimaryProvider);
  377. CString csCA16kFriendlyName(TEXT("Cyberflex Access 16K"),
  378. _tcslen(TEXT("Cyberflex Access 16K")));
  379. CardProfile cpCA16k(atrCA16k,
  380. csCA16kFriendlyName,
  381. csCardNamePrefix + csCA16kFriendlyName,
  382. g_guidPrimaryProvider);
  383. CString csCACampusFriendlyName(TEXT("Cyberflex Access Campus"),
  384. _tcslen(TEXT("Cyberflex Access Campus")));
  385. CardProfile cpCACampus(atrCACampus,
  386. csCACampusFriendlyName,
  387. csCardNamePrefix + csCACampusFriendlyName,
  388. g_guidPrimaryProvider);
  389. CString csCFActivCardFriendlyName(TEXT("Cryptoflex ActivCard"),
  390. _tcslen(TEXT("Cryptoflex ActivCard")));
  391. CardProfile cpCFActivCard(atrCFActivCard,
  392. csCFActivCardFriendlyName,
  393. csCardNamePrefix + csCFActivCardFriendlyName,
  394. g_guidPrimaryProvider);
  395. vector<CardProfile> vcp;
  396. vcp.push_back(cpCF4k);
  397. vcp.push_back(cpCF8k);
  398. vcp.push_back(cpCF8kV2);
  399. // vcp.push_back(cpCF16k);
  400. vcp.push_back(cpCFe_gate);
  401. vcp.push_back(cpCA16k);
  402. vcp.push_back(cpCACampus);
  403. vcp.push_back(cpCFActivCard);
  404. m_pInstance = new CspProfile(PROV_RSA_FULL, vcp);
  405. }
  406. return *m_pInstance;
  407. }
  408. void
  409. CspProfile::Release()
  410. {
  411. if (m_pInstance)
  412. {
  413. Guard<Lockable> guard(TheMasterLock());
  414. if (m_pInstance)
  415. {
  416. // in case delete throws, this is VC++ you know...
  417. CspProfile *pTmp = m_pInstance;
  418. m_pInstance = 0;
  419. delete m_pInstance;
  420. }
  421. }
  422. }
  423. CspProfile *CspProfile::m_pInstance = 0;