def test_sign(): privkey_path = os.path.join(ED25519_DIR, 'scriptworker_private_key') privkey = swed25519.ed25519_private_key_from_file(privkey_path) pubkey_path = os.path.join(ED25519_DIR, 'scriptworker_public_key') pubkey = swed25519.ed25519_public_key_from_file(pubkey_path) binary_contents = read_from_file(os.path.join(ED25519_DIR, 'foo.json'), file_type='binary') detached_sig = read_from_file(os.path.join(ED25519_DIR, 'foo.json.scriptworker.sig'), file_type='binary') assert privkey.sign(binary_contents) == detached_sig
def test_verify_ed25519_signature(unsigned_path, signature_path, public_key_path, raises): pubkey = swed25519.ed25519_public_key_from_file(public_key_path) contents = read_from_file(unsigned_path, file_type='binary') sig = read_from_file(signature_path, file_type='binary') if raises: with pytest.raises(ScriptWorkerEd25519Error): swed25519.verify_ed25519_signature(pubkey, contents, sig, "foo") else: swed25519.verify_ed25519_signature(pubkey, contents, sig, "foo")
def test_from_file(): privkey_path = os.path.join(ED25519_DIR, 'scriptworker_private_key') privkey_string = read_from_file(privkey_path) privkey = swed25519.ed25519_private_key_from_file(privkey_path) pubkey_path = os.path.join(ED25519_DIR, 'scriptworker_public_key') pubkey_string = read_from_file(pubkey_path) pubkey = swed25519.ed25519_public_key_from_file(pubkey_path) assert swed25519.ed25519_public_key_to_string(privkey.public_key()) == pubkey_string assert swed25519.ed25519_private_key_to_string(privkey) == privkey_string assert swed25519.ed25519_public_key_to_string(pubkey) == pubkey_string
def test_read_from_file(tmpdir, file_type, contents_or_path, expected, exception, raises, is_path): path = os.path.join(tmpdir, "foo") if is_path: with open(contents_or_path, "rb") as fh: contents_or_path = fh.read() expected = contents_or_path if contents_or_path is not None: with open(path, "wb") as fh: fh.write(contents_or_path) if raises: with pytest.raises(exception): utils.read_from_file(path, file_type=file_type, exception=exception) else: assert utils.read_from_file(path, file_type=file_type, exception=exception) == expected
def test_read_from_file(tmpdir, file_type, contents_or_path, expected, exception, raises, is_path): path = os.path.join(tmpdir, 'foo') if is_path: with open(contents_or_path, 'rb') as fh: contents_or_path = fh.read() expected = contents_or_path if contents_or_path is not None: with open(path, 'wb') as fh: fh.write(contents_or_path) if raises: with pytest.raises(exception): utils.read_from_file(path, file_type=file_type, exception=exception) else: assert utils.read_from_file(path, file_type=file_type, exception=exception) == expected
def verify_ed25519_signature_cmdln(args=None, exception=SystemExit): """Verify an ed25519 signature from the command line. Args: args (list, optional): the commandline args to parse. If ``None``, use ``sys.argv[1:]``. Defaults to ``None``. exception (Exception, optional): the exception to raise on failure. Defaults to ``SystemExit``. """ args = args or sys.argv[1:] parser = argparse.ArgumentParser( description="""Verify an ed25519 signature from the command line. Given a file and its detached signature, verify that it has been signed with a valid key. This key can be specified on the command line; otherwise we'll default to ``config['ed25519_public_keys']``.""") parser.add_argument('--pubkey', help='path to a base64-encoded ed25519 pubkey, optional') parser.add_argument('file_path') parser.add_argument('sig_path') opts = parser.parse_args(args) log = logging.getLogger('scriptworker') log.setLevel(logging.DEBUG) logging.basicConfig() pubkeys = {} if opts.pubkey: pubkeys['cmdln'] = [read_from_file(opts.pubkey)] pubkeys.update(dict(DEFAULT_CONFIG['ed25519_public_keys'])) contents = read_from_file(opts.file_path, file_type='binary') signature = read_from_file(opts.sig_path, file_type='binary') for key_type, seeds in pubkeys.items(): for seed in seeds: try: verify_ed25519_signature( ed25519_public_key_from_string(seed), contents, signature, "didn't work with {}".format(seed) ) log.info("Verified good with {} seed {} !".format( key_type, seed )) sys.exit(0) except ScriptWorkerEd25519Error: pass raise exception("This is not a valid signature!")
def verify_ed25519_signature_cmdln(args=None, exception=SystemExit): """Verify an ed25519 signature from the command line. Args: args (list, optional): the commandline args to parse. If ``None``, use ``sys.argv[1:]``. Defaults to ``None``. exception (Exception, optional): the exception to raise on failure. Defaults to ``SystemExit``. """ args = args or sys.argv[1:] parser = argparse.ArgumentParser( description="""Verify an ed25519 signature from the command line. Given a file and its detached signature, verify that it has been signed with a valid key. This key can be specified on the command line; otherwise we'll default to ``config['ed25519_public_keys']``.""") parser.add_argument( '--pubkey', help='path to a base64-encoded ed25519 pubkey, optional') parser.add_argument('file_path') parser.add_argument('sig_path') opts = parser.parse_args(args) log = logging.getLogger('scriptworker') log.setLevel(logging.DEBUG) logging.basicConfig() pubkeys = {} if opts.pubkey: pubkeys['cmdln'] = [read_from_file(opts.pubkey)] pubkeys.update(dict(DEFAULT_CONFIG['ed25519_public_keys'])) contents = read_from_file(opts.file_path, file_type='binary') signature = read_from_file(opts.sig_path, file_type='binary') for key_type, seeds in pubkeys.items(): for seed in seeds: try: verify_ed25519_signature(ed25519_public_key_from_string(seed), contents, signature, "didn't work with {}".format(seed)) log.info("Verified good with {} seed {} !".format( key_type, seed)) sys.exit(0) except ScriptWorkerEd25519Error: pass raise exception("This is not a valid signature!")
def _ed25519_key_from_file(fn, path): """Create an ed25519 key from the contents of ``path``. ``path`` is a filepath containing a base64-encoded ed25519 key seed. Args: fn (callable): the function to call with the contents from ``path`` path (str): the file path to the base64-encoded key seed. Returns: obj: the appropriate key type from ``path`` Raises: ScriptWorkerEd25519Error """ try: return fn(read_from_file(path, exception=ScriptWorkerEd25519Error)) except ScriptWorkerException as exc: raise ScriptWorkerEd25519Error("Failed calling {} for {}: {}!".format(fn, path, str(exc)))