def main() -> None:
    """Main function."""
    # Set the folder for data (certificates, keys)
    data_dir = path.join(path.dirname(__file__), 'data')
    os.makedirs(data_dir, exist_ok=True)
    # load private key from data folder
    private_key_2048_ca = load_private_key(path.join(data_dir, "ca_privatekey_rsa2048.pem"))
    assert isinstance(private_key_2048_ca, RSAPrivateKey)
    # load associated public key
    public_key_2048_ca = load_public_key(path.join(data_dir, "ca_publickey_rsa2048.pem"))
    assert isinstance(public_key_2048_ca, RSAPublicKey)
    subject = issuer = generate_name_struct("first", "CZ")
    # generate CA certificate (self-signed certificate)
    ca_cert = generate_certificate(subject=subject, issuer=issuer, subject_public_key=public_key_2048_ca,
                                   issuer_private_key=private_key_2048_ca, serial_number=0x1,
                                   if_ca=True, duration=20 * 365, path_length=5)
    # Save certificates in two formats (pem and der)
    save_crypto_item(ca_cert, path.join(data_dir, "ca_cert_pem.crt"))
    save_crypto_item(ca_cert, path.join(data_dir, "ca_cert_der.crt"), encoding_type=Encoding.DER)
    print("The CA Certificate was created in der and pem format.")

    # Create first chain certificate signed by private key of the CA certificate
    subject_crt1 = generate_name_struct("second", "CZ")
    public_key_2048_subject = load_public_key(path.join(data_dir, "crt_publickey_rsa2048.pem"))
    assert isinstance(public_key_2048_subject, RSAPublicKey)
    crt1 = generate_certificate(subject=subject_crt1, issuer=issuer, subject_public_key=public_key_2048_subject,
                                issuer_private_key=private_key_2048_ca,
                                serial_number=0x3cc30000babadeda, if_ca=False, duration=20 * 365)
    # Save certificates in two formats (pem and der)
    save_crypto_item(crt1, path.join(data_dir, "crt_pem.crt"))
    save_crypto_item(crt1, path.join(data_dir, "crt_der.crt"), encoding_type=Encoding.DER)
    print("The first chain certificate (signed by CA certificate) was created in der and pem format.")

    # First chain certificate signed by private key of the CA certificate
    subject_crt2 = generate_name_struct("third", "CZ")
    private_key_2048_subject_1 = load_private_key(path.join(data_dir, "chain_privatekey_rsa2048.pem"))
    assert isinstance(private_key_2048_subject_1, RSAPrivateKey)
    public_key_2048_subject_1 = load_public_key(path.join(data_dir, "chain_publickey_rsa2048.pem"))
    assert isinstance(public_key_2048_subject_1, RSAPublicKey)
    crt1 = generate_certificate(subject=subject_crt2, issuer=issuer, subject_public_key=public_key_2048_subject_1,
                                issuer_private_key=private_key_2048_ca,
                                serial_number=0x2, if_ca=True, duration=20 * 365, path_length=3)
    # Save certificates in two formats (pem and der)
    save_crypto_item(crt1, path.join(data_dir, "chain_crt_pem.crt"))
    save_crypto_item(crt1, path.join(data_dir, "chain_crt_der.crt"), encoding_type=Encoding.DER)
    print("The first chain certificate (signed by CA certificate) was created in der and pem format.")

    # Create first chain certificate signed by private key of first certificate
    subject_crt3 = generate_name_struct("fourth", "CZ")
    issuer_crt3 = subject_crt2
    public_key_2048_subject_2 = load_public_key(path.join(data_dir, "chain_crt2_publickey_rsa2048.pem"))
    assert isinstance(public_key_2048_subject_2, RSAPublicKey)
    crt1 = generate_certificate(subject=subject_crt3, issuer=issuer_crt3, subject_public_key=public_key_2048_subject_2,
                                issuer_private_key=private_key_2048_subject_1,
                                serial_number=0x3cc30000babadeda, if_ca=False, duration=20 * 365)
    # Save certificates in two formats (pem and der)
    save_crypto_item(crt1, path.join(data_dir, "chain_crt2_pem.crt"))
    save_crypto_item(crt1, path.join(data_dir, "chain_crt2_der.crt"), encoding_type=Encoding.DER)
    print("The second certificate in a chain was created in der and pem format.")
