507 lines
17 KiB
C++
507 lines
17 KiB
C++
// 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_)
|