def setUpClass(self): # Create layout with one inspection self.layout = Layout.read({ "_type": "layout", "inspect": [], "steps": [{ "name": "run-command", "expected_command": ["{EDITOR}"], }] }) # Find demo files demo_files = os.path.join(os.path.dirname(os.path.realpath(__file__)), "demo_files") self.set_up_test_dir() # Copy demo files to temp dir for fn in os.listdir(demo_files): shutil.copy(os.path.join(demo_files, fn), self.test_dir) # load alice's key self.alice = import_rsa_privatekey_from_file("alice") self.alice_pub_dict = import_publickeys_from_file(["alice.pub"])
def test_import_publickeys_from_file(self): """Test import multiple public keys with different types. """ # Successfully import key dict with one key per supported key type key_dict = import_publickeys_from_file([ self.path_rsa + ".pub", self.path_ed25519 + ".pub", self.path_ecdsa + ".pub" ], [KEY_TYPE_RSA, KEY_TYPE_ED25519, KEY_TYPE_ECDSA]) ANY_PUBKEY_DICT_SCHEMA.check_match(key_dict) self.assertListEqual( sorted([key["keytype"] for key in key_dict.values()]), sorted([KEY_TYPE_RSA, KEY_TYPE_ED25519, KEY_TYPE_ECDSA])) # Successfully import default rsa key key_dict = import_publickeys_from_file([self.path_rsa + ".pub"]) ANY_PUBKEY_DICT_SCHEMA.check_match(key_dict) RSAKEY_SCHEMA.check_match(list(key_dict.values()).pop()) # Bad default rsa key type for ed25519 with self.assertRaises(Error): import_publickeys_from_file([self.path_ed25519 + ".pub"]) # Bad ed25519 key type for rsa key with self.assertRaises(Error): import_publickeys_from_file([self.path_rsa + ".pub"], [KEY_TYPE_ED25519]) # Unsupported key type with self.assertRaises(FormatError): import_publickeys_from_file([self.path_ed25519 + ".pub"], ["KEY_TYPE_UNSUPPORTED"]) # Mismatching arguments lists lenghts with self.assertRaises(FormatError): import_publickeys_from_file( [self.path_rsa + ".pub", self.path_ed25519 + ".pub"], [KEY_TYPE_ED25519])
def _verify_metadata(metadata, args): """ <Purpose> Internal method to verify link or layout signatures. <Arguments> metadata: Metablock object (contains Link or Layout object) args: see argparser <Exceptions> SystemExit(0) if verification passes SystemExit(1) if verification fails SystemExit(2) if any exception occurs """ try: # Load pubkeys from disk .... if args.key is not None: pub_key_dict = interface.import_publickeys_from_file(args.key, args.key_type) # ... or from gpg keyring elif args.gpg is not None: # pragma: no branch pub_key_dict = gpg_interface.export_pubkeys( args.gpg, args.gpg_home) for keyid, verification_key in six.iteritems(pub_key_dict): metadata.verify_signature(verification_key) LOG.info("Signature verification passed for keyid '{}'" .format(keyid)) sys.exit(0) except exceptions.SignatureVerificationError as e: LOG.error("Signature verification failed: {}".format(e)) sys.exit(1) except Exception as e: LOG.error("The following error occurred while verifying signatures: " "{}".format(e)) sys.exit(2)
def main(): """Parse arguments and call in_toto_verify. """ parser = create_parser() args = parser.parse_args() LOG.setLevelVerboseOrQuiet(args.verbose, args.quiet) # For verifying at least one of --layout-keys or --gpg must be specified # Note: Passing both at the same time is possible. if (args.layout_keys is None) and (args.gpg is None): parser.print_help() parser.error("wrong arguments: specify at least one of" " '--layout-keys path [path ...]' or '--gpg id [id ...]'") try: LOG.info("Loading layout...") layout = Metablock.load(args.layout) layout_key_dict = {} if args.layout_keys is not None: LOG.info("Loading layout key(s)...") layout_key_dict.update( interface.import_publickeys_from_file(args.layout_keys, args.key_types)) if args.gpg is not None: LOG.info("Loading layout gpg key(s)...") layout_key_dict.update( gpg_interface.export_pubkeys(args.gpg, homedir=args.gpg_home)) verifylib.in_toto_verify(layout, layout_key_dict, args.link_dir) except Exception as e: LOG.error("(in-toto-verify) {0}: {1}".format(type(e).__name__, e)) sys.exit(1) sys.exit(0)
def setUp(self): """Imports keys, generates layout and layout_key_dict for the clone, update-version, and package step.""" self.key_alice = interface.import_rsa_privatekey_from_file( "keys/alice") # Fetch and load Bob's and Carl's public keys # to specify that they are authorized to perform certain step in the layout self.key_bob = interface.import_rsa_publickey_from_file("keys/bob.pub") self.key_carl = interface.import_rsa_publickey_from_file( "keys/carl.pub") # Create layout self.layout = Layout.read({ "_type": "layout", "keys": { self.key_bob["keyid"]: self.key_bob, self.key_carl["keyid"]: self.key_carl, }, "steps": [{ "name": "clone", "expected_materials": [], "expected_products": [["CREATE", "demo-project/foo.py"], ["DISALLOW", "*"]], "pubkeys": [self.key_bob["keyid"]], "expected_command": [ "git", "clone", "https://github.com/in-toto/demo-project.git" ], "threshold": 1, }, { "name": "update-version", "expected_materials": [[ "MATCH", "demo-project/*", "WITH", "PRODUCTS", "FROM", "clone" ], ["DISALLOW", "*"]], "expected_products": [["ALLOW", "demo-project/foo.py"], ["DISALLOW", "*"]], "pubkeys": [self.key_bob["keyid"]], "expected_command": [], "threshold": 1, }, { "name": "package", "expected_materials": [ [ "MATCH", "demo-project/*", "WITH", "PRODUCTS", "FROM", "update-version" ], ["DISALLOW", "*"], ], "expected_products": [ ["CREATE", "demo-project.tar.gz"], ["DISALLOW", "*"], ], "pubkeys": [self.key_carl["keyid"]], "expected_command": [ "tar", "--exclude", ".git", "-zcvf", "demo-project.tar.gz", "demo-project", ], "threshold": 1, }], "inspect": [], }) self.metadata = Metablock(signed=self.layout) self.metadata.sign(self.key_alice) # Create the public key dict self.layout_key_dict = {} self.layout_key_dict.update( interface.import_publickeys_from_file(["keys/alice.pub"]))