def create_secondary_pinning_file(): """ Load the template pinned.json file and save a filled in version that points to the client's own directory. (The TUF repository that a Secondary points to is local, retrieved from the Primary and placed in the Secondary itself to validate the file internally.) Returns the filename of the created file. """ pinnings = json.load( open(demo.DEMO_SECONDARY_PINNING_FNAME, 'r', encoding='utf-8')) fname_to_create = os.path.join( demo.DEMO_DIR, 'pinned.json_secondary_' + demo.get_random_string(5)) atexit.register(clean_up_temp_file, fname_to_create) # To delete the temp pinned file after the script ends for repo_name in pinnings['repositories']: assert 1 == len( pinnings['repositories'][repo_name]['mirrors']), 'Config error.' mirror = pinnings['repositories'][repo_name]['mirrors'][0] mirror = mirror.replace('<full_client_dir>', CLIENT_DIRECTORY) pinnings['repositories'][repo_name]['mirrors'][0] = mirror with open(fname_to_create, 'wb') as fobj: fobj.write(canonicaljson.encode_canonical_json(pinnings)) return fname_to_create
def create_primary_pinning_file(): """ Load the template pinned.json file and save a filled in version that, for the Director repository, points to a subdirectory intended for this specific vehicle. Returns the filename of the created file. """ with open(demo.DEMO_PRIMARY_PINNING_FNAME, 'r') as fobj: pinnings = json.load(fobj) fname_to_create = os.path.join( demo.DEMO_DIR, 'pinned.json_primary_' + demo.get_random_string(5)) # Trigger deletion of temp_secondary* folder after demo script ends atexit.register(clean_up_temp_file, fname_to_create) assert 1 == len(pinnings['repositories'][demo.DIRECTOR_REPO_NAME] ['mirrors']), 'Config error.' mirror = pinnings['repositories'][demo.DIRECTOR_REPO_NAME]['mirrors'][0] mirror = mirror.replace('<VIN>', _vin) pinnings['repositories'][demo.DIRECTOR_REPO_NAME]['mirrors'][0] = mirror with open(fname_to_create, 'wb') as fobj: fobj.write(canonicaljson.encode_canonical_json(pinnings)) return fname_to_create
def clean_slate( use_new_keys=False, #client_directory_name=None, vin=_vin, ecu_serial=_ecu_serial, primary_host=None, primary_port=None): """ """ global secondary_ecu global _vin global _ecu_serial global _primary_host global _primary_port global nonce global CLIENT_DIRECTORY global attacks_detected _vin = vin _ecu_serial = ecu_serial if primary_host is not None: _primary_host = primary_host if primary_port is not None: _primary_port = primary_port CLIENT_DIRECTORY = os.path.join( uptane.WORKING_DIR, CLIENT_DIRECTORY_PREFIX + demo.get_random_string(5)) # Load the public timeserver key. key_timeserver_pub = demo.import_public_key('timeserver') # Set starting firmware fileinfo (that this ECU had coming from the factory) factory_firmware_fileinfo = { 'filepath': '/secondary_firmware.txt', 'fileinfo': { 'hashes': { 'sha512': '706c283972c5ae69864b199e1cdd9b4b8babc14f5a454d0fd4d3b35396a04ca0b40af731671b74020a738b5108a78deb032332c36d6ae9f31fae2f8a70f7e1ce', 'sha256': '6b9f987226610bfed08b824c93bf8b2f59521fce9a2adef80c495f363c1c9c44' }, 'length': 37 } } # Prepare this ECU's key. load_or_generate_key(use_new_keys) # Generate a trusted initial time for the Secondary. clock = tuf.formats.unix_timestamp_to_datetime(int(time.time())) clock = clock.isoformat() + 'Z' tuf.formats.ISO8601_DATETIME_SCHEMA.check_match(clock) # Create directory structure for the client and copy the root files from the # repositories. First, schedule the deletion of this directory to occur when # the script ends (so that it's deleted even if an error occurs here). atexit.register(clean_up_temp_folder) uptane.common.create_directory_structure_for_client( CLIENT_DIRECTORY, create_secondary_pinning_file(), { demo.IMAGE_REPO_NAME: demo.IMAGE_REPO_ROOT_FNAME, demo.DIRECTOR_REPO_NAME: os.path.join(demo.DIRECTOR_REPO_DIR, vin, 'metadata', 'root' + demo.METADATA_EXTENSION) }) # Configure tuf with the client's metadata directories (where it stores the # metadata it has collected from each repository, in subdirectories). tuf.conf.repository_directory = CLIENT_DIRECTORY # This setting should probably be called CLIENT_DIRECTORY instead, post-TAP4. # Initialize a full verification Secondary ECU. # This also generates a nonce to use in the next time query, sets the initial # firmware fileinfo, etc. secondary_ecu = secondary.Secondary( full_client_dir=CLIENT_DIRECTORY, director_repo_name=demo.DIRECTOR_REPO_NAME, vin=_vin, ecu_serial=_ecu_serial, ecu_key=ecu_key, time=clock, firmware_fileinfo=factory_firmware_fileinfo, timeserver_public_key=key_timeserver_pub) try: register_self_with_director() except xmlrpc_client.Fault: print( 'Registration with Director failed. Now assuming this Secondary is ' 'already registered.') try: register_self_with_primary() except xmlrpc_client.Fault: print( 'Registration with Primary failed. Now assuming this Secondary is ' 'already registered.') print('\n' + GREEN + ' Now simulating a Secondary that rolled off the ' 'assembly line\n and has never seen an update.' + ENDCOLORS) print("Generating this Secondary's first ECU Version Manifest and sending " "it to the Primary.") generate_signed_ecu_manifest() submit_ecu_manifest_to_primary()
def clean_slate( use_new_keys=False, # client_directory_name=None, vin=_vin, ecu_serial=_ecu_serial): """ """ I_TO_PRINT = TO_PRINT + uptane.YELLOW + '[clean_slate(use_new_keys, vin, ecu_serial)]: ' + uptane.ENDCOLORS #TODO: Print to be deleted print(str('%s %s' % (I_TO_PRINT, 'clean_slate()'))) #TODO: Until here global primary_ecu global CLIENT_DIRECTORY global _vin global _ecu_serial global listener_thread _vin = vin _ecu_serial = ecu_serial # if client_directory_name is not None: # CLIENT_DIRECTORY = client_directory_name # else: CLIENT_DIRECTORY = os.path.join( uptane.WORKING_DIR, CLIENT_DIRECTORY_PREFIX + demo.get_random_string(5)) # TODO: Print to be deleted print( str('%s %s %s' % (I_TO_PRINT, 'Creating client directory:', CLIENT_DIRECTORY))) # TODO: Until here # Load the public timeserver key. key_timeserver_pub = demo.import_public_key('timeserver') #TODO: Print to be deleted print( str('%s %s %s' % (I_TO_PRINT, 'key_timeserver_pub:', key_timeserver_pub))) #TODO: Until here #TODO: Print to be deleted print( str('%s %s' % (I_TO_PRINT, 'Generate a trusted initial time for the Primary'))) #TODO: Until here # Generate a trusted initial time for the Primary. clock = tuf.formats.unix_timestamp_to_datetime(int(time.time())) clock = clock.isoformat() + 'Z' tuf.formats.ISO8601_DATETIME_SCHEMA.check_match(clock) #TODO: Print to be deleted print( str('%s %s' % (I_TO_PRINT, 'Loading or generating the Private key for this Primary ECU'))) #TODO: Until here # Load the private key for this Primary ECU. load_or_generate_key(vin, use_new_keys) # TODO: Print to be deleted print( str('%s %s' % ( I_TO_PRINT, 'Craft the directory structure for the client directory. Schecules deletion for temporary files' ))) # TODO: Until here # Craft the directory structure for the client directory, including the # creation of repository metadata directories, current and previous, putting # the pinning.json file in place, etc. First, schedule the deletion of this # directory to occur when the script ends (so that it's deleted even if an # error occurs here). atexit.register(clean_up_temp_folder) try: uptane.common.create_directory_structure_for_client( CLIENT_DIRECTORY, create_primary_pinning_file(), { demo.IMAGE_REPO_NAME: demo.IMAGE_REPO_ROOT_FNAME, demo.DIRECTOR_REPO_NAME: os.path.join(demo.DIRECTOR_REPO_DIR, vin, 'metadata', 'root' + demo.METADATA_EXTENSION) }) atexit.register(clean_up_temp_folder) except IOError: raise Exception( RED + 'Unable to create Primary client directory ' 'structure. Does the Director Repo for the vehicle exist yet?' + ENDCOLORS) # Configure tuf with the client's metadata directories (where it stores the # metadata it has collected from each repository, in subdirectories). tuf.conf.repository_directory = CLIENT_DIRECTORY #TODO: Print to be deleted print( str('%s %s %s %s %s %s %s' % (I_TO_PRINT, 'Initializating Primary ECU full_client_dir:', os.path.join(uptane.WORKING_DIR, CLIENT_DIRECTORY), 'vin:', vin, 'ecu_serial:', ecu_serial))) #TODO: Until here # Initialize a Primary ECU, making a client directory and copying the root # file from the repositories. primary_ecu = primary.Primary(full_client_dir=os.path.join( uptane.WORKING_DIR, CLIENT_DIRECTORY), director_repo_name=demo.DIRECTOR_REPO_NAME, vin=_vin, ecu_serial=_ecu_serial, primary_key=ecu_key, time=clock, timeserver_public_key=key_timeserver_pub) #TODO: Print to be deleted print( str('%s %s %s' % (I_TO_PRINT, 'Primary_ecu dictionary:', primary_ecu.__dict__))) #TODO: Until here if listener_thread is None: # TODO: Print to be deleted print( str('%s %s' % (I_TO_PRINT, 'Creating listener_thread for Primary'))) # TODO: Until here listener_thread = threading.Thread(target=listen) listener_thread.setDaemon(True) listener_thread.start() print('\n' + GREEN + 'Primary is now listening for messages from ' + 'Secondaries.' + ENDCOLORS) try: register_self_with_director() except xmlrpc_client.Fault: print( 'Registration with Director failed. Now assuming this Primary is ' 'already registered.') print(GREEN + '\n Now simulating a Primary that rolled off the assembly line' '\n and has never seen an update.' + ENDCOLORS) print( "Generating this Primary's first Vehicle Version Manifest and sending " "it to the Director.") #TODO: Print to be deleted print( str('%s %s' % (I_TO_PRINT, 'Trying to generate signed vehicle manifest'))) #TODO: Until here generate_signed_vehicle_manifest() #TODO: Print to be deleted print( str('%s %s' % (I_TO_PRINT, 'Trying to submit vehicle manifest to director'))) #TODO: Until here submit_vehicle_manifest_to_director() #TODO: Print to be deleted print(str('%s %s' % (I_TO_PRINT, 'Returning...')))