Ejemplo n.º 1
0
    def setUp(self):
        self.item_name = "item"
        self.sha256_1 = \
            "d65165279105ca6773180500688df4bdc69a2c7b771752f0a46ef120b7fd8ec3"
        self.sha256_2 = \
            "cfdaaf1ab2e4661952a9dec5e8fa3c360c1b06b1a073e8493a7c46d2af8c504b"

        self.links = {
            "item":
            Metablock(signed=Link(name="item",
                                  materials={
                                      "foo": {
                                          "sha256": self.sha256_1
                                      },
                                      "foobar": {
                                          "sha256": self.sha256_1
                                      },
                                      "bar": {
                                          "sha256": self.sha256_1
                                      }
                                  },
                                  products={
                                      "baz": {
                                          "sha256": self.sha256_1
                                      },
                                      "foo": {
                                          "sha256": self.sha256_1
                                      },
                                      "bar": {
                                          "sha256": self.sha256_2
                                      }
                                  }))
        }
Ejemplo n.º 2
0
    def load(path):
        """Loads the JSON string representation of in-toto metadata from disk.

    Arguments:
      path: The path to read the file from.

    Raises:
      IOError: The file cannot be written.
      securesystemslib.exceptions.FormatError: Metadata format is invalid.

    Returns:
      A Metablock object whose signable attribute is either a Link or a Layout
      object.

    """
        with open(path, "r") as fp:
            data = json.load(fp)

        signatures = data.get("signatures", [])
        signed_data = data.get("signed", {})
        signed_type = signed_data.get("_type")

        if signed_type == "link":
            signed = Link.read(signed_data)

        elif signed_type == "layout":
            signed = Layout.read(signed_data)

        else:
            raise securesystemslib.exceptions.FormatError(
                "Invalid Metadata format")

        return Metablock(signatures=signatures, signed=signed)
Ejemplo n.º 3
0
    def test_validate_byproducts(self):
        """Test `byproducts` field. Must be a `dict` """
        test_link = Link()
        # Good byproducts
        test_link.byproducts = {}
        test_link.validate()

        # Bad byproducts
        test_link.byproducts = "not a dict"
        with self.assertRaises(FormatError):
            test_link.validate()
Ejemplo n.º 4
0
    def test_validate_command(self):
        """Test `command` field. Must be either a `list` """
        test_link = Link()

        # Good command
        test_link.command = ["echo", "'good command'"]
        test_link.validate()

        # Bad command
        test_link.command = "echo 'bad command'"
        with self.assertRaises(FormatError):
            test_link.validate()
Ejemplo n.º 5
0
    def test_validate_type(self):
        """Test `_type` field. Must be "link" """
        test_link = Link()

        # Good type
        test_link._type = "link"
        test_link.validate()

        # Bad type
        test_link._type = "bad link"
        with self.assertRaises(FormatError):
            test_link.validate()
Ejemplo n.º 6
0
    def test_validate_environment(self):
        """Test `environment` field. Must be a `dict` """
        test_link = Link()

        # good env per default
        test_link.validate()

        # Bad env
        test_link.environment = "not a dict"
        with self.assertRaises(FormatError):
            test_link.validate()
Ejemplo n.º 7
0
    def setUp(self):
        """Setup artifact queues, artifacts dictionary and Link dictionary. """

        # Dummy artifact hashes
        self.sha256_foo = \
            "d65165279105ca6773180500688df4bdc69a2c7b771752f0a46ef120b7fd8ec3"
        self.sha256_foobar = \
            "155c693a6b7481f48626ebfc545f05236df679f0099225d6d0bc472e6dd21155"
        self.sha256_bar = \
            "cfdaaf1ab2e4661952a9dec5e8fa3c360c1b06b1a073e8493a7c46d2af8c504b"
        self.sha256_barfoo = \
            "2036784917e49b7685c7c17e03ddcae4a063979aa296ee5090b5bb8f8aeafc5d"

        # Link dictionary containing dummy artifacts related to Steps the rule is
        # matched with (match destination).
        materials = {
            "foo": {
                "sha256": self.sha256_foo
            },
            "foobar": {
                "sha256": self.sha256_foobar
            },
            "dev/foo": {
                "sha256": self.sha256_foo
            },
            "dev/foobar": {
                "sha256": self.sha256_foobar
            }
        }
        products = {
            "bar": {
                "sha256": self.sha256_bar
            },
            "barfoo": {
                "sha256": self.sha256_barfoo
            },
            "dev/bar": {
                "sha256": self.sha256_bar
            },
            "dev/barfoo": {
                "sha256": self.sha256_barfoo
            },
        }

        # Note: For simplicity the Links don't have all usually required fields set
        self.links = {
            "link-1":
            Metablock(signed=Link(
                name="link-1", materials=materials, products=products)),
        }