示例#2
0
def generate(config: TextIO, output: BinaryIO, encoding: str,
             force: bool) -> None:
    """Generate certificate."""
    logger.info("Generating Certificate...")
    logger.info("Loading configuration from yml file...")

    check_destination_dir(output.name, force)
    check_file_exists(output.name, force)

    config_data = load_configuration(config.name)
    cert_config = CertificateParametersConfig(config_data)

    priv_key = load_private_key(cert_config.issuer_private_key)
    pub_key = load_public_key(cert_config.subject_public_key)

    certificate = generate_certificate(
        subject=cert_config.subject_name,
        issuer=cert_config.issuer_name,
        subject_public_key=pub_key,
        issuer_private_key=priv_key,
        serial_number=cert_config.serial_number,
        duration=cert_config.duration,
        if_ca=cert_config.BasicConstrains_ca,
        path_length=cert_config.BasicConstrains_path_length,
    )
    logger.info("Saving the generated certificate to the specified path...")
    encoding_type = Encoding.PEM if encoding.lower() == "pem" else Encoding.DER
    save_crypto_item(certificate, output.name, encoding_type=encoding_type)
    logger.info("Certificate generated successfully...")
    click.echo(
        f"The certificate file has been created: {os.path.abspath(output.name)}"
    )
示例#3
0
    def _get_dck(dck_key_path: str) -> bytes:
        """Loads the Debugger Public Key (DCK).

        :return: binary representing the DCK key
        """
        dck_key = crypto.load_public_key(file_path=dck_key_path)
        assert isinstance(dck_key, crypto.RSAPublicKey)
        return rsa_key_to_bytes(key=dck_key, exp_length=4)
示例#4
0
    def _get_dck(dck_key_path: str) -> bytes:
        """Loads the Debugger Public Key (DCK).

        :return: binary representing the DCK key
        """
        dck_key = crypto.load_public_key(file_path=dck_key_path)
        assert isinstance(dck_key, crypto.EllipticCurvePublicKey)
        return ecc_key_to_bytes(key=dck_key, length=66)
示例#5
0
    def _get_rot_pub(rot_pub_id: int, rot_pub_keys: List[str]) -> bytes:
        """Loads the vendor RoT Public key that corresponds to the private key used for singing.

        :return: binary representing the rotk public key
        """
        root_key = rot_pub_keys[rot_pub_id]
        root_public_key = crypto.load_public_key(root_key)
        length = root_public_key.key_size // 8
        assert isinstance(root_public_key, crypto.EllipticCurvePublicKey)
        data = ecc_key_to_bytes(root_public_key, length=length)
        return data
示例#6
0
def _extract_public_key(file_path: str, password: Optional[str]) -> crypto.RSAPublicKey:
    cert_candidate = crypto.load_certificate(file_path)
    if cert_candidate:
        return cert_candidate.public_key()
    private_candidate = crypto.load_private_key(file_path, password.encode() if password else None)
    if private_candidate:
        return private_candidate.public_key()
    public_candidate = crypto.load_public_key(file_path)
    if public_candidate:
        return public_candidate
    assert False, f"Unable to load secret file '{file_path}'."
示例#7
0
    def _get_rot_pub(rot_pub_id: int, rot_pub_keys: List[str]) -> bytes:
        """Loads the vendor RoT private key.

         It corresponds to the (default) position zero RoT key in the rot_meta list of public keys.
         Derive public key from RoT private keys and converts it to the bytes.

        :return: binary representing the rotk public key
        """
        pub_key_path = rot_pub_keys[rot_pub_id]
        pub_key = crypto.load_public_key(pub_key_path)
        assert isinstance(pub_key, crypto.RSAPublicKey)
        return rsa_key_to_bytes(key=pub_key, exp_length=4)
