def __init__(self, pin, can, mrz, puk, mf, default_se = nPA_SE): SAM.__init__(self, pin, None, mf) self.active = True self.current_SE = default_se(self.mf, self) self.can = can self.mrz = mrz self.puk = puk self.counter_puk = 10
def __init__(self, pin, can, mrz, puk, mf, default_se=nPA_SE): SAM.__init__(self, pin, None, mf) self.active = True self.current_SE = default_se(self.mf, self) self.can = can self.mrz = mrz self.puk = puk self.counter_puk = 10
def __init__(self, mf): import virtualsmartcard.SmartcardFilesystem as vsFS SAM.__init__(self, None, None, mf, default_se=ePass_SE) ef_dg1 = vsFS.walk(mf, "\x00\x04\x01\x01") dg1 = ef_dg1.readbinary(5) self.mrz1 = dg1[:43] self.mrz2 = dg1[44:] self.KSeed = None self.KEnc = None self.KMac = None self.__computeKeys()
def get_challenge(self, p1, p2, data): if self.current_SE.eac_step == 4: # TA if (p1 != 0x00 or p2 != 0x00): raise SwError(SW["ERR_INCORRECTP1P2"]) self.last_challenge = eac.TA_STEP4_get_nonce(self.current_SE.eac_ctx) if not self.last_challenge: eac.print_ossl_err() raise SwError(SW["ERR_NOINFO69"]) else: SAM.get_challenge(self, p1, p2, data) return SW["NORMAL"], self.last_challenge
def get_challenge(self, p1, p2, data): if self.current_SE.eac_step == 4: # TA if (p1 != 0x00 or p2 != 0x00): raise SwError(SW["ERR_INCORRECTP1P2"]) self.last_challenge = \ eac.TA_STEP4_get_nonce(self.current_SE.eac_ctx) if not self.last_challenge: eac.print_ossl_err() raise SwError(SW["ERR_NOINFO69"]) else: SAM.get_challenge(self, p1, p2, data) return SW["NORMAL"], self.last_challenge
def verify(self, p1, p2, data): if p1 == 0x80 and p2 == 0x00: if self.current_SE.eac_step == 6: # data should only contain exactly OID [(tag, _, value)] = structure = unpack(data) if tag == 6: mapped_algo = ALGO_MAPPING[value] eid = self.mf.select("dfname", "\xe8\x07\x04\x00\x7f\x00\x07\x03\x02") if mapped_algo == "DateOfExpiry": [(_, _, [(_, _, mine)])] = unpack(eid.select("fid", 0x0103).data) logging.info( "DateOfExpiry: " + str(mine) + "; reference: " + str(self.current_SE.at.DateOfExpiry) ) if self.current_SE.at.DateOfExpiry < mine: print ("Date of expiry verified") return SW["NORMAL"], "" else: print ("Date of expiry not verified (expired)") return SW["WARN_NOINFO63"], "" elif mapped_algo == "DateOfBirth": [(_, _, [(_, _, mine)])] = unpack(eid.select("fid", 0x0108).data) # case1: YYYYMMDD -> good # case2: YYYYMM -> mapped to last day of given month, i.e. YYYYMM31 ;-) # case3: YYYY -> mapped to YYYY-12-31 if len(str(mine)) == 6: mine = int(str(mine) + "31") elif len(str(mine)) == 4: mine = int(str(mine) + "1231") logging.info( "DateOfBirth: " + str(mine) + "; reference: " + str(self.current_SE.at.DateOfExpiry) ) if self.current_SE.at.DateOfBirth < mine: print ("Date of birth verified (old enough)") return SW["NORMAL"], "" else: print ("Date of birth not verified (too young)") return SW["WARN_NOINFO63"], "" elif mapped_algo == "CommunityID": [(_, _, [(_, _, mine)])] = unpack(eid.select("fid", 0x0112).data) mine = binascii.hexlify(mine) logging.info( "CommunityID: " + str(mine) + "; reference: " + str(self.current_SE.at.CommunityID) ) if mine.startswith(self.current_SE.at.CommunityID): print ("Community ID verified (living there)") return SW["NORMAL"], "" else: print ("Community ID not verified (not living there)") return SW["WARN_NOINFO63"], "" else: return SwError(SW["ERR_DATANOTFOUND"]) else: return SwError(SW["ERR_DATANOTFOUND"]) else: return SAM.verify(self, p1, p2, data)
def __generate_iso_card(self): default_pin = "1234" default_cardno = "1234567890" logging.warning("Using default SAM parameters. PIN=%s, Card Nr=%s" % (default_pin, default_cardno)) # TODO: Use user provided data self.sam = SAM(default_pin, default_cardno) self.mf = MF(filedescriptor=FDB["DF"]) self.sam.set_MF(self.mf)
def parse_SM_CAPDU(self, CAPDU, header_authentication): if hasattr(self.current_SE, "new_encryption_ctx"): if self.current_SE.new_encryption_ctx == eac.EAC_ID_PACE: protocol = "PACE" else: protocol = "CA" logging.info("switching to new encryption context established in %s:" % protocol) logging.info(eac.EAC_CTX_print_private(self.current_SE.eac_ctx, 4)) eac.EAC_CTX_set_encryption_ctx(self.current_SE.eac_ctx, self.current_SE.new_encryption_ctx) delattr(self.current_SE, "new_encryption_ctx") eac.EAC_increment_ssc(self.current_SE.eac_ctx) return SAM.parse_SM_CAPDU(self, CAPDU, 1)
def parse_SM_CAPDU(self, CAPDU, header_authentication): if hasattr(self.current_SE, "new_encryption_ctx"): if self.current_SE.new_encryption_ctx == eac.EAC_ID_PACE: protocol = "PACE" else: protocol = "CA" print "switching to new encryption context established in %s:" % protocol print eac.EAC_CTX_print_private(self.current_SE.eac_ctx, 4) eac.EAC_CTX_set_encryption_ctx(self.current_SE.eac_ctx, self.current_SE.new_encryption_ctx) delattr(self.current_SE, "new_encryption_ctx") eac.EAC_increment_ssc(self.current_SE.eac_ctx) return SAM.parse_SM_CAPDU(self, CAPDU, 1)
def protect_result(self, sw, unprotected_result): eac.EAC_increment_ssc(self.current_SE.eac_ctx) return SAM.protect_result(self, sw, unprotected_result)
def internal_authenticate(self, p1, p2, data): data = data[::-1] # Reverse Byte order sw, data = SAM.internal_authenticate(self, p1, p2, data) if data != "": data = data[::-1] return sw, data
def __init__(self, mf=None): SAM.__init__(self, None, None, mf, default_se=CryptoflexSE) self.current_SE = self.default_se(self.mf, self)
def verify(self, p1, p2, data): if p1 == 0x80 and p2 == 0x00: if self.current_SE.eac_step == 6: # data should only contain exactly OID [(tag, _, value)] = structure = unpack(data) if tag == 6: mapped_algo = ALGO_MAPPING[value] eid = self.mf.select( 'dfname', b'\xe8\x07\x04\x00\x7f\x00' b'\x07\x03\x02') if mapped_algo == "DateOfExpiry": [(_, _, [(_, _, mine)])] = \ unpack(eid.select('fid', 0x0103).data) logging.info("DateOfExpiry: " + str(mine) + "; reference: " + str(self.current_SE.at.DateOfExpiry)) if self.current_SE.at.DateOfExpiry < mine: print("Date of expiry verified") return SW["NORMAL"], "" else: print("Date of expiry not verified (expired)") return SW["WARN_NOINFO63"], "" elif mapped_algo == "DateOfBirth": [(_, _, [(_, _, mine)])] = \ unpack(eid.select('fid', 0x0108).data) # case1: YYYYMMDD -> good # case2: YYYYMM -> mapped to last day of given month, # i.e. YYYYMM31 ;-) # case3: YYYY -> mapped to YYYY-12-31 if len(str(mine)) == 6: mine = int(str(mine) + "31") elif len(str(mine)) == 4: mine = int(str(mine) + "1231") logging.info("DateOfBirth: " + str(mine) + "; reference: " + str(self.current_SE.at.DateOfExpiry)) if self.current_SE.at.DateOfBirth < mine: print("Date of birth verified (old enough)") return SW["NORMAL"], "" else: print("Date of birth not verified (too young)") return SW["WARN_NOINFO63"], "" elif mapped_algo == "CommunityID": [(_, _, [(_, _, mine)])] = \ unpack(eid.select('fid', 0x0112).data) mine = binascii.hexlify(mine) logging.info("CommunityID: " + str(mine) + "; reference: " + str(self.current_SE.at.CommunityID)) if mine.startswith(self.current_SE.at.CommunityID): print("Community ID verified (living there)") return SW["NORMAL"], b"" else: print("Community ID not verified (not living" "there)") return SW["WARN_NOINFO63"], b"" else: return SwError(SW["ERR_DATANOTFOUND"]) else: return SwError(SW["ERR_DATANOTFOUND"]) else: return SAM.verify(self, p1, p2, data)