Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | from smartcard.scard import * |
| 4 | import smartcard.util |
| 5 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 6 | import array |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 7 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 8 | class SmartcardException(Exception): |
| 9 | pass |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 10 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 11 | class SmartcardConnection: |
| 12 | # hcard, dwActiveProtocol, hcontext, reader |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 13 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 14 | def __init__(self): |
| 15 | self.establish_context() |
| 16 | self.connect_card() |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 17 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 18 | def connect_card(self): |
| 19 | hresult, self.hcard, self.dwActiveProtocol = SCardConnect(self.hcontext, self.reader, |
| 20 | SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) |
| 21 | if hresult != SCARD_S_SUCCESS: |
| 22 | raise SmartcardException('Unable to connect: ' + |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 23 | SCardGetErrorMessage(hresult)) |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 24 | print 'Connected with active protocol', self.dwActiveProtocol |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 25 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 26 | def establish_context(self): |
| 27 | hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) |
| 28 | if hresult != SCARD_S_SUCCESS: |
| 29 | raise SmartcardException('Failed to establish context : ' + |
| 30 | SCardGetErrorMessage(hresult)) |
| 31 | print 'Context established!' |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 32 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 33 | hresult, readers = SCardListReaders(self.hcontext, []) |
| 34 | if hresult != SCARD_S_SUCCESS: |
| 35 | raise SmartcardException('Failed to list readers: ' + |
| 36 | SCardGetErrorMessage(hresult)) |
| 37 | print 'PCSC Readers:', readers |
| 38 | |
| 39 | if len(readers) < 1: |
| 40 | raise SmartcardException('No smart card readers') |
| 41 | |
| 42 | self.reader = readers[0] |
| 43 | print "Using reader:", self.reader |
| 44 | |
| 45 | def release_context(self): |
| 46 | hresult = SCardReleaseContext(self.hcontext) |
| 47 | if hresult != SCARD_S_SUCCESS: |
| 48 | raise SmartcardException('Failed to release context: ' + |
| 49 | SCardGetErrorMessage(hresult)) |
| 50 | print 'Released context.' |
| 51 | |
| 52 | def send_receive_cmd(self, cmd): |
| 53 | print("Cmd: ") |
| 54 | hresult, resp = SCardTransmit(self.hcard, self.dwActiveProtocol, |
| 55 | cmd.tolist()) |
| 56 | if hresult != SCARD_S_SUCCESS: |
| 57 | raise SmartcardException('Failed to transmit: ' + |
| 58 | SCardGetErrorMessage(hresult)) |
| 59 | print 'Ans: ' + smartcard.util.toHexString(resp, |
| 60 | smartcard.util.HEX) |
| 61 | return array.array('B', resp) |
| 62 | |
| 63 | def disconnect_card(self): |
| 64 | hresult = SCardDisconnect(self.hcard, SCARD_UNPOWER_CARD) |
| 65 | if hresult != SCARD_S_SUCCESS: |
| 66 | raise SmartcardException('Failed to disconnect: ' + |
| 67 | SCardGetErrorMessage(hresult)) |
| 68 | print 'Disconnected' |
Christina Quast | 254acae | 2015-04-01 19:36:34 +0200 | [diff] [blame] | 69 | |
| 70 | |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 71 | def close(self): |
| 72 | self.disconnect_card() |
| 73 | self.release_context() |
Christina Quast | 097b218 | 2015-04-05 10:21:11 +0200 | [diff] [blame] | 74 | |
| 75 | |
| 76 | if __name__ == '__main__': |
Christina Quast | 5149cd6 | 2015-04-06 00:33:52 +0200 | [diff] [blame] | 77 | import constants |
| 78 | |
| 79 | sm_con = SmartcardConnection() |
| 80 | print(sm_con.send_receive_cmd(constants.CMD_SEL_ROOT)) |
| 81 | print(sm_con.send_receive_cmd(constants.CMD_SEL_FILE)) |
| 82 | print(sm_con.send_receive_cmd(constants.CMD_GET_DATA)) |
| 83 | sm_con.close() |