Example #1
0
    def decipher(self, p1, p2, data):
        plain = pace.EAC_decrypt(self.eac_ctx, data)
        if not plain:
            pace.print_ossl_err()
            raise SwError(SW["ERR_NOINFO69"]) 

        return plain
Example #2
0
    def compute_cryptographic_checksum(self, p1, p2, data):
        checksum = pace.EAC_authenticate(self.eac_ctx, data)
        if not checksum:
            pace.print_ossl_err()
            raise SwError(SW["ERR_NOINFO69"]) 

        return checksum
Example #3
0
    def __eac_ca(self, data):
        tlv_data = nPA_SE.__unpack_general_authenticate(data)

        pubkey = ""
        for tag, length, value in tlv_data:
            if tag == 0x80:
                pubkey = value
            else:
                raise SwError(SW["ERR_INCORRECTPARAMETERS"])

        if pace.CA_STEP4_compute_shared_secret(self.eac_ctx, pubkey) != 1:
            pace.print_ossl_err()
            raise SwError(SW["ERR_NOINFO69"]) 

        nonce, token = pace.CA_STEP5_derive_keys(self.eac_ctx, pubkey)
        if not nonce or not token:
            pace.print_ossl_err()
            raise SwError(SW["WARN_NOINFO63"])

        self.eac_step += 1

        print "Generated Nonce and Authentication Token for CA"

        # TODO activate SM
        self.new_encryption_ctx = pace.EAC_ID_CA

        return 0x9000, nPA_SE.__pack_general_authenticate([[0x81,
            len(nonce), nonce], [0x82, len(token), token]])
Example #4
0
    def external_authenticate(self, p1, p2, data):
        """
        Authenticate the terminal to the card. Check whether Terminal correctly
        encrypted the given challenge or not
        """
        if self.dst.keyref_public_key: # TODO check if this is the correct CAR
            id_picc = pace.EAC_Comp(self.eac_ctx, pace.EAC_ID_PACE, self.my_pace_eph_pubkey)

            # FIXME auxiliary_data might be from an older run of PACE
            if hasattr(self.at, "auxiliary_data"):
                auxiliary_data = self.at.auxiliary_data
            else:
                auxiliary_data = None

            if 1 != pace.TA_STEP6_verify(self.eac_ctx, self.at.iv, id_picc,
                    auxiliary_data, data):
                pace.print_ossl_err()
                raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])

            print "Terminal's signature verified"

            self.eac_step += 1

            return 0x9000, ""

        raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
Example #5
0
    def encipher(self, p1, p2, data):
        padded = vsCrypto.append_padding(self.cct.blocklength, data)
        cipher = pace.EAC_encrypt(self.eac_ctx, padded)
        if not cipher:
            pace.print_ossl_err()
            raise SwError(SW["ERR_NOINFO69"]) 

        return cipher
Example #6
0
    def verify_certificate(self, p1, p2, data):
        if (p1, p2) != (0x00, 0xbe):
            raise SwError(SW["ERR_INCORRECTPARAMETERS"])

        cert = bertlv_pack([[0x7f21, len(data), data]])
        if 1 != pace.TA_STEP2_import_certificate(self.eac_ctx, cert):
            pace.print_ossl_err()
            raise SwError(SW["ERR_NOINFO69"]) 

        print "Imported Certificate"

        return ""
Example #7
0
    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 = pace.TA_STEP4_get_nonce(self.current_SE.eac_ctx)
            if not self.last_challenge:
                pace.print_ossl_err()
                raise SwError(SW["ERR_NOINFO69"])
        else:
            SAM.get_challenge(self, p1, p2, data)

        return SW["NORMAL"], self.last_challenge
Example #8
0
    def __eac_pace_step4(self, data):
        tlv_data = nPA_SE.__unpack_general_authenticate(data)
        pace.PACE_STEP3C_derive_keys(self.eac_ctx)
        my_token = pace.PACE_STEP3D_compute_authentication_token(self.eac_ctx, self.pace_opp_pub_key)
        token = ""
        for tag, length, value in tlv_data:
            if tag == 0x85:
                token = value
            else:
                raise SwError(SW["ERR_INCORRECTPARAMETERS"])

        if not my_token or 1 != pace.PACE_STEP3D_verify_authentication_token(self.eac_ctx, token):
            pace.print_ossl_err()
            raise SwError(SW["WARN_NOINFO63"])

        print "Established PACE channel"

        if self.at.keyref_is_can():
            if (self.sam.counter == 1):
                self.sam.active = True
                print "PIN resumed"
        elif self.at.keyref_is_pin():
            self.sam.active = True
            self.sam.counter = 3
        elif self.at.keyref_is_puk():
            self.sam.active = True
            self.sam.counter = 3
            print "PIN unblocked"

        self.eac_step += 1
        self.at.algorithm = "TA"

        self.new_encryption_ctx = pace.EAC_ID_PACE

        result = [[0x86, len(my_token), my_token]]
        if self.at.chat:
            if self.cvca:
                self.car = CVC(self.cvca).get_chr()
            result.append([0x87, len(self.car), self.car])
            if (self.disable_checks):
                pace.TA_disable_checks(self.eac_ctx)
            if not pace.EAC_CTX_init_ta(self.eac_ctx, None, self.cvca):
                pace.print_ossl_err()
                raise SwError(SW["WARN_NOINFO63"])


        return 0x9000, nPA_SE.__pack_general_authenticate(result)
