示例#1
0
def _dnskey_to_ec(alg, key):
    if alg == 13:
        curve = EC.NID_X9_62_prime256v1
    elif alg == 14:
        curve = EC.NID_secp384r1
    else:
        raise ValueError('Algorithm not supported')

    return EC.pub_key_from_params(curve, EC_NOCOMPRESSION + key)
示例#2
0
def _dnskey_to_ec(alg, key):
    if alg == 13:
        curve = EC.NID_X9_62_prime256v1
    elif alg == 14:
        curve = EC.NID_secp384r1
    else:
        raise ValueError("Algorithm not supported")

    return EC.pub_key_from_params(curve, key)
示例#3
0
 def test_pub_key_from_params(self):
     curve = EC.NID_prime256v1
     ec = EC.gen_params(curve)
     ec.gen_key()
     ec_pub = ec.pub()
     k = ec_pub.get_key()
     ec2 = EC.pub_key_from_params(curve, k)
     assert ec2.check_key()
     r, s = ec.sign_dsa(self.data)
     assert ec2.verify_dsa(self.data, r, s)
示例#4
0
def _dnskey_to_ec(alg, key):
    if alg == 13:
        curve = EC.NID_X9_62_prime256v1
    elif alg == 14:
        curve = EC.NID_secp384r1
    else:
        raise ValueError('Algorithm not supported')

    try:
        return EC.pub_key_from_params(curve, EC_NOCOMPRESSION + key)
    except ValueError:
        return None
