Example #1
0
    def validate_primary_certification_in_vehicle_manifest(
            self, vin, primary_ecu_serial, vehicle_manifest):
        """
    Check the Primary's signature on the Vehicle Manifest and any other data
    the Primary is certifying, without diving into the individual ECU Manifests
    in the Vehicle Manifest.

    Raises an exception if there is an issue with the Primary's signature.
    No return value.
    """
        # If args don't match expectations, error out here.
        log.info(
            'Beginning validate_primary_certification_in_vehicle_manifest')
        uptane.formats.VIN_SCHEMA.check_match(vin)
        uptane.formats.ECU_SERIAL_SCHEMA.check_match(primary_ecu_serial)
        uptane.formats.SIGNABLE_VEHICLE_VERSION_MANIFEST_SCHEMA.check_match(
            vehicle_manifest)

        if primary_ecu_serial != vehicle_manifest['signed'][
                'primary_ecu_serial']:
            raise uptane.Spoofing(
                'Received a spoofed or mistaken vehicle manifest: '
                'the supposed origin Primary ECU (' +
                repr(primary_ecu_serial) + ') '
                'is not the same as what is signed in the vehicle manifest itself '
                + '(' +
                repr(vehicle_manifest['signed']['primary_ecu_serial']) + ').')

        # TODO: Consider mechanism for fetching keys from inventorydb itself,
        # rather than always registering them after Director svc starts up.
        if primary_ecu_serial not in self.ecu_public_keys:
            log.debug('Rejecting a vehicle manifest from a Primary ECU whose '
                      'key is not registered.')
            # Raise a fault for the offending ECU's XMLRPC request.
            raise uptane.UnknownECU(
                'The Director is not aware of the given Primary '
                'ECU Serial (' + repr(primary_ecu_serial) +
                '. Manifest rejected. If '
                'the ECU is new, Register the new ECU with its key in order to be '
                'able to submit its manifests.')

        ecu_public_key = self.ecu_public_keys[primary_ecu_serial]

        valid = tuf.keys.verify_signature(
            ecu_public_key,
            vehicle_manifest['signatures'][0],  # TODO: Fix assumptions.
            vehicle_manifest['signed'])

        if not valid:
            log.debug(
                'Rejecting a vehicle manifest because the Primary signature on it is '
                'not valid.It must be correctly signed by the expected Primary ECU '
                'key.')
            # Raise a fault for the offending ECU's XMLRPC request.
            raise tuf.BadSignatureError(
                'Sender supplied an invalid signature. '
                'Vehicle Manifest is questionable; discarding. If you see this '
                'persistently, it is possible that there is a man in the middle '
                'attack or misconfiguration.')
Example #2
0
    def validate_ecu_manifest(self, ecu_serial, signed_ecu_manifest):
        """
    Arguments:
      ecuid: uptane.formats.ECU_SERIAL_SCHEMA
      manifest: uptane.formats.SIGNABLE_ECU_VERSION_MANIFEST_SCHEMA
    """
        uptane.formats.SIGNABLE_ECU_VERSION_MANIFEST_SCHEMA.check_match(
            signed_ecu_manifest)

        # If it doesn't match expectations, error out here.

        if ecu_serial != signed_ecu_manifest['signed']['ecu_serial']:
            raise uptane.Spoofing(
                'Received a spoofed or mistaken manifest: supposed '
                'origin ECU (' + repr(ecu_serial) +
                ') is not the same as what is '
                'signed in the manifest itself (' +
                repr(signed_ecu_manifest['signed']['ecu_serial']) + ').')

        # TODO: Consider mechanism for fetching keys from inventorydb itself,
        # rather than always registering them after Director svc starts up.
        if ecu_serial not in self.ecu_public_keys:
            log.info('Validation failed on an ECU Manifest: ECU ' +
                     repr(ecu_serial) + ' is not registered.')
            # Raise a fault for the offending ECU's XMLRPC request.
            raise uptane.UnknownECU(
                'The Director is not aware of the given ECU '
                'SERIAL (' + repr(ecu_serial) +
                '. Manifest rejected. If the ECU is '
                'new, Register the new ECU with its key in order to be able to '
                'submit its manifests.')

        ecu_public_key = self.ecu_public_keys[ecu_serial]

        valid = tuf.keys.verify_signature(
            ecu_public_key,
            signed_ecu_manifest['signatures'][0],  # TODO: Fix assumptions.
            signed_ecu_manifest['signed'])

        if not valid:
            log.info(
                'Validation failed on an ECU Manifest: signature is not valid. It'
                'It must be correctly signed by the expected key for that ECU.'
            )
            # Raise a fault for the offending ECU's XMLRPC request.
            raise tuf.BadSignatureError(
                'Sender supplied an invalid signature. '
                'ECU Manifest is unacceptable. If you see this persistently, it is'
                'possible that the Primary is compromised or that there is a man in '
                'the middle attack or misconfiguration.')
