diff --git a/edk2toolext/capsule/signtool_signer.py b/edk2toolext/capsule/signtool_signer.py index cd15865e..f4e29287 100644 --- a/edk2toolext/capsule/signtool_signer.py +++ b/edk2toolext/capsule/signtool_signer.py @@ -22,7 +22,7 @@ GLOBAL_SIGNTOOL_PATH = None SUPPORTED_SIGNATURE_TYPE_OPTIONS = { - 'pkcs7': {'detachedSignedData', 'embedded'} + 'pkcs7': {'detachedSignedData', 'embedded', 'pkcs7DetachedSignedData'} } @@ -66,9 +66,16 @@ def sign(data: bytes, signature_options: dict, signer_options: dict) -> bytes: for opt in signature_options['type_options']: if opt not in SUPPORTED_SIGNATURE_TYPE_OPTIONS[signature_options['type']]: raise ValueError(f"Unsupported type option: {opt}! Ensure you have provied a set") - if 'embedded' in signature_options['type_options']: - if 'detachedSignedData' in signature_options['type_options']: - raise ValueError("type_options 'detachedSignedData' and 'embedded' are mutually exclusive") + + mutually_exclusive_options = ('embedded', 'detachedSignedData', 'pkcs7DetachedSignedData') + option_found = None + for option in mutually_exclusive_options: + if option in signature_options['type_options']: + if option_found is None: + option_found = option + else: + raise ValueError("type_options '%s' and '%s' are mutually exclusive" % (option_found, option)) + if signature_options['encoding'] != 'DER': raise ValueError(f"Unsupported signature encoding: {signature_options['type']}!") if signature_options['hash_alg'] != 'sha256': @@ -92,6 +99,8 @@ def sign(data: bytes, signature_options: dict, signer_options: dict) -> bytes: signtool_params += ['/fd', signature_options['hash_alg']] if 'detachedSignedData' in signature_options['type_options']: signtool_params += ['/p7ce', 'DetachedSignedData'] + elif 'pkcs7DetachedSignedData' in signature_options['type_options']: + signtool_params += ['/p7ce', 'PKCS7DetachedSignedData'] elif 'embedded' in signature_options['type_options']: signtool_params += ['/p7ce', 'Embedded'] else: diff --git a/edk2toolext/tests/test_signtool_signer.py b/edk2toolext/tests/test_signtool_signer.py index d7231e8f..15df359c 100644 --- a/edk2toolext/tests/test_signtool_signer.py +++ b/edk2toolext/tests/test_signtool_signer.py @@ -11,7 +11,7 @@ from edk2toolext.capsule import signtool_signer -class Test_pyopenssl_signer(unittest.TestCase): +class Test_signtool_signer(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") def test_get_path(self): @@ -43,7 +43,7 @@ def test_sign_with_good_options(self): signtool_signer.sign(b"data", signature, signer) @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") - def test_sign_with_embed_type_and_detached_signdata(self): + def test_sign_with_mutually_exclusive_options(self): signature = { "type": "pkcs7", "type_options": ["embedded", "detachedSignedData"] @@ -51,3 +51,27 @@ def test_sign_with_embed_type_and_detached_signdata(self): signer = {} with self.assertRaises(ValueError): signtool_signer.sign(b"data", signature, signer) + + signature = { + "type": "pkcs7", + "type_options": ["pkcs7DetachedSignedData", "detachedSignedData"] + } + signer = {} + with self.assertRaises(ValueError): + signtool_signer.sign(b"data", signature, signer) + + signature = { + "type": "pkcs7", + "type_options": ["pkcs7DetachedSignedData", "embedded"] + } + signer = {} + with self.assertRaises(ValueError): + signtool_signer.sign(b"data", signature, signer) + + signature = { + "type": "pkcs7", + "type_options": ["detachedSignedData", "pkcs7DetachedSignedData", "embedded"] + } + signer = {} + with self.assertRaises(ValueError): + signtool_signer.sign(b"data", signature, signer)