def deformat_response(self, tlv_data, sw): WHITELIST = (0x84, 0x86, 0x98) result = [] is_ok = True for data in tlv_data: t = data[0] & ~0x01 if t not in WHITELIST and t in range(0x80, 0xBF+1): is_ok = False # Unrecognized SM field present if is_ok: for data in tlv_data: t = data[0] & ~0x01 value = data[2] if t in WHITELIST: if t == 0x86: result.append( value[1:] ) elif t == 0x98: if sw != value: print "Warning: SW from SM not equal SW from RAPDU" sw = value else: result.append( value ) else: result.append( TLV_utils.pack( (data,), recalculate_length = True) ) else: result.append( TLV_utils.pack( tlv_data, recalculate_length = True) ) return "".join(result), sw
def process_apdu(self, apdu): if apdu.cla & 0x0c in (0x0c, 0x08): tlv_data = TLV_utils.unpack(apdu.data, with_marks = apdu.marks, include_filler=True) tlv_data = self.encrypt_command(tlv_data) tlv_data = self.authenticate_command(apdu, tlv_data) data = TLV_utils.pack(tlv_data, recalculate_length = True) new_apdu = C_APDU(apdu, data = data) return new_apdu else: return apdu
def calculate_cct(self, config, tlv_data, startblock = "", print_buffer=True): """Calculate the Cryptographic Checksum for some TLV data. tlv_data MUST be of the format generated by the include_filler=True parameter to unpack.""" if print_buffer: print "| Calculating cryptographic checksum:" def do_block(buffer, block): block_ = self.pad("".join(block), pi = PI_ISO) offset = sum( [len(b) for b in buffer] ) buffer.append(block_) del block[:] if print_buffer: print "|| " + "\n|| ".join( utils.hexdump( block_, offset = offset ).splitlines() ) buffer = [] if startblock != "": do_block(buffer, [startblock]) block = [] for data in tlv_data: tag, length, value = data[:3] if (tag & 0x01 == 0x01 or tag not in range(0x80, 0xbf+1)) and tag not in (0xff, 0x00): value_ = TLV_utils.pack( (data, ), recalculate_length=True ) block.append( value_ ) elif tag in (0xff, 0x00) and len(block) > 0: block.append( chr(tag) ) else: if len(block) > 0: do_block(buffer, block) if len(block) > 0: do_block(buffer, block) cct = self._mac(config, "".join(buffer)) if print_buffer: print "| Result (Tag 0x8e, length: 0x%02x):" % len(cct) print "|| " + "\n|| ".join( utils.hexdump( cct ).splitlines() ) return cct
def verify_cms(self, data): """Verify a pkcs7 SMIME message""" from M2Crypto import SMIME, X509, BIO import base64, TLV_utils, os data3 = "-----BEGIN PKCS7-----\n" data3 += base64.encodestring(data) data3 += "-----END PKCS7-----" #print data3 p7_bio = BIO.MemoryBuffer(data3) # Instantiate an SMIME object. s = SMIME.SMIME() # TODO: ugly hack for M2Crypto body = TLV_utils.tlv_find_tag(TLV_utils.unpack(data), 0xA0, 1)[0][2] thecert = TLV_utils.tlv_find_tag(body, 0xA0, 2)[1][2] cert_bio = BIO.MemoryBuffer(TLV_utils.pack(thecert)) # Load the signer's cert. x509 = X509.load_cert_bio(cert_bio, format=0) sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) country = str(x509.get_issuer()).split('/')[1][2:] #print country cacert = country + "-cacert.der" #print cacert msgErr = "couldn't parse certificate to determine URL for CACert, search the intertubes," msg = "download CACert (convert to DER if necessary) and save it as \n\"%s\"" % cacert if not os.path.isfile(cacert): try: v = x509.get_ext("certificatePolicies").get_value() start = v.find("CPS: ") if start != -1: url = v[start + 5:-1] print "visit %s" % url, msg else: print msgErr, msg except Exception: print msgErr, msg return "" # Load the signer's CA cert. st = X509.X509_Store() #st.load_info('main') x509CA = X509.load_cert(cacert, format=0) st.add_x509(x509CA) s.set_x509_store(st) # Load the data, verify it. #p7, data = SMIME.smime_load_pkcs7_bio(p7_bio) p7 = SMIME.load_pkcs7_bio(p7_bio) v = s.verify(p7) return v