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.

632 lines
15 KiB

  1. // V1Card.cpp: implementation of the CV2Card class.
  2. //
  3. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  4. // 1999. This computer program includes Confidential, Proprietary
  5. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  6. // use, disclosure, and/or reproduction is prohibited unless authorized
  7. // in writing. All Rights Reserved.
  8. //////////////////////////////////////////////////////////////////////
  9. #include "NoWarning.h"
  10. #include <algorithm>
  11. #include <functional>
  12. #include <memory> // for auto_ptr
  13. #include <scuArrayP.h>
  14. #include <SmartCard.h>
  15. #include "TransactionWrap.h"
  16. #include "cciExc.h"
  17. #include "MethodHelp.h"
  18. #include "cciCert.h"
  19. #include "cciKeyPair.h"
  20. #include "cciPriKey.h"
  21. #include "cciPubKey.h"
  22. #include "V1Cert.h"
  23. #include "V1Cont.h"
  24. #include "V1ContRec.h"
  25. #include "V1KeyPair.h"
  26. #include "V1PriKey.h"
  27. #include "V1PubKey.h"
  28. #include "V1Paths.h"
  29. #include "V1Card.h"
  30. using namespace std;
  31. using namespace cci;
  32. using namespace scu;
  33. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  34. namespace
  35. {
  36. // Enumerate T type objects in the exchange and signature key pair
  37. // using C::<Accessor> to get the T object, returning vector<T>
  38. // objects.
  39. template<class T>
  40. class EnumItems
  41. : std::unary_function<void, vector<T> >
  42. {
  43. public:
  44. EnumItems(CV1Card const &rv1card,
  45. ObjectAccess oa,
  46. typename AccessorMethod<T, CAbstractKeyPair>::AccessorPtr Accessor)
  47. : m_rv1card(rv1card),
  48. m_oa(oa),
  49. m_matAccess(Accessor),
  50. m_Result()
  51. {}
  52. result_type
  53. operator()(argument_type)
  54. {
  55. DoAppend(m_rv1card.DefaultContainer());
  56. return m_Result;
  57. }
  58. protected:
  59. void
  60. DoAppend(CContainer &rhcntr)
  61. {
  62. if (rhcntr)
  63. {
  64. AppendItem(rhcntr->ExchangeKeyPair());
  65. AppendItem(rhcntr->SignatureKeyPair());
  66. }
  67. }
  68. private:
  69. void
  70. AppendItem(CKeyPair &rhkp)
  71. {
  72. if (rhkp)
  73. {
  74. T hObject(m_matAccess(*rhkp));
  75. if (hObject && (m_oa == hObject->Access()))
  76. m_Result.push_back(hObject);
  77. }
  78. }
  79. CV1Card const &m_rv1card;
  80. ObjectAccess m_oa;
  81. MemberAccessorType<T, CAbstractKeyPair> m_matAccess;
  82. result_type m_Result;
  83. };
  84. bool
  85. IsSupported(iop::CSmartCard &rSmartCard) throw()
  86. {
  87. bool fSupported = false;
  88. try
  89. {
  90. rSmartCard.Select(CV1Paths::Chv());
  91. rSmartCard.Select(CV1Paths::IcFile());
  92. rSmartCard.Select(CV1Paths::RootContainers());
  93. rSmartCard.Select(CV1Paths::PrivateKeys());
  94. rSmartCard.Select(CV1Paths::PublicKeys());
  95. fSupported = true;
  96. }
  97. catch(scu::Exception &)
  98. {}
  99. return fSupported;
  100. }
  101. } // namespace
  102. /////////////////////////// PUBLIC /////////////////////////////////
  103. // Types
  104. // C'tors/D'tors
  105. CV1Card::~CV1Card() throw()
  106. {}
  107. // Operators
  108. // Operations
  109. void
  110. CV1Card::CardId(string const &rsNewCardId) const
  111. {
  112. CTransactionWrap(this);
  113. DWORD dwLen = OpenFile(CV1Paths::IcFile());
  114. if (0 == dwLen)
  115. throw scu::OsException(NTE_FAIL);
  116. if (rsNewCardId.length() > dwLen)
  117. throw scu::OsException(ERROR_INVALID_PARAMETER);
  118. if (rsNewCardId.length() < dwLen)
  119. SmartCard().WriteBinary(0, rsNewCardId.length() + 1,
  120. reinterpret_cast<BYTE const *>(rsNewCardId.c_str()));
  121. else
  122. SmartCard().WriteBinary(0,
  123. static_cast<WORD>(rsNewCardId.length()),
  124. reinterpret_cast<BYTE const *>(rsNewCardId.data()));
  125. RefreshCardId();
  126. }
  127. void
  128. CV1Card::ChangePIN(SecureArray<BYTE> const &rstrOldPIN,
  129. SecureArray<BYTE> const &rstrNewPIN)
  130. {
  131. CTransactionWrap wrap(this);
  132. SmartCard().Select(CV1Paths::Root());
  133. SuperClass::ChangePIN(rstrOldPIN, rstrNewPIN);
  134. }
  135. void
  136. CV1Card::DefaultContainer(CContainer const &rcont)
  137. {
  138. m_avhDefaultCntr.Value(rcont);
  139. if(!m_avhDefaultCntr.Value())
  140. m_avhDefaultCntr.Dirty();
  141. // Nothing more to do since, by definition, the one and only
  142. // container is already the default container.
  143. }
  144. pair<string, // interpreted as the public modulus
  145. CPrivateKey>
  146. CV1Card::GenerateKeyPair(KeyType kt,
  147. string const &rsExponent,
  148. ObjectAccess oaPrivateKey)
  149. {
  150. throw Exception(ccNotImplemented);
  151. return pair<string, CPrivateKey>();
  152. }
  153. void
  154. CV1Card::InitCard()
  155. {
  156. // We want to select /3f00/0015 (length 1744) and /3f00/3f11/0015 (length 300), and clear both files.
  157. CTransactionWrap wrap(this);
  158. BYTE bData[1744];
  159. memset(bData, 0, 1744);
  160. SmartCard().Select(CV1Paths::RootContainers());
  161. SmartCard().WriteBinary(0x0000, 0x06d0, bData);
  162. SmartCard().Select(CV1Paths::PublicKeys());
  163. SmartCard().WriteBinary(0x0000, 0x012c, bData);
  164. }
  165. void
  166. CV1Card::InvalidateCache()
  167. {
  168. m_avhDefaultCntr.Value(CContainer());
  169. m_avhDefaultCntr.Dirty();
  170. m_avhExchangeKeyPair.Value(CKeyPair());
  171. m_avhExchangeKeyPair.Dirty();
  172. m_avhSignatureKeyPair.Value(CKeyPair());
  173. m_avhSignatureKeyPair.Dirty();
  174. }
  175. void
  176. CV1Card::Label(string const &rLabel)
  177. {
  178. throw Exception(ccNotImplemented);
  179. }
  180. DWORD
  181. CV1Card::OpenFile(char const *szPath) const
  182. {
  183. iop::FILE_HEADER fh;
  184. SmartCard().Select(szPath, &fh);
  185. return fh.file_size;
  186. }
  187. void
  188. CV1Card::VerifyKey(string const &rstrKey,
  189. BYTE bKeyNum)
  190. {
  191. CTransactionWrap wrap(this);
  192. SmartCard().Select(CV1Paths::CryptoSys());
  193. SuperClass::VerifyKey(rstrKey, bKeyNum);
  194. }
  195. // Access
  196. size_t
  197. CV1Card::AvailableStringSpace(ObjectAccess oa) const
  198. {
  199. throw Exception(ccNotImplemented);
  200. return 0;
  201. }
  202. string
  203. CV1Card::CardId() const
  204. {
  205. return m_sCardId;
  206. }
  207. CContainer
  208. CV1Card::DefaultContainer() const
  209. {
  210. CTransactionWrap wrap(this);
  211. if (!m_avhDefaultCntr.IsCached())
  212. {
  213. auto_ptr<CV1Container> apv1cntr(new CV1Container(*this,
  214. CV1ContainerRecord::DefaultName(),
  215. false));
  216. if (apv1cntr->Exists())
  217. {
  218. CContainer hcntr;
  219. hcntr = CContainer(apv1cntr.get());
  220. apv1cntr.release();
  221. m_avhDefaultCntr.Value(hcntr);
  222. }
  223. }
  224. return m_avhDefaultCntr.Value();
  225. }
  226. vector<CContainer>
  227. CV1Card::EnumContainers() const
  228. {
  229. CContainer hcntr(0);
  230. auto_ptr<CV1Container> apv1cntr(new CV1Container(*this,
  231. CV1ContainerRecord::DefaultName(),
  232. false));
  233. if (apv1cntr->Exists())
  234. {
  235. hcntr = CContainer(apv1cntr.get());
  236. apv1cntr.release();
  237. }
  238. vector<CContainer> vhcntr;
  239. if (hcntr)
  240. vhcntr.push_back(hcntr);
  241. return vhcntr;
  242. }
  243. vector<CCertificate>
  244. CV1Card::EnumCertificates(ObjectAccess access) const
  245. {
  246. CTransactionWrap wrap(this);
  247. EnumItems<CCertificate> Enumerator(*this, access,
  248. CAbstractKeyPair::Certificate);
  249. return Enumerator();
  250. }
  251. vector<CPublicKey>
  252. CV1Card::EnumPublicKeys(ObjectAccess access) const
  253. {
  254. CTransactionWrap wrap(this);
  255. EnumItems<CPublicKey> Enumerator(*this, access,
  256. CAbstractKeyPair::PublicKey);
  257. return Enumerator();
  258. }
  259. vector<CPrivateKey>
  260. CV1Card::EnumPrivateKeys(ObjectAccess access) const
  261. {
  262. CTransactionWrap wrap(this);
  263. EnumItems<CPrivateKey> Enumerator(*this, access,
  264. CAbstractKeyPair::PrivateKey);
  265. return Enumerator();
  266. }
  267. vector<CDataObject>
  268. CV1Card::EnumDataObjects(ObjectAccess access) const
  269. {
  270. return vector<CDataObject>(); // can never have data objects
  271. }
  272. string
  273. CV1Card::Label() const
  274. {
  275. throw Exception(ccNotImplemented);
  276. return string();
  277. }
  278. CAbstractCertificate *
  279. CV1Card::MakeCertificate(ObjectAccess oa) const
  280. {
  281. CTransactionWrap wrap(this);
  282. if (oaPublicAccess != oa)
  283. throw Exception(ccInvalidParameter);
  284. return new CV1Certificate(*this, ksNone);
  285. }
  286. CAbstractContainer *
  287. CV1Card::MakeContainer() const
  288. {
  289. CTransactionWrap wrap(this);
  290. return new CV1Container(*this,
  291. CV1ContainerRecord::DefaultName(), true);
  292. }
  293. CAbstractDataObject *
  294. CV1Card::MakeDataObject(ObjectAccess oa) const
  295. {
  296. throw Exception(ccNotImplemented);
  297. return 0;
  298. }
  299. CAbstractKeyPair *
  300. CV1Card::MakeKeyPair(CContainer const &rhcont,
  301. KeySpec ks) const
  302. {
  303. CTransactionWrap wrap(this);
  304. // If the key pair is cached, return it; otherwise make a new one
  305. // and cache it.
  306. CArchivedValue<CKeyPair> *pavhkp = 0;
  307. switch (ks)
  308. {
  309. case ksExchange:
  310. pavhkp = &m_avhExchangeKeyPair;
  311. break;
  312. case ksSignature:
  313. pavhkp = &m_avhSignatureKeyPair;
  314. break;
  315. default:
  316. throw Exception(ccBadKeySpec);
  317. break;
  318. }
  319. if (!pavhkp->IsCached() || !pavhkp->Value())
  320. pavhkp->Value(CKeyPair(new CV1KeyPair(*this, rhcont, ks)));
  321. return pavhkp->Value().operator->(); // yuk!
  322. }
  323. CAbstractPrivateKey *
  324. CV1Card::MakePrivateKey(ObjectAccess oa) const
  325. {
  326. CTransactionWrap wrap(this);
  327. if (oaPrivateAccess != oa)
  328. throw Exception(ccInvalidParameter);
  329. return new CV1PrivateKey(*this, ksNone);
  330. }
  331. CAbstractPublicKey *
  332. CV1Card::MakePublicKey(ObjectAccess oa) const
  333. {
  334. CTransactionWrap wrap(this);
  335. if (oaPublicAccess != oa)
  336. throw Exception(ccInvalidParameter);
  337. return new CV1PublicKey(*this, ksNone);
  338. }
  339. BYTE
  340. CV1Card::MaxKeys(KeyType kt) const
  341. {
  342. BYTE bCount;
  343. switch (kt)
  344. {
  345. case ktRSA1024:
  346. bCount = 2;
  347. break;
  348. default:
  349. bCount = 0;
  350. break;
  351. }
  352. return bCount;
  353. }
  354. size_t
  355. CV1Card::MaxStringSpace(ObjectAccess oa) const
  356. {
  357. throw Exception(ccNotImplemented);
  358. return 0;
  359. }
  360. bool
  361. CV1Card::SupportedKeyFunction(KeyType kt,
  362. CardOperation oper) const
  363. {
  364. bool fSupported = false;
  365. switch (oper)
  366. {
  367. case coEncryption: // .. or public key operations
  368. break;
  369. case coDecryption: // .. or private key operations
  370. switch (kt)
  371. {
  372. case ktRSA1024:
  373. fSupported = true;
  374. break;
  375. default:
  376. break;
  377. }
  378. default:
  379. break;
  380. }
  381. return fSupported;
  382. }
  383. scu::Marker<unsigned int>
  384. CV1Card::MarkerOnCard() const
  385. {
  386. return scu::Marker<unsigned int>();
  387. }
  388. // Predicates
  389. bool
  390. CV1Card::IsCAPIEnabled() const
  391. {
  392. return true;
  393. }
  394. bool
  395. CV1Card::IsPKCS11Enabled() const
  396. {
  397. return false;
  398. }
  399. bool
  400. CV1Card::IsProtectedMode() const
  401. {
  402. return true;
  403. }
  404. bool
  405. CV1Card::IsKeyGenEnabled() const
  406. {
  407. return false;
  408. }
  409. bool
  410. CV1Card::IsEntrustEnabled() const
  411. {
  412. return false;
  413. }
  414. BYTE
  415. CV1Card::MajorVersion() const
  416. {
  417. return (BYTE)0;
  418. }
  419. bool
  420. CV1Card::IsMarkerOnCard() const
  421. {
  422. return false;
  423. }
  424. // Static Variables
  425. /////////////////////////// PROTECTED /////////////////////////////////
  426. // C'tors/D'tors
  427. CV1Card::CV1Card(string const &rstrReaderName,
  428. auto_ptr<iop::CIOP> &rapiop,
  429. auto_ptr<iop::CSmartCard> &rapSmartCard)
  430. : SuperClass(rstrReaderName, rapiop, rapSmartCard),
  431. m_sCardId(),
  432. m_avhDefaultCntr(),
  433. m_avhExchangeKeyPair(),
  434. m_avhSignatureKeyPair()
  435. {}
  436. // Operators
  437. // Operations
  438. void
  439. CV1Card::DoSetup()
  440. {
  441. CAbstractCard::DoSetup();
  442. RefreshCardId();
  443. }
  444. // Access
  445. // Predicates
  446. // Static Variables
  447. /////////////////////////// PRIVATE /////////////////////////////////
  448. // C'tors/D'tors
  449. // Operators
  450. // Operations
  451. auto_ptr<CAbstractCard>
  452. CV1Card::DoMake(string const &rstrReaderName,
  453. auto_ptr<iop::CIOP> &rapiop,
  454. auto_ptr<iop::CSmartCard> &rapSmartCard)
  455. {
  456. return IsSupported(*rapSmartCard.get())
  457. ? auto_ptr<CAbstractCard>(new CV1Card(rstrReaderName, rapiop,
  458. rapSmartCard))
  459. : auto_ptr<CAbstractCard>(0);
  460. }
  461. string
  462. CV1Card::ReadCardId() const
  463. {
  464. string sCardId;
  465. // *** BEGIN WORKAROUND ***
  466. // The following SetContext and OpenFile call is made to
  467. // make sure the card and this system's current path are
  468. // synchronized, pointing to the right directory. Without
  469. // it, the subsequent call to ReadBinaryFile fails because
  470. // they appear to be out of synch. It's not clear why
  471. // this happens but this workaround avoids the problem.
  472. try
  473. {
  474. SmartCard().Select(CV1Paths::RootContainers());
  475. }
  476. catch (...)
  477. {
  478. }
  479. // *** END WORKAROUND ***
  480. try
  481. {
  482. iop::FILE_HEADER fh;
  483. SmartCard().Select(CV1Paths::IcFile(), &fh);
  484. DWORD dwLen = fh.file_size;
  485. scu::AutoArrayPtr<BYTE> aaCardId(new BYTE[dwLen + 1]);
  486. SmartCard().ReadBinary(0, dwLen, aaCardId.Get());
  487. aaCardId[dwLen] = '\0';
  488. sCardId.assign(reinterpret_cast<char *>(aaCardId.Get()));
  489. }
  490. catch (...)
  491. {
  492. }
  493. return sCardId;
  494. }
  495. void
  496. CV1Card::RefreshCardId() const
  497. {
  498. m_sCardId = ReadCardId();
  499. }
  500. // Access
  501. // Predicates
  502. // Static Variables