Example #3
0
    def validate_ecu_manifest(self, ecu_serial, signed_ecu_manifest):
        """
    Arguments:
      ecuid: uptane.formats.ECU_SERIAL_SCHEMA
      manifest: uptane.formats.SIGNABLE_ECU_VERSION_MANIFEST_SCHEMA
    """
        uptane.formats.ECU_SERIAL_SCHEMA.check_match(ecu_serial)
        uptane.formats.SIGNABLE_ECU_VERSION_MANIFEST_SCHEMA.check_match(
            signed_ecu_manifest)

        # If it doesn't match expectations, error out here.

        if ecu_serial != signed_ecu_manifest['signed']['ecu_serial']:
            raise uptane.Spoofing(
                'Received a spoofed or mistaken manifest: supposed '
                'origin ECU (' + repr(ecu_serial) +
                ') is not the same as what is '
                'signed in the manifest itself (' +
                repr(signed_ecu_manifest['signed']['ecu_serial']) + ').')

        if ecu_serial not in inventory.ecu_public_keys:
            log.info('Validation failed on an ECU Manifest: ECU ' +
                     repr(ecu_serial) + ' is not registered.')
            raise uptane.UnknownECU(
                'The Director is not aware of the given ECU '
                'SERIAL (' + repr(ecu_serial) +
                '. Manifest rejected. If the ECU is '
                'new, Register the new ECU with its key in order to be able to '
                'submit its manifests.')

        ecu_public_key = inventory.ecu_public_keys[ecu_serial]

        valid = uptane.common.verify_signature_over_metadata(
            ecu_public_key,
            signed_ecu_manifest['signatures']
            [0],  # TODO: Fix single-signature assumption
            signed_ecu_manifest['signed'],
            DATATYPE_ECU_MANIFEST)

        if not valid:
            log.info(
                'Validation failed on an ECU Manifest: signature is not valid. '
                'It must be correctly signed by the expected key for that ECU.'
            )
            raise tuf.BadSignatureError(
                'Sender supplied an invalid signature. '
                'ECU Manifest is unacceptable. If you see this persistently, it is '
                'possible that the Primary is compromised or that there is a man in '
                'the middle attack or misconfiguration.')
