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.

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