diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py b/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py index a97ae99..89830d9 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py @@ -166,6 +166,7 @@ class Security_Environment(object): def __init__(self, MF, SAM): self.sam = SAM + self.mf = MF self.SEID = None self.sm_objects = "" diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/cards/nPA.py b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/nPA.py index a77acbe..8bc5de8 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/cards/nPA.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/nPA.py @@ -17,7 +17,7 @@ # virtualsmartcard. If not, see . from virtualsmartcard.SmartcardSAM import SAM -from virtualsmartcard.SEutils import ControlReferenceTemplate +from virtualsmartcard.SEutils import ControlReferenceTemplate, Security_Environment from virtualsmartcard.SWutils import SwError, SW from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE from virtualsmartcard.TLVutils import unpack, bertlv_pack @@ -53,28 +53,17 @@ class nPA_AT_CRT(ControlReferenceTemplate): return 0x9000 , "" -class nPA_SAM(SAM): - # TODO move EAC to the securiity environment +class nPA_SE(Security_Environment): # TODO call __eac_abort whenever an error occurred - eac_step = make_property("eac_step", "next step to performed for EAC") - - def __init__(self, pin, can, mrz, puk, mf): - SAM.__init__(self, None, None, mf) - self.current_SE.at = nPA_AT_CRT() - self.current_SE.verify_certificate = self.__eac_ta_verify_certificate + def __init__(self, MF, SAM): + Security_Environment.__init__(self, MF, SAM) + self.at = nPA_AT_CRT() self.eac_step = 0 - self.current_SE.eac_ctx = None self.sec = None - self.pin = pin - self.can = can - self.mrz = mrz - self.puk = puk + self.eac_ctx = None def general_authenticate(self, p1, p2, data): - def notImplemented(*argz, **args): - raise SwError(SW["WARN_NOINFO63"]) - if (p1, p2) != (0x00, 0x00): raise SwError(SW["ERR_INCORRECTPARAMETERS"]) @@ -90,7 +79,7 @@ class nPA_SAM(SAM): raise SwError(SW["ERR_INCORRECTPARAMETERS"]) def __eac_abort(self): - pace.EAC_CTX_clear_free(self.current_SE.eac_ctx) + pace.EAC_CTX_clear_free(self.eac_ctx) pace.PACE_SEC_clear_free(self.sec) @staticmethod @@ -111,82 +100,82 @@ class nPA_SAM(SAM): return bertlv_pack([[0x7c, len(tlv_data), tlv_data]]) def __eac_pace_step1(self, data): - tlv_data = nPA_SAM.__unpack_general_authenticate(data) - if self.current_SE.at.algorithm != "PACE" or tlv_data != []: + tlv_data = nPA_SE.__unpack_general_authenticate(data) + if self.at.algorithm != "PACE" or tlv_data != []: print 'value %r' % tlv_data raise SwError(SW["WARN_NOINFO63"]) self.__eac_abort() - self.current_SE.eac_ctx = pace.EAC_CTX_new() - if self.current_SE.at.keyref == '\x01': - self.sec = pace.PACE_SEC_new(self.mrz, pace.PACE_MRZ) - elif self.current_SE.at.keyref == '\x02': - self.sec = pace.PACE_SEC_new(self.can, pace.PACE_CAN) - elif self.current_SE.at.keyref == '\x03': - self.sec = pace.PACE_SEC_new(self.pin, pace.PACE_PIN) - elif self.current_SE.at.keyref == '\x04': - self.sec = pace.PACE_SEC_new(self.puk, pace.PACE_PUK) + self.eac_ctx = pace.EAC_CTX_new() + if self.at.keyref == '\x01': + self.sec = pace.PACE_SEC_new(self.sam.mrz, pace.PACE_MRZ) + elif self.at.keyref == '\x02': + self.sec = pace.PACE_SEC_new(self.sam.can, pace.PACE_CAN) + elif self.at.keyref == '\x03': + self.sec = pace.PACE_SEC_new(self.sam.pin, pace.PACE_PIN) + elif self.at.keyref == '\x04': + self.sec = pace.PACE_SEC_new(self.sam.puk, pace.PACE_PUK) else: raise SwError(SW["ERR_INCORRECTPARAMETERS"]) ef_card_access = self.mf.select('fid', 0x011c) ef_card_access_data = ef_card_access.getenc('data') - pace.EAC_CTX_init_ef_cardaccess(ef_card_access_data, self.current_SE.eac_ctx) + pace.EAC_CTX_init_ef_cardaccess(ef_card_access_data, self.eac_ctx) - nonce = pace.buf2string(pace.PACE_STEP1_enc_nonce(self.current_SE.eac_ctx, self.sec)) - resp = nPA_SAM.__pack_general_authenticate([[0x80, len(nonce), nonce]]) + nonce = pace.buf2string(pace.PACE_STEP1_enc_nonce(self.eac_ctx, self.sec)) + resp = nPA_SE.__pack_general_authenticate([[0x80, len(nonce), nonce]]) self.eac_step += 1 return 0x9000, resp def __eac_pace_step2(self, data): - tlv_data = nPA_SAM.__unpack_general_authenticate(data) - if self.current_SE.at.algorithm != "PACE": + tlv_data = nPA_SE.__unpack_general_authenticate(data) + if self.at.algorithm != "PACE": raise SwError(SW["WARN_NOINFO63"]) - pubkey = pace.buf2string(pace.PACE_STEP3A_generate_mapping_data(self.current_SE.eac_ctx)) + pubkey = pace.buf2string(pace.PACE_STEP3A_generate_mapping_data(self.eac_ctx)) for tag, length, value in tlv_data: if tag == 0x81: - pace.PACE_STEP3A_map_generator(self.current_SE.eac_ctx, pace.get_buf(value)) + pace.PACE_STEP3A_map_generator(self.eac_ctx, pace.get_buf(value)) else: raise SwError(SW["ERR_INCORRECTPARAMETERS"]) self.eac_step += 1 - return 0x9000, nPA_SAM.__pack_general_authenticate([[0x82, len(pubkey), pubkey]]) + return 0x9000, nPA_SE.__pack_general_authenticate([[0x82, len(pubkey), pubkey]]) def __eac_pace_step3(self, data): - tlv_data = nPA_SAM.__unpack_general_authenticate(data) - if self.current_SE.at.algorithm != "PACE": + tlv_data = nPA_SE.__unpack_general_authenticate(data) + if self.at.algorithm != "PACE": raise SwError(SW["WARN_NOINFO63"]) - my_epp_pubkey = pace.buf2string(pace.PACE_STEP3B_generate_ephemeral_key(self.current_SE.eac_ctx)) + my_epp_pubkey = pace.buf2string(pace.PACE_STEP3B_generate_ephemeral_key(self.eac_ctx)) for tag, length, value in tlv_data: if tag == 0x83: self.pace_opp_pub_key = pace.get_buf(value) - pace.PACE_STEP3B_compute_shared_secret(self.current_SE.eac_ctx, self.pace_opp_pub_key) + pace.PACE_STEP3B_compute_shared_secret(self.eac_ctx, self.pace_opp_pub_key) else: raise SwError(SW["ERR_INCORRECTPARAMETERS"]) self.eac_step += 1 - return 0x9000, nPA_SAM.__pack_general_authenticate([[0x84, len(my_epp_pubkey), my_epp_pubkey]]) + return 0x9000, nPA_SE.__pack_general_authenticate([[0x84, len(my_epp_pubkey), my_epp_pubkey]]) def __eac_pace_step4(self, data): - tlv_data = nPA_SAM.__unpack_general_authenticate(data) - if self.current_SE.at.algorithm != "PACE": + tlv_data = nPA_SE.__unpack_general_authenticate(data) + if self.at.algorithm != "PACE": raise SwError(SW["WARN_NOINFO63"]) - pace.PACE_STEP3C_derive_keys(self.current_SE.eac_ctx) - my_token = pace.buf2string(pace.PACE_STEP3D_compute_authentication_token(self.current_SE.eac_ctx, self.pace_opp_pub_key)) + pace.PACE_STEP3C_derive_keys(self.eac_ctx) + my_token = pace.buf2string(pace.PACE_STEP3D_compute_authentication_token(self.eac_ctx, self.pace_opp_pub_key)) for tag, length, value in tlv_data: if tag == 0x85: - pace.PACE_STEP3D_verify_authentication_token(self.current_SE.eac_ctx, pace.get_buf(value)) + pace.PACE_STEP3D_verify_authentication_token(self.eac_ctx, pace.get_buf(value)) else: raise SwError(SW["ERR_INCORRECTPARAMETERS"]) @@ -194,7 +183,22 @@ class nPA_SAM(SAM): # TODO activate SM - return 0x9000, nPA_SAM.__pack_general_authenticate([[0x86, len(my_token), my_token]]) + return 0x9000, nPA_SE.__pack_general_authenticate([[0x86, len(my_token), my_token]]) - def __eac_ta_verify_certificate(se, p1, p2, data): + def verify_certificate(se, p1, p2, data): pass + +class nPA_SAM(SAM): + + eac_step = make_property("eac_step", "next step to performed for EAC") + + def __init__(self, pin, can, mrz, puk, mf, default_se = nPA_SE): + SAM.__init__(self, None, None, mf) + self.current_SE = default_se(self.mf, self) + self.pin = pin + self.can = can + self.mrz = mrz + self.puk = puk + + def general_authenticate(self, p1, p2, data): + return self.current_SE.general_authenticate(p1, p2, data)