Example #4
0
    def validate_primary_certification_in_vehicle_manifest(
            self, vin, primary_ecu_serial, vehicle_manifest):
        """
    Check the Primary's signature on the Vehicle Manifest and any other data
    the Primary is certifying, without diving into the individual ECU Manifests
    in the Vehicle Manifest.

    Raises an exception if there is an issue with the Primary's signature.
    No return value.
    """
        # If args don't match expectations, error out here.
        log.info(
            'Beginning validate_primary_certification_in_vehicle_manifest')
        uptane.formats.VIN_SCHEMA.check_match(vin)
        uptane.formats.ECU_SERIAL_SCHEMA.check_match(primary_ecu_serial)
        uptane.formats.SIGNABLE_VEHICLE_VERSION_MANIFEST_SCHEMA.check_match(
            vehicle_manifest)

        if primary_ecu_serial != vehicle_manifest['signed'][
                'primary_ecu_serial']:
            raise uptane.Spoofing(
                'Received a spoofed or mistaken vehicle manifest: '
                'the supposed origin Primary ECU (' +
                repr(primary_ecu_serial) + ') '
                'is not the same as what is signed in the vehicle manifest itself '
                + '(' +
                repr(vehicle_manifest['signed']['primary_ecu_serial']) + ').')

        # # TODO: Consider mechanism for fetching keys from inventorydb itself,
        # # rather than always registering them after Director svc starts up.
        # if primary_ecu_serial not in inventory.ecu_public_keys:
        #   log.debug(
        #       'Rejecting a vehicle manifest from a Primary ECU whose '
        #       'key is not registered.')
        #   raise uptane.UnknownECU('The Director is not aware of the given Primary '
        #       'ECU Serial (' + repr(primary_ecu_serial) + '. Manifest rejected. If '
        #       'the ECU is new, Register the new ECU with its key in order to be '
        #       'able to submit its manifests.')

        ecu_public_key = inventory.get_ecu_public_key(primary_ecu_serial)

        # Here, we check to see if the key that signed the Vehicle Manifest is the
        # same key as ecu_public_key (the one the director expects), so that we can
        # generate a more informative error, allowing user/debugger to distinguish
        # between a bad signature ostensibly from the right key and a signature
        # from the wrong key.
        # TODO: Fix(?) assumption that one signature is used below.
        keyid_used_in_signature = vehicle_manifest['signatures'][0]['keyid']
        # Note, though, that there could be some edge cases here that the TUF code
        # might actually resolve: for example, if the keyid hash algorithm used
        # in the signature is not the same one as the one used in the key listing,
        # this check would provide a false failure. So we don't raise an error here,
        # and instead just log this difference and let the final arbiter of the
        # validity of the signature be the dedicated code in tuf.keys.
        if keyid_used_in_signature != ecu_public_key['keyid']:
            log.info(
                'Key used to sign Vehicle Manifest has a different keyid from that '
                'listed in the inventory DB. Expect signature validation to fail, '
                'unless the key is the same but the keyid differently hashed. '
                'Expected keyid: ' + repr(ecu_public_key['keyid']) +
                '; keyid used '
                'in signature: ' + repr(keyid_used_in_signature))

        if tuf.conf.METADATA_FORMAT == 'der':
            # To check the signature, we have to make sure to encode the data as it
            # was when the signature was made. If we're using ASN.1/DER as the
            # data format/encoding, then we convert the 'signed' portion of the data
            # back to ASN.1/DER to check it.
            # Further, since for ASN.1/DER, a SHA256 hash is taken of the data and
            # *that* is what is signed, we perform that hashing as well and retrieve
            # the raw binary digest.
            data_to_check = asn1_codec.convert_signed_metadata_to_der(
                vehicle_manifest, DATATYPE_VEHICLE_MANIFEST, only_signed=True)
            data_to_check = hashlib.sha256(data_to_check).digest()

        else:
            data_to_check = vehicle_manifest['signed']

        valid = uptane.common.verify_signature_over_metadata(
            ecu_public_key,
            vehicle_manifest['signatures'][0],  # TODO: Fix assumptions.
            vehicle_manifest['signed'],
            DATATYPE_VEHICLE_MANIFEST)

        if not valid:
            log.debug(
                'Rejecting a vehicle manifest because the Primary signature on it is '
                'not valid. It must be correctly signed by the expected Primary ECU '
                'key.')
            raise tuf.BadSignatureError(
                'Sender supplied an invalid signature. '
                'Vehicle Manifest is questionable; discarding. If you see this '
                'persistently, it is possible that there is a man in the middle '
                'attack or misconfiguration.')
Example #5
0
 def test_bad_signature_error(self):
     bad_signature_error = tuf.BadSignatureError('bad_role')
     logger.error(bad_signature_error)