Example #1
0
    def add_target_for_ecu(self, vin, ecu_serial, target_filepath):
        """
    Add a target to the repository for a vehicle, marked as being for a
    specific ECU.

    The target file at the provided path will be analyzed, and its hashes
    and file length will be saved in target metadata in memory, which will then
    be signed with the appropriate Director keys and written to disk when the
    "write" method is called on the vehicle repository.
    """
        uptane.formats.VIN_SCHEMA.check_match(vin)
        uptane.formats.ECU_SERIAL_SCHEMA.check_match(ecu_serial)
        tuf.formats.RELPATH_SCHEMA.check_match(target_filepath)

        if vin not in self.vehicle_repositories:
            raise uptane.UnknownVehicle(
                'The VIN provided, ' + repr(vin) + ' is not '
                'that of a vehicle known to this Director.')

        # With the below off, we will save targets for ECUs we didn't previously
        # know exist.
        # elif ecu_serial not in inventory.ecu_public_keys:
        #   raise uptane.UnknownECU('The ECU Serial provided, ' + repr(ecu_serial) +
        #       ' is not that of an ECU known to this Director.')

        self.vehicle_repositories[vin].targets.add_target(
            target_filepath, custom={'ecu_serial': ecu_serial})
Example #2
0
def check_vin_registered(vin):

    _check_registration_is_sane(vin)

    if vin not in vehicle_manifests:
        # TODO: Should we also log here? Review logging before exceptions
        # throughout the reference implementation.
        raise uptane.UnknownVehicle('The given VIN, ' + repr(vin) + ', is not '
                                    'known.')
Example #3
0
def add_target_to_director(target_fname, filepath_in_repo, vin, ecu_serial):
  """
  For use in attacks and more specific demonstration.

  Given the filename of the file to add, the path relative to the repository
  root to which to copy it, the VIN of the vehicle whose repository it should
  be added to, and the ECU's serial directory, adds that file
  as a target file (calculating its cryptographic hash and length) to the
  appropriate repository for the given VIN.

  <Arguments>
    target_fname
      The full filename of the file to be added as a target to the Director's
      targets role metadata. This file doesn't have to be in any particular
      place; it will be copied into the repository directory structure.

    filepath_in_repo
      The path relative to the root of the repository's targets directory
      where this file will be kept and accessed by clients. (e.g. 'file1.txt'
      or 'brakes/firmware.tar.gz')

    ecu_serial
      The ECU to assign this target to in the targets metadata.
      Complies with uptane.formats.ECU_SERIAL_SCHEMA

  """

  I_TO_PRINT = TO_PRINT + uptane.YELLOW + '[adding_target_to_director(target_fname, filepath_in_repo, vin, ecu_serial)]: ' + ENDCOLORS
  #TODO: Print to be deleted
  print(str('%s %s %s %s %s %s %s %s %s' % (I_TO_PRINT, 'Adding target to director with target_fname:', target_fname, 'filepath_in_repo:', filepath_in_repo, 'vin:', vin, 'ecu_serial:', ecu_serial)))
  #TODO: Until here

  uptane.formats.VIN_SCHEMA.check_match(vin)
  uptane.formats.ECU_SERIAL_SCHEMA.check_match(ecu_serial)
  tuf.formats.RELPATH_SCHEMA.check_match(target_fname)
  tuf.formats.RELPATH_SCHEMA.check_match(filepath_in_repo)

  if vin not in director_service_instance.vehicle_repositories:
    raise uptane.UnknownVehicle('The VIN provided, ' + repr(vin) + ' is not '
        'that of a vehicle known to this Director.')

  repo = director_service_instance.vehicle_repositories[vin]
  repo_dir = repo._repository_directory

  print(LOG_PREFIX + 'Copying target file into place.')
  destination_filepath = os.path.join(repo_dir, 'targets', filepath_in_repo)

  # TODO: This should probably place the file into a common targets directory
  # that is then softlinked to all repositories.
  shutil.copy(target_fname, destination_filepath)

  print(LOG_PREFIX + 'Adding target ' + repr(target_fname) + ' for ECU ' +
      repr(ecu_serial))

  # This calls the appropriate vehicle repository.
  director_service_instance.add_target_for_ecu(
      vin, ecu_serial, destination_filepath)
Example #4
0
    def delete_target_for_vechile(self, vin, target_filepath):
        uptane.formats.VIN_SCHEMA.check_match(vin)
        tuf.formats.RELPATH_SCHEMA.check_match(target_filepath)

        if vin not in self.vehicle_repositories:
            raise uptane.UnknownVehicle(
                'The VIN provided, ' + repr(vin) + ' is not '
                'that of a vehicle known to this Director.')

        # With the below off, we will save targets for ECUs we didn't previously
        # know exist.
        # elif ecu_serial not in inventory.ecu_public_keys:
        #   raise uptane.UnknownECU('The ECU Serial provided, ' + repr(ecu_serial) +
        #       ' is not that of an ECU known to this Director.')

        self.vehicle_repositories[vin].targets.remove_target(target_filepath)
