diff options
| author | Alex Gaynor <alex.gaynor@gmail.com> | 2023-02-25 21:09:35 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-26 10:09:35 +0800 |
| commit | bc61b605c75e3e6d271b1b597e778fc335ba2e98 (patch) | |
| tree | f6380e418ebcd38757e20d2402befa6c90f248bc /src/cryptography/hazmat/primitives | |
| parent | 008e69d755b4a7adbbad212211a5967ccceb930c (diff) | |
| download | cryptography-bc61b605c75e3e6d271b1b597e778fc335ba2e98.tar.gz | |
fixes #8298 -- correctly generate content-type header in PKCS#7 SMIME (#8389)
Diffstat (limited to 'src/cryptography/hazmat/primitives')
| -rw-r--r-- | src/cryptography/hazmat/primitives/serialization/pkcs7.py | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py index 7b8ab300f..593c9b159 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -5,6 +5,7 @@ import email.base64mime import email.generator import email.message +import email.policy import io import typing @@ -176,7 +177,9 @@ class PKCS7SignatureBuilder: return rust_pkcs7.sign_and_serialize(self, encoding, options) -def _smime_encode(data: bytes, signature: bytes, micalg: str) -> bytes: +def _smime_encode( + data: bytes, signature: bytes, micalg: str, text_mode: bool +) -> bytes: # This function works pretty hard to replicate what OpenSSL does # precisely. For good and for ill. @@ -191,9 +194,10 @@ def _smime_encode(data: bytes, signature: bytes, micalg: str) -> bytes: m.preamble = "This is an S/MIME signed message\n" - msg_part = email.message.MIMEPart() + msg_part = OpenSSLMimePart() msg_part.set_payload(data) - msg_part.add_header("Content-Type", "text/plain") + if text_mode: + msg_part.add_header("Content-Type", "text/plain") m.attach(msg_part) sig_part = email.message.MIMEPart() @@ -212,7 +216,18 @@ def _smime_encode(data: bytes, signature: bytes, micalg: str) -> bytes: fp = io.BytesIO() g = email.generator.BytesGenerator( - fp, maxheaderlen=0, mangle_from_=False, policy=m.policy + fp, + maxheaderlen=0, + mangle_from_=False, + policy=m.policy.clone(linesep="\r\n"), ) g.flatten(m) return fp.getvalue() + + +class OpenSSLMimePart(email.message.MIMEPart): + # A MIMEPart subclass that replicates OpenSSL's behavior of not including + # a newline if there are no headers. + def _write_headers(self, generator) -> None: + if list(self.raw_items()): + generator._write_headers(self) |
