def test_01_init(self): """ Note that this doesn't test the root files provided, as those aren't used at all in the initialization; for that, we'll have to test the update cycle. """ global primary_instance # Now try creating a Primary with a series of bad arguments, expecting # errors. # Invalid Pinning File with self.assertRaises(tuf.FormatError): p = primary.Primary( full_client_dir=os.path.join(TEST_DATA_DIR, client_directory_name), pinning_filename= TEST_OEM_ROOT_FNAME, # INVALID: WRONG TYPE OF FILE vin=vin, ecu_serial=primary_ecu_serial, fname_root_from_mainrepo=TEST_OEM_ROOT_FNAME, fname_root_from_directorrepo=TEST_DIRECTOR_ROOT_FNAME, primary_key=primary_ecu_key, time=clock, timeserver_public_key=key_timeserver_pub) # Invalid VIN: with self.assertRaises(tuf.FormatError): p = primary.Primary( full_client_dir=os.path.join(TEST_DATA_DIR, client_directory_name), pinning_filename=TEST_PINNING_FNAME, vin=5, # INVALID ecu_serial=primary_ecu_serial, fname_root_from_mainrepo=TEST_OEM_ROOT_FNAME, fname_root_from_directorrepo=TEST_DIRECTOR_ROOT_FNAME, primary_key=primary_ecu_key, time=clock, timeserver_public_key=key_timeserver_pub) # Invalid ECU Serial with self.assertRaises(tuf.FormatError): p = primary.Primary( full_client_dir=os.path.join(TEST_DATA_DIR, client_directory_name), pinning_filename=TEST_PINNING_FNAME, vin=vin, ecu_serial=500, # INVALID fname_root_from_mainrepo=TEST_OEM_ROOT_FNAME, fname_root_from_directorrepo=TEST_DIRECTOR_ROOT_FNAME, primary_key=primary_ecu_key, time=clock, timeserver_public_key=key_timeserver_pub) # Invalid ECU Key with self.assertRaises(tuf.FormatError): p = primary.Primary( full_client_dir=os.path.join(TEST_DATA_DIR, client_directory_name), pinning_filename=TEST_PINNING_FNAME, vin=vin, ecu_serial=primary_ecu_serial, fname_root_from_mainrepo=TEST_OEM_ROOT_FNAME, fname_root_from_directorrepo=TEST_DIRECTOR_ROOT_FNAME, primary_key={''}, # INVALID time=clock, timeserver_public_key=key_timeserver_pub) # Invalid time: with self.assertRaises(tuf.FormatError): p = primary.Primary( full_client_dir=os.path.join(TEST_DATA_DIR, client_directory_name), pinning_filename=TEST_PINNING_FNAME, vin=vin, ecu_serial=primary_ecu_serial, fname_root_from_mainrepo=TEST_OEM_ROOT_FNAME, fname_root_from_directorrepo=TEST_DIRECTOR_ROOT_FNAME, primary_key=primary_ecu_key, time='potato', # INVALID timeserver_public_key=key_timeserver_pub) # Invalid timeserver key with self.assertRaises(tuf.FormatError): p = primary.Primary( full_client_dir=os.path.join(TEST_DATA_DIR, client_directory_name), pinning_filename=TEST_PINNING_FNAME, vin=vin, ecu_serial=primary_ecu_serial, fname_root_from_mainrepo=TEST_OEM_ROOT_FNAME, fname_root_from_directorrepo=TEST_DIRECTOR_ROOT_FNAME, primary_key=primary_ecu_key, time=clock, timeserver_public_key=clock) # INVALID # Try creating a Primary, expecting it to work. # Initializes a Primary ECU, making a client directory and copying the root # file from the repositories. # Save the result for future tests, to save time and code. primary_instance = primary.Primary( full_client_dir=os.path.join(TEST_DATA_DIR, client_directory_name), pinning_filename=TEST_PINNING_FNAME, vin=vin, ecu_serial=primary_ecu_serial, fname_root_from_mainrepo=TEST_OEM_ROOT_FNAME, fname_root_from_directorrepo=TEST_DIRECTOR_ROOT_FNAME, primary_key=primary_ecu_key, time=clock, timeserver_public_key=key_timeserver_pub) # Check the fields initialized in the instance to make sure they're correct. self.assertEqual([], primary_instance.nonces_to_send) self.assertEqual([], primary_instance.nonces_sent) self.assertEqual(vin, primary_instance.vin) self.assertEqual(primary_ecu_serial, primary_instance.ecu_serial) self.assertEqual(primary_ecu_key, primary_instance.primary_key) self.assertEqual(dict(), primary_instance.ecu_manifests) self.assertEqual(primary_instance.full_client_dir, os.path.join(TEST_DATA_DIR, client_directory_name)) self.assertIsInstance(primary_instance.updater, tuf.client.updater.Updater) tuf.formats.ANYKEY_SCHEMA.check_match( primary_instance.timeserver_public_key) self.assertEqual([], primary_instance.my_secondaries)
def test_01_init(self): """ Note that this doesn't test the root files provided, as those aren't used at all in the initialization; for that, we'll have to test the update cycle. """ # Set up a client directory first. uptane.common.create_directory_structure_for_client( TEMP_CLIENT_DIR, TEST_PINNING_FNAME, {'imagerepo': TEST_IMAGE_REPO_ROOT_FNAME, 'director': TEST_DIRECTOR_ROOT_FNAME}) # Create repository directories that will be accessed locally (using # file:// URLs) from which to "download" test metadata and targets. for repository in ["director", "imagerepo"]: shutil.copytree( os.path.join(SAMPLE_METADATA, repository), os.path.join(TEMP_CLIENT_DIR, repository)) # Note that there may be extra targets available here. shutil.copytree( SAMPLE_TARGETS, os.path.join(TEMP_CLIENT_DIR, 'imagerepo', 'targets')) # TODO: Test with invalid pinning file # TODO: Test with pinning file lacking a Director repo. # Now try creating a Primary with a series of bad arguments, expecting # errors. # TODO: Add test for my_secondaries argument. # Invalid VIN: with self.assertRaises(tuf.FormatError): primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name=demo.DIRECTOR_REPO_NAME, vin=5, # INVALID ecu_serial=PRIMARY_ECU_SERIAL, primary_key=TestPrimary.ecu_key, time=TestPrimary.initial_time, timeserver_public_key=TestPrimary.key_timeserver_pub, my_secondaries=[]) # Invalid ECU Serial with self.assertRaises(tuf.FormatError): primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name=demo.DIRECTOR_REPO_NAME, vin=VIN, ecu_serial=500, # INVALID primary_key=TestPrimary.ecu_key, time=TestPrimary.initial_time, timeserver_public_key=TestPrimary.key_timeserver_pub, my_secondaries=[]) # Invalid ECU Key with self.assertRaises(tuf.FormatError): primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name=demo.DIRECTOR_REPO_NAME, vin=VIN, ecu_serial=PRIMARY_ECU_SERIAL, primary_key={''}, # INVALID time=TestPrimary.initial_time, timeserver_public_key=TestPrimary.key_timeserver_pub, my_secondaries=[]) # Invalid time: with self.assertRaises(tuf.FormatError): primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name=demo.DIRECTOR_REPO_NAME, vin=VIN, ecu_serial=PRIMARY_ECU_SERIAL, primary_key=TestPrimary.ecu_key, time='invalid because this is not a time', # INVALID timeserver_public_key=TestPrimary.key_timeserver_pub, my_secondaries=[]) # Invalid timeserver key with self.assertRaises(tuf.FormatError): primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name=demo.DIRECTOR_REPO_NAME, vin=VIN, ecu_serial=PRIMARY_ECU_SERIAL, primary_key=TestPrimary.ecu_key, time=TestPrimary.initial_time, timeserver_public_key=TestPrimary.initial_time, # INVALID my_secondaries=[]) # Invalid format for Director Repository name with self.assertRaises(tuf.FormatError): primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name=5, #INVALID vin=VIN, ecu_serial=PRIMARY_ECU_SERIAL, primary_key=TestPrimary.ecu_key, time=TestPrimary.initial_time, timeserver_public_key = TestPrimary.key_timeserver_pub, my_secondaries=[]) # Invalid name for Director repository with self.assertRaises(uptane.Error): primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name= "invalid", #INVALID vin=VIN, ecu_serial=PRIMARY_ECU_SERIAL, primary_key=TestPrimary.ecu_key, time=TestPrimary.initial_time, timeserver_public_key = TestPrimary.key_timeserver_pub, my_secondaries=[]) # Try creating a Primary, expecting it to work. # Initializes a Primary ECU, making a client directory and copying the root # file from the repositories. # Save the result for future tests, to save time and code. TestPrimary.instance = primary.Primary( full_client_dir=TEMP_CLIENT_DIR, director_repo_name=demo.DIRECTOR_REPO_NAME, vin=VIN, ecu_serial=PRIMARY_ECU_SERIAL, primary_key=TestPrimary.ecu_key, time=TestPrimary.initial_time, timeserver_public_key=TestPrimary.key_timeserver_pub) # Check the fields initialized in the instance to make sure they're correct. self.assertEqual([], TestPrimary.instance.nonces_to_send) self.assertEqual([], TestPrimary.instance.nonces_sent) self.assertEqual(VIN, TestPrimary.instance.vin) self.assertEqual(PRIMARY_ECU_SERIAL, TestPrimary.instance.ecu_serial) self.assertEqual(TestPrimary.ecu_key, TestPrimary.instance.primary_key) self.assertEqual(dict(), TestPrimary.instance.ecu_manifests) self.assertEqual( TestPrimary.instance.full_client_dir, TEMP_CLIENT_DIR) self.assertIsInstance( TestPrimary.instance.updater, tuf.client.updater.Updater) tuf.formats.ANYKEY_SCHEMA.check_match( TestPrimary.instance.timeserver_public_key) self.assertEqual([], TestPrimary.instance.my_secondaries) # Now, fix the updater's pinned metadata to point it to the appropriate # local directory, since the pinned metadata we fed in was actually for the # live demo, connecting to localhost:30401. We instead want to use a # local directory via file://. # TODO: Determine if this code should be adjusted to use os.path.join(), # or if that's not appropriate for file:// links. image_repo_mirror = ['file://' + TEMP_CLIENT_DIR + '/imagerepo'] director_mirror = ['file://' + TEMP_CLIENT_DIR + '/director'] repository_urls = TestPrimary.instance.updater.pinned_metadata['repositories'] repository_urls['imagerepo']['mirrors'] = image_repo_mirror repository_urls['director']['mirrors'] = director_mirror # Also fix the copied pinned metadata in the individual repo updaters # in the updater. TestPrimary.instance.updater.repositories['imagerepo'].mirrors = image_repo_mirror TestPrimary.instance.updater.repositories['director'].mirrors = director_mirror
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...')))