示例#8
0
 def create_ctrk_table(rot_pub_keys: List[str]) -> bytes:
     """Creates ctrk table."""
     if len(rot_pub_keys) == 1:
         return bytes()
     ctrk_table = bytes()
     for pub_key_path in rot_pub_keys:
         pub_key = crypto.load_public_key(pub_key_path)
         assert isinstance(pub_key, crypto.EllipticCurvePublicKey)
         key_length = pub_key.key_size
         data = ecc_key_to_bytes(key=pub_key, length=key_length // 8)
         ctrk_hash = internal_backend.hash(data=data,
                                           algorithm=f'sha{key_length}')
         ctrk_table += ctrk_hash
     return ctrk_table
示例#9
0
    def _get_rot_meta(used_root_cert: int, rot_pub_keys: List[str]) -> bytes:
        """Creates the RoT meta-data required by the device to corroborate.

        The meta-data is created by getting the public numbers (modulus and exponent)
        from each of the RoT public keys, hashing them and combing together.

        :return: binary representing the rot-meta data
        """
        rot_meta = bytearray(528)
        for index, rot_key in enumerate(rot_pub_keys):
            rot = crypto.load_public_key(file_path=rot_key)
            assert isinstance(rot, crypto.EllipticCurvePublicKey)
            data = ecc_key_to_bytes(key=rot, length=66)
            rot_meta[index * 132:(index + 1) * 132] = data
        return bytes(rot_meta)
示例#10
0
    def _get_rot_meta(used_root_cert: int, rot_pub_keys: List[str]) -> bytes:
        """Creates the RoT meta-data required by the device to corroborate.

        The meta-data is created by getting the public numbers (modulus and exponent)
        from each of the RoT public keys, hashing them and combing together.

        :return: binary representing the rot-meta data
        """
        rot_meta = bytearray(128)
        for index, rot_key in enumerate(rot_pub_keys):
            rot = crypto.load_public_key(file_path=rot_key)
            assert isinstance(rot, crypto.RSAPublicKey)
            data = rsa_key_to_bytes(key=rot, exp_length=3, modulus_length=None)
            result = internal_backend.hash(data)
            rot_meta[index * 32:(index + 1) * 32] = result
        return bytes(rot_meta)
示例#11
0
    def _get_rot_pub(rot_pub_id: int, rot_pub_keys: List[str]) -> bytes:
        """Creates RoTKey_Pub (2 element 16-bit array (little endian).

        CTRKtable index (RoT meta-data) of the public key used by the vendor to sign the DC.
        Curve identifier:
        - Secp256r1: 0x0001
        - Secp384r1: 0x0002
        - Secp521r1: 0x0003

        :return: binary representation
        """
        pub_key_path = rot_pub_keys[rot_pub_id]
        pub_key = crypto.load_public_key(pub_key_path)
        assert isinstance(pub_key, crypto.EllipticCurvePublicKey)
        curve_index = {256: 1, 386: 2, 521: 3}[pub_key.curve.key_size]
        return pack('<2H', rot_pub_id, curve_index)
示例#12
0
def test_generate_rsa_key(tmpdir) -> None:
    """Test generate rsa key pair."""

    cmd = f'genkey {os.path.join(tmpdir, "key_rsa.pem")}'
    runner = CliRunner()
    result = runner.invoke(main, cmd.split())
    assert result.exit_code == 0
    assert os.path.isfile(os.path.join(tmpdir, "key_rsa.pem"))
    assert os.path.isfile(os.path.join(tmpdir, "key_rsa.pub"))

    pub_key_from_file = load_public_key(os.path.join(tmpdir, "key_rsa.pub"))
    assert isinstance(pub_key_from_file, RSAPublicKey)
    assert pub_key_from_file.key_size == 2048

    priv_key_from_file = load_private_key(os.path.join(tmpdir, "key_rsa.pem"))
    assert isinstance(priv_key_from_file, RSAPrivateKey)
    assert priv_key_from_file.key_size == 2048
示例#13
0
def test_generate_ecc_key(tmpdir, protocol_version, curve_name) -> None:
    """Test generate ecc key pair."""
    pem_path = os.path.join(tmpdir, f'{curve_name}_key_ecc.pem')
    pub_path = os.path.join(tmpdir, f'{curve_name}_key_ecc.pub')

    cmd = f'-p {protocol_version} genkey {pem_path}'
    runner = CliRunner()
    result = runner.invoke(main, cmd.split())
    assert result.exit_code == 0
    assert os.path.isfile(pem_path)
    assert os.path.isfile(pub_path)

    pub_key_from_file = load_public_key(pub_path)
    assert isinstance(pub_key_from_file, EllipticCurvePublicKey)
    assert pub_key_from_file.curve.name == curve_name

    priv_key_from_file = load_private_key(pem_path)
    assert isinstance(priv_key_from_file, EllipticCurvePrivateKey)
    assert pub_key_from_file.curve.name == curve_name
示例#14
0
def main() -> None:
    """Main function."""
    # Set the folder for data (certificates, keys)
    data_dir = path.join(path.dirname(__file__), "data")
    os.makedirs(data_dir, exist_ok=True)
    # Load public key of CA certificate
    ca0_pubkey_rsa2048 = load_public_key(
        path.join(data_dir, "ca_publickey_rsa2048.pem"))
    # Load CA certificate
    ca0_cert = load_certificate(path.join(data_dir, "ca_cert_pem.crt"))
    # Obtain public key from CA certificate
    pubkey_from_ca0_cert = get_public_key_from_certificate(ca0_cert)
    # Check if public key of certificate has proper format
    assert isinstance(pubkey_from_ca0_cert, RSAPublicKey)
    # Compare CA's public key from file and the one from certificate
    if ca0_pubkey_rsa2048.public_numbers(
    ) != pubkey_from_ca0_cert.public_numbers():
        raise SPSDKError(
            "Keys are not the same (the one from disc and the one from cert)")
    # Load certificate, which is singed by CA
    crt = load_certificate(path.join(data_dir, "crt_pem.crt"))
    if not validate_certificate(crt, ca0_cert):
        raise SPSDKError("The certificate is not valid")
    print("The certificate was signed by the CA.")
    # Load chain of certificate
    chain = ["chain_crt2_pem.crt", "chain_crt_pem.crt", "ca_cert_pem.crt"]
    chain_cert = [
        load_certificate(path.join(data_dir, cert_name)) for cert_name in chain
    ]
    ch3_crt2 = load_certificate(path.join(data_dir, "chain_crt2_pem.crt"))
    ch3_crt = load_certificate(path.join(data_dir, "chain_crt_pem.crt"))
    ch3_ca = load_certificate(path.join(data_dir, "ca_cert_pem.crt"))
    # Validate the chain (if corresponding items in chain are singed by one another)
    if not validate_certificate_chain(chain_cert):
        raise SPSDKError("The certificate chain is not valid")
    print("The chain of certificates is valid.")
    # Checks if CA flag is set correctly
    if is_ca_flag_set(ch3_crt2):
        raise SPSDKError("CA flag is set")
    if not is_ca_flag_set(ch3_crt):
        raise SPSDKError("CA flag is not set")
    if not is_ca_flag_set(ch3_ca):
        raise SPSDKError("CA flag is not set")
示例#15
0
    def _get_rotk(rotk_priv_key: str, rot_pub_keys: List[str]) -> bytes:
        """Creates RoTKey_Pub (2 element 16-bit array (little endian).

        CTRKtable index (RoT meta-data) of the public key used by the vendor to sign the DC.
        Curve identifier:
        - Secp256r1: 0x0001
        - Secp384r1: 0x0002
        - Secp521r1: 0x0003

        :return: binary representation
        """
        priv_loaded = crypto.load_private_key(rotk_priv_key)
        pub_from_priv = priv_loaded.public_key()
        pub_numbers = pub_from_priv.public_numbers()
        rot_pub_numbers = [
            crypto.load_public_key(k).public_numbers() for k in rot_pub_keys
        ]
        key_index = rot_pub_numbers.index(pub_numbers)
        assert key_index is not None, "ROTK private key does not correspond to any of RotMeta public keys."
        curve_index = {256: 1, 384: 2, 521: 3}[pub_from_priv.key_size]
        return pack('<2H', key_index, curve_index)
示例#16
0
def main(json_conf: click.File, cert_path: str) -> None:
    """Utility for certificate generation."""
    logger.info("Generating Certificate...")
    logger.info("Loading configuration from json file...")

    json_content = json.load(json_conf)  # type: ignore
    cert_config = CertificateParametersConfig(json_content)

    priv_key = load_private_key(cert_config.issuer_private_key)
    pub_key = load_public_key(cert_config.subject_public_key)

    certificate = generate_certificate(
        subject=cert_config.subject_name,
        issuer=cert_config.issuer_name,
        subject_public_key=pub_key,
        issuer_private_key=priv_key,
        serial_number=cert_config.serial_number,
        duration=cert_config.duration,
        if_ca=cert_config.BasicConstrains_ca,
        path_length=cert_config.BasicConstrains_path_length)
    logger.info("Saving the generated certificate to the specified path...")
    save_crypto_item(certificate, cert_path)
    logger.info("Certificate generated successfully...")
示例#17
0
def test_is_key_pub(data_dir, file_name, expect_pub_key):
    key_path = path.join(data_dir, file_name)
    result = bool(load_public_key(key_path))
    assert result is expect_pub_key