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.

506 lines
17 KiB

  1. // SmartCard.h: interface for the CSmartCard class.
  2. //
  3. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  4. // 2000. 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. #if !defined(AFX_CSmartCard_H__INCLUDED_)
  10. #define AFX_CSmartCard_H__INCLUDED_
  11. #include <vector>
  12. #include <string>
  13. #include <memory> // for auto_ptr
  14. #include <windows.h>
  15. #include <winscard.h>
  16. #include <scuExc.h>
  17. #include <scuArrayP.h>
  18. #include "iopExc.h"
  19. #include "iopPubBlob.h"
  20. #include "iopPriBlob.h"
  21. #include "IOPLock.h"
  22. #include "SharedMarker.h"
  23. #include "Marker.h"
  24. #include "FilePath.h"
  25. #include "DllSymDefn.h"
  26. /////////////////////////
  27. // MACRO DEFINITIONS //
  28. /////////////////////////
  29. // only compile these for the iopdll project
  30. #ifdef IOPDLL_EXPORTS
  31. #define LSB(a) (BYTE)((a)%256)
  32. #define MSB(a) (BYTE)((a)/256)
  33. #endif //IOPDLL_EXPORTS
  34. /////////////////////////////
  35. // END MACRO DEFINITIONS //
  36. /////////////////////////////
  37. namespace iop
  38. {
  39. enum FileType
  40. {
  41. directory,
  42. Binary_File,
  43. Cyclic_File,
  44. Variable_Record_File,
  45. Fixed_Record_File,
  46. Instance,
  47. Program_File,
  48. Unknown
  49. };
  50. typedef IOPDLL_API struct
  51. {
  52. WORD file_size; // Size of the file / remaining space in directory
  53. WORD file_id; // Logical file Id of the DF
  54. FileType file_type; // Type of the file
  55. BYTE file_status; // Validated == 1 or Invalidated == 0
  56. BYTE nb_sub_dir; // Nuber of sub-directory/ record_length
  57. BYTE nb_file; // Number of EF files in dir/ nb of records
  58. BYTE access_cond[8]; // Access condition matrix
  59. BYTE applicationID[16]; // AID of cyberflex application files
  60. BYTE AIDLength; // length in bytes of the application ID
  61. BYTE CryptoflexACL[7]; // A Cryptoflex ACL.
  62. } FILE_HEADER;
  63. enum IOPDLL_API KeyType {ktRSA512 = 1, ktRSA768 = 2, ktRSA1024 = 3, ktDES = 0};
  64. enum IOPDLL_API CardOperation {coEncryption, coDecryption, coKeyGeneration};
  65. typedef struct
  66. {
  67. DWORD dwHandle;
  68. void (*FireEvent)(void *pToCard, int iEventCode, DWORD dwLen, BYTE* bData);
  69. void *pToCard;
  70. } EventInfo;
  71. // Instantiate the templates so they will be properly accessible
  72. // as data members to the exported class CSmartCard in the DLL. See
  73. // MSDN Knowledge Base Article Q168958 for more information.
  74. #pragma warning(push)
  75. // Non-standard extension used: 'extern' before template explicit
  76. // instantiation
  77. #pragma warning(disable : 4231)
  78. IOPDLL_EXPIMP_TEMPLATE template class IOPDLL_API std::auto_ptr<CSharedMarker>;
  79. IOPDLL_EXPIMP_TEMPLATE template class IOPDLL_API std::vector<EventInfo *>;
  80. #pragma warning(pop)
  81. class IOPDLL_API CSmartCard
  82. {
  83. public:
  84. typedef BYTE ClassByte;
  85. typedef BYTE Instruction;
  86. enum
  87. {
  88. cMaxAtrLength = 32,
  89. };
  90. enum
  91. {
  92. swSuccess = 0x9000,
  93. };
  94. typedef WORD StatusWord;
  95. enum CauseCode
  96. {
  97. ccAccessConditionsNotMet,
  98. ccAlgorithmIdNotSupported,
  99. ccAskRandomNotLastApdu,
  100. ccAuthenticationFailed,
  101. ccBadFilePath,
  102. ccBadState,
  103. ccCannotReadOutsideFileBoundaries,
  104. ccCannotWriteOutsideFileBoundaries,
  105. ccCardletNotInRegisteredState,
  106. ccChvNotInitialized,
  107. ccChvVerificationFailedMoreAttempts,
  108. ccContradictionWithInvalidationStatus,
  109. ccCurrentDirectoryIsNotSelected,
  110. ccDataPossiblyCorrupted,
  111. ccDefaultLoaderNotSelected,
  112. ccDirectoryNotEmpty,
  113. ccFileAlreadyInvalidated,
  114. ccFileExists,
  115. ccFileIdExistsOrTypeInconsistentOrRecordTooLong,
  116. ccFileIndexDoesNotExist,
  117. ccFileInvalidated,
  118. ccFileNotFound,
  119. ccFileNotFoundOrNoMoreFilesInDf,
  120. ccFileTypeInvalid,
  121. ccIncorrectKey,
  122. ccIncorrectP1P2,
  123. ccIncorrectP3,
  124. ccInstallCannotRun,
  125. ccInstanceIdInUse,
  126. ccInsufficientSpace,
  127. ccInvalidAnswerReceived,
  128. ccInvalidKey,
  129. ccInvalidSignature,
  130. ccJava,
  131. ccKeyBlocked,
  132. ccLimitReached,
  133. ccMemoryProblem,
  134. ccNoAccess,
  135. ccNoEfSelected,
  136. ccNoEfExistsOrNoChvKeyDefined,
  137. ccNoFileSelected,
  138. ccNoGetChallengeBefore,
  139. ccOperationNotActivatedForApdu,
  140. ccOutOfRangeOrRecordNotFound,
  141. ccOutOfSpaceToCreateFile,
  142. ccProgramFileInvalidated,
  143. ccRecordInfoIncompatible,
  144. ccRecordLengthTooLong,
  145. ccRequestedAlgIdMayNotMatchKeyUse,
  146. ccReturnedDataCorrupted,
  147. ccRootDirectoryNotErasable,
  148. ccTimeOut,
  149. ccTooMuchDataForProMode,
  150. ccUnknownInstructionClass,
  151. ccUnknownInstructionCode,
  152. ccUnknownStatus,
  153. ccUnidentifiedTechnicalProblem,
  154. ccUpdateImpossible,
  155. ccVerificationFailed,
  156. };
  157. // Note: scu::ExcTemplate isn't used here because of problems
  158. // getting the DLL to compile and link properly. Instead, the
  159. // Exception class inherits directly from scu::Exception and
  160. // fills in what ExcTemplate provides to complete the implementation.
  161. class IOPDLL_API Exception
  162. : public scu::Exception
  163. {
  164. public:
  165. // Types
  166. typedef Exception::CauseCode CauseCode;
  167. // C'tors/D'tors
  168. Exception(CauseCode cc,
  169. ClassByte cb,
  170. Instruction ins,
  171. StatusWord sw) throw();
  172. virtual
  173. ~Exception() throw();
  174. // Operators
  175. // Operations
  176. virtual scu::Exception *
  177. Clone() const;
  178. virtual void
  179. Raise() const;
  180. // Access
  181. CauseCode
  182. Cause() const throw();
  183. ClassByte
  184. Class() const throw();
  185. char const *
  186. Description() const;
  187. ErrorCode
  188. Error() const throw();
  189. Instruction
  190. Ins() const throw();
  191. StatusWord
  192. Status() const throw();
  193. // Predicates
  194. protected:
  195. // Types
  196. // C'tors/D'tors
  197. // Operators
  198. // Operations
  199. // Access
  200. // Predicates
  201. // Variables
  202. private:
  203. // Types
  204. // C'tors/D'tors
  205. // Operators
  206. // Operations
  207. // Access
  208. // Predicates
  209. // Variables
  210. CauseCode m_cc;
  211. ClassByte m_cb;
  212. Instruction m_ins;
  213. StatusWord m_sw;
  214. };
  215. CSmartCard(const SCARDHANDLE hCardHandle,
  216. const char* szReader,
  217. const SCARDCONTEXT hContext,
  218. const DWORD dwMode);
  219. virtual ~CSmartCard();
  220. void ReConnect();
  221. void ResetCard();
  222. void SendCardAPDU(const BYTE bCLA, const BYTE bINS, const BYTE bP1,
  223. const BYTE bP2, const BYTE bLenghtIn, const BYTE* bDataIn,
  224. const BYTE bLengthOut, BYTE* bDataOut);
  225. void getATR(BYTE* bATR, BYTE& iATRLength);
  226. virtual void DeleteFile(const WORD wFileID)
  227. { throw iop::Exception(ccNotImplemented); };
  228. virtual void CreateFile(const FILE_HEADER* pMyFile)
  229. { throw iop::Exception(ccNotImplemented); };
  230. virtual void SelectParent()
  231. { throw iop::Exception(ccNotImplemented); };
  232. virtual void SelectCardlet(const BYTE *bAID,
  233. const BYTE bAIDLen)
  234. { throw iop::Exception(ccNotImplemented); };
  235. virtual void SelectLoader()
  236. { throw iop::Exception(ccNotImplemented); };
  237. void ResetSelect();
  238. virtual void GetSerial(BYTE* bSerial, size_t &SerialLength)
  239. { throw iop::Exception(ccNotImplemented); };
  240. virtual void DeleteApplet()
  241. { throw iop::Exception(ccNotImplemented); };
  242. virtual void ResetInstance()
  243. { throw iop::Exception(ccNotImplemented); };
  244. virtual void SetCurrentAsLoader()
  245. { throw iop::Exception(ccNotImplemented); };
  246. virtual void SetDefaultAsLoader()
  247. { throw iop::Exception(ccNotImplemented); };
  248. virtual void BlockApplet()
  249. { throw iop::Exception(ccNotImplemented); };
  250. virtual void ValidateProgram(const BYTE *bSig,
  251. const BYTE bSigLength)
  252. { throw iop::Exception(ccNotImplemented); };
  253. virtual void ResetProgram()
  254. { throw iop::Exception(ccNotImplemented); };
  255. virtual void GetACL(BYTE *bData)
  256. { throw iop::Exception(ccNotImplemented); };
  257. virtual void ExecuteMain()
  258. { throw iop::Exception(ccNotImplemented); };
  259. virtual void ExecuteInstall(const BYTE *bBlock,
  260. const BYTE bLen)
  261. { throw iop::Exception(ccNotImplemented); };
  262. virtual void Directory (const BYTE bFile_Nb,
  263. FILE_HEADER* pMyFile)
  264. { throw iop::Exception(ccNotImplemented); };
  265. virtual void Select (const char* szFileFullPath,
  266. FILE_HEADER* pMyFile = NULL,
  267. const bool fSelectAll = false)
  268. { throw iop::Exception(ccNotImplemented); };
  269. virtual void GetResponse(ClassByte cb, const BYTE bDataLength,
  270. BYTE* bDataOut);
  271. virtual void ReadBinary (const WORD wOffset,
  272. const WORD wDataLength,
  273. BYTE* bDATA);
  274. virtual void WriteBinary(const WORD wOffset,
  275. const WORD wDataLength,
  276. const BYTE* bDATA);
  277. virtual void ReadRecord(const BYTE bRecNum, const BYTE bMode,
  278. const BYTE bDataLen, BYTE *bData)
  279. { throw iop::Exception(ccNotImplemented); };
  280. virtual void UpdateRecord(const BYTE bRecNum, const BYTE
  281. bMode, const BYTE bDataLen,
  282. BYTE *bData)
  283. { throw iop::Exception(ccNotImplemented); };
  284. virtual void VerifyKey (const BYTE bKeyNumber,
  285. const BYTE bKeyLength, const BYTE* bKey)
  286. { throw iop::Exception(ccNotImplemented); };
  287. virtual void VerifyCHV (const BYTE bCHVNumber,
  288. const BYTE* bCHV)
  289. { throw iop::Exception(ccNotImplemented); };
  290. virtual void VerifyTransportKey(const BYTE *bKey)
  291. { throw iop::Exception(ccNotImplemented); };
  292. virtual void GetChallenge(const DWORD dwNumberLength,
  293. BYTE* bRandomNumber)
  294. { throw iop::Exception(ccNotImplemented); };
  295. virtual void ExternalAuth(const KeyType kt, const BYTE bKeyNb,
  296. const BYTE bDataLength,
  297. const BYTE* bData)
  298. { throw iop::Exception(ccNotImplemented); };
  299. virtual void InternalAuth(const KeyType kt, const BYTE bKeyNb,
  300. const BYTE bDataLength,
  301. const BYTE* bDataIn,
  302. BYTE* bDataOut)
  303. { throw iop::Exception(ccNotImplemented); };
  304. virtual void ReadPublicKey (CPublicKeyBlob *aKey,
  305. const BYTE bKeyNum)
  306. { throw iop::Exception(ccNotImplemented); };
  307. virtual void WritePublicKey (const CPublicKeyBlob aKey,
  308. const BYTE bKeyNum)
  309. { throw iop::Exception(ccNotImplemented); };
  310. virtual void WritePrivateKey(const CPrivateKeyBlob aKey,
  311. const BYTE bKeyNum)
  312. { throw iop::Exception(ccNotImplemented); };
  313. virtual CPublicKeyBlob GenerateKeyPair(const BYTE *bpPublExp,
  314. const WORD wPublExpLen,
  315. const BYTE bKeyNum,
  316. const KeyType kt)
  317. { throw iop::Exception(ccNotImplemented); }
  318. virtual void ChangeACL (const BYTE *bACL)
  319. { throw iop::Exception(ccNotImplemented); };
  320. virtual void ChangeCHV (const BYTE bKey_nb,
  321. const BYTE *bOldCHV,
  322. const BYTE *bNewCHV)
  323. { throw iop::Exception(ccNotImplemented); };
  324. virtual void ChangeCHV (const BYTE bKey_nb,
  325. const BYTE *bNewCHV)
  326. { throw iop::Exception(ccNotImplemented); };
  327. virtual void UnblockCHV (const BYTE bKey_nb, const BYTE
  328. *bUnblockPIN,
  329. const BYTE *bNewPin)
  330. { throw iop::Exception(ccNotImplemented); };
  331. virtual void ChangeUnblockKey (const BYTE bKey_nb,
  332. const BYTE *bNewPIN)
  333. { throw iop::Exception(ccNotImplemented); };
  334. virtual void ChangeTransportKey(const BYTE *bNewKey)
  335. { throw iop::Exception(ccNotImplemented); };
  336. virtual void LogoutAll()
  337. { throw iop::Exception(ccNotImplemented); };
  338. void GetCurrentDir (char*);
  339. void GetCurrentFile(char*);
  340. char const *getCardName() const;
  341. void setCardName(char const *);
  342. DWORD RegisterEvent(void (*FireEvent)(void *pToCard, int iEventCode, DWORD dwLen, BYTE* bData), void *pToCard);
  343. bool UnregisterEvent(DWORD dwHandle);
  344. bool HasProperty(WORD wPropNumber);
  345. CIOPLock* Lock() { return &m_IOPLock; };
  346. void FireEvents(int iEventCode, DWORD dwLength, BYTE* bsData);
  347. CMarker Marker(CMarker::MarkerType Type);
  348. SCARDHANDLE getCardHandle() { return m_hCard; };
  349. void
  350. GetState(DWORD &rdwState,
  351. DWORD &rdwProtocol);
  352. protected:
  353. enum // size_t/counter
  354. {
  355. cMaxApduLength = 255,
  356. cMaxRwDataBlock = /*cMaxApduLength*/ 160 /*until SCM fixes their reader*/,
  357. cMaxGetResponseLength = cMaxApduLength + sizeof StatusWord,
  358. cMaxPathLength = 1024,
  359. };
  360. enum // Instruction
  361. {
  362. insCreateFile = 0xE0,
  363. insGetResponse = 0xC0,
  364. insInternalAuth = 0x88,
  365. insReadBinary = 0xB0,
  366. insUpdateBinary = 0xD6,
  367. insVerifyChv = 0x20,
  368. };
  369. virtual void
  370. DefaultDispatchError(ClassByte cb,
  371. Instruction ins,
  372. StatusWord sw) const;
  373. virtual void
  374. DispatchError(ClassByte cb,
  375. Instruction ins,
  376. StatusWord sw) const;
  377. virtual void
  378. DoReadBlock(WORD wOffset,
  379. BYTE *pbBuffer,
  380. BYTE bLength) = 0;
  381. virtual void
  382. DoWriteBlock(WORD wOffset,
  383. BYTE const *pbBuffer,
  384. BYTE cLength) = 0;
  385. virtual bool
  386. SupportLogout() = 0;
  387. BYTE
  388. ResponseLengthAvailable() const;
  389. void
  390. ResponseLengthAvailable(BYTE cResponseLength);
  391. BYTE FormatPath(char *szOutputPath, const char *szInputPath);
  392. void RequireSelect();
  393. SCARDHANDLE m_hCard;
  394. SCARDCONTEXT m_hContext;
  395. FilePath m_CurrentDirectory;
  396. FilePath m_CurrentFile;
  397. DWORD m_dwShareMode;
  398. bool m_fSupportLogout;
  399. CIOPLock m_IOPLock;
  400. std::auto_ptr<CSharedMarker> m_apSharedMarker;
  401. private:
  402. void
  403. ProcessReturnStatus(ClassByte cb,
  404. Instruction ins,
  405. StatusWord sw);
  406. void
  407. WriteBlock(WORD wOffset,
  408. BYTE const *pbBuffer,
  409. BYTE cLength);
  410. std::vector<EventInfo*> m_vecEvents;
  411. DWORD m_dwEventCounter;
  412. BYTE m_cResponseAvailable;
  413. std::string m_sCardName;
  414. };
  415. } // namespace iop
  416. #endif // !defined(AFX_CSmartCard_H__INCLUDED_)