def readFileData(self, file): sw1, sw2, data = self.readFile(file) if types.assertSw(sw1, sw2, checkSw='NO_ERROR'): return None if not isinstance(data[0], list): str = "%s" %hextools.bytes2hex(data) else: str = '' for record in data: str += "%s;" %hextools.bytes2hex(record) str.strip(";") return str
def readFileData(self, file): sw1, sw2, data = self.readFile(file) if types.assertSw(sw1, sw2, checkSw='NO_ERROR'): return None if not isinstance(data[0], list): str = "%s" % hextools.bytes2hex(data) else: str = '' for record in data: str += "%s;" % hextools.bytes2hex(record) str.strip(";") return str
def setEfEcc(self, data): data = data.split(';') dataNew = '' for record in data: number = types.getParamValue(record, "number") if not number: return False category = types.getParamValue(record, "cat") number = number.replace('F','') if number: numberBcd = hextools.encode_BCD(number) numberBcd = hextools.bytes2hex(numberBcd) numberBcd = types.addTrailingBytes(numberBcd, 0xFF, 3) else: numberBcd = "FFFFFF" dataTmp = numberBcd if category: raise Exception("Not implemented") #TODO: move it to the last byte dataTmp += "%02X" %int(category) if dataNew: dataNew = "%s;%s" %(dataNew, dataTmp) else: dataNew = dataTmp return dataNew
def setEfOpl(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue mccMnc = types.getParamValue(record, "mcc_mnc") if not mccMnc: raise Exception("mcc_mnc not provided") if len(mccMnc) != 6: mnc3 = 'F' else: mnc3 = mccMnc[5] mccMnc = "%s%s%s" % (mccMnc[0:3], mnc3, mccMnc[3:5]) lacRange = types.getParamValue(record, "lac") if not lacRange: lacRange = '0000-FFFE' lacStart = lacRange.split("-")[0] lacEnd = lacRange.split("-")[1] pnnId = int(types.getParamValue(record, "pnnId"), 16) lai = "%s%04X%04X" % (hextools.bytes2hex( hextools.encode_BCD(mccMnc)), int(lacStart, 16), int( lacEnd, 16)) dataNew += "%s%02X;" % (lai, pnnId) return dataNew
def setEfEcc(self, data): data = data.split(';') dataNew = '' for record in data: number = types.getParamValue(record, "number") if not number: return False category = types.getParamValue(record, "cat") number = number.replace('F', '') if number: numberBcd = hextools.encode_BCD(number) numberBcd = hextools.bytes2hex(numberBcd) numberBcd = types.addTrailingBytes(numberBcd, 0xFF, 3) else: numberBcd = "FFFFFF" dataTmp = numberBcd if category: raise Exception("Not implemented") #TODO: move it to the last byte dataTmp += "%02X" % int(category) if dataNew: dataNew = "%s;%s" % (dataNew, dataTmp) else: dataNew = dataTmp return dataNew
def tick(self): with self.lock: inject = INJECT_READY evt, apdu = self.receiveCommandApdu() if evt == EVT_RESET: self.resetCards() return if not apdu: if (not self.inject or self.rapduInject): # Wait until rapduInject is consumed return else: inject = self.inject apdu = self.apduInjectedData self.apduInjectedData = None if not apdu: raise Exception("APDU is empty") self.lastUpdate = time.time() cardsData = self.getHandlers(apdu, inject) responseApdu = None for cardData in cardsData: if cardData == cardsData[0]: apduHex = hextools.bytes2hex(apdu) self.loggingApdu.info("") self.loggingApdu.info("C-APDU%d: %s" %(self.getSimId(cardData[0]), apduHex)) responseApduTemp = self.handleApdu(cardData, apdu) if cardData[1]: if cardData[0] != self.getMainCard(0): self.loggingApdu.info("*R-APDU%d" %self.getSimId(cardData[0])) responseApdu = responseApduTemp self.updateHandler(cardData, apdu, responseApduTemp) if not responseApdu and not inject: raise Exception("No response received") if inject: self.rapduInject = responseApduTemp
def getEfPcscf(self, data): #TODO: handle many records firstRecord = data.split(';')[0] value = types.removeTrailingBytes(hextools.hex2bytes(firstRecord), 0xFF) if len(value) < 3: return '' cscf = hextools.bytes2hex(value[3:]).decode("hex") return "cscf=%s" %cscf
def getEfSpn(self, data): spnRaw = types.removeTrailingBytes(hextools.hex2bytes(data), 0xFF) if spnRaw: displayByte = spnRaw[0] name = hextools.bytes2hex(spnRaw[1:]).decode("hex") else: return '' return "name=%s,display=%02X" % (name, displayByte)
def getEfSpn(self, data): spnRaw = types.removeTrailingBytes(hextools.hex2bytes(data), 0xFF) if spnRaw: displayByte = spnRaw[0] name = hextools.bytes2hex(spnRaw[1:]).decode("hex") else: return '' return "name=%s,display=%02X" %(name, displayByte)
def getEfPnn(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue binRecord = hextools.hex2bytes(record) if binRecord.count(0xFF) == len(binRecord): continue fullNameRaw = types.parseTlv(binRecord, types.FULL_NW_NAME_TAG) shortNameRaw = types.parseTlv(binRecord, types.SHORT_NW_NAME_TAG) additionalInfo = types.parseTlv( binRecord, types.ADDITIONAL_INFORMATION_PLMN_TAG) if fullNameRaw: infoByte = fullNameRaw[0] spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception( "Only GSM coding is supported in DCS, current coding: %02X" % dcs) fullName = coder.decodeGsm7(hextools.bytes2hex( fullNameRaw[1:])) else: fullName = None if shortNameRaw: infoByte = shortNameRaw[0] spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception( "Only GSM coding is supported in DCS, current coding: %02X" % dcs) shortName = coder.decodeGsm7( hextools.bytes2hex(shortNameRaw[1:])) else: shortName = None dataNew += "full_name=%s,short_name=%s"\ %(fullName, shortName) if additionalInfo: dataNew += ",additional_info=%s" % additionalInfo dataNew += ";" return dataNew
def setEfImsi(self, imsi): if len(imsi) % 2: dataLow = 9 else: dataLow = 1 firstByte = dataLow<<4 | int(imsi[0], 16) imsi = "%02X%s" %(firstByte, imsi[1:]) imsi = hextools.encode_BCD(imsi) return "08%s" %hextools.bytes2hex(imsi)
def getEfPcscf(self, data): #TODO: handle many records firstRecord = data.split(';')[0] value = types.removeTrailingBytes(hextools.hex2bytes(firstRecord), 0xFF) if len(value) < 3: return '' cscf = hextools.bytes2hex(value[3:]).decode("hex") return "cscf=%s" % cscf
def setEfImsi(self, imsi): if len(imsi) % 2: dataLow = 9 else: dataLow = 1 firstByte = dataLow << 4 | int(imsi[0], 16) imsi = "%02X%s" % (firstByte, imsi[1:]) imsi = hextools.encode_BCD(imsi) return "08%s" % hextools.bytes2hex(imsi)
def setImsi(self, imsi): if len(imsi) % 2: dataLow = 9 else: dataLow = 1 firstByte = dataLow << 4 | int(imsi[0], 16) imsi = "%02X%s" % (firstByte, imsi[1:]) imsi = hextools.encode_BCD(imsi) imsi = "08%s" % hextools.bytes2hex(imsi) return self.writeFileBinary("6F07", imsi)
def setImsi(self, imsi): if len(imsi) % 2: dataLow = 9 else: dataLow = 1 firstByte = dataLow<<4 | int(imsi[0], 16) imsi = "%02X%s" %(firstByte, imsi[1:]) imsi = hextools.encode_BCD(imsi) imsi = "08%s" %hextools.bytes2hex(imsi) return self.writeFileBinary("6F07", imsi)
def setEfPnn(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue tmpData = [] infoFull = types.getParamValue(record, "info_full") fullName = types.getParamValue(record, "full_name") infoShort = types.getParamValue(record, "info_short") shortName = types.getParamValue(record, "short_name") additionalInfo = types.getParamValue(record, "additional_info") if fullName: fullNameGsm7 = coder.encodeGsm7(fullName) if infoFull: infoByte = int(infoFull, 16) spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception("Only GSM coding is supported in DCS") ext = infoByte >> 7 & 0b00000001 else: spareBits = len(fullName) % 8 ci = 0 #don't add the letters for the Country's Initials dcs = 0 #GSM ext = 1 #? infoByte = ext << 7 | dcs << 3 | ci << 2 | spareBits fullNameGsm7 = "%02X%s" % (infoByte, fullNameGsm7) types.addTlv(tmpData, types.FULL_NW_NAME_TAG, hextools.hex2bytes(fullNameGsm7)) if shortName: shortNameGsm7 = coder.encodeGsm7(shortName) if infoShort: infoByte = int(infoShort, 16) spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception("Only GSM coding is supported in DCS") ext = infoByte >> 7 & 0b00000001 else: spareBits = len(shortName) % 8 ci = 0 #don't add the letters for the Country's Initials dcs = 0 #GSM ext = 1 #? infoByte = ext << 7 | dcs << 3 | ci << 2 | spareBits shortNameGsm7 = "%02X%s" % (infoByte, shortNameGsm7) types.addTlv(tmpData, types.SHORT_NW_NAME_TAG, hextools.hex2bytes(shortNameGsm7)) if additionalInfo: types.addTlv(tmpData, types.ADDITIONAL_INFORMATION_PLMN_TAG, hextools.hex2bytes(additionalInfo)) dataNew += "%s;" % hextools.bytes2hex(tmpData) return dataNew
def getEfLoci(self, data): valueRaw = hextools.hex2bytes(data) tmsi = hextools.bytes2hex(valueRaw[0:4]) lai = hextools.bytes2hex(valueRaw[4:9]) #TODO: check for mnc containing 3digits mcc_mnc = hextools.decode_BCD(hextools.hex2bytes(lai)[0:3]) lac = lai[6:10] rfu = hextools.bytes2hex([valueRaw[9]]) loction_status = hextools.bytes2hex([valueRaw[10]]) ''' loction_status Bits: b3 b2 b1 0 0 0 : updated. 0 0 1 : not updated. 0 1 0 : PLMN not allowed. 0 1 1 : Location Area not allowed. 1 1 1 : reserved ''' return "tmsi=%s,mcc_mnc=%s,lac=%s,loc_status=%s"\ %(tmsi, mcc_mnc, lac, loction_status)
def getEfImpu(self, data): impuStr = '' data = data.split(';') for record in data: value = types.removeTrailingBytes(hextools.hex2bytes(record), 0xFF) if len(value) < 3: continue if impuStr: impuStr += ";" impuStr += hextools.bytes2hex(value[2:]).decode("hex") return impuStr
def apdu(self, c_apdu): c_apdu = hextools.bytes(c_apdu) # Delegate try: (data,sw1,sw2) = self.simReader.c_transmit(list(c_apdu), self.index) except Exception as e: #TODO: Remove printing the error. Check why exception is not printed in tes_sat logging.error(str(e) + "\n\n") raise Exception("Failed to transmit C_APDU: " + hextools.bytes2hex(c_apdu) + "\n" + str(e)) self.updateSwNoError(sw1, sw2) return pack(data,sw1,sw2)
def onUssdSendCallback2(self, status, respData, handlerData): if status and 'result' in status.keys(): error = general_result[status['result']] else: error = None if not self.statusOk(status, error) or not respData: return dcs = respData.pop(0) # dcs - Data Coding Style text = coder.decodeGsm7(hextools.bytes2hex(respData)) #response = data self.displayText(text)
def setEfPnn(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue tmpData = [] infoFull = types.getParamValue(record, "info_full") fullName = types.getParamValue(record, "full_name") infoShort = types.getParamValue(record, "info_short") shortName = types.getParamValue(record, "short_name") additionalInfo = types.getParamValue(record, "additional_info") if fullName: fullNameGsm7 = coder.encodeGsm7(fullName) if infoFull: infoByte = int(infoFull, 16) spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception("Only GSM coding is supported in DCS") ext = infoByte >> 7 & 0b00000001 else: spareBits = len(fullName) % 8 ci = 0 #don't add the letters for the Country's Initials dcs = 0 #GSM ext = 1 #? infoByte = ext << 7 | dcs << 3 | ci << 2 | spareBits fullNameGsm7 = "%02X%s" %(infoByte, fullNameGsm7) types.addTlv(tmpData, types.FULL_NW_NAME_TAG, hextools.hex2bytes(fullNameGsm7)) if shortName: shortNameGsm7 = coder.encodeGsm7(shortName) if infoShort: infoByte = int(infoShort, 16) spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception("Only GSM coding is supported in DCS") ext = infoByte >> 7 & 0b00000001 else: spareBits = len(shortName) % 8 ci = 0 #don't add the letters for the Country's Initials dcs = 0 #GSM ext = 1 #? infoByte = ext << 7 | dcs << 3 | ci << 2 | spareBits shortNameGsm7 = "%02X%s" %(infoByte, shortNameGsm7) types.addTlv(tmpData, types.SHORT_NW_NAME_TAG, hextools.hex2bytes(shortNameGsm7)) if additionalInfo: types.addTlv(tmpData, types.ADDITIONAL_INFORMATION_PLMN_TAG, hextools.hex2bytes(additionalInfo)) dataNew += "%s;" %hextools.bytes2hex(tmpData) return dataNew
def setEfUst(self, data): ustTable = data ustRaw = [] for i, bitValue in enumerate(ustTable): byteId = i / 8 bitId = i % 8 if len(ustRaw) <= byteId: ustRaw.append(0x00) if bitValue: ustRaw[byteId] |= (1 << bitId) else: ustRaw[byteId] &= ~(1 << bitId) return hextools.bytes2hex(ustRaw)
def getEfPnn(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue binRecord = hextools.hex2bytes(record) if binRecord.count(0xFF) == len(binRecord): continue fullNameRaw = types.parseTlv(binRecord, types.FULL_NW_NAME_TAG) shortNameRaw = types.parseTlv(binRecord, types.SHORT_NW_NAME_TAG) additionalInfo = types.parseTlv(binRecord, types.ADDITIONAL_INFORMATION_PLMN_TAG) if fullNameRaw: infoByte = fullNameRaw[0] spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception("Only GSM coding is supported in DCS, current coding: %02X" %dcs) fullName = coder.decodeGsm7(hextools.bytes2hex(fullNameRaw[1:])) else: fullName = None if shortNameRaw: infoByte = shortNameRaw[0] spareBits = infoByte & 0b00000111 ci = infoByte >> 3 & 0b00000001 dcs = infoByte >> 4 & 0b00000111 if dcs != 0x00: raise Exception("Only GSM coding is supported in DCS, current coding: %02X" %dcs) shortName = coder.decodeGsm7(hextools.bytes2hex(shortNameRaw[1:])) else: shortName = None dataNew += "full_name=%s,short_name=%s"\ %(fullName, shortName) if additionalInfo: dataNew += ",additional_info=%s" %additionalInfo dataNew += ";" return dataNew
def fileName(self, apdu): if types.p1(apdu) != types.SELECT_BY_DF_NAME: fid = types.fileId(apdu) fid = "%04X" %fid if fid == "7FFF": return "ADF" try: fileName = self.simCtrl.simFiles.getNameFromFid(fid) except: #TODO: try to remove fileName = fid else: # AID fileName = hextools.bytes2hex(types.aid(apdu)) #'A000' return fileName
def fileName(self, apdu): if types.p1(apdu) != types.SELECT_BY_DF_NAME: fid = types.fileId(apdu) fid = "%04X" % fid if fid == "7FFF": return "ADF" try: fileName = self.simCtrl.simFiles.getNameFromFid(fid) except: #TODO: try to remove fileName = fid else: # AID fileName = hextools.bytes2hex(types.aid(apdu)) #'A000' return fileName
def updateHandler(self, cardData, apdu, rapdu): if ( self.aidCommon(cardData[0]) and not cardData[0].routingAttr.aidToSelect and cardData[0].routingAttr.getFileSelected(apdu[0]) == 'EF_DIR' and types.insName(apdu) == 'READ_RECORD' and len(rapdu) > 3 and rapdu[3] != 0xFF and types.swNoError(rapdu)): # keep the same class - apdu[0], change length and avalue of selected AID cardData[0].routingAttr.aidToSelect = "%02XA40404%s" %(apdu[0], hextools.bytes2hex(rapdu[3 : (rapdu[3] + 4)])) if types.sw1(rapdu) in [types_g.sw1.RESPONSE_DATA_AVAILABLE_2G, types_g.sw1.RESPONSE_DATA_AVAILABLE_3G]: # cache 'GET_RESPONSE' getResponseLength = types.sw2(rapdu) cla = apdu[0] apdu = "%02XC00000%02X" %(cla, getResponseLength) cardData[0].routingAttr.getResponse = cardData[0].apdu(apdu)
def getEfOpl(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue binRecord = hextools.hex2bytes(record) if binRecord.count(0xFF) == len(binRecord): continue lai = hextools.bytes2hex(binRecord[0:7]) mccMnc = hextools.decode_BCD(hextools.hex2bytes(lai)[0:3]) lacStart = lai[6:10] lacEnd = lai[10:14] lacRange = "%s-%s" %(lacStart, lacEnd) pnnId = binRecord[7] dataNew += "mcc_mnc=%s,lac=%s,pnnId=%d;" %(mccMnc, lacRange, pnnId) return dataNew
def receiveCommandApdu(self): msg = [] # FIXME: This is the main event loop. Move it to top level. msg = list(self.receiveData(CMD_POLL)) if not len(msg): return None, None data = None evt = msg[0] if evt == EVT_C_APDU: data = msg[4:] elif evt == EVT_RESET: pass elif evt == EVT_UNKNOWN: return None, None else: self.loggingApdu.info("unknown event: %s\n" % hextools.bytes2hex(msg)) return (evt, data)
def getEfOpl(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue binRecord = hextools.hex2bytes(record) if binRecord.count(0xFF) == len(binRecord): continue lai = hextools.bytes2hex(binRecord[0:7]) mccMnc = hextools.decode_BCD(hextools.hex2bytes(lai)[0:3]) lacStart = lai[6:10] lacEnd = lai[10:14] lacRange = "%s-%s" % (lacStart, lacEnd) pnnId = binRecord[7] dataNew += "mcc_mnc=%s,lac=%s,pnnId=%d;" % (mccMnc, lacRange, pnnId) return dataNew
def updateHandler(self, cardData, apdu, rapdu): if (self.aidCommon(cardData[0]) and not cardData[0].routingAttr.aidToSelect and cardData[0].routingAttr.getFileSelected(apdu[0]) == 'EF_DIR' and types.insName(apdu) == 'READ_RECORD' and len(rapdu) > 3 and rapdu[3] != 0xFF and types.swNoError(rapdu)): # keep the same class - apdu[0], change length and avalue of selected AID cardData[0].routingAttr.aidToSelect = "%02XA40404%s" % ( apdu[0], hextools.bytes2hex(rapdu[3:(rapdu[3] + 4)])) if types.sw1(rapdu) in [ types_g.sw1.RESPONSE_DATA_AVAILABLE_2G, types_g.sw1.RESPONSE_DATA_AVAILABLE_3G ]: # cache 'GET_RESPONSE' getResponseLength = types.sw2(rapdu) cla = apdu[0] apdu = "%02XC00000%02X" % (cla, getResponseLength) cardData[0].routingAttr.getResponse = cardData[0].apdu(apdu)
def setEfLoci(self, data): param = "tmsi" tmsi = types.getParamValue(data, param) if not tmsi: raise Exception("%s not provided" % param) param = "lai" lai = types.getParamValue(data, param) if not lai: #if lai is not provided, check mcc_mnc and lac param = "mcc_mnc" mccMnc = types.getParamValue(data, param) if not mccMnc: raise Exception("%s not provided" % param) if len(mccMnc) != 6: mnc3 = 'F' else: mnc3 = mccMnc[5] mccMnc = "%s%s%s" % (mccMnc[0:3], mnc3, mccMnc[3:5]) param = "lac" lac = types.getParamValue(data, param) if not lac: raise Exception("%s not provided" % param) lai = "%s%04X" % (hextools.bytes2hex( hextools.encode_BCD(mccMnc)), int(lac, 16)) param = "rfu" rfu = types.getParamValue(data, param) if not rfu: rfu = "FF" param = "loc_status" locStatus = types.getParamValue(data, param) if not locStatus: locStatus = "00" loci = "%s%s%s%s" % (tmsi, lai, rfu, locStatus) return loci
def setEfOpl(self, data): data = data.split(';') dataNew = '' for record in data: if not record: continue mccMnc = types.getParamValue(record, "mcc_mnc") if not mccMnc: raise Exception("mcc_mnc not provided") if len(mccMnc) != 6: mnc3 = 'F' else: mnc3 = mccMnc[5] mccMnc = "%s%s%s" %(mccMnc[0:3], mnc3, mccMnc[3:5]) lacRange = types.getParamValue(record, "lac") if not lacRange: lacRange = '0000-FFFE' lacStart = lacRange.split("-")[0] lacEnd = lacRange.split("-")[1] pnnId = int(types.getParamValue(record, "pnnId"), 16) lai = "%s%04X%04X" %(hextools.bytes2hex(hextools.encode_BCD(mccMnc)), int(lacStart, 16), int(lacEnd, 16)) dataNew += "%s%02X;" %(lai, pnnId) return dataNew
def tick(self): with self.lock: inject = INJECT_READY evt, apdu = self.receiveCommandApdu() if evt == EVT_RESET: self.resetCards() return if not apdu: if (not self.inject or self.rapduInject ): # Wait until rapduInject is consumed return else: inject = self.inject apdu = self.apduInjectedData self.apduInjectedData = None if not apdu: raise Exception("APDU is empty") self.lastUpdate = time.time() cardsData = self.getHandlers(apdu, inject) responseApdu = None for cardData in cardsData: if cardData == cardsData[0]: apduHex = hextools.bytes2hex(apdu) self.loggingApdu.info("") self.loggingApdu.info( "C-APDU%d: %s" % (self.getSimId(cardData[0]), apduHex)) responseApduTemp = self.handleApdu(cardData, apdu) if cardData[1]: if cardData[0] != self.getMainCard(0): self.loggingApdu.info("*R-APDU%d" % self.getSimId(cardData[0])) responseApdu = responseApduTemp self.updateHandler(cardData, apdu, responseApduTemp) if not responseApdu and not inject: raise Exception("No response received") if inject: self.rapduInject = responseApduTemp
def setEfLoci(self, data): param = "tmsi" tmsi = types.getParamValue(data, param) if not tmsi: raise Exception("%s not provided" %param) param = "lai" lai = types.getParamValue(data, param) if not lai: #if lai is not provided, check mcc_mnc and lac param = "mcc_mnc" mccMnc = types.getParamValue(data, param) if not mccMnc: raise Exception("%s not provided" %param) if len(mccMnc) != 6: mnc3 = 'F' else: mnc3 = mccMnc[5] mccMnc = "%s%s%s" %(mccMnc[0:3], mnc3, mccMnc[3:5]) param = "lac" lac = types.getParamValue(data, param) if not lac: raise Exception("%s not provided" %param) lai = "%s%04X" %(hextools.bytes2hex(hextools.encode_BCD(mccMnc)), int(lac, 16)) param = "rfu" rfu = types.getParamValue(data, param) if not rfu: rfu = "FF" param = "loc_status" locStatus = types.getParamValue(data, param) if not locStatus: locStatus = "00" loci = "%s%s%s%s" %(tmsi, lai, rfu, locStatus) return loci
def test_1_getAtr(self): atr = self.simCard.getATR() logging.info("ATR: %s" %hextools.bytes2hex(atr)) self.assertGreater(len(atr), 4)
def setBinaryValue(self, file, data): value = hextools.bytes2hex(data) #value = bytesToXmlValue(data) self.setValue(file, value)
def handleApdu(self, cardData, apdu): card = cardData[0] sendData = cardData[1] if card == None: raise Exception("card not initialized") ins = types.insName(apdu) if card != self.getMainCard(0): origApdu = apdu if (self.aidCommon(card) and card.routingAttr.aidToSelect and self.getMainCard(0).routingAttr.aidToSelect == hextools.bytes2hex(apdu) and #origin apdu is AID int(card.routingAttr.aidToSelect[0:2], 16) == apdu[0]): #check the same class apdu = hextools.hex2bytes(card.routingAttr.aidToSelect) card.routingAttr.aidToSelect = None elif (self.aidCommon(card) and card.routingAttr.getFileSelected(apdu[0]) == 'EF_DIR' and ins == 'READ_RECORD' and card.routingAttr.recordEfDirLength): apdu[4] = card.routingAttr.recordEfDirLength if origApdu != apdu: self.loggingApdu.info("") self.loggingApdu.info( "*C-APDU%d: %s" % (self.getSimId(card), hextools.bytes2hex(apdu))) if self.simType == types.TYPE_SIM and (apdu[0] & 0xF0) != 0xA0: #force 2G on USIM cards sw = types_g.sw.CLASS_NOT_SUPPORTED sw1 = sw >> 8 sw2 = sw & 0x00FF responseApdu = [sw1, sw2] elif ins == 'GET_RESPONSE' and card.routingAttr.getResponse: responseApdu = card.routingAttr.getResponse card.routingAttr.getResponse = None else: responseApdu = card.apdu(apdu) if card != self.getMainCard(0): if (self.aidCommon(card) and card.routingAttr.getFileSelected(apdu[0]) == 'EF_DIR' and ins == 'GET_RESPONSE' and types.swNoError(responseApdu) and len(responseApdu) > 7): card.routingAttr.recordEfDirLength = responseApdu[7] if (TRY_ANOTHER_CARD_ON_AUTH_FAILURE and self.getNbrOfCards() > 1 and card.routingAttr.getFileSelected(apdu[0]) == 'AUTH' and types.sw(responseApdu) == types_g.sw.AUTHENTICATION_ERROR_APPLICATION_SPECIFIC): sw1Name, swName = types.swName( types.sw(responseApdu) >> 8, types.sw(responseApdu) & 0x00FF) self.logging.warning("Response not expected. SW1: %s, SW: %s" % (sw1Name, swName)) self.logging.warning("Change card to process AUTHENTICATION") if card == self.getMainCard(0): cardTmp = self.getMainCard(1) else: cardTmp = self.getMainCard(0) responseApdu = cardTmp.apdu(apdu) cardTmp.routingAttr.setFileSelected('AUTH', apdu[0]) card.routingAttr.setFileSelected(None, apdu[0]) # TODO: check if exist cardTmp.routingAttr.insReplaced.append('INTERNAL_AUTHENTICATE') if types.sw1(responseApdu) in [ types_g.sw1.RESPONSE_DATA_AVAILABLE_2G, types_g.sw1.RESPONSE_DATA_AVAILABLE_3G ]: # cache 'GET_RESPONSE' getResponseLength = types.sw2(responseApdu) cla = apdu[0] apduTmp = "%02XC00000%02X" % (cla, getResponseLength) self.loggingApdu.info("**C-APDU%d: %s" % (self.getSimId(cardTmp), apduTmp)) cardTmp.routingAttr.getResponse = cardTmp.apdu(apduTmp) if card.routingAttr.getFileSelected( apdu[0]) == 'EF_IMSI' and types.swNoError(responseApdu): #cache imsi responseData = types.responseData(responseApdu) if ins == 'READ_BINARY' and types.p1(apdu) == 0 and types.p2( apdu) == 0: #When P1=8X then SFI is used to select the file. #Remove the check when SFI checking is implemented imsi = hextools.decode_BCD(responseData)[3:] #TODO: remove length check when name for the file comes from #the whole path and not fid. 6f07 is also in ADF_ISIM if len(imsi) > 10: card.imsi = imsi #update associated interface if self.isCardCtrl(card): self.getRelatedMainCard(card).imsi = imsi else: self.getRelatedCtrlCard(card).imsi = imsi elif ins == 'UPDATE_BINARY': card.imsi = None responseApduHex = hextools.bytes2hex(responseApdu) #example of APDU modification if responseApduHex == "02542D4D6F62696C652E706CFFFFFFFFFF9000": #change SPN name 'T-mobile.pl' for 'Tmobile-SPN' responseApdu = hextools.hex2bytes( "02546D6F62696C652D53504EFFFFFFFFFF9000") if sendData: if ((types.sw(responseApdu) == types_g.sw.NO_ERROR or types.sw1(responseApdu) == types_g.sw1.NO_ERROR_PROACTIVE_DATA) and self.getNbrOfCards() > 1): # Check for pending SAT command for cardDict in self.cardsDict: cardTmp = cardDict[MAIN_INTERFACE] if card == cardTmp: continue if set(sim_card.SAT_INS) <= set( cardTmp.routingAttr.insReplaced): swNoError = cardTmp.swNoError if types.unpackSw(swNoError)[ 0] == types_g.sw1.NO_ERROR_PROACTIVE_DATA: #update r-apdu with proactive data information responseApdu[-2] = swNoError >> 8 responseApdu[-1] = swNoError & 0x00FF break self.sendResponseApdu(responseApdu) if card == self.getMainCard(0) or sendData: self.pretty_apdu(apdu) responseApduHex = hextools.bytes2hex(responseApdu) self.loggingApdu.info("R-APDU%d: %s" % (self.getSimId(card), responseApduHex)) # gsmtap.log(apdu,responseApdu) # Uncomment for wireshark return responseApdu
def getEfImpi(self, data): valueRaw = types.removeTrailingBytes(hextools.hex2bytes(data), 0xFF) if len(valueRaw) < 3: return '' value = hextools.bytes2hex(valueRaw[2:]).decode("hex") return "impi=%s" % value
def getEfCphs_onstr(self, data): nameHex = types.removeTrailingBytes(hextools.hex2bytes(data), 0xFF) #fullName = coder.decodeGsm7(hextools.bytes2hex(nameHex)) #return fullName return hextools.bytes2hex(nameHex.decode("hex"))
def getEfImpi(self, data): valueRaw = types.removeTrailingBytes(hextools.hex2bytes(data), 0xFF) if len(valueRaw) < 3: return '' value = hextools.bytes2hex(valueRaw[2:]).decode("hex") return "impi=%s" %value
def command(self, tag, payload=[]): # dummy byte self.loggingApdu.debug("CMD %d %s" % (tag, hextools.bytes2hex(payload))) self.usbCtrlOut(tag, payload)
def handleApdu(self, cardData, apdu): card = cardData[0] sendData = cardData[1] if card == None: raise Exception("card not initialized") ins = types.insName(apdu) if card != self.getMainCard(0): origApdu = apdu if ( self.aidCommon(card) and card.routingAttr.aidToSelect and self.getMainCard(0).routingAttr.aidToSelect == hextools.bytes2hex(apdu) and #origin apdu is AID int(card.routingAttr.aidToSelect[0:2], 16) == apdu[0]): #check the same class apdu = hextools.hex2bytes(card.routingAttr.aidToSelect) card.routingAttr.aidToSelect = None elif ( self.aidCommon(card) and card.routingAttr.getFileSelected(apdu[0]) == 'EF_DIR' and ins == 'READ_RECORD' and card.routingAttr.recordEfDirLength): apdu[4] = card.routingAttr.recordEfDirLength if origApdu != apdu: self.loggingApdu.info("") self.loggingApdu.info("*C-APDU%d: %s" %(self.getSimId(card), hextools.bytes2hex(apdu))) if self.simType == types.TYPE_SIM and (apdu[0] & 0xF0) != 0xA0: #force 2G on USIM cards sw = types_g.sw.CLASS_NOT_SUPPORTED sw1 = sw>>8 sw2 = sw & 0x00FF responseApdu = [sw1, sw2] elif ins == 'GET_RESPONSE' and card.routingAttr.getResponse: responseApdu = card.routingAttr.getResponse card.routingAttr.getResponse = None else: responseApdu = card.apdu(apdu) if card != self.getMainCard(0): if (self.aidCommon(card) and card.routingAttr.getFileSelected(apdu[0]) == 'EF_DIR' and ins == 'GET_RESPONSE' and types.swNoError(responseApdu) and len(responseApdu) > 7): card.routingAttr.recordEfDirLength = responseApdu[7] if (TRY_ANOTHER_CARD_ON_AUTH_FAILURE and self.getNbrOfCards() > 1 and card.routingAttr.getFileSelected(apdu[0]) == 'AUTH' and types.sw(responseApdu) == types_g.sw.AUTHENTICATION_ERROR_APPLICATION_SPECIFIC): sw1Name, swName = types.swName(types.sw(responseApdu) >> 8, types.sw(responseApdu) & 0x00FF) self.logging.warning("Response not expected. SW1: %s, SW: %s" %(sw1Name, swName)) self.logging.warning("Change card to process AUTHENTICATION") if card == self.getMainCard(0): cardTmp = self.getMainCard(1) else: cardTmp = self.getMainCard(0) responseApdu = cardTmp.apdu(apdu) cardTmp.routingAttr.setFileSelected('AUTH', apdu[0]) card.routingAttr.setFileSelected(None, apdu[0]) # TODO: check if exist cardTmp.routingAttr.insReplaced.append('INTERNAL_AUTHENTICATE') if types.sw1(responseApdu) in [types_g.sw1.RESPONSE_DATA_AVAILABLE_2G, types_g.sw1.RESPONSE_DATA_AVAILABLE_3G]: # cache 'GET_RESPONSE' getResponseLength = types.sw2(responseApdu) cla = apdu[0] apduTmp = "%02XC00000%02X" %(cla, getResponseLength) self.loggingApdu.info("**C-APDU%d: %s" %(self.getSimId(cardTmp), apduTmp)) cardTmp.routingAttr.getResponse = cardTmp.apdu(apduTmp) if card.routingAttr.getFileSelected(apdu[0]) == 'EF_IMSI' and types.swNoError(responseApdu): #cache imsi responseData = types.responseData(responseApdu) if ins == 'READ_BINARY' and types.p1(apdu) == 0 and types.p2(apdu) == 0: #When P1=8X then SFI is used to select the file. #Remove the check when SFI checking is implemented imsi = hextools.decode_BCD(responseData)[3:] #TODO: remove length check when name for the file comes from #the whole path and not fid. 6f07 is also in ADF_ISIM if len(imsi) > 10: card.imsi = imsi #update associated interface if self.isCardCtrl(card): self.getRelatedMainCard(card).imsi = imsi else: self.getRelatedCtrlCard(card).imsi = imsi elif ins == 'UPDATE_BINARY': card.imsi = None responseApduHex = hextools.bytes2hex(responseApdu) #example of APDU modification if responseApduHex == "02542D4D6F62696C652E706CFFFFFFFFFF9000": #change SPN name 'T-mobile.pl' for 'Tmobile-SPN' responseApdu = hextools.hex2bytes("02546D6F62696C652D53504EFFFFFFFFFF9000") if sendData: if ((types.sw(responseApdu) == types_g.sw.NO_ERROR or types.sw1(responseApdu) == types_g.sw1.NO_ERROR_PROACTIVE_DATA) and self.getNbrOfCards() > 1): # Check for pending SAT command for cardDict in self.cardsDict: cardTmp = cardDict[MAIN_INTERFACE] if card == cardTmp: continue if set(sim_card.SAT_INS) <= set(cardTmp.routingAttr.insReplaced): swNoError = cardTmp.swNoError if types.unpackSw(swNoError)[0] == types_g.sw1.NO_ERROR_PROACTIVE_DATA: #update r-apdu with proactive data information responseApdu[-2] = swNoError >> 8 responseApdu[-1] = swNoError & 0x00FF break self.sendResponseApdu(responseApdu) if card == self.getMainCard(0) or sendData: self.pretty_apdu(apdu) responseApduHex = hextools.bytes2hex(responseApdu) self.loggingApdu.info("R-APDU%d: %s" %(self.getSimId(card), responseApduHex)) # gsmtap.log(apdu,responseApdu) # Uncomment for wireshark return responseApdu
def test_1_getAtr(self): atr = self.simCard.getATR() logging.info("ATR: %s" % hextools.bytes2hex(atr)) self.assertGreater(len(atr), 4)