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.

692 lines
16 KiB

  1. // V2Card.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 <scuCast.h>
  11. #include "TransactionWrap.h"
  12. #include "V2Card.h"
  13. #include "V2Cert.h"
  14. #include "V2Cont.h"
  15. #include "V2PriKey.h"
  16. #include "V2PubKey.h"
  17. #include "V2KeyPair.h"
  18. #include "V2DataObj.h"
  19. using namespace std;
  20. using namespace cci;
  21. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  22. namespace
  23. {
  24. // Functors to make a T for a given symbol id (handle/symbol id)
  25. template<class T>
  26. class MakerFunction
  27. {
  28. public:
  29. typedef T ValueType;
  30. virtual
  31. ~MakerFunction() throw()
  32. {}
  33. virtual auto_ptr<T>
  34. operator()(SymbolID sid) const = 0;
  35. protected:
  36. MakerFunction(CV2Card const &rv2card)
  37. : m_rv2card(rv2card)
  38. {}
  39. CV2Card const &m_rv2card;
  40. };
  41. template<class T>
  42. class Maker2
  43. : public MakerFunction<T>
  44. {
  45. public:
  46. Maker2(CV2Card const &rv2card)
  47. : MakerFunction<T>(rv2card)
  48. {}
  49. auto_ptr<T>
  50. operator()(SymbolID sid) const
  51. {
  52. return auto_ptr<T>(new T(m_rv2card, sid));
  53. }
  54. };
  55. template<class T>
  56. class Maker3
  57. : public MakerFunction<T>
  58. {
  59. public:
  60. Maker3(CV2Card const &rv2card,
  61. ObjectAccess oa)
  62. : MakerFunction<T>(rv2card),
  63. m_oa(oa)
  64. {}
  65. auto_ptr<T>
  66. operator()(SymbolID sid) const
  67. {
  68. return auto_ptr<T>(new T(m_rv2card, sid, m_oa));
  69. }
  70. private:
  71. ObjectAccess m_oa;
  72. };
  73. // Enumerate objects in the object info file of object type OT,
  74. // returning a vector of R(object)
  75. template<class R, ObjectType OT, class T>
  76. vector<R>
  77. EnumPriviledgedObjects(CObjectInfoFile &rObjInfo,
  78. MakerFunction<T> &rMaker)
  79. {
  80. SymbolID sid = rObjInfo.FirstObject(OT);
  81. vector<R> vResult;
  82. while (sid)
  83. {
  84. auto_ptr<MakerFunction<T>::ValueType> apObject(rMaker(sid));
  85. R Handle(apObject.get());
  86. apObject.release(); // transfer ownership to handle
  87. vResult.push_back(Handle);
  88. sid = rObjInfo.NextObject(sid);
  89. }
  90. return vResult;
  91. }
  92. bool
  93. IsSupported(iop::CSmartCard &rSmartCard) throw()
  94. {
  95. bool fSupported = false;
  96. try
  97. {
  98. rSmartCard.Select("/3f00/0000");
  99. rSmartCard.Select("/3f00/3f11/0020");
  100. rSmartCard.Select("/3f00/3f11/0030");
  101. rSmartCard.Select("/3f00/3f11/0031");
  102. fSupported = true;
  103. }
  104. catch(scu::Exception &)
  105. {}
  106. return fSupported;
  107. }
  108. } // namespace
  109. /////////////////////////// PUBLIC /////////////////////////////////
  110. // Types
  111. // C'tors/D'tors
  112. CV2Card::~CV2Card() throw()
  113. {}
  114. // Operators
  115. // Operations
  116. void
  117. CV2Card::ChangePIN(string const &rstrOldPIN,
  118. string const &rstrNewPIN)
  119. {
  120. CTransactionWrap wrap(this);
  121. SmartCard().Select(RootPath().c_str());
  122. SuperClass::ChangePIN(rstrOldPIN, rstrNewPIN);
  123. }
  124. void
  125. CV2Card::DefaultContainer(CContainer const &rcont)
  126. {
  127. SymbolID sid = 0;
  128. if (rcont)
  129. {
  130. CV2Container &rv2cont = scu::DownCast<CV2Container &, CAbstractContainer &>(*rcont);
  131. sid = rv2cont.Handle();
  132. }
  133. ObjectInfoFile(oaPublicAccess).DefaultContainer(sid);
  134. }
  135. pair<string, // interpreted as the public modulus
  136. CPrivateKey>
  137. CV2Card::GenerateKeyPair(KeyType kt,
  138. string const &rsExponent,
  139. ObjectAccess oaPrivateKey)
  140. {
  141. CTransactionWrap wrap(this);
  142. // For the time being, assume this is implict RSA only....
  143. string::size_type const cExponentLength = rsExponent.size();
  144. if ((cExponentLength < 1) || (cExponentLength > 4))
  145. throw Exception(ccInvalidParameter);
  146. BYTE bKeyType;
  147. switch (kt)
  148. {
  149. case ktRSA512:
  150. bKeyType = CardKeyTypeRSA512;
  151. break;
  152. case ktRSA768:
  153. bKeyType = CardKeyTypeRSA768;
  154. break;
  155. case ktRSA1024:
  156. bKeyType = CardKeyTypeRSA1024;
  157. break;
  158. default:
  159. throw Exception(ccBadKeySpec);
  160. break;
  161. }
  162. // Allocated a slot in the key file, unless a correct one is
  163. // already allocated?
  164. CCardInfo &rci = this->CardInfo();
  165. BYTE bKeyNum = rci.AllocatePrivateKey(bKeyType);
  166. // Generate private key
  167. this->SmartCard().Select(PrivateKeyPath(kt).c_str());
  168. iop::CPublicKeyBlob pubkb(this->SmartCard().GenerateKeyPair(reinterpret_cast<BYTE const *>(rsExponent.data()),
  169. static_cast<WORD>(cExponentLength),
  170. bKeyNum,
  171. kt));
  172. this->SmartCard().Select(RootPath().c_str());
  173. auto_ptr<CV2PrivateKey> apv2prikey(new CV2PrivateKey(*this,
  174. bKeyType,
  175. bKeyNum,
  176. oaPrivateKey));
  177. string sModulus(reinterpret_cast<char *>(pubkb.bModulus),
  178. pubkb.bModulusLength);
  179. return pair<string, CPrivateKey>(sModulus, apv2prikey.release());
  180. }
  181. void
  182. CV2Card::InitCard()
  183. {
  184. CTransactionWrap wrap(this);
  185. m_apCardInfo->Reset();
  186. ObjectInfoFile(oaPublicAccess).Reset();
  187. ObjectInfoFile(oaPrivateAccess).Reset();
  188. }
  189. void
  190. CV2Card::InvalidateCache()
  191. {
  192. CTransactionWrap wrap(this);
  193. m_apCardInfo->UpdateCache();
  194. m_asLabel.Dirty();
  195. m_apPublicObjectInfoFile = auto_ptr<CObjectInfoFile>(0);
  196. m_apPrivateObjectInfoFile = auto_ptr<CObjectInfoFile>(0);
  197. }
  198. void
  199. CV2Card::Label(string const &rLabel)
  200. {
  201. CTransactionWrap wrap(this);
  202. m_apCardInfo->Label(rLabel);
  203. m_asLabel.Value(rLabel);
  204. }
  205. void
  206. CV2Card::VerifyKey(string const &rstrKey,
  207. BYTE bKeyNum)
  208. {
  209. CTransactionWrap wrap(this);
  210. SmartCard().Select(RootPath().c_str());
  211. SuperClass::VerifyKey(rstrKey, bKeyNum);
  212. }
  213. // Access
  214. size_t
  215. CV2Card::AvailableStringSpace(ObjectAccess oa) const
  216. {
  217. CTransactionWrap wrap(this);
  218. return ObjectInfoFile(oa).FreeSpace();
  219. }
  220. CCardInfo &
  221. CV2Card::CardInfo() const
  222. {
  223. return *m_apCardInfo;
  224. }
  225. CContainer
  226. CV2Card::DefaultContainer() const
  227. {
  228. CTransactionWrap wrap(this);
  229. SymbolID sid = ObjectInfoFile(oaPublicAccess).DefaultContainer();
  230. return sid
  231. ? CContainer(CV2Container::Make(*this, sid))
  232. : CContainer();
  233. }
  234. vector<CContainer>
  235. CV2Card::EnumContainers() const
  236. {
  237. CTransactionWrap wrap(this);
  238. Maker2<CV2Container> Maker(*this);
  239. return
  240. EnumPriviledgedObjects<CContainer,
  241. otContainerObject>(ObjectInfoFile(oaPublicAccess),
  242. Maker);
  243. }
  244. vector<CCertificate>
  245. CV2Card::EnumCertificates(ObjectAccess access) const
  246. {
  247. CTransactionWrap wrap(this);
  248. Maker3<CV2Certificate> Maker(*this, access);
  249. return
  250. EnumPriviledgedObjects<CCertificate,
  251. otCertificateObject>(ObjectInfoFile(access),
  252. Maker);
  253. }
  254. vector<CPublicKey>
  255. CV2Card::EnumPublicKeys(ObjectAccess access) const
  256. {
  257. CTransactionWrap wrap(this);
  258. Maker3<CV2PublicKey> Maker(*this, access);
  259. return
  260. EnumPriviledgedObjects<CPublicKey,
  261. otPublicKeyObject>(ObjectInfoFile(access),
  262. Maker);
  263. }
  264. vector<CPrivateKey>
  265. CV2Card::EnumPrivateKeys(ObjectAccess access) const
  266. {
  267. CTransactionWrap wrap(this);
  268. Maker3<CV2PrivateKey> Maker(*this, access);
  269. return
  270. EnumPriviledgedObjects<CPrivateKey,
  271. otPrivateKeyObject>(ObjectInfoFile(access),
  272. Maker);
  273. }
  274. vector<CDataObject>
  275. CV2Card::EnumDataObjects(ObjectAccess access) const
  276. {
  277. CTransactionWrap wrap(this);
  278. Maker3<CV2DataObject> Maker(*this, access);
  279. return
  280. EnumPriviledgedObjects<CDataObject,
  281. otDataObjectObject>(ObjectInfoFile(access),
  282. Maker);
  283. }
  284. string
  285. CV2Card::Label() const
  286. {
  287. CTransactionWrap wrap(this);
  288. if (!m_asLabel.IsCached())
  289. m_asLabel.Value(m_apCardInfo->Label());
  290. return m_asLabel.Value();
  291. }
  292. CAbstractCertificate *
  293. CV2Card::MakeCertificate(ObjectAccess oa) const
  294. {
  295. CTransactionWrap wrap(this);
  296. return new CV2Certificate(*this, oa);
  297. }
  298. CAbstractContainer *
  299. CV2Card::MakeContainer() const
  300. {
  301. CTransactionWrap wrap(this);
  302. return new CV2Container(*this);
  303. }
  304. CAbstractDataObject *
  305. CV2Card::MakeDataObject(ObjectAccess oa) const
  306. {
  307. CTransactionWrap wrap(this);
  308. return new CV2DataObject(*this, oa);
  309. }
  310. CAbstractKeyPair *
  311. CV2Card::MakeKeyPair(CContainer const &rhcont,
  312. KeySpec ks) const
  313. {
  314. CTransactionWrap wrap(this);
  315. return new CV2KeyPair(*this, rhcont, ks);
  316. }
  317. CAbstractPrivateKey *
  318. CV2Card::MakePrivateKey(ObjectAccess oa) const
  319. {
  320. CTransactionWrap wrap(this);
  321. return new CV2PrivateKey(*this, oa);
  322. }
  323. CAbstractPublicKey *
  324. CV2Card::MakePublicKey(ObjectAccess oa) const
  325. {
  326. CTransactionWrap wrap(this);
  327. return new CV2PublicKey(*this, oa);
  328. }
  329. BYTE
  330. CV2Card::MaxKeys(KeyType kt) const
  331. {
  332. BYTE bCount;
  333. switch (kt)
  334. {
  335. case ktRSA512:
  336. bCount = m_apCardInfo->NumRSA512Keys();
  337. break;
  338. case ktRSA768:
  339. bCount = m_apCardInfo->NumRSA768Keys();
  340. break;
  341. case ktRSA1024:
  342. bCount = m_apCardInfo->NumRSA1024Keys();
  343. break;
  344. default:
  345. bCount = 0;
  346. break;
  347. }
  348. return bCount;
  349. }
  350. size_t
  351. CV2Card::MaxStringSpace(ObjectAccess oa) const
  352. {
  353. return ObjectInfoFile(oa).TableSize();
  354. }
  355. string
  356. CV2Card::PrivateKeyPath(KeyType kt) const
  357. {
  358. string sPrivateKeyPath(RootPath());
  359. switch (kt)
  360. {
  361. case ktRSA512:
  362. sPrivateKeyPath += "3f01";
  363. break;
  364. case ktRSA768:
  365. sPrivateKeyPath += "3f02";
  366. break;
  367. case ktRSA1024:
  368. sPrivateKeyPath += "3f03";
  369. break;
  370. default:
  371. throw Exception(ccBadKeySpec);
  372. break;
  373. }
  374. return sPrivateKeyPath;
  375. }
  376. string const &
  377. CV2Card::RootPath() const
  378. {
  379. static string const sRootPath("/3f00/3f11/");
  380. return sRootPath;
  381. }
  382. bool
  383. CV2Card::SupportedKeyFunction(KeyType kt,
  384. CardOperation oper) const
  385. {
  386. bool fSupported = false;
  387. switch (oper)
  388. {
  389. case coEncryption: // .. or public key operations
  390. switch (kt)
  391. {
  392. case ktRSA512:
  393. case ktRSA768:
  394. case ktRSA1024:
  395. fSupported = false;
  396. break;
  397. default:
  398. fSupported = false;
  399. break;
  400. }
  401. case coDecryption: // .. or private key operations
  402. switch (kt)
  403. {
  404. case ktRSA512:
  405. case ktRSA768:
  406. case ktRSA1024:
  407. fSupported = true;
  408. break;
  409. default:
  410. fSupported = false;
  411. break;
  412. }
  413. case coKeyGeneration:
  414. switch (kt)
  415. {
  416. case ktRSA512:
  417. case ktRSA768:
  418. case ktRSA1024:
  419. {
  420. BYTE flag = m_apCardInfo->UsagePolicy();
  421. fSupported = BitSet(&flag, CardKeyGenSupportedFlag);
  422. break;
  423. }
  424. default:
  425. break;
  426. }
  427. default:
  428. break;
  429. }
  430. return fSupported;
  431. }
  432. // Predicates
  433. bool
  434. CV2Card::IsCAPIEnabled() const
  435. {
  436. BYTE flag = m_apCardInfo->UsagePolicy();
  437. return BitSet(&flag,CardCryptoAPIEnabledFlag);
  438. }
  439. bool
  440. CV2Card::IsPKCS11Enabled() const
  441. {
  442. BYTE flag = m_apCardInfo->UsagePolicy();
  443. return BitSet(&flag,CardPKCS11EnabledFlag);
  444. }
  445. bool
  446. CV2Card::IsProtectedMode() const
  447. {
  448. BYTE flag = m_apCardInfo->UsagePolicy();
  449. return BitSet(&flag,CardProtectedWriteFlag);
  450. }
  451. bool
  452. CV2Card::IsKeyGenEnabled() const
  453. {
  454. BYTE flag = m_apCardInfo->UsagePolicy();
  455. return BitSet(&flag,CardKeyGenSupportedFlag);
  456. }
  457. bool
  458. CV2Card::IsEntrustEnabled() const
  459. {
  460. BYTE flag = m_apCardInfo->UsagePolicy();
  461. return BitSet(&flag,CardEntrustEnabledFlag);
  462. }
  463. BYTE
  464. CV2Card::MajorVersion() const
  465. {
  466. return m_apCardInfo->FormatVersion().bMajor;
  467. }
  468. // Static Variables
  469. /////////////////////////// PROTECTED /////////////////////////////////
  470. // C'tors/D'tors
  471. CV2Card::CV2Card(string const &rstrReaderName,
  472. auto_ptr<iop::CIOP> &rapiop,
  473. auto_ptr<iop::CSmartCard> &rapSmartCard)
  474. : SuperClass(rstrReaderName, rapiop, rapSmartCard),
  475. m_apCardInfo(auto_ptr<CCardInfo>(new CCardInfo(*rapSmartCard.get()))),
  476. m_apPublicObjectInfoFile(),
  477. m_apPrivateObjectInfoFile(),
  478. m_asLabel()
  479. {}
  480. // Operators
  481. // Operations
  482. void
  483. CV2Card::DoSetup()
  484. {
  485. CAbstractCard::DoSetup();
  486. m_apCardInfo->UpdateCache();
  487. }
  488. // Access
  489. // Predicates
  490. // Static Variables
  491. /////////////////////////// PRIVATE /////////////////////////////////
  492. // C'tors/D'tors
  493. // Operators
  494. // Operations
  495. auto_ptr<CAbstractCard>
  496. CV2Card::DoMake(string const &rstrReaderName,
  497. auto_ptr<iop::CIOP> &rapiop,
  498. auto_ptr<iop::CSmartCard> &rapSmartCard)
  499. {
  500. return IsSupported(*rapSmartCard.get())
  501. ? auto_ptr<CAbstractCard>(new CV2Card(rstrReaderName, rapiop,
  502. rapSmartCard))
  503. : auto_ptr<CAbstractCard>(0);
  504. }
  505. // Access
  506. CObjectInfoFile &
  507. CV2Card::ObjectInfoFile(ObjectAccess oa) const
  508. {
  509. CObjectInfoFile *poif;
  510. switch (oa)
  511. {
  512. case oaPublicAccess:
  513. if (!m_apPublicObjectInfoFile.get())
  514. {
  515. m_apPublicObjectInfoFile =
  516. auto_ptr<CObjectInfoFile>(new
  517. CObjectInfoFile(SmartCard(),
  518. "/3f00/3f11/0030",
  519. oa));
  520. m_apPublicObjectInfoFile->UpdateCache();
  521. }
  522. poif = m_apPublicObjectInfoFile.get();
  523. break;
  524. case oaPrivateAccess:
  525. if (!m_apPrivateObjectInfoFile.get())
  526. {
  527. m_apPrivateObjectInfoFile =
  528. auto_ptr<CObjectInfoFile>(new
  529. CObjectInfoFile(SmartCard(),
  530. "/3f00/3f11/0031",
  531. oa));
  532. m_apPrivateObjectInfoFile->UpdateCache();
  533. }
  534. poif = m_apPrivateObjectInfoFile.get();
  535. break;
  536. default:
  537. throw Exception(ccBadAccessSpec);
  538. }
  539. return *poif;
  540. }
  541. // Predicates
  542. // Static Variables