示例#5
0
def pace(security_infos_efca: List[bytes], sm_object: SMObject, secret: bytes, pub_key_ref: str):
    """
    List of Security Infos from EF.CardAccesss
    SMObject,
    Secret (MRZ info or CAN)
    pub_key_ref choices ("MRZ" or "CAN")
    """
    openssl_nid_to_name = {
        409: "prime192v1",
        923: "brainpoolP192r1",
        713: "secp224r1",
        925: "brainpoolP224r1",
        415: "prime256v1",
        927: "brainpoolP256r1",
        929: "brainpoolP320r1",
        715: "secp384r1",
        931: "brainpoolP384r1",
        933: "brainpoolP512r1",
        716: "secp521r1",
    }

    domain_parameters: Dict[int, Union[Tuple[str], Tuple[int, str]]] = {
        0: ("1024-bit MODP Group with 160-bit Prime Order Subgroup",),
        1: ("2048-bit MODP Group with 224-bit Prime Order Subgroup",),
        2: ("2048-bit MODP Group with 256-bit Prime Order Subgroup",),
        3: ("Reserved for Future Use",),
        4: ("Reserved for Future Use",),
        5: ("Reserved for Future Use",),
        6: ("Reserved for Future Use",),
        7: ("Reserved for Future Use",),
        8: (
            409,
            "NIST P-192 (secp192r1)",
        ),  #  https://stackoverflow.com/a/41953717/6077951
        9: (
            923,
            "BrainpoolP192r1",
        ),
        10: (
            713,
            "NIST P-224 (secp224r1) (can't be used with im)",
        ),
        11: (
            925,
            "BrainpoolP224r1",
        ),
        12: (
            415,
            "NIST P-256 (secp256r1)",
        ),  #  https://stackoverflow.com/a/41953717/6077951
        13: (
            927,
            "BrainpoolP256r1",
        ),
        14: (
            929,
            "BrainpoolP320r1",
        ),
        15: (
            715,
            "NIST P-384 (secp384r1)",
        ),
        16: (
            931,
            "BrainpoolP384r1",
        ),
        17: (
            933,
            "BrainpoolP512r1",
        ),
        18: (
            716,
            "NIST P-521 (secp521r1)",
        ),
        19: ("Reserved for Future Use",),
        20: ("Reserved for Future Use",),
        21: ("Reserved for Future Use",),
        22: ("Reserved for Future Use",),
        23: ("Reserved for Future Use",),
        24: ("Reserved for Future Use",),
        25: ("Reserved for Future Use",),
        26: ("Reserved for Future Use",),
        27: ("Reserved for Future Use",),
        28: ("Reserved for Future Use",),
        29: ("Reserved for Future Use",),
        30: ("Reserved for Future Use",),
        31: ("Reserved for Future Use",),
    }

    id_pace = "0.4.0.127.0.7.2.2.4"
    pace_protocol_dict = {
        encode_oid_string(id_pace + ".1.1"): "id-PACE-DH-GM-3DES-CBC-CBC",
        encode_oid_string(id_pace + ".1.2"): "id-PACE-DH-GM-AES-CBC-CMAC-128",
        encode_oid_string(id_pace + ".1.3"): "id-PACE-DH-GM-AES-CBC-CMAC-192",
        encode_oid_string(id_pace + ".1.4"): "id-PACE-DH-GM-AES-CBC-CMAC-256",
        encode_oid_string(id_pace + ".2.1"): "id-PACE-ECDH-GM-3DES-CBC-CBC",
        encode_oid_string(id_pace + ".2.2"): "id-PACE-ECDH-GM-AES-CBC-CMAC-128",
        encode_oid_string(id_pace + ".2.3"): "id-PACE-ECDH-GM-AES-CBC-CMAC-192",
        encode_oid_string(id_pace + ".2.4"): "id-PACE-ECDH-GM-AES-CBC-CMAC-256",
        encode_oid_string(id_pace + ".3.1"): "id-PACE-DH-IM-3DES-CBC-CBC",
        encode_oid_string(id_pace + ".3.2"): "id-PACE-DH-IM-AES-CBC-CMAC-128",
        encode_oid_string(id_pace + ".3.3"): "id-PACE-DH-IM-AES-CBC-CMAC-192",
        encode_oid_string(id_pace + ".3.4"): "id-PACE-DH-IM-AES-CBC-CMAC-256",
        encode_oid_string(id_pace + ".4.1"): "id-PACE-ECDH-IM-3DES-CBC-CBC",
        encode_oid_string(id_pace + ".4.2"): "id-PACE-ECDH-IM-AES-CBC-CMAC-128",
        encode_oid_string(id_pace + ".4.3"): "id-PACE-ECDH-IM-AES-CBC-CMAC-192",
        encode_oid_string(id_pace + ".4.4"): "id-PACE-ECDH-IM-AES-CBC-CMAC-256",
        encode_oid_string(id_pace + ".6.2"): "id-PACE-ECDH-CAM-AES-CBC-CMAC-128",
        encode_oid_string(id_pace + ".6.3"): "id-PACE-ECDH-CAM-AES-CBC-CMAC-192",
        encode_oid_string(id_pace + ".6.4"): "id-PACE-ECDH-CAM-AES-CBC-CMAC-256",
    }

    supported_pace: List[Tuple[bytes, int]] = find_paceinfos(security_infos_efca)

    if supported_pace == []:
        raise PACEError("[-] No supported PACEInfo found.")

    used_pace = supported_pace[0]
    used_pace_str = pace_protocol_dict[used_pace[0]].split("-")

    if pub_key_ref == "MRZ":
        key_seed = hashlib.sha1(secret).digest()
    if used_pace_str[4] == "3DES":
        k_dec = compute_key(key_seed, "pace", "3DES")
    else:  # AES
        k_dec = compute_key(key_seed, "pace", "AES-" + used_pace_str[7])

    payload = b"\x80" + used_pace[0][1:]
    if pub_key_ref == "MRZ":
        payload += b"\x83" + b"\x01" + b"\x01"
    elif pub_key_ref == "CAN":
        payload += b"\x83" + b"\x01" + b"\x02"
    else:
        raise PACEError("[-] Only MRZ and CAN are supported.")

    # if more than one set of DomainParameters is available:
    # payload = b"\x84" + reference of ...

    # MSE: AT
    ########data = send(sm_object, APDU(b"\x00", b"\x22", b"\xC1", b"\xA4", Lc=nb(len(payload)), cdata=payload))

    # Query encrypted nonce
    ########data = send(sm_object,APDU(b"\x10", b"\x86", b"\x00", b"\x00", Lc=b"\x02", cdata=b"\x7C\x00", Le=b"\x00"))
    data = bytes.fromhex("7C12801095A3A016522EE98D01E76CB6B98B42C3")
    # THE EXAMPLES ARE TAKEN FROM ICAO Doc 9303-11 App G-1

    i = asn1_node_root(data)  # Dynamic authentication data (0x7C)
    i = asn1_node_first_child(data, i)  # Encrypted Nonce (0x80)
    encrypted_nonce = asn1_get_value(data, i)

    if used_pace_str[4] == "3DES":
        decrypted_nonce = DES3.new(k_dec, DES3.MODE_CBC, iv=bytes([0] * 8)).decrypt(encrypted_nonce)
    else:
        decrypted_nonce = AES.new(k_dec, AES.MODE_CBC, iv=bytes([0] * 16)).decrypt(encrypted_nonce)

    assert decrypted_nonce == bytes.fromhex("3F00C4D39D153F2B2A214A078D899B22")

    if used_pace_str[3] == "GM":
        if used_pace_str[2] == "ECDH":
            used_domain_par = domain_parameters[used_pace[1]]
            if not isinstance(used_domain_par[0], int):
                raise PACEError("[-] These Domain parameters are not supported.")

            # ec_key_pair = EC.gen_params(used_domain_par[0])
            # ec_key_pair.gen_key()
            ec_key_pair = EC.load_key("tests/brainpoolP256r1.pem")
            ec_pub_key = ec_key_pair.pub().get_key()

            payload = b"\x81" + asn1_len(ec_pub_key) + ec_pub_key
            payload = b"\x7C" + asn1_len(payload) + payload

            # data = send(sm_object,APDU(b"\x10", b"\x86", b"\x00", b"\x00", Lc=nb(len(payload)), cdata=payload, Le=b"\x00"))
            data = bytes.fromhex(
                "7C43824104824FBA91C9CBE26BEF53A0EBE7342A3BF178CEA9F45DE0B70AA601651FBA3F5730D8C879AAA9C9F73991E61B58F4D52EB87A0A0C709A49DC63719363CCD13C54"
            )

            i = asn1_node_root(data)  # Dynamic Authentication Data (0x7C)
            i = asn1_node_first_child(data, i)  # Mapping Data (0x82)

            card_pace_pub_key = EC.pub_key_from_params(
                used_domain_par[0], asn1_get_value(data, i)
            )  # https://gitlab.com/m2crypto/m2crypto/-/blob/master/tests/test_ecdsa.py

            print((card_pace_pub_key.pub().get_key().hex()))
            # A different ecdsa library might be needed.
            shared_secret = ec_key_pair.compute_dh_key(card_pace_pub_key.pub())

            ec_pem_buf = BIO.MemoryBuffer()
            card_pace_pub_key.save_pub_key_bio(ec_pem_buf)
            ec_pem = ec_pem_buf.read()

            cmd = (
                "openssl ecparam -name "
                + openssl_nid_to_name[used_domain_par[0]]
                + " -param_enc explicit -text -noout"
            )
            ec_parameters, err = execute(cmd, ec_pem)

            generator = bytes.fromhex(
                ec_parameters.split(b"Generator (uncompressed):", 1)[1]
                .split(b"Order:", 1)[0]
                .replace(b"    ", b"")
                .replace(b":", b"")
                .replace(b"\n", b"")
                .decode("utf-8")
            )
            if generator[0] != 0x04:
                raise PACEError("[-] Problem in openssl.")

            generator = generator[1:]
            generator_x = generator[: len(generator) // 2]
            generator_y = generator[len(generator) // 2 :]