예제 #1
0
    def do_parse(cls, manifest_data: bytes, certificate_data: bytes,
                 public_key_data: bytes, private_key_data: bytes):
        dom = None

        public_key = None
        if private_key_data:
            public_key = ecdsa_helper.public_key_from_private(private_key_data)
        elif certificate_data:
            try:
                public_key = ecdsa_helper.public_key_from_certificate(
                    certificate_data)
            except ValueError as ex:
                raise AssertionError('Malformed certificate') from ex
        elif public_key_data:
            public_key = ecdsa_helper.public_key_from_bytes(public_key_data)

        for codec_class in ManifestVersion.list_codecs():
            try:
                dom = codec_class.decode(manifest_data, public_key)
                break
            except PyAsn1Error:
                continue
        if not dom:
            raise AssertionError('Malformed manifest')

        logging.info(
            '\n----- Manifest dump start -----\n'
            '%s----- Manifest dump end -----',
            yaml.dump(dom, default_flow_style=False))
예제 #2
0
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

from manifesttool.dev_tool.actions.init import generate_credentials
from manifesttool.mtool import mtool
from manifesttool.mtool.actions.create import CreateAction
from manifesttool.mtool.actions.parse import ParseAction
from manifesttool.mtool.asn1 import ManifestVersion

logging.basicConfig(
    stream=sys.stdout,
    format='%(asctime)s %(levelname)s %(message)s',
    level=logging.DEBUG
)

@pytest.fixture(params=ManifestVersion.list_codecs())
def happy_day_data(
        tmp_path_factory: TempPathFactory,
        request
):
    tmp_path = tmp_path_factory.mktemp("data")
    key_file = tmp_path / 'dev.key.pem'
    certificate_file = tmp_path / 'dev.cert.der'
    manifest_version = request.param  # Type[ManifestAsnCodecBase]
    generate_credentials(
        key_file=key_file,
        certificate_file=certificate_file,
        do_overwrite=False,
        cred_valid_time=8
    )
    fw_file = tmp_path / 'fw.bin'
예제 #3
0
def test_create_happy_day_full(tmp_path_factory, fw_size):
    global FILE_ID
    GEN_DIR.mkdir(exist_ok=True)
    happy_day_data = data_generator(tmp_path_factory, fw_size)
    manifest = None
    for manifest_codec in ManifestVersion.list_codecs():
        input_cfg = {
            'vendor': {
                'domain': 'arm.com'
            },
            'device': {
                'model-name': 'my-device'
            },
            'priority': 15,
            'payload': {
                'url': '../test_data/{}_f_payload.bin'.format(FILE_ID),
                'file-path': happy_day_data['fw_file'].as_posix(),
                'format': 'raw-binary'
            }
        }
        if issubclass(manifest_codec, ManifestAsnCodecV1):
            version = 100500
            version_file = GEN_DIR / '{}_f_version_{}.txt'.format(
                FILE_ID, manifest_codec.get_name())
            version_file.write_text(str(version))
        else:
            component = 'MAIN'
            if (FILE_ID % 2) == 0:
                component = 'TESTCOMP'
                input_cfg['component'] = component
            elif (FILE_ID % 3) == 0:
                input_cfg['component'] = component
            version = '100.500.0'

            version_file = GEN_DIR / '{}_f_version_{}.txt'.format(
                FILE_ID, manifest_codec.get_name())
            version_file.write_text('.'.join(version))

            component_file = GEN_DIR / '{}_f_component.txt'.format(FILE_ID)
            component_file.write_text(component)

        manifest = CreateAction.do_create(
            pem_key_data=happy_day_data['key_file'].read_bytes(),
            input_cfg=input_cfg,
            fw_version=version,
            update_certificate=happy_day_data['certificate_file'],
            asn1_codec_class=manifest_codec)
        GEN_DIR.mkdir(exist_ok=True)

        manifest_file = GEN_DIR / '{}_f_manifest_{}.bin'.format(
            FILE_ID, manifest_codec.get_name())
        manifest_file.write_bytes(manifest)

        certificate_file = GEN_DIR / '{}_f_certificate.bin'.format(FILE_ID)
        certificate_file.write_bytes(
            happy_day_data['certificate_file'].read_bytes())

        payload_file = GEN_DIR / '{}_f_payload.bin'.format(FILE_ID)
        payload_file.write_bytes(happy_day_data['fw_file'].read_bytes())

        orig_fw_file = GEN_DIR / '{}_f_curr_fw.bin'.format(FILE_ID)
        orig_fw_file.write_bytes(happy_day_data['fw_file'].read_bytes())

        new_fw_file = GEN_DIR / '{}_f_final_image.bin'.format(FILE_ID)
        new_fw_file.write_bytes(happy_day_data['fw_file'].read_bytes())

        dom = manifest_codec.decode(manifest, None)

        vendor_id_file = GEN_DIR / '{}_f_vendor_id.bin'.format(FILE_ID)
        if manifest_codec.get_name() == 'v3':
            vendor_id_bytes = dom['manifest']['vendor-id']
            class_id_bytes = dom['manifest']['class-id']
        elif manifest_codec.get_name() == 'v1':
            vendor_id_bytes = \
                dom['resource']['resource']['manifest']['vendorId']
            class_id_bytes = dom['resource']['resource']['manifest']['classId']
        else:
            raise AssertionError('invalid manifest version ' +
                                 manifest_codec.get_name())
        vendor_id_file.write_bytes(vendor_id_bytes)

        class_id_file = GEN_DIR / '{}_f_class_id.bin'.format(FILE_ID)

        class_id_file.write_bytes(class_id_bytes)

        key_file = GEN_DIR / '{}_f_priv_key.bin'.format(FILE_ID)
        private_key_data = happy_day_data['key_file'].read_bytes()
        key_file.write_bytes(private_key_data)

        public_key = ecdsa_helper.public_key_from_private(private_key_data)
        public_key_bytes = ecdsa_helper.public_key_to_bytes(public_key)

        public_key_file = GEN_DIR / '{}_f_pub_key.bin'.format(FILE_ID)
        public_key_file.write_bytes(public_key_bytes)

    FILE_ID += 1

    print('Full manifest in HEX to be viewed on '
          'https://asn1.io/asn1playground/ \n' +
          binascii.hexlify(manifest).decode('utf-8'))