def test_sign_metadata(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) metadata_path = os.path.join('repository_data', 'repository', 'metadata') keystore_path = os.path.join('repository_data', 'keystore') root_filename = os.path.join(metadata_path, 'root.json') root_metadata = tuf.util.load_json_file(root_filename)['signed'] tuf.keydb.create_keydb_from_root_metadata(root_metadata) tuf.roledb.create_roledb_from_root_metadata(root_metadata) root_keyids = tuf.roledb.get_role_keyids('root') root_private_keypath = os.path.join(keystore_path, 'root_key') root_private_key = \ repo_lib.import_rsa_privatekey_from_file(root_private_keypath, 'password') # Sign with a valid, but not a threshold, key. targets_private_keypath = os.path.join(keystore_path, 'targets_key') targets_private_key = \ repo_lib.import_rsa_privatekey_from_file(targets_private_keypath, 'password') # sign_metadata() expects the private key 'root_metadata' to be in # 'tuf.keydb'. Remove any public keys that may be loaded before # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is # raised. tuf.keydb.remove_key(root_private_key['keyid']) tuf.keydb.add_key(root_private_key) tuf.keydb.remove_key(targets_private_key['keyid']) tuf.keydb.add_key(targets_private_key) root_keyids.extend(tuf.roledb.get_role_keyids('targets')) # Add the snapshot's public key (to test whether non-private keys are # ignored by sign_metadata()). root_keyids.extend(tuf.roledb.get_role_keyids('snapshot')) root_signable = repo_lib.sign_metadata(root_metadata, root_keyids, root_filename) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable)) # Test improperly formatted arguments. self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, 3, root_keyids, 'root.json') self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, 3, 'root.json') self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, root_keyids, 3)
def test_import_rsa_privatekey_from_file(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) # Load one of the pre-generated key files from 'tuf/tests/repository_data'. # 'password' unlocks the pre-generated key files. key_filepath = os.path.join('repository_data', 'keystore', 'root_key') self.assertTrue(os.path.exists(key_filepath)) imported_rsa_key = repo_lib.import_rsa_privatekey_from_file( key_filepath, 'password') self.assertTrue( securesystemslib.formats.RSAKEY_SCHEMA.matches(imported_rsa_key)) # Test improperly formatted argument. self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.import_rsa_privatekey_from_file, 3, 'pw') # Test invalid argument. # Non-existent key file. nonexistent_keypath = os.path.join(temporary_directory, 'nonexistent_keypath') self.assertRaises(IOError, repo_lib.import_rsa_privatekey_from_file, nonexistent_keypath, 'pw') # Invalid key file argument. invalid_keyfile = os.path.join(temporary_directory, 'invalid_keyfile') with open(invalid_keyfile, 'wb') as file_object: file_object.write(b'bad keyfile') self.assertRaises(securesystemslib.exceptions.CryptoError, repo_lib.import_rsa_privatekey_from_file, invalid_keyfile, 'pw')
def test__remove_invalid_and_duplicate_signatures(self): # Remove duplicate PSS signatures (same key generates valid, but different # signatures). First load a valid signable (in this case, the root role). root_filepath = os.path.join('repository_data', 'repository', 'metadata', 'root.json') root_signable = tuf.util.load_json_file(root_filepath) key_filepath = os.path.join('repository_data', 'keystore', 'root_key') root_rsa_key = repo_lib.import_rsa_privatekey_from_file( key_filepath, 'password') # Add 'root_rsa_key' to tuf.keydb, since # _remove_invalid_and_duplicate_signatures() checks for unknown keys in # tuf.keydb. tuf.keydb.add_key(root_rsa_key) # Append the new valid, but duplicate PSS signature, and test that # duplicates are removed. create_signature() generates a key for the # key type of the first argument (i.e., root_rsa_key). new_pss_signature = tuf.keys.create_signature( root_rsa_key, tuf.formats.encode_canonical( root_signable['signed']).encode('utf-8')) root_signable['signatures'].append(new_pss_signature) expected_number_of_signatures = len(root_signable['signatures']) tuf.repository_lib._remove_invalid_and_duplicate_signatures( root_signable) self.assertEqual(len(root_signable), expected_number_of_signatures) # Test that invalid keyid are ignored. root_signable['signatures'][0]['keyid'] = '404' tuf.repository_lib._remove_invalid_and_duplicate_signatures( root_signable)
def test_generate_and_write_rsa_keypair(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) test_keypath = os.path.join(temporary_directory, "rsa_key") repo_lib.generate_and_write_rsa_keypair(test_keypath, password="******") self.assertTrue(os.path.exists(test_keypath)) self.assertTrue(os.path.exists(test_keypath + ".pub")) # Ensure the generated key files are importable. imported_pubkey = repo_lib.import_rsa_publickey_from_file(test_keypath + ".pub") self.assertTrue(tuf.formats.RSAKEY_SCHEMA.matches(imported_pubkey)) imported_privkey = repo_lib.import_rsa_privatekey_from_file(test_keypath, "pw") self.assertTrue(tuf.formats.RSAKEY_SCHEMA.matches(imported_privkey)) # Custom 'bits' argument. os.remove(test_keypath) os.remove(test_keypath + ".pub") repo_lib.generate_and_write_rsa_keypair(test_keypath, bits=2048, password="******") self.assertTrue(os.path.exists(test_keypath)) self.assertTrue(os.path.exists(test_keypath + ".pub")) # Test improperly formatted arguments. self.assertRaises(tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, 3, bits=2048, password="******") self.assertRaises( tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, test_keypath, bits="bad", password="******" ) self.assertRaises(tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, test_keypath, bits=2048, password=3) # Test invalid 'bits' argument. self.assertRaises( tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, test_keypath, bits=1024, password="******" )
def test_import_rsa_privatekey_from_file(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) # Load one of the pre-generated key files from 'tuf/tests/repository_data'. # 'password' unlocks the pre-generated key files. key_filepath = os.path.join("repository_data", "keystore", "root_key") self.assertTrue(os.path.exists(key_filepath)) imported_rsa_key = repo_lib.import_rsa_privatekey_from_file(key_filepath, "password") self.assertTrue(tuf.formats.RSAKEY_SCHEMA.matches(imported_rsa_key)) # Test improperly formatted argument. self.assertRaises(tuf.FormatError, repo_lib.import_rsa_privatekey_from_file, 3, "pw") # Test invalid argument. # Non-existent key file. nonexistent_keypath = os.path.join(temporary_directory, "nonexistent_keypath") self.assertRaises(IOError, repo_lib.import_rsa_privatekey_from_file, nonexistent_keypath, "pw") # Invalid key file argument. invalid_keyfile = os.path.join(temporary_directory, "invalid_keyfile") with open(invalid_keyfile, "wb") as file_object: file_object.write(b"bad keyfile") self.assertRaises(tuf.CryptoError, repo_lib.import_rsa_privatekey_from_file, invalid_keyfile, "pw")
def test_sign_metadata(self): # Test normal case. repository_name = 'test_repository' temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) metadata_path = os.path.join('repository_data', 'repository', 'metadata') keystore_path = os.path.join('repository_data', 'keystore') root_filename = os.path.join(metadata_path, 'root.json') root_metadata = securesystemslib.util.load_json_file(root_filename)['signed'] targets_filename = os.path.join(metadata_path, 'targets.json') targets_metadata = securesystemslib.util.load_json_file(targets_filename)['signed'] tuf.keydb.create_keydb_from_root_metadata(root_metadata, repository_name) tuf.roledb.create_roledb_from_root_metadata(root_metadata, repository_name) root_keyids = tuf.roledb.get_role_keyids('root', repository_name) targets_keyids = tuf.roledb.get_role_keyids('targets', repository_name) root_private_keypath = os.path.join(keystore_path, 'root_key') root_private_key = repo_lib.import_rsa_privatekey_from_file(root_private_keypath, 'password') # Sign with a valid, but not a threshold, key. targets_public_keypath = os.path.join(keystore_path, 'targets_key.pub') targets_public_key = securesystemslib.interface.\ import_ed25519_publickey_from_file(targets_public_keypath) # sign_metadata() expects the private key 'root_metadata' to be in # 'tuf.keydb'. Remove any public keys that may be loaded before # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is # raised. tuf.keydb.remove_key(root_private_key['keyid'], repository_name=repository_name) tuf.keydb.add_key(root_private_key, repository_name=repository_name) tuf.keydb.remove_key(targets_public_key['keyid'], repository_name=repository_name) tuf.keydb.add_key(targets_public_key, repository_name=repository_name) # Verify that a valid root signable is generated. root_signable = repo_lib.sign_metadata(root_metadata, root_keyids, root_filename, repository_name) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable)) # Test for an unset private key (in this case, target's). repo_lib.sign_metadata(targets_metadata, targets_keyids, targets_filename, repository_name) # Add an invalid keytype to one of the root keys. root_keyid = root_keyids[0] tuf.keydb._keydb_dict[repository_name][root_keyid]['keytype'] = 'bad_keytype' self.assertRaises(securesystemslib.exceptions.Error, repo_lib.sign_metadata, root_metadata, root_keyids, root_filename, repository_name) # Test improperly formatted arguments. self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.sign_metadata, 3, root_keyids, 'root.json', repository_name) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.sign_metadata, root_metadata, 3, 'root.json', repository_name) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.sign_metadata, root_metadata, root_keyids, 3, repository_name)
def test_sign_metadata(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) metadata_path = os.path.join("repository_data", "repository", "metadata") keystore_path = os.path.join("repository_data", "keystore") root_filename = os.path.join(metadata_path, "root.json") root_metadata = tuf.util.load_json_file(root_filename)["signed"] tuf.keydb.create_keydb_from_root_metadata(root_metadata) tuf.roledb.create_roledb_from_root_metadata(root_metadata) root_keyids = tuf.roledb.get_role_keyids("root") root_private_keypath = os.path.join(keystore_path, "root_key") root_private_key = repo_lib.import_rsa_privatekey_from_file(root_private_keypath, "password") # Sign with a valid, but not a threshold, key. targets_private_keypath = os.path.join(keystore_path, "targets_key") targets_private_key = repo_lib.import_rsa_privatekey_from_file(targets_private_keypath, "password") # sign_metadata() expects the private key 'root_metadata' to be in # 'tuf.keydb'. Remove any public keys that may be loaded before # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is # raised. tuf.keydb.remove_key(root_private_key["keyid"]) tuf.keydb.add_key(root_private_key) tuf.keydb.remove_key(targets_private_key["keyid"]) tuf.keydb.add_key(targets_private_key) root_keyids.extend(tuf.roledb.get_role_keyids("targets")) # Add the snapshot's public key (to test whether non-private keys are # ignored by sign_metadata()). root_keyids.extend(tuf.roledb.get_role_keyids("snapshot")) root_signable = repo_lib.sign_metadata(root_metadata, root_keyids, root_filename) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable)) # Test improperly formatted arguments. self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, 3, root_keyids, "root.json") self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, 3, "root.json") self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, root_keyids, 3)
def test_generate_and_write_rsa_keypair(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) test_keypath = os.path.join(temporary_directory, 'rsa_key') repo_lib.generate_and_write_rsa_keypair(test_keypath, password='******') self.assertTrue(os.path.exists(test_keypath)) self.assertTrue(os.path.exists(test_keypath + '.pub')) # Ensure the generated key files are importable. imported_pubkey = \ repo_lib.import_rsa_publickey_from_file(test_keypath + '.pub') self.assertTrue(tuf.formats.RSAKEY_SCHEMA.matches(imported_pubkey)) imported_privkey = \ repo_lib.import_rsa_privatekey_from_file(test_keypath, 'pw') self.assertTrue(tuf.formats.RSAKEY_SCHEMA.matches(imported_privkey)) # Custom 'bits' argument. os.remove(test_keypath) os.remove(test_keypath + '.pub') repo_lib.generate_and_write_rsa_keypair(test_keypath, bits=2048, password='******') self.assertTrue(os.path.exists(test_keypath)) self.assertTrue(os.path.exists(test_keypath + '.pub')) # Test improperly formatted arguments. self.assertRaises(tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, 3, bits=2048, password='******') self.assertRaises(tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, test_keypath, bits='bad', password='******') self.assertRaises(tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, test_keypath, bits=2048, password=3) # Test invalid 'bits' argument. self.assertRaises(tuf.FormatError, repo_lib.generate_and_write_rsa_keypair, test_keypath, bits=1024, password='******')
def test__remove_invalid_and_duplicate_signatures(self): # Remove duplicate PSS signatures (same key generates valid, but different # signatures). First load a valid signable (in this case, the root role). repository_name = 'test_repository' root_filepath = os.path.join('repository_data', 'repository', 'metadata', 'root.json') root_signable = securesystemslib.util.load_json_file(root_filepath) key_filepath = os.path.join('repository_data', 'keystore', 'root_key') root_rsa_key = repo_lib.import_rsa_privatekey_from_file( key_filepath, 'password') # Add 'root_rsa_key' to tuf.keydb, since # _remove_invalid_and_duplicate_signatures() checks for unknown keys in # tuf.keydb. tuf.keydb.add_key(root_rsa_key, repository_name=repository_name) # Append the new valid, but duplicate PSS signature, and test that # duplicates are removed. create_signature() generates a key for the # key type of the first argument (i.e., root_rsa_key). data = securesystemslib.formats.encode_canonical( root_signable['signed']).encode('utf-8') new_pss_signature = securesystemslib.keys.create_signature( root_rsa_key, data) root_signable['signatures'].append(new_pss_signature) expected_number_of_signatures = len(root_signable['signatures']) tuf.repository_lib._remove_invalid_and_duplicate_signatures( root_signable, repository_name) self.assertEqual(len(root_signable), expected_number_of_signatures) # Test for an invalid keyid. root_signable['signatures'][0]['keyid'] = '404' tuf.repository_lib._remove_invalid_and_duplicate_signatures( root_signable, repository_name) # Re-add a valid signature for the following test condition. root_signable['signatures'].append(new_pss_signature) # Test that an exception is not raised if an invalid sig is present, # and that the duplicate key is removed 'root_signable'. root_signable['signatures'][0]['sig'] = '4040' invalid_keyid = root_signable['signatures'][0]['keyid'] tuf.repository_lib._remove_invalid_and_duplicate_signatures( root_signable, repository_name) for signature in root_signable['signatures']: self.assertFalse(invalid_keyid == signature['keyid'])
def test__remove_invalid_and_duplicate_signatures(self): # Remove duplicate PSS signatures (same key generates valid, but different # signatures). First load a valid signable (in this case, the root role). root_filepath = os.path.join("repository_data", "repository", "metadata", "root.json") root_signable = tuf.util.load_json_file(root_filepath) key_filepath = os.path.join("repository_data", "keystore", "root_key") root_rsa_key = repo_lib.import_rsa_privatekey_from_file(key_filepath, "password") # Append the new valid, but duplicate PSS signature, and test that # duplicates are removed. new_pss_signature = tuf.keys.create_signature(root_rsa_key, root_signable["signed"]) root_signable["signatures"].append(new_pss_signature) expected_number_of_signatures = len(root_signable["signatures"]) tuf.repository_lib._remove_invalid_and_duplicate_signatures(root_signable) self.assertEqual(len(root_signable), expected_number_of_signatures) # Test that invalid keyid are ignored. root_signable["signatures"][0]["keyid"] = "404" tuf.repository_lib._remove_invalid_and_duplicate_signatures(root_signable)
def test__remove_invalid_and_duplicate_signatures(self): # Remove duplicate PSS signatures (same key generates valid, but different # signatures). First load a valid signable (in this case, the root role). root_filepath = os.path.join('repository_data', 'repository', 'metadata', 'root.json') root_signable = tuf.util.load_json_file(root_filepath) key_filepath = os.path.join('repository_data', 'keystore', 'root_key') root_rsa_key = repo_lib.import_rsa_privatekey_from_file(key_filepath, 'password') # Append the new valid, but duplicate PSS signature, and test that # duplicates are removed. new_pss_signature = tuf.keys.create_signature(root_rsa_key, root_signable['signed']) root_signable['signatures'].append(new_pss_signature) expected_number_of_signatures = len(root_signable['signatures']) tuf.repository_lib._remove_invalid_and_duplicate_signatures(root_signable) self.assertEqual(len(root_signable), expected_number_of_signatures) # Test that invalid keyid are ignored. root_signable['signatures'][0]['keyid'] = '404' tuf.repository_lib._remove_invalid_and_duplicate_signatures(root_signable)
def import_rsa_privatekey_from_file(filepath, password): return repo_lib.import_rsa_privatekey_from_file(filepath, password)