def mut_auth(self, SL, logCh=0, **kw): """ Perform mutual authentication. Optional paramters in kw: - host_challenge """ # select SD self.scp.logCh = logCh aid = self.scp.SD_AID cla = self.scp.CLA(False, 0) apdu = [ cla, 0xA4, 0x04, 0, len( aid ) ] + \ [ ord( x ) for x in aid ] resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu) if sw1 == 0x61: apdu = [cla, 0xC0, 0, 0, sw2] resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) # Initial update host_challenge = kw.get('host_challenge', '\0' * 8) apdu = self.scp.initUpdate(host_challenge, logCh) resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu) if sw1 == 0x61: apdu = [cla, 0xC0, 0, 0, sw2] resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) # parse response to initial update in order to derive keys self.scp.parseInitUpdateResp(resp) # External authenticate apdu = self.scp.extAuth(SL) resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw)
def openLogCh(c): """ Manage channel to open logical channel. """ apdu = [0, INS_MANAGE_LOGCH, 0, 0, 1] resp, sw1, sw2 = c.transmit(apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) return resp[0]
def readBinary(c, le, logCh=0, offset=0): """Read Binary on currently selected EF""" P1 = (offset >> 8) & 0x7F P2 = offset & 0xFF apdu = [logCh, INS_READBIN, P1, P2, le] resp, sw1, sw2 = c.transmit(apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) return l2s(resp)
def readRecord(c, recNum, logCh=0): """ Read record from currently selected EF""" apdu = [logCh, INS_READREC, recNum, 4, 0] resp, sw1, sw2 = c.transmit(apdu) if sw1 == 0x6C: apdu[4] = sw2 resp, sw1, sw2 = c.transmit(apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) return l2s(resp)
def getData(c, tag): P1 = tag >> 8 P2 = tag & 0xFF apdu = [0x80, INS_GETDATA, P1, P2, 0] resp, sw1, sw2 = c.transmit(apdu) if sw1 == 0x6C: apdu[4] = sw2 resp, sw1, sw2 = c.transmit(apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) return l2s(resp)
def selectFile(c, path, logCh=0): """ Select file by path from MF or MF for empty path """ if len(path) > 0: apdu = [logCh, INS_SELECT, 8, 4, len(path)] + [ord(x) for x in path] else: apdu = [logCh, INS_SELECT, 0, 4, 2, 0x3F, 0x00] resp, sw1, sw2 = c.transmit(apdu) if sw1 == 0x61: resp, sw1, sw2 = c.transmit([0, 0xC0, 0, 0, sw2]) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) return l2s(resp)
def getExtCardRes(c): """ Issue GET DATA with tag FF21 in order to receive Extended Card Resources (GP 2.2.1, 11.3 & ETSI TS 102.226, 8.2.1.7). Returns [ num. of install applets, free NVM, free RAM ]""" # CLA = 0x00: return only value # CLA = 0x80: return TLV, i.e. 0xFF21 #( value ) apdu = [0x80, INS_GETDATA, 0xFF, 0x21, 0] resp, sw1, sw2 = c.transmit(apdu) if sw1 == 0x6C: apdu[4] = sw2 resp, sw1, sw2 = c.transmit(apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) payload = l2s(resp) result = [ s2int(findTLValue(payload, (0xFF21, tag))) for tag in (0x81, 0x82, 0x83) ] return result
def selectApplet(c, AID, logCh=0): """ Select applet on a given logical channel or open new log. channel if logCh is None. """ if logCh is None: logCh = openLogCh(c) # select the Applet on the given logical channel apdu = [logCh, INS_SELECT, 4, 0, len(AID)] + [ord(x) for x in AID] resp, sw1, sw2 = c.transmit(apdu) if sw1 == 0x6C and len(AID) == 0: apdu = [logCh, INS_SELECT, 4, 0, sw2] resp, sw1, sw2 = c.transmit(apdu) if (sw1 == 0x61): apdu = [logCh, 0xC0, 0, 0, sw2] resp, sw1, sw2 = c.transmit(apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) respdata = l2s(resp) # close channel return (respdata, logCh)
def getStatus(sc, AID_pref=''): """ Issue GET STATUS apdu for packages and modules, and instances. """ res = {} for P1 in (0x10, 0x40): apdu = [ 0x80, INS_GETSTATUS, P1, 0, 2 + len(AID_pref), 0x4F, len(AID_pref) ] + [ord(x) for x in AID_pref] respdata, sw1, sw2 = sc.transmit(apdu) sw = (sw1 << 8) + sw2 while sw == 0x6310: apdu = [ 0x80, INS_GETSTATUS, P1, 1, 2 + len(AID_pref), 0x4F, len(AID_pref) ] + [ord(x) for x in AID_pref] resp, sw1, sw2 = sc.transmit(apdu) respdata += resp sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw) res[P1] = respdata return GetStatusData(res[0x10], res[0x40])
def closeLogCh(c, logCh): apdu = [0, INS_MANAGE_LOGCH, 0x80, logCh, 0] resp, sw1, sw2 = c.transmit(apdu) sw = (sw1 << 8) + sw2 if sw != 0x9000: raise ISOException(sw)