diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index cc6d2bae5f75..a75c675513d3 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -699,6 +699,13 @@ contain certificates, CRLs, and much more. PKCS7 files commonly have a ``p7b``, pass ``NoAttributes`` you can't pass ``NoCapabilities`` since ``NoAttributes`` removes ``MIMECapabilities`` and more. + .. attribute:: NoCerts + + Don't include the signer's certificate in the PKCS7 structure. This can + reduce the size of the signature but requires that the recipient can + obtain the signer's certificate by other means (for example from a + previously signed message). + Serialization Formats ~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 81e4289e8b37..3cccb4079256 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -2719,6 +2719,10 @@ def pkcs7_sign(self, builder, encoding, options): signer_flags |= self._lib.PKCS7_NOSMIMECAP elif pkcs7.PKCS7Options.NoAttributes in options: signer_flags |= self._lib.PKCS7_NOATTR + + if pkcs7.PKCS7Options.NoCerts in options: + signer_flags |= self._lib.PKCS7_NOCERTS + for certificate, private_key, hash_algorithm in builder._signers: md = self._evp_md_non_null_from_algorithm(hash_algorithm) p7signerinfo = self._lib.PKCS7_sign_add_signer( diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py index b33cb7094c63..8f74423f384f 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -120,3 +120,4 @@ class PKCS7Options(Enum): DetachedSignature = "Don't embed data in the PKCS7 structure" NoCapabilities = "Don't embed SMIME capabilities" NoAttributes = "Don't embed authenticatedAttributes" + NoCerts = "Don't embed signer certificate" diff --git a/tests/hazmat/primitives/test_pkcs7.py b/tests/hazmat/primitives/test_pkcs7.py index f60467c2915d..79746cf3386e 100644 --- a/tests/hazmat/primitives/test_pkcs7.py +++ b/tests/hazmat/primitives/test_pkcs7.py @@ -535,6 +535,23 @@ def test_sign_no_attributes(self, backend): backend, ) + def test_sign_no_certs(self, backend): + data = b"hello world" + cert, key = _load_cert_key() + builder = ( + pkcs7.PKCS7SignatureBuilder() + .set_data(data) + .add_signer(cert, key, hashes.SHA256()) + ) + + options = [] + sig = builder.sign(serialization.Encoding.DER, options) + assert sig.count(cert.public_bytes(serialization.Encoding.DER)) == 1 + + options = [pkcs7.PKCS7Options.NoCerts] + sig_no = builder.sign(serialization.Encoding.DER, options) + assert sig_no.count(cert.public_bytes(serialization.Encoding.DER)) == 0 + def test_multiple_signers(self, backend): data = b"hello world" cert, key = _load_cert_key()