Ejemplo n.º 8
0
    def to_link(self, step_name):
        """Returns an in-toto link Metablock class from a GrafeasInTotoOccurrence
    class.
    """
        materials = {}
        products = {}
        command = []
        byproducts = {}
        environment = {}

        for item in self.intoto["signed"]["materials"]:
            materials[item["resource_uri"]] = item["hashes"]

        for item in self.intoto["signed"]["products"]:
            products[item["resource_uri"]] = item["hashes"]

        command = self.intoto["signed"]["command"]

        for key, value in self.intoto["signed"]["byproducts"].items():
            if key != "custom_values":
                byproducts[key] = value
        if "custom_values" in self.intoto["signed"]["byproducts"]:
            for key, value in \
                self.intoto["signed"]["byproducts"]["custom_values"].items():
                if key == "return-value":
                    # This highlights a special case - in-toto's reference implementations
                    # store return value as an integer while Grafeas allows only strings
                    byproducts[key] = int(value)
                else:
                    byproducts[key] = value

        for key, value in self.intoto["signed"]["environment"].items():
            if key != "custom_values":
                environment[key] = value
        if "custom_values" in self.intoto["signed"]["environment"]:
            for key, value in \
                self.intoto["signed"]["environment"]["custom_values"].items():
                environment[key] = value

        return Metablock(signed=Link(name=step_name,
                                     materials=materials,
                                     products=products,
                                     command=command,
                                     byproducts=byproducts,
                                     environment=environment),
                         signatures=self.intoto["signatures"])
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
    def load(path):
        """
    <Purpose>
      Loads the JSON string representation of signed metadata from disk
      and creates a Metablock object.
      The `signed` attribute of the Metablock object is assigned a Link
      or Layout object, depending on the `_type` field in the loaded
      metadata file.

    <Arguments>
      path:
              The path to write the file to.

    <Side Effects>
      Reading metadata file from disk

    <Returns>
      None.

    """

        with open(path, "r") as fp:
            data = json.load(fp)

        signatures = data.get("signatures", [])
        signed_data = data.get("signed", {})
        signed_type = signed_data.get("_type")

        if signed_type == "link":
            signed = Link.read(signed_data)

        elif signed_type == "layout":
            signed = Layout.read(signed_data)

        else:
            raise securesystemslib.exceptions.FormatError(
                "Invalid Metadata format")

        return Metablock(signatures=signatures, signed=signed)
Ejemplo n.º 11
0
    def test_validate_products(self):
        """Test `products` field. Must be a `dict` of HASH_DICTs """
        test_link = Link()

        # Good products
        sha = "cfdaaf1ab2e4661952a9dec5e8fa3c360c1b06b1a073e8493a7c46d2af8c504b"
        test_link.products = {"bar": {"sha256": sha}}
        test_link.validate()

        # Bad products 1
        test_link = Link()
        test_link.products = "not a dict"
        with self.assertRaises(FormatError):
            test_link.validate()

        # Bad products 2
        test_link.products = {"not": "a product dict"}
        with self.assertRaises(FormatError):
            test_link.validate()
Ejemplo n.º 12
0
    def test_validate_materials(self):
        """Test `materials` field. Must be a `dict` of HASH_DICTs """
        test_link = Link()

        # Good materials
        sha = "d65165279105ca6773180500688df4bdc69a2c7b771752f0a46ef120b7fd8ec3"
        test_link.materials = {"foo": {"sha256": sha}}
        test_link.validate()

        # Bad materials 1
        test_link.materials = "not a dict"
        with self.assertRaises(FormatError):
            test_link.validate()

        # Bad materials 1
        test_link.materials = {"not": "a material dict"}
        with self.assertRaises(FormatError):
            test_link.validate()
Ejemplo n.º 13
0
    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
                    },
                }))
        }