Пример #1
0
def generate_update_default_resources_c(c_source: Path, vendor_id: uuid.UUID,
                                        class_id: uuid.UUID,
                                        private_key_file: Path,
                                        certificate_file: Path,
                                        do_overwrite: bool):
    """
    Generate update resources C source file for developer convenience.

    :param c_source: generated C source file
    :param vendor_id: vendor UUID
    :param class_id: class UUID
    :param private_key_file: private key file
    :param certificate_file: update certificate file
    :param do_overwrite: do overwrite existing file
    """

    if c_source.is_file() and not do_overwrite:
        logger.info('%s - exists', c_source)
        return

    vendor_id_str = pretty_print(vendor_id.bytes)
    class_id_str = pretty_print(class_id.bytes)

    cert_data = certificate_file.read_bytes()

    cert_str = pretty_print(cert_data)

    template = (SCRIPT_DIR / 'code_template.txt').read_text()

    public_key = ecdsa_helper.public_key_from_private(
        private_key_file.read_bytes())
    public_key_bytes = ecdsa_helper.public_key_to_bytes(public_key)
    update_public_key_str = pretty_print(public_key_bytes)

    c_source.write_text(
        template.format(vendor_id=vendor_id_str,
                        class_id=class_id_str,
                        cert=cert_str,
                        timestamp=time.strftime("%Y-%m-%d %H:%M:%S %Z"),
                        tool='manifest-dev-tool init',
                        version=__version__,
                        update_pub_key=update_public_key_str))
    logger.info('generated update source %s', c_source)
Пример #2
0
 def get_key(cls, private_key_bytes: bytes):
     public_key = ecdsa_helper.public_key_from_private(private_key_bytes)
     public_key_bytes = ecdsa_helper.public_key_to_bytes(public_key)
     return public_key_bytes
Пример #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'))
Пример #4
0
def test_create_happy_day_full(tmp_path_factory, fw_size, manifest_codec,
                               payload_format):
    global FILE_ID
    GEN_DIR.mkdir(exist_ok=True)
    happy_day_data = data_generator(tmp_path_factory, fw_size, ENCRYPTION_KEY)

    payload_file_path = happy_day_data['fw_file'].as_posix()
    if payload_format in ('combined', 'encrypted-combined'):
        generate_encrypted_package(happy_day_data)
        payload_file_path = happy_day_data['package_data']['out_file_name']

    manifest = None

    input_cfg = {
        'vendor': {
            'domain': 'pelion.com'
        },
        'device': {
            'model-name': 'my-device'
        },
        'priority': 15,
        'payload': {
            'url': '../test_data/{}_f_payload.bin'.format(FILE_ID),
            'file-path': payload_file_path,
            'format': payload_format
        },
        'component': 'MAIN'
    }
    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 payload_format in ('raw-binary', 'combined') and (FILE_ID % 2) == 0:
            component = 'TESTCOMP'
            input_cfg['component'] = component
        elif payload_format == 'encrypted-raw':
            input_cfg['component'] = component
            # encrypted payload with dummy metadata
            input_cfg['payload']['encrypted'] = {
                'digest': calc_digest(happy_day_data['encrypted_fw_file']),
                'size': happy_day_data['encrypted_fw_file'].stat().st_size
            }
            input_cfg['payload'][
                'url'] = '../test_data/{}_f_encrypted_payload.bin'.format(
                    FILE_ID)
        elif payload_format == 'encrypted-combined':
            input_cfg['component'] = component
            # create encrypted package
            generate_encrypted_package(happy_day_data)
            # encrypted payload with dummy metadata
            input_cfg['payload']['encrypted'] = {
                'digest': calc_digest(happy_day_data['encrypted_fw_file']),
                'size': happy_day_data['encrypted_fw_file'].stat().st_size
            }
            input_cfg['payload'][
                'url'] = '../test_data/{}_f_encrypted_payload.bin'.format(
                    FILE_ID)

        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())
    if 'encrypted' in input_cfg['payload']:
        # mimic service behaviour,
        # concatenate DER with dummy aes-128-bit key
        manifest_file.write_bytes(manifest + bytearray.fromhex('8110') +
                                  ENCRYPTION_KEY)
    else:
        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())

    if input_cfg['payload']['format'] == 'encrypted-raw':
        encrypted_payload_file = GEN_DIR / '{}_f_encrypted_payload.bin'.format(
            FILE_ID)
        encrypted_payload_file.write_bytes(
            happy_day_data['encrypted_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'))