Example #9
0
    def __eac_pace_step2(self, data):
        tlv_data = nPA_SE.__unpack_general_authenticate(data)

        pubkey = pace.PACE_STEP3A_generate_mapping_data(self.eac_ctx)
        if not pubkey:
            pace.print_ossl_err()
            raise SwError(SW["WARN_NOINFO63"])

        for tag, length, value in tlv_data:
            if tag == 0x81:
                pace.PACE_STEP3A_map_generator(self.eac_ctx, value)
            else:
                raise SwError(SW["ERR_INCORRECTPARAMETERS"])

        self.eac_step += 1

        return 0x9000, nPA_SE.__pack_general_authenticate([[0x82, len(pubkey), pubkey]])
Example #10
0
    def __eac_pace_step3(self, data):
        tlv_data = nPA_SE.__unpack_general_authenticate(data)

        self.my_pace_eph_pubkey = pace.PACE_STEP3B_generate_ephemeral_key(self.eac_ctx)
        if not self.my_pace_eph_pubkey:
            pace.print_ossl_err()
            raise SwError(SW["WARN_NOINFO63"])
        eph_pubkey = self.my_pace_eph_pubkey

        for tag, length, value in tlv_data:
            if tag == 0x83:
                self.pace_opp_pub_key = value
                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_SE.__pack_general_authenticate([[0x84, len(eph_pubkey), eph_pubkey]])
Example #11
0
    def __eac_pace_step1(self, data):
        tlv_data = nPA_SE.__unpack_general_authenticate(data)
        if  tlv_data != []:
            raise SwError(SW["WARN_NOINFO63"])

        if self.at.keyref_is_mrz():
            self.PACE_SEC = PACE_SEC(self.sam.mrz, pace.PACE_MRZ)
        elif self.at.keyref_is_can():
            self.PACE_SEC = PACE_SEC(self.sam.can, pace.PACE_CAN)
        elif self.at.keyref_is_pin():
            if self.sam.counter <= 0:
                print "Must use PUK to unblock"
                raise SwError(SW["WARN_NOINFO63"])
            if self.sam.counter == 1 and not self.sam.active:
                print "Must use CAN to activate"
                return 0x63c1, ""
            self.PACE_SEC = PACE_SEC(self.sam.PIN, pace.PACE_PIN)
            self.sam.counter -= 1
            if self.sam.counter <= 1:
                self.sam.active = False
        elif self.at.keyref_is_puk():
            if self.sam.counter_puk <= 0:
                raise SwError(SW["WARN_NOINFO63"])
            self.PACE_SEC = PACE_SEC(self.sam.puk, pace.PACE_PUK)
            self.sam.counter_puk -= 1
        else:
            raise SwError(SW["ERR_INCORRECTPARAMETERS"])
        self.sec = self.PACE_SEC.sec

        if not self.eac_ctx:
            pace.EAC_init()

            self.EAC_CTX = EAC_CTX()
            self.eac_ctx = self.EAC_CTX.ctx
            pace.CA_disable_passive_authentication(self.eac_ctx)

            ef_card_security = self.mf.select('fid', 0x011d)
            ef_card_security_data = ef_card_security.data
            pace.EAC_CTX_init_ef_cardsecurity(ef_card_security_data, self.eac_ctx)

            if self.ca_key:
                ca_pubkey = pace.CA_get_pubkey(self.eac_ctx, ef_card_security_data)
                if 1 != pace.CA_set_key(self.eac_ctx, self.ca_key, ca_pubkey):
                    pace.print_ossl_err()
                    raise SwError(SW["WARN_NOINFO63"])
            else:
                # we don't have a good CA key, so we simply generate an ephemeral one
                comp_pubkey = pace.TA_STEP3_generate_ephemeral_key(self.eac_ctx)
                pubkey = pace.CA_STEP2_get_eph_pubkey(self.eac_ctx)
                if not comp_pubkey or not pubkey:
                    pace.print_ossl_err()
                    raise SwError(SW["WARN_NOINFO63"])

                # save public key in EF.CardSecurity (and invalidate the signature)
                # FIXME this only works for the default EF.CardSecurity.
                # Better use an ASN.1 parser to do this manipulation
                ef_card_security = self.mf.select('fid', 0x011d)
                ef_card_security_data = ef_card_security.data
                ef_card_security_data = ef_card_security_data[:61+4+239+2+1] + pubkey + ef_card_security_data[61+4+239+2+1+len(pubkey):]
                ef_card_security.data = ef_card_security_data

        nonce = pace.PACE_STEP1_enc_nonce(self.eac_ctx, self.sec)
        if not nonce:
            pace.print_ossl_err()
            raise SwError(SW["WARN_NOINFO63"])

        resp = nPA_SE.__pack_general_authenticate([[0x80, len(nonce), nonce]])

        self.eac_step += 1

        return 0x9000, resp