blob: 4447e3485a280a69e7c68ba520bbf9cb5a9ad23e [file] [log] [blame]
Christina Quast254acae2015-04-01 19:36:34 +02001#!/usr/bin/env python
2
3from smartcard.scard import *
4import smartcard.util
5
Christina Quast5149cd62015-04-06 00:33:52 +02006import array
Christina Quast254acae2015-04-01 19:36:34 +02007
Christina Quastf2e53f02015-04-11 08:42:38 +02008from util import HEX
9
Christina Quast5149cd62015-04-06 00:33:52 +020010class SmartcardException(Exception):
11 pass
Christina Quast254acae2015-04-01 19:36:34 +020012
Christina Quast5149cd62015-04-06 00:33:52 +020013class SmartcardConnection:
14# hcard, dwActiveProtocol, hcontext, reader
Christina Quast254acae2015-04-01 19:36:34 +020015
Christina Quast5149cd62015-04-06 00:33:52 +020016 def __init__(self):
17 self.establish_context()
18 self.connect_card()
Christina Quast254acae2015-04-01 19:36:34 +020019
Christina Quast51636242015-04-06 00:44:50 +020020 def getATR(self):
21 hresult, reader, state, protocol, atr = SCardStatus(self.hcard)
22 if hresult != SCARD_S_SUCCESS:
23 print 'failed to get status: ' + SCardGetErrorMessage(hresult)
24 print 'Reader:', reader
25 print 'State:', state
26 print 'Protocol:', protocol
Christina Quastf2e53f02015-04-11 08:42:38 +020027 print 'ATR:', HEX(atr)
Christina Quast7741f712015-04-06 19:06:05 +020028 return array.array('B', atr)
29
30 def reset_card(self):
31 hresult, self.dwActiveProtocol = SCardReconnect(self.hcard, SCARD_SHARE_SHARED,
32 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD)
33 if hresult != SCARD_S_SUCCESS:
34 raise SmartcardException('Unable to retrieve Atr: ' +
35 SCardGetErrorMessage(hresult))
Christina Quast51636242015-04-06 00:44:50 +020036
Christina Quast5149cd62015-04-06 00:33:52 +020037 def connect_card(self):
38 hresult, self.hcard, self.dwActiveProtocol = SCardConnect(self.hcontext, self.reader,
39 SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
40 if hresult != SCARD_S_SUCCESS:
41 raise SmartcardException('Unable to connect: ' +
Christina Quast254acae2015-04-01 19:36:34 +020042 SCardGetErrorMessage(hresult))
Christina Quast5149cd62015-04-06 00:33:52 +020043 print 'Connected with active protocol', self.dwActiveProtocol
Christina Quast254acae2015-04-01 19:36:34 +020044
Christina Quast5149cd62015-04-06 00:33:52 +020045 def establish_context(self):
46 hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
47 if hresult != SCARD_S_SUCCESS:
48 raise SmartcardException('Failed to establish context : ' +
49 SCardGetErrorMessage(hresult))
50 print 'Context established!'
Christina Quast254acae2015-04-01 19:36:34 +020051
Christina Quast5149cd62015-04-06 00:33:52 +020052 hresult, readers = SCardListReaders(self.hcontext, [])
53 if hresult != SCARD_S_SUCCESS:
54 raise SmartcardException('Failed to list readers: ' +
55 SCardGetErrorMessage(hresult))
56 print 'PCSC Readers:', readers
57
58 if len(readers) < 1:
59 raise SmartcardException('No smart card readers')
60
61 self.reader = readers[0]
62 print "Using reader:", self.reader
63
64 def release_context(self):
65 hresult = SCardReleaseContext(self.hcontext)
66 if hresult != SCARD_S_SUCCESS:
67 raise SmartcardException('Failed to release context: ' +
68 SCardGetErrorMessage(hresult))
69 print 'Released context.'
70
71 def send_receive_cmd(self, cmd):
Christina Quastf2e53f02015-04-11 08:42:38 +020072 print("Cmd to SIM: " + HEX(cmd))
Christina Quast5149cd62015-04-06 00:33:52 +020073 hresult, resp = SCardTransmit(self.hcard, self.dwActiveProtocol,
74 cmd.tolist())
75 if hresult != SCARD_S_SUCCESS:
76 raise SmartcardException('Failed to transmit: ' +
77 SCardGetErrorMessage(hresult))
Christina Quastf2e53f02015-04-11 08:42:38 +020078 print 'SIM Ans: ' + HEX(resp)
Christina Quast5149cd62015-04-06 00:33:52 +020079 return array.array('B', resp)
80
81 def disconnect_card(self):
82 hresult = SCardDisconnect(self.hcard, SCARD_UNPOWER_CARD)
83 if hresult != SCARD_S_SUCCESS:
84 raise SmartcardException('Failed to disconnect: ' +
85 SCardGetErrorMessage(hresult))
86 print 'Disconnected'
Christina Quast254acae2015-04-01 19:36:34 +020087
88
Christina Quast5149cd62015-04-06 00:33:52 +020089 def close(self):
90 self.disconnect_card()
91 self.release_context()
Christina Quast097b2182015-04-05 10:21:11 +020092
93
94if __name__ == '__main__':
Christina Quast5149cd62015-04-06 00:33:52 +020095 import constants
96
97 sm_con = SmartcardConnection()
Christina Quast51636242015-04-06 00:44:50 +020098 sm_con.getATR()
Christina Quast5149cd62015-04-06 00:33:52 +020099 print(sm_con.send_receive_cmd(constants.CMD_SEL_ROOT))
100 print(sm_con.send_receive_cmd(constants.CMD_SEL_FILE))
101 print(sm_con.send_receive_cmd(constants.CMD_GET_DATA))
102 sm_con.close()