This repository has been archived by the owner on Dec 4, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
PCSCManager.h
203 lines (181 loc) · 5.5 KB
/
PCSCManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
* SMARTCARDPP
*
* This software is released under either the GNU Library General Public
* License (see LICENSE.LGPL) or the BSD License (see LICENSE.BSD).
*
* Note that the only valid version of the LGPL license as far as this
* project is concerned is the original GNU Library General Public License
* Version 2.1, February 1999
*
*/
#ifndef PCSCMANAGER_H
#define PCSCMANAGER_H
#ifndef WIN32
#include <stdio.h>
#include <cstdlib>
#include <stdarg.h>
#include <unistd.h>
#include <PCSC/wintypes.h>
#include <PCSC/pcsclite.h>
#include <PCSC/winscard.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/time.h>
#ifndef __APPLE__
#include <reader.h>
//#define SCARD_E_NO_READERS_AVAILABLE 0x8010002EL
#else
#define ERROR_NO_MEDIA_IN_DRIVE 1112L
#endif
#else
#pragma warning(push)
#pragma warning(disable:4201)
#undef UNICODE
#include <winscard.h>
#pragma warning(pop)
#include <Windows.h>
#include <time.h>
#include <WinNT.h>
#include <Psapi.h>
#include <stdlib.h>
#endif
#include <string.h>
#include <sys/stat.h>
#include "common.h"
#include "SCError.h"
#include "SCardLog.h"
#include "helperMacro.h"
#ifndef CM_IOCTL_GET_FEATURE_REQUEST
// FIXME: We should use internal-winscard.h from OpenSC project instead
// This will clean up PCSCManager.h header considerably and
// allows us to use Mingw32 for building
#include "internal-pcsc22.h"
#endif
#define SS(a) if ((theState & SCARD_STATE_##a ) == SCARD_STATE_##a) stateStr += string(#a) + string("|")
struct ConnectionBase;
struct PCSCConnection;
/// WinSCard/PCSCLite wrapper
/** PCSCManager represents WinSCard subsystem on Windows or PCSCLite libary
on platforms where it is available. It loads the libraries dynamically to avoid
linked-in dependencies */
class PCSCManager
{
private:
bool mOwnContext;
SCARDCONTEXT hContext;
SCARDHANDLE hScard;
std::vector<char > mReaders;
std::vector<SCARD_READERSTATE> mReaderStates;
unsigned int transactionID;
unsigned int connectionID;
int readerLanguageId;
uint cIndex;
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
struct osver {
int minor;
int sub;
} ;
typedef struct osver osxver;
void construct(void);
void ensureReaders();
void execPinCommand(/*ConnectionBase *c, */bool verify, std::vector<byte> &cmd);
std::string translateReaderState(DWORD state);
std::string translateDwEventState(DWORD state);
void resetCurrentContext();
DWORD proto;
DWORD verify_ioctl;
DWORD verify_ioctl_start;
DWORD verify_ioctl_finish;
DWORD modify_ioctl;
DWORD modify_ioctl_start;
DWORD modify_ioctl_finish;
bool display;
bool pinpad;
std::string readerName;
bool mOwnConnection;
#ifdef WIN32
int gettimeofday(struct timeval *tv, struct timezone *tz);
#elif __APPLE__
void macosx_ver(char *darwinversion, osxver *osxversion ) ;
char *osversionString(void);
#endif
public:
PCSCManager();
PCSCManager(std::string readerName);
PCSCManager(SCARDCONTEXT existingContext, SCARDHANDLE hScard);
~PCSCManager(void);
uint getReaderCount(bool forceRefresh = false);
std::string getReaderName(uint idx);
std::string getReaderName();
std::string getReaderState(uint idx);
std::string getReaderState();
std::string getATRHex(uint idx);
std::string getATRHex();
bool isPinPad(uint index);
bool isPinPad();
void connect(uint idx);
/// connect using an application-supplied connection handle
void connect(SCARDHANDLE existingHandle);
void reconnect();
void reconnect(unsigned long SCARD_PROTO);
void setReaderLanguageId(int langId);
int getReaderLanguageId(void);
int getTransactionId(void);
uint getConnectionIndex();
void setConnectionID();
uint getConnectionID();
unsigned long getProtocol();
void makeConnection(uint idx);
void makeConnection(std::string readerName);
void deleteConnection(bool reset);
void beginTransaction();
void endTransaction(bool forceReset = false);
void execCommand(std::vector<BYTE> &cmd,std::vector<BYTE> &recv, unsigned int &recvLen);
void execPinEntryCommand(std::vector<byte> &cmd);
void execPinChangeCommand(std::vector<byte> &cmd, size_t oldPinLen, size_t newPinLen);
bool isT1Protocol();
bool isOwnConnection();
std::vector<std::string> getReadersList();
void deleteContext(void);
void resetCurrentConnection();
};
class CardError: public std::runtime_error
{
const CardError operator=(const CardError &);
public:
const byte SW1,SW2;
std::string desc;
CardError(byte a,byte b);
virtual const char * what() const throw() { return desc.c_str();}
virtual ~CardError() throw(){};
};
/// Exception class thrown when unexpected or inconistent data is read from card
class CardDataError: public std::runtime_error
{
public:
CardDataError( std::string p):runtime_error(p) {}
};
/// Exception class for authentication errors, like wrong PIN input etc.
class AuthError :public CardError
{
public:
//FIXME: Refactor to enum and single variable. IB-2880
bool m_blocked;
bool m_badinput;
bool m_aborted;
bool m_timeout;
AuthError(byte a,byte b) : CardError(a,b), m_blocked(false),m_badinput(false),m_aborted(false) {};
AuthError(byte a,byte b,bool block) : CardError(a,b), m_blocked(block),m_badinput(false),m_aborted(false) {};
AuthError(CardError _base) : CardError(_base) , m_blocked(false),m_badinput(false),m_aborted(false) {}
};
#endif