|
|
// SmartCard.h: interface for the CSmartCard class.
//
// (c) Copyright Schlumberger Technology Corp., unpublished work, created
// 2000. This computer program includes Confidential, Proprietary
// Information and is a Trade Secret of Schlumberger Technology Corp. All
// use, disclosure, and/or reproduction is prohibited unless authorized
// in writing. All Rights Reserved.
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CSmartCard_H__INCLUDED_)
#define AFX_CSmartCard_H__INCLUDED_
#include <vector>
#include <string>
#include <memory> // for auto_ptr
#include <windows.h>
#include <winscard.h>
#include <scuExc.h>
#include <scuArrayP.h>
#include "iopExc.h"
#include "iopPubBlob.h"
#include "iopPriBlob.h"
#include "IOPLock.h"
#include "SharedMarker.h"
#include "Marker.h"
#include "FilePath.h"
#include "DllSymDefn.h"
/////////////////////////
// MACRO DEFINITIONS //
/////////////////////////
// only compile these for the iopdll project
#ifdef IOPDLL_EXPORTS
#define LSB(a) (BYTE)((a)%256)
#define MSB(a) (BYTE)((a)/256)
#endif //IOPDLL_EXPORTS
/////////////////////////////
// END MACRO DEFINITIONS //
/////////////////////////////
namespace iop {
enum FileType
{ directory, Binary_File, Cyclic_File, Variable_Record_File, Fixed_Record_File, Instance, Program_File, Unknown };
typedef IOPDLL_API struct { WORD file_size; // Size of the file / remaining space in directory
WORD file_id; // Logical file Id of the DF
FileType file_type; // Type of the file
BYTE file_status; // Validated == 1 or Invalidated == 0
BYTE nb_sub_dir; // Nuber of sub-directory/ record_length
BYTE nb_file; // Number of EF files in dir/ nb of records
BYTE access_cond[8]; // Access condition matrix
BYTE applicationID[16]; // AID of cyberflex application files
BYTE AIDLength; // length in bytes of the application ID
BYTE CryptoflexACL[7]; // A Cryptoflex ACL.
} FILE_HEADER;
enum IOPDLL_API KeyType {ktRSA512 = 1, ktRSA768 = 2, ktRSA1024 = 3, ktDES = 0}; enum IOPDLL_API CardOperation {coEncryption, coDecryption, coKeyGeneration};
typedef struct { DWORD dwHandle; void (*FireEvent)(void *pToCard, int iEventCode, DWORD dwLen, BYTE* bData); void *pToCard; } EventInfo;
// Instantiate the templates so they will be properly accessible
// as data members to the exported class CSmartCard in the DLL. See
// MSDN Knowledge Base Article Q168958 for more information.
#pragma warning(push)
// Non-standard extension used: 'extern' before template explicit
// instantiation
#pragma warning(disable : 4231)
IOPDLL_EXPIMP_TEMPLATE template class IOPDLL_API std::auto_ptr<CSharedMarker>; IOPDLL_EXPIMP_TEMPLATE template class IOPDLL_API std::vector<EventInfo *>;
#pragma warning(pop)
class IOPDLL_API CSmartCard { public: typedef BYTE ClassByte; typedef BYTE Instruction;
enum { cMaxAtrLength = 32, };
enum { swSuccess = 0x9000, }; typedef WORD StatusWord;
enum CauseCode { ccAccessConditionsNotMet, ccAlgorithmIdNotSupported, ccAskRandomNotLastApdu, ccAuthenticationFailed, ccBadFilePath, ccBadState, ccCannotReadOutsideFileBoundaries, ccCannotWriteOutsideFileBoundaries, ccCardletNotInRegisteredState, ccChvNotInitialized, ccChvVerificationFailedMoreAttempts, ccContradictionWithInvalidationStatus, ccCurrentDirectoryIsNotSelected, ccDataPossiblyCorrupted, ccDefaultLoaderNotSelected, ccDirectoryNotEmpty, ccFileAlreadyInvalidated, ccFileExists, ccFileIdExistsOrTypeInconsistentOrRecordTooLong, ccFileIndexDoesNotExist, ccFileInvalidated, ccFileNotFound, ccFileNotFoundOrNoMoreFilesInDf, ccFileTypeInvalid, ccIncorrectKey, ccIncorrectP1P2, ccIncorrectP3, ccInstallCannotRun, ccInstanceIdInUse, ccInsufficientSpace, ccInvalidAnswerReceived, ccInvalidKey, ccInvalidSignature, ccJava, ccKeyBlocked, ccLimitReached, ccMemoryProblem, ccNoAccess, ccNoEfSelected, ccNoEfExistsOrNoChvKeyDefined, ccNoFileSelected, ccNoGetChallengeBefore, ccOperationNotActivatedForApdu, ccOutOfRangeOrRecordNotFound, ccOutOfSpaceToCreateFile, ccProgramFileInvalidated, ccRecordInfoIncompatible, ccRecordLengthTooLong, ccRequestedAlgIdMayNotMatchKeyUse, ccReturnedDataCorrupted, ccRootDirectoryNotErasable, ccTimeOut, ccTooMuchDataForProMode, ccUnknownInstructionClass, ccUnknownInstructionCode, ccUnknownStatus, ccUnidentifiedTechnicalProblem, ccUpdateImpossible, ccVerificationFailed, };
// Note: scu::ExcTemplate isn't used here because of problems
// getting the DLL to compile and link properly. Instead, the
// Exception class inherits directly from scu::Exception and
// fills in what ExcTemplate provides to complete the implementation.
class IOPDLL_API Exception : public scu::Exception { public: // Types
typedef Exception::CauseCode CauseCode; // C'tors/D'tors
Exception(CauseCode cc, ClassByte cb, Instruction ins, StatusWord sw) throw();
virtual ~Exception() throw(); // Operators
// Operations
virtual scu::Exception * Clone() const;
virtual void Raise() const;
// Access
CauseCode Cause() const throw(); ClassByte Class() const throw();
char const * Description() const; ErrorCode Error() const throw(); Instruction Ins() const throw(); StatusWord Status() const throw();
// Predicates
protected: // Types
// C'tors/D'tors
// Operators
// Operations
// Access
// Predicates
// Variables
private: // Types
// C'tors/D'tors
// Operators
// Operations
// Access
// Predicates
// Variables
CauseCode m_cc; ClassByte m_cb; Instruction m_ins; StatusWord m_sw; };
CSmartCard(const SCARDHANDLE hCardHandle, const char* szReader, const SCARDCONTEXT hContext, const DWORD dwMode); virtual ~CSmartCard(); void ReConnect(); void ResetCard();
void SendCardAPDU(const BYTE bCLA, const BYTE bINS, const BYTE bP1, const BYTE bP2, const BYTE bLenghtIn, const BYTE* bDataIn, const BYTE bLengthOut, BYTE* bDataOut);
void getATR(BYTE* bATR, BYTE& iATRLength);
virtual void DeleteFile(const WORD wFileID) { throw iop::Exception(ccNotImplemented); }; virtual void CreateFile(const FILE_HEADER* pMyFile) { throw iop::Exception(ccNotImplemented); }; virtual void SelectParent() { throw iop::Exception(ccNotImplemented); }; virtual void SelectCardlet(const BYTE *bAID, const BYTE bAIDLen) { throw iop::Exception(ccNotImplemented); };
virtual void SelectLoader() { throw iop::Exception(ccNotImplemented); }; void ResetSelect(); virtual void GetSerial(BYTE* bSerial, size_t &SerialLength) { throw iop::Exception(ccNotImplemented); }; virtual void DeleteApplet() { throw iop::Exception(ccNotImplemented); }; virtual void ResetInstance() { throw iop::Exception(ccNotImplemented); }; virtual void SetCurrentAsLoader() { throw iop::Exception(ccNotImplemented); }; virtual void SetDefaultAsLoader() { throw iop::Exception(ccNotImplemented); }; virtual void BlockApplet() { throw iop::Exception(ccNotImplemented); };
virtual void ValidateProgram(const BYTE *bSig, const BYTE bSigLength) { throw iop::Exception(ccNotImplemented); };
virtual void ResetProgram() { throw iop::Exception(ccNotImplemented); };
virtual void GetACL(BYTE *bData) { throw iop::Exception(ccNotImplemented); };
virtual void ExecuteMain() { throw iop::Exception(ccNotImplemented); }; virtual void ExecuteInstall(const BYTE *bBlock, const BYTE bLen) { throw iop::Exception(ccNotImplemented); };
virtual void Directory (const BYTE bFile_Nb, FILE_HEADER* pMyFile) { throw iop::Exception(ccNotImplemented); }; virtual void Select (const char* szFileFullPath, FILE_HEADER* pMyFile = NULL, const bool fSelectAll = false) { throw iop::Exception(ccNotImplemented); }; virtual void GetResponse(ClassByte cb, const BYTE bDataLength, BYTE* bDataOut); virtual void ReadBinary (const WORD wOffset, const WORD wDataLength, BYTE* bDATA); virtual void WriteBinary(const WORD wOffset, const WORD wDataLength, const BYTE* bDATA);
virtual void ReadRecord(const BYTE bRecNum, const BYTE bMode, const BYTE bDataLen, BYTE *bData) { throw iop::Exception(ccNotImplemented); }; virtual void UpdateRecord(const BYTE bRecNum, const BYTE bMode, const BYTE bDataLen, BYTE *bData) { throw iop::Exception(ccNotImplemented); };
virtual void VerifyKey (const BYTE bKeyNumber, const BYTE bKeyLength, const BYTE* bKey) { throw iop::Exception(ccNotImplemented); }; virtual void VerifyCHV (const BYTE bCHVNumber, const BYTE* bCHV) { throw iop::Exception(ccNotImplemented); }; virtual void VerifyTransportKey(const BYTE *bKey) { throw iop::Exception(ccNotImplemented); };
virtual void GetChallenge(const DWORD dwNumberLength, BYTE* bRandomNumber) { throw iop::Exception(ccNotImplemented); }; virtual void ExternalAuth(const KeyType kt, const BYTE bKeyNb, const BYTE bDataLength, const BYTE* bData) { throw iop::Exception(ccNotImplemented); }; virtual void InternalAuth(const KeyType kt, const BYTE bKeyNb, const BYTE bDataLength, const BYTE* bDataIn, BYTE* bDataOut) { throw iop::Exception(ccNotImplemented); };
virtual void ReadPublicKey (CPublicKeyBlob *aKey, const BYTE bKeyNum) { throw iop::Exception(ccNotImplemented); }; virtual void WritePublicKey (const CPublicKeyBlob aKey, const BYTE bKeyNum) { throw iop::Exception(ccNotImplemented); }; virtual void WritePrivateKey(const CPrivateKeyBlob aKey, const BYTE bKeyNum) { throw iop::Exception(ccNotImplemented); }; virtual CPublicKeyBlob GenerateKeyPair(const BYTE *bpPublExp, const WORD wPublExpLen, const BYTE bKeyNum, const KeyType kt) { throw iop::Exception(ccNotImplemented); }
virtual void ChangeACL (const BYTE *bACL) { throw iop::Exception(ccNotImplemented); }; virtual void ChangeCHV (const BYTE bKey_nb, const BYTE *bOldCHV, const BYTE *bNewCHV) { throw iop::Exception(ccNotImplemented); }; virtual void ChangeCHV (const BYTE bKey_nb, const BYTE *bNewCHV) { throw iop::Exception(ccNotImplemented); }; virtual void UnblockCHV (const BYTE bKey_nb, const BYTE *bUnblockPIN, const BYTE *bNewPin) { throw iop::Exception(ccNotImplemented); }; virtual void ChangeUnblockKey (const BYTE bKey_nb, const BYTE *bNewPIN) { throw iop::Exception(ccNotImplemented); }; virtual void ChangeTransportKey(const BYTE *bNewKey) { throw iop::Exception(ccNotImplemented); }; virtual void LogoutAll() { throw iop::Exception(ccNotImplemented); }; void GetCurrentDir (char*); void GetCurrentFile(char*); char const *getCardName() const; void setCardName(char const *);
DWORD RegisterEvent(void (*FireEvent)(void *pToCard, int iEventCode, DWORD dwLen, BYTE* bData), void *pToCard); bool UnregisterEvent(DWORD dwHandle);
bool HasProperty(WORD wPropNumber);
CIOPLock* Lock() { return &m_IOPLock; };
void FireEvents(int iEventCode, DWORD dwLength, BYTE* bsData);
CMarker Marker(CMarker::MarkerType Type);
SCARDHANDLE getCardHandle() { return m_hCard; };
void GetState(DWORD &rdwState, DWORD &rdwProtocol);
protected: enum // size_t/counter
{ cMaxApduLength = 255, cMaxRwDataBlock = /*cMaxApduLength*/ 160 /*until SCM fixes their reader*/, cMaxGetResponseLength = cMaxApduLength + sizeof StatusWord,
cMaxPathLength = 1024, };
enum // Instruction
{ insCreateFile = 0xE0, insGetResponse = 0xC0, insInternalAuth = 0x88, insReadBinary = 0xB0, insUpdateBinary = 0xD6, insVerifyChv = 0x20, }; virtual void DefaultDispatchError(ClassByte cb, Instruction ins, StatusWord sw) const;
virtual void DispatchError(ClassByte cb, Instruction ins, StatusWord sw) const;
virtual void DoReadBlock(WORD wOffset, BYTE *pbBuffer, BYTE bLength) = 0;
virtual void DoWriteBlock(WORD wOffset, BYTE const *pbBuffer, BYTE cLength) = 0; virtual bool SupportLogout() = 0; BYTE ResponseLengthAvailable() const;
void ResponseLengthAvailable(BYTE cResponseLength); BYTE FormatPath(char *szOutputPath, const char *szInputPath); void RequireSelect();
SCARDHANDLE m_hCard; SCARDCONTEXT m_hContext;
FilePath m_CurrentDirectory; FilePath m_CurrentFile;
DWORD m_dwShareMode; bool m_fSupportLogout;
CIOPLock m_IOPLock; std::auto_ptr<CSharedMarker> m_apSharedMarker;
private:
void ProcessReturnStatus(ClassByte cb, Instruction ins, StatusWord sw); void WriteBlock(WORD wOffset, BYTE const *pbBuffer, BYTE cLength); std::vector<EventInfo*> m_vecEvents; DWORD m_dwEventCounter; BYTE m_cResponseAvailable; std::string m_sCardName; };
} // namespace iop
#endif // !defined(AFX_CSmartCard_H__INCLUDED_)
|