def test_validate_signatures(self): """Test validate Metablock's 'signatures' property. """ # An empty signature list is okay metablock = Metablock(signed=Layout()) metablock._validate_signatures() # Fail with signatures property not a list metablock.signatures = "not-a-signatures-list" with self.assertRaises(FormatError): metablock._validate_signatures() # Fail with invalid signature metablock.signatures = [] metablock.signatures.append("not-a-signature") with self.assertRaises(FormatError): metablock._validate_signatures() # Load signed demo link demo_link_path = os.path.join( os.path.dirname(os.path.realpath(__file__)), "..", "demo_files", "write-code.776a00e2.link") metablock = Metablock.load(demo_link_path) # Verify that there is a signature and that it is valid self.assertTrue(len(metablock.signatures) > 0) metablock._validate_signatures()
def test_get_inspection_by_name(self): """Test getting inspection by name. """ names = ["a", "b", "c"] layout = Layout(inspect=[Inspection(name=name) for name in names]) self.assertEqual(layout.get_inspection_by_name("b").name, "b") with self.assertRaises(securesystemslib.exceptions.FormatError): layout.get_inspection_by_name(1)
def test_get_step_by_name(self): """Test getting step by name. """ names = ["a", "b", "c"] layout = Layout(steps=[Step(name=name) for name in names]) self.assertEqual(layout.get_step_by_name("b").name, "b") with self.assertRaises(securesystemslib.exceptions.FormatError): layout.get_step_by_name(None)
def test_validate_signed(self): """Test validate Metablock's 'signed' property. """ # Valid Layout Metablock metablock = Metablock(signed=Layout()) metablock._validate_signed() # Valid Link Metablock Metablock(signed=Link()) metablock._validate_signed() # Fail instantiation with empty or invalid signed property # Metablock is validated on instantiation with self.assertRaises(FormatError): Metablock() with self.assertRaises(FormatError): Metablock(signed="not-a-layout-or-link") # Fail with invalid signed property metablock = Metablock(signed=Layout()) metablock.signed._type = "bogus type" with self.assertRaises(FormatError): metablock._validate_signed()
def test_remove_inspection_by_name(self): """Test removing inspection by name. """ names = ["a", "b", "c"] layout = Layout(inspect=[Inspection(name=name) for name in names]) self.assertEqual(len(layout.inspect), 3) self.assertTrue("b" in layout.get_inspection_name_list()) # Items are only removed if they exist for _ in range(2): layout.remove_inspection_by_name("b") self.assertEqual(len(layout.inspect), 2) self.assertTrue("b" not in layout.get_inspection_name_list()) with self.assertRaises(securesystemslib.exceptions.FormatError): layout.remove_inspection_by_name(False)
def test_remove_step_by_name(self): """Test removing step by name. """ names = ["a", "b", "c"] layout = Layout(steps=[Step(name=name) for name in names]) self.assertEqual(len(layout.steps), 3) self.assertTrue("b" in layout.get_step_name_list()) # Items are only removed if they exist for _ in range(2): layout.remove_step_by_name("b") self.assertEqual(len(layout.steps), 2) self.assertTrue("b" not in layout.get_step_name_list()) with self.assertRaises(securesystemslib.exceptions.FormatError): layout.get_step_by_name([])
def test_functionary_keys(self): """Test adding and listing functionary keys (securesystemslib and gpg). """ layout = Layout() self.assertEqual(len(layout.get_functionary_key_id_list()), 0) layout.add_functionary_keys_from_paths( [self.pubkey_path1, self.pubkey_path2]) layout.add_functionary_keys_from_gpg_keyids( [self.gpg_key_768C43, self.gpg_key_85DA58], gpg_home=self.gnupg_home) layout._validate_keys() self.assertEqual(len(layout.get_functionary_key_id_list()), 4) # Must be a valid key object with self.assertRaises(securesystemslib.exceptions.FormatError): layout.add_functionary_key("abcd") # Must be pubkey and not private key with self.assertRaises(securesystemslib.exceptions.Error): layout.add_functionary_key_from_path(self.key_path) # Must be a valid path with self.assertRaises(securesystemslib.exceptions.FormatError): layout.add_functionary_key_from_path(123) # Must be a valid keyid with self.assertRaises(securesystemslib.exceptions.FormatError): layout.add_functionary_key_from_gpg_keyid("abcdefg") # Must be a list of paths with self.assertRaises(securesystemslib.exceptions.FormatError): layout.add_functionary_keys_from_paths("abcd") with self.assertRaises(securesystemslib.exceptions.FormatError): layout.add_functionary_keys_from_paths([1]) # Must be a list of keyids with self.assertRaises(securesystemslib.exceptions.FormatError): layout.add_functionary_keys_from_gpg_keyids(None) with self.assertRaises(securesystemslib.exceptions.FormatError): layout.add_functionary_keys_from_gpg_keyids(["abcdefg"])
def setUpClass(self): """Creates and changes into temporary directory and prepares two layouts. The superlayout, which has one step and its sublayout, which is the usual demo layout (write code, package, inspect tar). """ # Backup original cwd self.working_dir = os.getcwd() # Find demo files demo_files = os.path.join(os.path.dirname(os.path.realpath(__file__)), "demo_files") # Create and change into temporary directory self.test_dir = os.path.realpath(tempfile.mkdtemp()) os.chdir(self.test_dir) # Copy demo files to temp dir for file in os.listdir(demo_files): shutil.copy(os.path.join(demo_files, file), self.test_dir) # Import sub layout signing (private) and verifying (public) keys alice = import_rsa_key_from_file("alice") alice_pub = import_rsa_key_from_file("alice.pub") # Copy, sign and dump sub layout as link from template layout_template = Metablock.load("demo.layout.template") sub_layout = copy.deepcopy(layout_template) sub_layout_name = "sub_layout" sub_layout_path = FILENAME_FORMAT.format(step_name=sub_layout_name, keyid=alice_pub["keyid"]) sub_layout.sign(alice) sub_layout.dump(sub_layout_path) # Create super layout that has only one step, the sublayout self.super_layout = Layout() self.super_layout.keys[alice_pub["keyid"]] = alice_pub sub_layout_step = Step(name=sub_layout_name, pubkeys=[alice_pub["keyid"]]) self.super_layout.steps.append(sub_layout_step) # Load the super layout links (i.e. the sublayout) self.super_layout_links = load_links_for_layout(self.super_layout)
def test_set_relative_expiration(self): """Test adding expiration date relative from today. """ layout = Layout() with self.assertRaises(securesystemslib.exceptions.FormatError): layout.set_relative_expiration(days=None, months=0, years=0) with self.assertRaises(securesystemslib.exceptions.FormatError): layout.set_relative_expiration(days=0, months="", years=0) with self.assertRaises(securesystemslib.exceptions.FormatError): layout.set_relative_expiration(days=0, months=0, years=[]) layout.set_relative_expiration(days=1) layout._validate_expires() layout.set_relative_expiration(months=2) layout._validate_expires() layout.set_relative_expiration(years=3) layout._validate_expires() layout.set_relative_expiration(days=3, months=2, years=1) layout._validate_expires() # It's possible to add an expiration date in the past layout.set_relative_expiration(days=-3, months=-2, years=-1) layout._validate_expires()
def test_get_step_name_list(self): """Test getting list of step names. """ names = ["a", "b", "c"] layout = Layout(steps=[Step(name=name) for name in names]) self.assertListEqual(layout.get_step_name_list(), names)
def setUp(self): """Populate a base layout that we can use.""" self.layout = Layout() self.layout.expires = '2016-11-18T16:44:55Z'
def test_get_inspection_name_list(self): """Test getting list of inspection names. """ names = ["a", "b", "c"] layout = Layout(inspect=[Inspection(name=name) for name in names]) self.assertListEqual(layout.get_inspection_name_list(), names)
#!/usr/bin/python from in_toto.models.layout import Layout, Step from in_toto.models.metadata import Metablock from in_toto.util import generate_and_write_rsa_keypair, import_rsa_key_from_file generate_and_write_rsa_keypair("build_key") build_key = import_rsa_key_from_file("build_key.pub") layout = Layout() build = Step(name="build") build.expected_materials.append(['ALLOW', 'package.json']) build.expected_materials.append(['ALLOW', 'index.js']) build.expected_command = ['npm', 'install'] layout.steps.append(build) layout.add_functionary_key(build_key) build.pubkeys.append(build_key['keyid']) generate_and_write_rsa_keypair("root_key") root_key = import_rsa_key_from_file("root_key") metablock = Metablock(signed=layout) metablock.sign(root_key) metablock.dump("root.layout")
], pubkeys=[santiago_key['keyid']]) dockerize = Step(name="dockerize", expected_command="docker build .", material_matchrules=[ ["CREATE", "Dockerfile"], ["MATCH", "*" "IN", "react-webapp", "WITH", "PRODUCTS", "IN", "build/*", "FROM", "build"], ], product_matchrules=[ ["CREATE", "blah"], ], pubkeys=[santiago_key['keyid']]) # someinspection = Inspection(name="untar", # run="tar xvf PolyPasswordHasher-0.2a0.tar.gz", # material_matchrules=[ # ], # product_matchrules=[ # ]) expiration = (datetime.datetime.now() + datetime.timedelta(days=30)).isoformat() + "Z" santiago_key['keyval']['private'] = None l = Layout(steps=[git, eslint, dockerize], inspect=[], keys={santiago_key['keyid']:santiago_key}, expires=expiration) l.sign(justin_key) l.dump()