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})
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.')
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)
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)
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))
def check_vin_registered(vin): try: Vehicle.objects.get(identifier=vin) except: raise uptane.UnknownVehicle('The given VIN, ' + repr(vin) + ', is not ' 'known.')