Example #5
0
    def register_vehicle_manifest(self, vin, primary_ecu_serial,
                                  signed_vehicle_manifest):
        """
    Saves the vehicle manifest in the InventoryDB, validating first the
    Primary's key on the full vehicle manifest, then each individual ECU
    Manifest's signature.

    If the Primary's signature over the whole Vehicle Manifest is invalid, then
    this raises an error (either tuf.BadSignatureError, uptane.Spoofing, or
    uptane.UnknownECU).

    Otherwise, if any of the individual ECU Manifests are invalid, those
    individual ECU Manifests are discarded, and others are processed. (No
    error is raised - only a warning.)

    Arguments:
      vin: vehicle's unique identifier, uptane.formats.VIN_SCHEMA
      primary_ecu_serial: Primary ECU's unique identifier,
                          uptane.formats.ECU_SERIAL_SCHEMA
      manifest: the vehicle manifest, as specified in the implementation
                specification and compliant with
                uptane.formats.SIGNABLE_VEHICLE_VERSION_MANIFEST_SCHEMA
                If, the metadata format is set to ASN.1/DER, then this will
                instead be compliant with uptane.formats.DER_DATA_SCHEMA,
                and will be decoded and converted back to be compliant with
                uptane.formats.SIGNABLE_VEHICLE_VERSION_MANIFEST_SCHEMA


    Exceptions:

        tuf.BadSignatureError
          if the Primary's signature on the vehicle manifest is invalid
          (An individual Secondary's signature on an ECU Version Manifests
          being invalid does not raise an exception, but instead results in
          a warning and that ECU Version Manifest alone being discarded.)

        uptane.Spoofing
          if the primary_ecu_serial argument does not match the ECU Serial
          for the Primary in the signed Vehicle Version Manifest.
          (As above, an ECU Version Manifest that is wrong in this respect is
          individually discarded with only a warning.)

        uptane.UnknownECU
          if the ECU Serial provided for the Primary is not known to this
          Director.
          (As above, an unknown Secondary ECU in an ECU Version Manifest is
          individually discarded with only a warning.)

        uptane.UnknownVehicle
          if the VIN provided is not known to this Director

    """
        uptane.formats.VIN_SCHEMA.check_match(vin)
        uptane.formats.ECU_SERIAL_SCHEMA.check_match(primary_ecu_serial)

        if tuf.conf.METADATA_FORMAT == 'der':
            # Check format and convert back to expected vehicle manifest format.
            uptane.formats.DER_DATA_SCHEMA.check_match(signed_vehicle_manifest)
            signed_vehicle_manifest = asn1_codec.convert_signed_der_to_dersigned_json(
                signed_vehicle_manifest, DATATYPE_VEHICLE_MANIFEST)

        uptane.formats.SIGNABLE_VEHICLE_VERSION_MANIFEST_SCHEMA.check_match(
            signed_vehicle_manifest)

        if vin not in inventory.ecus_by_vin:
            raise uptane.UnknownVehicle(
                'Received a vehicle manifest purportedly '
                'from a vehicle with a VIN that is not known to this Director.'
            )

        # Process Primary's signature on full manifest here.
        # If it doesn't match expectations, error out here.
        self.validate_primary_certification_in_vehicle_manifest(
            vin, primary_ecu_serial, signed_vehicle_manifest)

        # If the Primary's signature is valid, save the whole vehicle manifest to
        # the inventorydb.
        inventory.save_vehicle_manifest(vin, signed_vehicle_manifest)

        log.info(GREEN + ' Received a Vehicle Manifest from Primary ECU ' +
                 repr(primary_ecu_serial) +
                 ', with a valid signature from that ECU.' + ENDCOLORS)
        # TODO: Note that the above hasn't checked that the signature was from
        # a Primary, just from an ECU. Fix.

        # Validate signatures on and register all individual ECU manifests for each
        # ECU (may have multiple manifests per ECU).
        all_ecu_manifests = \
            signed_vehicle_manifest['signed']['ecu_version_manifests']

        for ecu_serial in all_ecu_manifests:
            ecu_manifests = all_ecu_manifests[ecu_serial]
            for manifest in ecu_manifests:
                try:
                    # This calls validate_ecu_manifest, which can raise the errors
                    # caught below.
                    self.register_ecu_manifest(vin, ecu_serial, manifest)
                except uptane.Spoofing as e:
                    log.warning(
                        RED +
                        'Discarding a spoofed or malformed ECU Manifest. Error '
                        ' from validating that ECU manifest follows:\n' +
                        ENDCOLORS + repr(e))
                except uptane.UnknownECU as e:
                    log.warning(
                        RED +
                        'Discarding an ECU Manifest from unknown ECU. Error from '
                        'validation attempt follows:\n' + ENDCOLORS + repr(e))
                except tuf.BadSignatureError as e:
                    log.warning(
                        RED +
                        'Rejecting an ECU Manifest whose signature is invalid, '
                        'from within an otherwise valid Vehicle Manifest. Error from '
                        'validation attempt follows:\n' + ENDCOLORS + repr(e))
Example #6
0
def check_vin_registered(vin):
    try:
        Vehicle.objects.get(identifier=vin)
    except:
        raise uptane.UnknownVehicle('The given VIN, ' + repr(vin) + ', is not '
                                    'known.')