def getCRT(self): """ Build CRT (B6 TLV) for token calculation""" data = '' for t in Token.CRTtags: if t in self.__dict__: data += unhexlify(t[1:]) + derLV(self.__dict__[t]) if data: return '\xB6' + derLV(data) else: return ''
def _doDelete(self, aid, P2, token): """ Build delete APDU (either package or instance) token - instance of Token, calculates token for Delegated management if present""" data = '\x4F' + derLV(aid) if token: data += token.getCRT() data2sign = pack("BBB", 0, P2, len(data)) + data data += '\x9E' + derLV(token.calc(data2sign)) apdu = [0x80, INS_DELETE, 0, P2, len(data)] + s2l(data) return apdu
def install_extradict(self, aid_sd, token=None): """ Build install for extradiction APDU aid_sd - AID of SD to extradite to/from token - instance of Token, calculates token for Delegated management if present """ assert 5 <= len(aid_sd) and len(aid_sd) <= 16 AID_inst = getattr(self, 'AID_instance', self.AID_module) params = token and token.getCRT() or '' data = derLV(aid_sd) + '\0' + derLV(AID_inst) + '\0' + derLV(params) if token: data2sign = pack("BBB", P1_INST_EXTRA, 0, len(data)) + data data += derLV(token.calc(data2sign)) else: data += '\0' assert len(data) < 0x100, "Data longer than 0xFF: 0x%X '%s'" % \ (len(data), hexlify(data).upper()) apdu = [0x80, INS_INSTALL, P1_INST_EXTRA, 0, len(data)] + s2l(data) return apdu
def install_inst(self, token=None): """ Build Install for install APDU. token - instance of Token, calculates token for Delegated management if present""" privileges = getattr(self, 'privileges', '\0') sys_spec_par = ''.join( getattr(self, 'par_sys', [unhexlify("C7020000"), unhexlify("C8020000")])) if 'par_sys_sim' in self.__dict__: sys_spec_par += '\xCA' + derLV(self.par_sys_sim) sys_spec_par = '\xEF' + derLV(sys_spec_par) app_spec_par = 'par_applet' in self.__dict__ \ and self.par_applet or '' app_spec_par = '\xC9' + derLV(app_spec_par) uicc_spec = [] if 'par_UICC_toolkit' in self.__dict__: uicc_spec.append('\x80' + derLV(self.par_UICC_toolkit)) if 'par_UICC_DAP' in self.__dict__: uicc_spec.append('\xC3' + derLV(self.par_UICC_DAP)) if 'par_UICC_access' in self.__dict__: uicc_spec.append('\x81' + derLV(self.par_UICC_access)) if 'par_UICC_admin_access' in self.__dict__: uicc_spec.append('\x82' + derLV(self.par_UICC_admin_access)) if uicc_spec: uicc_sys_par = '\xEA' + derLV(''.join(uicc_spec)) else: uicc_sys_par = '' AID_inst = getattr(self, 'AID_instance', self.AID_module) params = app_spec_par + sys_spec_par + uicc_sys_par if token: params += token.getCRT() data = derLV(self.AID_package) + \ derLV(self.AID_module) + \ derLV(AID_inst) + \ derLV(privileges) + \ derLV(params) if token: data2sign = pack("BBB", P1_INST_INSMSEL, 0, len(data)) + data data += derLV(token.calc(data2sign)) else: data += '\0' assert len(data) < 0x100, "Data longer than 0xFF: 0x%X '%s'" % \ (len(data), hexlify(data).upper()) apdu = [0x80, INS_INSTALL, P1_INST_INSMSEL, 0, len(data)] + s2l(data) return apdu
def install_perso(self): """ Build install for perso APDU """ AID_inst = getattr(self, 'AID_instance', self.AID_module) data = '\0\0' + derLV(AID_inst) + '\0\0\0' apdu = [0x80, INS_INSTALL, P1_INST_PERSO, 0, len(data)] + s2l(data) return apdu
def load(self, datalen=239, token=None, DAP=[], cipher=None, AID_SD=''): """ Build list of APDUs for InstallForLoad and Load. datalen - data length in Load APDUs token - instance of Token, calculates token for Delegated management if present DAP - list of (aid, signature_function). For each item, E2 TLV is inserted (each signature_function called on LFDB hash). Example of signature_function: DESsign.calc or RSAsign.calc cipher - cipher function for Ciphere Load File Data Block if present, D4#(cipher(<ijc content>)) sent instead of C4 AID_SD - AID of SD to load package to """ f = open(self.file_ijc, "rb") ijc_data = f.read() ijc_len = len(ijc_data) h = hashlib.new('sha1') h.update(ijc_data) ijc_hash = h.digest() print "Loading '%s', len = %d, SHA1 = %s" % \ (self.file_ijc, ijc_len, hexlify(ijc_hash).upper()) # build Install for load APDU sysparams = ''.join( getattr(self, 'par_sysLoad', [ unhexlify("C6020000"), unhexlify("C7020000"), unhexlify("C8020000") ])) params = '\xEF' + derLV(sysparams) if token: params += token.getCRT() # put ijc hash only if token or DAP is present ins_hash = (token is not None or len(DAP) > 0) and ijc_hash or '' data = derLV(self.AID_package) + \ derLV(AID_SD) + \ derLV(ins_hash) + \ derLV(params) if token: data2sign = pack("BBB", P1_INST_LOAD, 0, len(data)) + data data += derLV(token.calc(data2sign)) else: data += '\0' assert len(data) < 0x100, "Data longer than 0xFF: 0x%X '%s'" % \ (len(data), hexlify(data).upper()) apdus = [[0x80, INS_INSTALL, 2, 0, len(data)] + s2l(data)] # build Load APDUs GP CS 2.2.1 11.6.2.3 load_data = '' E2template = GAF("E2 #(4F #($aid) C3 #($sig))") for d in DAP: sig = d[1](ijc_hash) # calculate signature load_data += E2template.eval(aid=d[0], sig=sig) if cipher: load_data += '\xD4' + derLV(cipher(ijc_data)) else: load_data += '\xC4' + derLV(ijc_data) napdu = (len(load_data) + datalen - 1) / datalen P1 = 0 for i in xrange(napdu): if i == napdu - 1: # the last block P1 = 0x80 datalen = len(load_data) apdus.append([0x80, INS_LOAD, P1, i, datalen] + s2l(load_data[:datalen])) load_data = load_data[datalen:] return apdus
def parseTPDU(self, tpdu): """ Parse TPDU from Envelope SMS-PP download 'D1', accumulate """ MTI = ord(tpdu[0]) ndig = ord(tpdu[1]) off = (ndig + 7) / 2 OA = tpdu[1:off] PID, DCS = [ord(x) for x in tpdu[off:off + 2]] SCTS = tpdu[off + 2:off + 9] assert len(tpdu) == off + 10 + ord(tpdu[off+9]), \ "Wrong UDL %d" % ord(tpdu[off+9]) off += 10 if MTI & 0x40: # UDH present noff = off + 1 + ord(tpdu[off]) UDH = tpdu[off + 1:noff] off = noff # split UDH to IE IE = [] o = 0 while o < len(UDH): try: l = ord(UDH[1]) IE.append(UDH[o:o + l + 2]) o += l + 2 except Exception: raise AssertionError("Mismatched UDH " + hexlify(UDH).upper()) # find concat IE concatUDH = [ u for u in IE if ord(u[0]) in (IEI_CONCAT8b, IEI_CONCAT16b) ] otherUDH = [ u for u in IE if ord(u[0]) not in (IEI_CONCAT8b, IEI_CONCAT16b) ] assert len(concatUDH) <= 1, "More than 1 concat IE" if len(concatUDH) == 0: self.UDH = UDH self.nMes = 1 self.messages[1] = tpdu[off:] return UDH = derLV(''.join(otherUDH)) concatIE = concatUDH[0] assert ord(concatIE[0]) in (IEI_CONCAT8b, IEI_CONCAT16b) zConc8b = ord(concatIE[0]) == IEI_CONCAT8b if zConc8b: assert len(concatIE) == 5, "Wrong Concat 8b IE" concRef, nMes, iMes = unpack("BBB", concatIE[2:]) else: assert len(concatIE) == 6, "Wrong Concat 16b IE" concRef, nMes, iMes = unpack(">HBB", concatIE[2:]) if self.messages: for i in ('MTI', 'OA', 'PID', 'DCS', 'SCTS', 'zConc8b', 'concRef', 'nMes'): if self.__dict__[i] != locals()[i]: print "Parameter %s changed: '%s' -> '%s'" % \ (i, self.__dict__[i].__str__(), locals()[i].__str__()) if iMes in self.messages: print "Duplicate message %d, ignored" % iMes else: # the first (or the only) message self.MTI, self.OA, self.PID, self.DCS, self.SCTS = \ MTI, OA, PID, DCS, SCTS self.zConc8b, self.concRef, self.nMes = zConc8b, concRef, nMes if iMes == 1: self.UDH = UDH self.messages[iMes] = tpdu[off:] else: # UDH not present self.UDH = '' self.nMes = 1 self.messages[1] = tpdu[off:]