| #!/usr/bin/env python |
| |
| from smartcard.scard import * |
| import smartcard.util |
| |
| import array |
| |
| from util import HEX |
| |
| class SmartcardException(Exception): |
| pass |
| |
| class SmartcardConnection: |
| # hcard, dwActiveProtocol, hcontext, reader |
| |
| def __init__(self): |
| self.establish_context() |
| self.connect_card() |
| |
| def getATR(self): |
| hresult, reader, state, protocol, atr = SCardStatus(self.hcard) |
| if hresult != SCARD_S_SUCCESS: |
| print 'failed to get status: ' + SCardGetErrorMessage(hresult) |
| print 'Reader:', reader |
| print 'State:', state |
| print 'Protocol:', protocol |
| print 'ATR:', HEX(atr) |
| return array.array('B', atr) |
| |
| def reset_card(self): |
| hresult, self.dwActiveProtocol = SCardReconnect(self.hcard, SCARD_SHARE_SHARED, |
| SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD) |
| if hresult != SCARD_S_SUCCESS: |
| raise SmartcardException('Unable to retrieve Atr: ' + |
| SCardGetErrorMessage(hresult)) |
| |
| def connect_card(self): |
| hresult, self.hcard, self.dwActiveProtocol = SCardConnect(self.hcontext, self.reader, |
| SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) |
| if hresult != SCARD_S_SUCCESS: |
| raise SmartcardException('Unable to connect: ' + |
| SCardGetErrorMessage(hresult)) |
| print 'Connected with active protocol', self.dwActiveProtocol |
| |
| def establish_context(self): |
| hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) |
| if hresult != SCARD_S_SUCCESS: |
| raise SmartcardException('Failed to establish context : ' + |
| SCardGetErrorMessage(hresult)) |
| print 'Context established!' |
| |
| hresult, readers = SCardListReaders(self.hcontext, []) |
| if hresult != SCARD_S_SUCCESS: |
| raise SmartcardException('Failed to list readers: ' + |
| SCardGetErrorMessage(hresult)) |
| print 'PCSC Readers:', readers |
| |
| if len(readers) < 1: |
| raise SmartcardException('No smart card readers') |
| |
| self.reader = readers[0] |
| print "Using reader:", self.reader |
| |
| def release_context(self): |
| hresult = SCardReleaseContext(self.hcontext) |
| if hresult != SCARD_S_SUCCESS: |
| raise SmartcardException('Failed to release context: ' + |
| SCardGetErrorMessage(hresult)) |
| print 'Released context.' |
| |
| def send_receive_cmd(self, cmd): |
| print("Cmd to SIM: " + HEX(cmd)) |
| hresult, resp = SCardTransmit(self.hcard, self.dwActiveProtocol, |
| cmd.tolist()) |
| if hresult != SCARD_S_SUCCESS: |
| raise SmartcardException('Failed to transmit: ' + |
| SCardGetErrorMessage(hresult)) |
| print 'SIM Ans: ' + HEX(resp) |
| return array.array('B', resp) |
| |
| def disconnect_card(self): |
| hresult = SCardDisconnect(self.hcard, SCARD_UNPOWER_CARD) |
| if hresult != SCARD_S_SUCCESS: |
| raise SmartcardException('Failed to disconnect: ' + |
| SCardGetErrorMessage(hresult)) |
| print 'Disconnected' |
| |
| |
| def close(self): |
| self.disconnect_card() |
| self.release_context() |
| |
| |
| if __name__ == '__main__': |
| import constants |
| |
| sm_con = SmartcardConnection() |
| sm_con.getATR() |
| print(sm_con.send_receive_cmd(constants.CMD_SEL_ROOT)) |
| print(sm_con.send_receive_cmd(constants.CMD_SEL_FILE)) |
| print(sm_con.send_receive_cmd(constants.CMD_GET_DATA)) |
| sm_con.close() |