def get_options(self, pdol_req, dol=None): if dol is None: dol = DOL() pdol = dol.get_dol(pdol_req) # FIXME: make the dol have a todata function which returns 0x83... resp = self.send(APDU(0x80, 0xa8, data=[0x83, len(pdol)] + pdol)) return self.BER(resp)
def read_record(self, record, sfi=None, which='index'): if sfi is None: sfi = 0 which = [ 'first', 'last', 'next', 'prev', 'index', 'indexfrom', 'indexto' ].index(which) resp = self.send(APDU(0, 0xb2, record, (sfi << 3) + which)) return resp
def generate_ac(self, type='aac'): #, cdol_req, data): # priority order is tc (transaction certificate), arqc (auth req), aac (app authentication - declined), aar p1 = ['aac', 'tc', 'arqc', 'aar'].index(type) * 0x40 #cdol_req = [(0x9f6a, 0x04)] #cdol = self.create_dol(cdol_req) #cdol = [0, 0, 0, 0, 1, 0] + [0, 0, 0, 0, 0, 0] + [0x8, 0x26] + [0, 0, 0, 0] + [0x8, 0x26] + [0x10, 0x10, 0x10] + [0] + [0x12, 0x34, 0x56, 0x78] resp = self.send(APDU(0x80, 0xae, p1, data=cdol)) return self.BER(resp)
def brute_instrs(tag): instrs = [] for i in [0x0, 0x80]: for j in range(0x100): resp = tag.send(APDU(i, j)) if resp != [0x6d, 0]: instrs.append([i, j]) print 'Valid instructions: %s' % ', '.join(map(toHexString, instrs))
def select_by_df(self, pattern, which='first'): which = ['first', 'last', 'next', 'prev'].index(which) resp = self.send(APDU(0, 0xa4, 4, which, data=pattern)) ber = self.BER(resp) fci = ber['FCI'] fci_issuer = fci['FCI_ISSUER'] # FIXME: this should be a class or dict df = format_dfname(fci['DFNAME']) sfi = fci_issuer.getparsed('SFI') pdol_req = fci_issuer.getparsed('PDOL') return df, sfi, pdol_req
def verify(self, pin): if self.pin_tries is None: self.get_pin_tries() print 'PIN tries left: %s' % self.pin_tries if not self.pin_tries: raise EMVError('No PIN retries left') assert pin.isdigit() pinhex = pin + 'f' * 14 hexdata = '2%s' % len(pin) + pinhex[:14] resp = self.send(APDU(0, 0x20, 0x61, 0x80, data=toBytes(hexdata))) self.pin_tries = None return resp
def external_auth(self): resp = self.send(APDU(0, 0x82)) return self.BER(resp)
def get_data(self, tag): if isinstance(tag, basestring): tag = self.TAGS[tag] # Seems to work with either 0 or 0x80 for class resp = self.send(APDU(0x80, 0xca, tag >> 8, tag & 0xff)) return resp
def get_challenge(self, length): resp = self.send(APDU(0, 0x84, data=[0] * length)) return self.BER(resp)
def select_by_id(self, type=0, id=None): # Doesn't seem to work if id is None: id = [] # or [0x3f, 0] resp = self.send(APDU(0, 0xa4, 0, type & 3, data=id)) return resp