def test_repeated_step_names(self): """Check that only unique names exist in the steps and inspect lists""" self.layout.steps = [Step(name="name"), Step(name="name")] with self.assertRaises(securesystemslib.exceptions.FormatError): self.layout.validate() self.layout.steps = [Step(name="name")] self.layout.inspect = [Inspection(name="name")] with self.assertRaises(securesystemslib.exceptions.FormatError): self.layout.validate() self.layout.step = [Step(name="name"), Step(name="othername")] self.layout.inspect = [Inspection(name="thirdname")] self.layout.validate()
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_wrong_pubkeys(self): """Check validate pubkeys fails with wrong keys.""" # Pubkeys must be lists ... tmp_step = Step() tmp_step.pubkeys = "abcd" with self.assertRaises(securesystemslib.exceptions.FormatError): tmp_step.validate() # ... of keyids (hex schema) tmp_step.pubkeys = ["abcdefg"] with self.assertRaises(securesystemslib.exceptions.FormatError): tmp_step.validate()
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 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_wrong_steps_list(self): """Check that the validate method checks the steps' correctness.""" self.layout.steps = "not-a-step" with self.assertRaises(securesystemslib.exceptions.FormatError): self.layout.validate() test_step = Step(name="this-is-a-step") with self.assertRaises(securesystemslib.exceptions.FormatError): test_step.expected_materials = ['this is a malformed step'] self.layout.steps = [test_step] self.layout.validate() test_step = Step(name="this-is-a-step") test_step.expected_materials = [["CREATE", "foo"]] test_step.threshold = 1 self.layout.steps = [test_step] self.layout.validate()
def test_import_step_metadata_wrong_type(self): functionary_key = securesystemslib.keys.generate_rsa_key() name = "name" # Create and dump a link file with a wrong type link_name = in_toto.models.link.FILENAME_FORMAT.format( step_name=name, keyid=functionary_key["keyid"]) link_path = os.path.abspath(link_name) link = in_toto.models.link.Link(name=name) metadata = Metablock(signed=link) metadata.signed._type = "wrong-type" metadata.dump(link_path) # Add the single step to the test layout and try to read the failing link self.layout.steps.append( Step(name=name, pubkeys=[functionary_key["keyid"]])) with self.assertRaises(securesystemslib.exceptions.FormatError): in_toto.verifylib.load_links_for_layout(self.layout, ".") # Clean up os.remove(link_path)
#!/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")
def setUp(self): """Create a dummy supply chain with two steps one inspection and the according link metadata: write-code (Step) -> package (step) -> untar (Inspection) 'write-code' creates an artifact foo 'package' creates foo.tar.gz and deletes foo 'untar' untars foo.tar.gz which results in foo.tar.gz and foo """ self.sha256_foo = \ "d65165279105ca6773180500688df4bdc69a2c7b771752f0a46ef120b7fd8ec3" self.sha256_foo_tar = \ "93c3c35a039a6a3d53e81c5dbee4ebb684de57b7c8be11b8739fd35804a0e918" self.steps = [ Step( name="write-code", expected_products=[["CREATE", "foo"]], ), Step( name="package", expected_materials=[[ "MATCH", "foo", "WITH", "PRODUCTS", "FROM", "write-code" ]], expected_products=[["CREATE", "foo.tar.gz"], ["DELETE", "foo"]], ) ] self.inspections = [ Inspection(name="untar", expected_materials=[[ "MATCH", "foo.tar.gz", "WITH", "PRODUCTS", "FROM", "package" ]], expected_products=[[ "MATCH", "foo", "IN", "dir", "WITH", "PRODUCTS", "FROM", "write-code" ]]) ] self.links = { "write-code": Metablock( signed=Link(name="write-code", products={"foo": { "sha256": self.sha256_foo }})), "package": Metablock(signed=Link( name="package", materials={"foo": { "sha256": self.sha256_foo }}, products={"foo.tar.gz": { "sha256": self.sha256_foo_tar }})), "untar": Metablock(signed=Link( name="untar", materials={"foo.tar.gz": { "sha256": self.sha256_foo_tar }}, products={ "dir/foo": { "sha256": self.sha256_foo }, })) }
#!/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 layout = Layout() build = Step(name="build") build.expected_materials.append(['ALLOW', 'src/*']) build.expected_products.append(['CREATE', 'foo']) analyze = Step(name="analyze") analyze.expected_materials.append( ['MATCH', 'foo', 'WITH', 'PRODUCTS', 'FROM', 'build']) layout.steps.append(build) layout.steps.append(analyze) 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")
def setUp(self): """Populate a base layout that we can use.""" self.step = Step(name="this-step")
class TestStepValidator(unittest.TestCase): """Test verifylib.verify_delete_rule(rule, artifact_queue) """ def setUp(self): """Populate a base layout that we can use.""" self.step = Step(name="this-step") def test_wrong_type(self): """Test the type field within Validate().""" self.step._type = "wrong" with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_type() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step._type = "step" self.step._validate_type() def test_wrong_threshold(self): """Test that the threshold value is correctly checked.""" # no, python is not *this* smart self.step.threshold = "Ten" with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_threshold() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.threshold = 10 self.step._validate_threshold() self.step.validate() def test_wrong_expected_materials(self): """Test that the material rule validators catch malformed ones.""" self.step.expected_materials = [["NONFOO"]] with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_expected_materials() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.expected_materials = "PFF" with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_expected_materials() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() # for more thorough tests, check the test_artifact_rules.py module self.step.expected_materials = [["CREATE", "foo"]] self.step._validate_expected_materials() self.step.validate() def test_wrong_expected_products(self): """Test that the product rule validators catch malformed ones.""" self.step.expected_products = [["NONFOO"]] with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_expected_products() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.expected_products = "PFF" with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_expected_products() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() # for more thorough tests, check the test_artifact_rules.py module self.step.expected_products = [["CREATE", "foo"]] self.step._validate_expected_products() self.step.validate() def test_wrong_pubkeys(self): # FIXME: generating keys for each test are expensive processes, maybe we # should have an asset/fixture folder/loader? rsa_key_one = securesystemslib.keys.generate_rsa_key() rsa_key_two = securesystemslib.keys.generate_rsa_key() self.step.pubkeys = ['bad-keyid'] with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_pubkeys() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.pubkeys = [rsa_key_one['keyid'], rsa_key_two['keyid']] self.step._validate_pubkeys() self.step.validate() def test_wrong_expected_command(self): """Test that the expected command validator catches malformed ones.""" self.step.expected_command = -1 with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_expected_command() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.expected_command = ["somecommand"] self.step._validate_expected_command() self.step.validate()
def test_set_expected_command_from_string(self): """Test shelx parse command string to list. """ step = Step() step.set_expected_command_from_string("echo 'foo bar'") self.assertListEqual(step.expected_command, ["echo", "foo bar"])
class TestStepValidator(unittest.TestCase): """Test verifylib.verify_delete_rule(rule, artifact_queue) """ def setUp(self): """Populate a base layout that we can use.""" self.step = Step(name="this-step") def test_wrong_type(self): """Test the type field within Validate().""" self.step._type = "wrong" with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_type() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step._type = "step" self.step._validate_type() def test_wrong_threshold(self): """Test that the threshold value is correctly checked.""" # no, python is not *this* smart self.step.threshold = "Ten" with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_threshold() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.threshold = 10 self.step._validate_threshold() self.step.validate() def test_wrong_pubkeys(self): # FIXME: generating keys for each test are expensive processes, maybe we # should have an asset/fixture folder/loader? rsa_key_one = securesystemslib.keys.generate_rsa_key() rsa_key_two = securesystemslib.keys.generate_rsa_key() self.step.pubkeys = ['bad-keyid'] with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_pubkeys() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.pubkeys = [rsa_key_one['keyid'], rsa_key_two['keyid']] self.step._validate_pubkeys() self.step.validate() def test_wrong_expected_command(self): """Test that the expected command validator catches malformed ones.""" self.step.expected_command = -1 with self.assertRaises(securesystemslib.exceptions.FormatError): self.step._validate_expected_command() with self.assertRaises(securesystemslib.exceptions.FormatError): self.step.validate() self.step.expected_command = ["somecommand"] self.step._validate_expected_command() self.step.validate() def test_set_expected_command_from_string(self): """Test shelx parse command string to list. """ step = Step() step.set_expected_command_from_string("echo 'foo bar'") self.assertListEqual(step.expected_command, ["echo", "foo bar"])
def test_step_expected_command_shlex(self): """Check that a step's `expected_command` passed as string is converted to a list (using `shlex`). """ step = Step(**{"expected_command": "rm -rf /"}) self.assertTrue(isinstance(step.expected_command, list)) self.assertTrue(len(step.expected_command) == 3)
#!/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") generate_and_write_rsa_keypair("analyze_key") analyze_key = import_rsa_key_from_file("analyze_key.pub") layout = Layout() build = Step(name="build") build.expected_materials.append(['ALLOW', 'src/*']) build.expected_products.append(['CREATE', 'foo']) build.expected_command = ['gcc', '-o foo', 'src/*'] analyze = Step(name="analyze") analyze.expected_materials.append( ['MATCH', 'foo', 'WITH', 'PRODUCTS', 'FROM', 'build']) analyze.expected_command = ['valgrind', './foo'] layout.steps.append(build) layout.steps.append(analyze) layout.add_functionary_key(build_key) layout.add_functionary_key(analyze_key) build.pubkeys.append(build_key['keyid']) analyze.pubkeys.append(analyze_key['keyid']) generate_and_write_rsa_keypair("root_key") root_key = import_rsa_key_from_file("root_key")
# generate root key (project owner key) generate_and_write_rsa_keypair("root_key") root_key = import_rsa_key_from_file("root_key") # Generate two functionary keys generate_and_write_rsa_keypair("build_key") generate_and_write_rsa_keypair("analyze_key") build_key = import_rsa_key_from_file("build_key.pub") analyze_key = import_rsa_key_from_file("analyze_key.pub") # create a layout layout = Layout() # create the bulid step and add restrictions build = Step(name='build') build.expected_materials.append(["ALLOW", "src/*"]) build.expected_products.append(["CREATE", "foo"]) build.expected_command = ['gcc', '-o foo', 'src/*'] build.pubkeys.append(build_key['keyid']) # create the analyze step and add restrictions analyze = Step(name='analyze') analyze.expected_materials.append( ['MATCH', 'foo', 'WITH', 'PRODUCTS', 'FROM', 'build']) analyze.expected_command = ['valgrind', './foo'] analyze.pubkeys.append(analyze_key['keyid']) # add the steps to the layout and register their keys layout.steps.append(build) layout.steps.append(analyze)
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)
from in_toto.models.layout import Layout, Step, Inspection import in_toto.util import datetime if __name__: # Get keys santiago_key = in_toto.util.import_rsa_key_from_file("santiago") justin_key = in_toto.util.import_rsa_key_from_file("justin") print("{}".format(justin_key['keyid'])) git = Step(name="tag-webapp", expected_command='git tag', material_matchrules=[], product_matchrules=[ ["CREATE", "src/*"], ["CREATE", "public/*"]], pubkeys=[santiago_key['keyid']]) eslint = Step(name="eslint", expected_command="eslint src/", material_matchrules=[ ["MATCH", "PRODUCT", "src/*", "from", "tag-webapp:"], ], product_matchrules=[], pubkeys=[santiago_key['keyid']]) build = Step(name="build", expected_command="npm run build", material_matchrules=[