diff --git a/securesystemslib/gpg/common.py b/securesystemslib/gpg/common.py index cbfaac20..676ce9ac 100644 --- a/securesystemslib/gpg/common.py +++ b/securesystemslib/gpg/common.py @@ -23,10 +23,10 @@ import logging import struct -from securesystemslib import formats from securesystemslib.gpg import util as gpg_util from securesystemslib.gpg.constants import ( FULL_KEYID_SUBPACKET, + GPG_HASH_ALGORITHM_STRING, KEY_EXPIRATION_SUBPACKET, PACKET_TYPE_PRIMARY_KEY, PACKET_TYPE_SIGNATURE, @@ -93,7 +93,7 @@ def parse_pubkey_payload(data): None. - A public key in the format securesystemslib.formats.GPG_PUBKEY_SCHEMA + A public key dict. """ if not data: @@ -145,7 +145,7 @@ def parse_pubkey_payload(data): return { "method": keyinfo["method"], "type": keyinfo["type"], - "hashes": [formats.GPG_HASH_ALGORITHM_STRING], + "hashes": [GPG_HASH_ALGORITHM_STRING], "creation_time": time_of_creation[0], "keyid": keyinfo["keyid"], "keyval": {"private": "", "public": key_params}, @@ -333,7 +333,7 @@ def _assign_certified_key_info(bundle): None. - A public key in the format securesystemslib.formats.GPG_PUBKEY_SCHEMA. + A public key dict. """ # Create handler shortcut @@ -476,8 +476,7 @@ def _get_verified_subkeys(bundle): None. - A dictionary of public keys in the format - securesystemslib.formats.GPG_PUBKEY_SCHEMA, with keyids as dict keys. + A dict of public keys dicts with keyids as dict keys. """ # Create handler shortcut @@ -601,19 +600,14 @@ def get_pubkey_bundle(data, keyid): If no master key or subkeys could be found that matches the passed keyid. - securesystemslib.exceptions.FormatError - If the passed keyid does not match - securesystemslib.formats.KEYID_SCHEMA None. - A public key in the format securesystemslib.formats.GPG_PUBKEY_SCHEMA with - optional subkeys. + A public key dict with optional subkeys. """ - formats.KEYID_SCHEMA.check_match(keyid) if not data: raise KeyNotFoundError( "Could not find gpg key '{}' in empty exported key " # pylint: disable=consider-using-f-string @@ -703,9 +697,7 @@ def parse_signature_packet( # pylint: disable=too-many-locals,too-many-branches None. - A signature dictionary matching - securesystemslib.formats.GPG_SIGNATURE_SCHEMA with the following special - characteristics: + A signature dict with the following special characteristics: - The "keyid" field is an empty string if it cannot be determined - The "short_keyid" is not added if it cannot be determined - At least one of non-empty "keyid" or "short_keyid" are part of the diff --git a/securesystemslib/gpg/constants.py b/securesystemslib/gpg/constants.py index 5ede8e11..58c60174 100644 --- a/securesystemslib/gpg/constants.py +++ b/securesystemslib/gpg/constants.py @@ -131,3 +131,5 @@ def gpg_export_pubkey_command(homearg: str, keyid: str) -> List[str]: PRIMARY_USERID_SUBPACKET = 0x19 # See section 5.2.3.28. (Issuer Fingerprint) of rfc4880bis-06 FULL_KEYID_SUBPACKET = 0x21 + +GPG_HASH_ALGORITHM_STRING = "pgp+SHA2" diff --git a/securesystemslib/gpg/dsa.py b/securesystemslib/gpg/dsa.py index 1ee119f6..66650513 100644 --- a/securesystemslib/gpg/dsa.py +++ b/securesystemslib/gpg/dsa.py @@ -28,7 +28,7 @@ CRYPTO = False # pylint: disable=wrong-import-position -from securesystemslib import exceptions, formats +from securesystemslib import exceptions from securesystemslib.gpg import util as gpg_util from securesystemslib.gpg.exceptions import PacketParsingError @@ -43,13 +43,9 @@ def create_pubkey(pubkey_info): pubkey_info: - The DSA pubkey info dictionary as specified by - securesystemslib.formats.GPG_DSA_PUBKEY_SCHEMA + The DSA pubkey dict. - securesystemslib.exceptions.FormatError if - pubkey_info does not match securesystemslib.formats.GPG_DSA_PUBKEY_SCHEMA - securesystemslib.exceptions.UnsupportedLibraryError if the cryptography module is not available @@ -61,8 +57,6 @@ def create_pubkey(pubkey_info): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - formats.GPG_DSA_PUBKEY_SCHEMA.check_match(pubkey_info) - y = int(pubkey_info["keyval"]["public"]["y"], 16) g = int(pubkey_info["keyval"]["public"]["g"], 16) p = int(pubkey_info["keyval"]["public"]["p"], 16) @@ -93,8 +87,7 @@ def get_pubkey_params(data): None. - The parsed DSA public key in the format - securesystemslib.formats.GPG_DSA_PUBKEY_SCHEMA. + A DSA public key dict. """ ptr = 0 @@ -190,12 +183,10 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): signature_object: - A signature dictionary as specified by - securesystemslib.formats.GPG_SIGNATURE_SCHEMA + A signature dict. pubkey_info: - The DSA public key info dictionary as specified by - securesystemslib.formats.GPG_DSA_PUBKEY_SCHEMA + The DSA public key dict. hash_algorithm_id: one of SHA1, SHA256, SHA512 (see securesystemslib.gpg.constants) @@ -207,10 +198,6 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): The signed bytes against which the signature is verified - securesystemslib.exceptions.FormatError if: - signature_object does not match securesystemslib.formats.GPG_SIGNATURE_SCHEMA - pubkey_info does not match securesystemslib.formats.GPG_DSA_PUBKEY_SCHEMA - securesystemslib.exceptions.UnsupportedLibraryError if: the cryptography module is not available @@ -225,9 +212,6 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - formats.GPG_SIGNATURE_SCHEMA.check_match(signature_object) - formats.GPG_DSA_PUBKEY_SCHEMA.check_match(pubkey_info) - hasher = gpg_util.get_hashing_class(hash_algorithm_id) pubkey_object = create_pubkey(pubkey_info) diff --git a/securesystemslib/gpg/eddsa.py b/securesystemslib/gpg/eddsa.py index 7a8c6c36..6d93163a 100644 --- a/securesystemslib/gpg/eddsa.py +++ b/securesystemslib/gpg/eddsa.py @@ -19,7 +19,7 @@ import binascii -from securesystemslib import exceptions, formats +from securesystemslib import exceptions from securesystemslib.gpg import util as gpg_util from securesystemslib.gpg.exceptions import PacketParsingError @@ -65,8 +65,7 @@ def get_pubkey_params(data): A dictionary with an element "q" that holds the ascii hex representation - of the MPI of an EC point representing an EdDSA public key that conforms - with securesystemslib.formats.GPG_ED25519_PUBKEY_SCHEMA. + of the MPI of an EC point representing an EdDSA public key. """ ptr = 0 @@ -163,12 +162,9 @@ def create_pubkey(pubkey_info): pubkey_info: - The ED25519 public key dictionary as specified by - securesystemslib.formats.GPG_ED25519_PUBKEY_SCHEMA + The ED25519 public key dict. - securesystemslib.exceptions.FormatError if - pubkey_info does not match securesystemslib.formats.GPG_DSA_PUBKEY_SCHEMA securesystemslib.exceptions.UnsupportedLibraryError if the cryptography module is unavailable @@ -181,8 +177,6 @@ def create_pubkey(pubkey_info): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - formats.GPG_ED25519_PUBKEY_SCHEMA.check_match(pubkey_info) - public_bytes = binascii.unhexlify(pubkey_info["keyval"]["public"]["q"]) public_key = pyca_ed25519.Ed25519PublicKey.from_public_bytes(public_bytes) @@ -197,12 +191,10 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): signature_object: - A signature dictionary as specified by - securesystemslib.formats.GPG_SIGNATURE_SCHEMA + A signature dict. pubkey_info: - The DSA public key info dictionary as specified by - securesystemslib.formats.GPG_ED25519_PUBKEY_SCHEMA + A DSA public key dict. hash_algorithm_id: one of SHA1, SHA256, SHA512 (see securesystemslib.gpg.constants) @@ -214,10 +206,6 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): The signed bytes against which the signature is verified - securesystemslib.exceptions.FormatError if: - signature_object does not match securesystemslib.formats.GPG_SIGNATURE_SCHEMA - pubkey_info does not match securesystemslib.formats.GPG_ED25519_PUBKEY_SCHEMA - securesystemslib.exceptions.UnsupportedLibraryError if: the cryptography module is unavailable @@ -232,9 +220,6 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - formats.GPG_SIGNATURE_SCHEMA.check_match(signature_object) - formats.GPG_ED25519_PUBKEY_SCHEMA.check_match(pubkey_info) - hasher = gpg_util.get_hashing_class(hash_algorithm_id) pubkey_object = create_pubkey(pubkey_info) diff --git a/securesystemslib/gpg/functions.py b/securesystemslib/gpg/functions.py index 889b4828..0b046b84 100644 --- a/securesystemslib/gpg/functions.py +++ b/securesystemslib/gpg/functions.py @@ -20,7 +20,7 @@ import subprocess # nosec import time -from securesystemslib import exceptions, formats +from securesystemslib import exceptions from securesystemslib.gpg.common import ( get_pubkey_bundle, parse_signature_packet, @@ -73,9 +73,6 @@ def create_signature(content, keyid=None, homedir=None, timeout=GPG_TIMEOUT): gpg command timeout in seconds. Default is 10. - securesystemslib.exceptions.FormatError: - If the keyid was passed and does not match - securesystemslib.formats.KEYID_SCHEMA ValueError: If the gpg command failed to create a valid signature. @@ -98,8 +95,7 @@ def create_signature(content, keyid=None, homedir=None, timeout=GPG_TIMEOUT): None. - The created signature in the format: - securesystemslib.formats.GPG_SIGNATURE_SCHEMA. + A signature dict. """ if not have_gpg(): # pragma: no cover @@ -110,7 +106,6 @@ def create_signature(content, keyid=None, homedir=None, timeout=GPG_TIMEOUT): keyarg = "" if keyid: - formats.KEYID_SCHEMA.check_match(keyid) keyarg = ( "--local-user {}".format( # pylint: disable=consider-using-f-string keyid @@ -211,12 +206,10 @@ def verify_signature(signature_object, pubkey_info, content): signature_object: - A signature object in the format: - securesystemslib.formats.GPG_SIGNATURE_SCHEMA + A signature dict. pubkey_info: - A public key object in the format: - securesystemslib.formats.GPG_PUBKEY_SCHEMA + A public key dict. content: The content to be verified. (bytes) @@ -238,9 +231,6 @@ def verify_signature(signature_object, pubkey_info, content): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - formats.GPG_PUBKEY_SCHEMA.check_match(pubkey_info) - formats.GPG_SIGNATURE_SCHEMA.check_match(signature_object) - handler = SIGNATURE_HANDLERS[pubkey_info["type"]] sig_keyid = signature_object["keyid"] @@ -270,13 +260,12 @@ def export_pubkey(keyid, homedir=None, timeout=GPG_TIMEOUT): """Exports a public key from a GnuPG keyring. Arguments: - keyid: An OpenPGP keyid in KEYID_SCHEMA format. + keyid: An OpenPGP keyid.. homedir (optional): A path to the GnuPG home directory. If not set the default GnuPG home directory is used. timeout (optional): gpg command timeout in seconds. Default is 10. Raises: - ValueError: Keyid is not a string. UnsupportedLibraryError: The gpg command or pyca/cryptography are not available. KeyNotFoundError: No key or subkey was found for that keyid. @@ -285,7 +274,7 @@ def export_pubkey(keyid, homedir=None, timeout=GPG_TIMEOUT): Calls system gpg command in a subprocess. Returns: - An OpenPGP public key object in GPG_PUBKEY_SCHEMA format. + An OpenPGP public key dict. """ if not have_gpg(): # pragma: no cover @@ -294,14 +283,6 @@ def export_pubkey(keyid, homedir=None, timeout=GPG_TIMEOUT): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - if not formats.KEYID_SCHEMA.matches(keyid): - # FIXME: probably needs smarter parsing of what a valid keyid is so as to - # not export more than one pubkey packet. - raise ValueError( - "we need to export an individual key. Please provide a " # pylint: disable=consider-using-f-string - " valid keyid! Keyid was '{}'.".format(keyid) - ) - homearg = "" if homedir: homearg = ( @@ -330,7 +311,7 @@ def export_pubkeys(keyids, homedir=None, timeout=GPG_TIMEOUT): """Exports multiple public keys from a GnuPG keyring. Arguments: - keyids: A list of OpenPGP keyids in KEYID_SCHEMA format. + keyids: A list of OpenPGP keyids. homedir (optional): A path to the GnuPG home directory. If not set the default GnuPG home directory is used. timeout (optional): gpg command timeout in seconds. Default is 10. @@ -346,7 +327,7 @@ def export_pubkeys(keyids, homedir=None, timeout=GPG_TIMEOUT): Calls system gpg command in a subprocess. Returns: - A dict of OpenPGP public key objects in GPG_PUBKEY_SCHEMA format as values, + A dict of OpenPGP public key dicts as values, and their keyids as dict keys. diff --git a/securesystemslib/gpg/rsa.py b/securesystemslib/gpg/rsa.py index b39dc168..9a876bdc 100644 --- a/securesystemslib/gpg/rsa.py +++ b/securesystemslib/gpg/rsa.py @@ -27,7 +27,7 @@ CRYPTO = False # pylint: disable=wrong-import-position -from securesystemslib import exceptions, formats +from securesystemslib import exceptions from securesystemslib.gpg import util as gpg_util from securesystemslib.gpg.exceptions import PacketParsingError @@ -42,13 +42,9 @@ def create_pubkey(pubkey_info): pubkey_info: - The RSA pubkey info dictionary as specified by - securesystemslib.formats.GPG_RSA_PUBKEY_SCHEMA + An RSA pubkey dict. - securesystemslib.exceptions.FormatError if - pubkey_info does not match securesystemslib.formats.GPG_RSA_PUBKEY_SCHEMA - securesystemslib.exceptions.UnsupportedLibraryError if the cryptography module is unavailable @@ -60,8 +56,6 @@ def create_pubkey(pubkey_info): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - formats.GPG_RSA_PUBKEY_SCHEMA.check_match(pubkey_info) - e = int(pubkey_info["keyval"]["public"]["e"], 16) n = int(pubkey_info["keyval"]["public"]["n"], 16) pubkey = rsa.RSAPublicNumbers(e, n).public_key(backends.default_backend()) @@ -87,9 +81,7 @@ def get_pubkey_params(data): None. - The parsed RSA public key in the format - securesystemslib.formats.GPG_RSA_PUBKEY_SCHEMA. - + An RSA public key dict. """ ptr = 0 @@ -151,12 +143,10 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): signature_object: - A signature dictionary as specified by - securesystemslib.formats.GPG_SIGNATURE_SCHEMA + A signature dict. pubkey_info: - The RSA public key info dictionary as specified by - securesystemslib.formats.GPG_RSA_PUBKEY_SCHEMA + The RSA public key dict. content: The signed bytes against which the signature is verified @@ -168,11 +158,6 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): "hashes" or "method" fields. - securesystemslib.exceptions.FormatError if: - signature_object does not match - securesystemslib.formats.GPG_SIGNATURE_SCHEMA, - pubkey_info does not match securesystemslib.formats.GPG_RSA_PUBKEY_SCHEMA - securesystemslib.exceptions.UnsupportedLibraryError if: the cryptography module is unavailable @@ -187,9 +172,6 @@ def verify_signature(signature_object, pubkey_info, content, hash_algorithm_id): if not CRYPTO: # pragma: no cover raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG) - formats.GPG_SIGNATURE_SCHEMA.check_match(signature_object) - formats.GPG_RSA_PUBKEY_SCHEMA.check_match(pubkey_info) - hasher = gpg_util.get_hashing_class(hash_algorithm_id) pubkey_object = create_pubkey(pubkey_info) diff --git a/securesystemslib/signer/_gpg_signer.py b/securesystemslib/signer/_gpg_signer.py index e4977ce3..b007241b 100644 --- a/securesystemslib/signer/_gpg_signer.py +++ b/securesystemslib/signer/_gpg_signer.py @@ -4,7 +4,8 @@ from typing import Any, Dict, Optional, Tuple from urllib import parse -from securesystemslib import exceptions, formats +from securesystemslib import exceptions +from securesystemslib.gpg import constants as gpg_constants from securesystemslib.gpg import exceptions as gpg_exceptions from securesystemslib.gpg import functions as gpg from securesystemslib.signer._key import Key @@ -52,10 +53,7 @@ def verify_signature(self, signature: Signature, data: bytes) -> None: raise exceptions.UnverifiedSignatureError( f"Failed to verify signature by {self.keyid}" ) - except ( - exceptions.FormatError, - exceptions.UnsupportedLibraryError, - ) as e: + except (exceptions.UnsupportedLibraryError,) as e: logger.info("Key %s failed to verify sig: %s", self.keyid, str(e)) raise exceptions.VerificationError( f"Unknown failure to verify signature by {self.keyid}" @@ -138,7 +136,7 @@ def _key_to_legacy_dict(key: GPGKey) -> Dict[str, Any]: "keyid": key.keyid, "type": key.keytype, "method": key.scheme, - "hashes": [formats.GPG_HASH_ALGORITHM_STRING], + "hashes": [gpg_constants.GPG_HASH_ALGORITHM_STRING], "keyval": key.keyval, } diff --git a/tests/test_gpg.py b/tests/test_gpg.py index 3144fe4d..4fd78fa2 100644 --- a/tests/test_gpg.py +++ b/tests/test_gpg.py @@ -31,7 +31,6 @@ from cryptography.hazmat import backends from cryptography.hazmat.primitives import serialization -from securesystemslib.formats import ANY_PUBKEY_DICT_SCHEMA, GPG_PUBKEY_SCHEMA from securesystemslib.gpg.common import ( _assign_certified_key_info, _get_verified_subkeys, @@ -286,11 +285,10 @@ def test_parse_pubkey_bundle(self): gpg --list-packets ``` """ - # Expect parsed primary key matching GPG_PUBKEY_SCHEMA - self.assertTrue( - GPG_PUBKEY_SCHEMA.matches( - self.raw_key_bundle[PACKET_TYPE_PRIMARY_KEY]["key"] - ) + # Expect parsed primary key + self.assertEqual( + self.raw_key_bundle[PACKET_TYPE_PRIMARY_KEY]["key"]["method"], + "pgp+rsa-pkcsv1.5", ) # Parse corresponding raw packet for comparison @@ -599,7 +597,7 @@ def tearDownClass(self): # pylint: disable=bad-classmethod-argument def test_export_pubkey_error(self): """Test correct error is raised if function called incorrectly.""" - with self.assertRaises(ValueError): + with self.assertRaises(KeyNotFoundError): export_pubkey("not-a-key-id") def test_export_pubkey(self): @@ -655,7 +653,6 @@ def test_export_pubkeys(self): [self.default_keyid, self.keyid_768C43], homedir=self.gnupg_home ) - ANY_PUBKEY_DICT_SCHEMA.check_match(key_dict) self.assertListEqual( sorted([self.default_keyid.lower(), self.keyid_768C43.lower()]), sorted(key_dict.keys()), diff --git a/tests/test_signer.py b/tests/test_signer.py index a2dba832..de0cb4a2 100644 --- a/tests/test_signer.py +++ b/tests/test_signer.py @@ -14,11 +14,7 @@ load_pem_public_key, ) -from securesystemslib.exceptions import ( - FormatError, - UnverifiedSignatureError, - VerificationError, -) +from securesystemslib.exceptions import FormatError, UnverifiedSignatureError from securesystemslib.gpg.constants import have_gpg from securesystemslib.gpg.exceptions import CommandError, KeyNotFoundError from securesystemslib.signer import ( @@ -441,10 +437,6 @@ def test_gpg_sign_and_verify_object(self): with self.assertRaises(UnverifiedSignatureError): public_key.verify_signature(sig, self.wrong_data) - sig.keyid = 123456 - with self.assertRaises(VerificationError): - public_key.verify_signature(sig, self.test_data) - def test_gpg_fail_sign_keyid_match(self): """Fail signing because signature keyid does not match public key.""" uri, public_key = GPGSigner.import_(self.default_keyid, self.gnupg_home)