From aeb610dab952d7499468e49cee9faa74ae0561e0 Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Fri, 5 Jul 2024 14:41:49 +0200 Subject: [PATCH] add first WIP version of encryption Signed-off-by: Florian Brandes --- smtprd.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/smtprd.py b/smtprd.py index cf7ef9e..d8bc4a0 100644 --- a/smtprd.py +++ b/smtprd.py @@ -34,6 +34,7 @@ from cryptography.hazmat.primitives.serialization import ( ) from cryptography.x509 import load_pem_x509_certificate from envelope import Envelope as EnvelopeEnvelope +from M2Crypto import BIO, SMIME, X509 @dataclass(frozen=True) @@ -163,6 +164,52 @@ class SMTPClient(SMTP): new_message["To"] = message["To"] return new_message + def _encrypt(self, message: bytes, subject: str) -> bytes: + """Encrypt the message + + Args: + message (bytes): message in bytes format (can/should be signed) + + Returns: + bytes: Encrypted message + """ + # Make a MemoryBuffer of the message. + buf = BIO.MemoryBuffer(message) + + # Seed the PRNG. + # Rand.load_file('randpool.dat', -1) + + # Instantiate an SMIME object. + s = SMIME.SMIME() + + # Load target cert to encrypt to. + x509 = X509.load_cert(self._config.smime_to_cert) + sk = X509.X509_Stack() + sk.push(x509) + s.set_x509_stack(sk) + + # Set cipher: 3-key triple-DES in CBC mode. + # TODO: Evaluate later + s.set_cipher(SMIME.Cipher("des_ede3_cbc")) + + # Encrypt the buffer. + p7 = s.encrypt(buf) + + # Output p7 in mail-friendly format. + out = BIO.MemoryBuffer() + + out.write("From: " + self._config.sender + "\r\n") + out.write("To: " + ", ".join(self._config.recipients) + "\r\n") + out.write("Subject: " + subject + "\r\n") + s.write(out, p7) + + # print(out.read().decode()) + + # Save the PRNG's state. + # Rand.save_file('randpool.dat') + + return out.read() + def _sign(self, message: Message) -> bytes: """Sign the message @@ -187,9 +234,10 @@ class SMTPClient(SMTP): .sign(Encoding.SMIME, [pkcs7.PKCS7Options.DetachedSignature]) ) # Add correct headers - new = b"From: " + self._config.sender.encode() + b"\r\n" + output - new = b"To: " + ", ".join(self._config.recipients).encode() + b"\r\n" + new - new = b"Subject: " + message.get("Subject", "").encode() + b"\r\n" + new + # new = b"From: " + self._config.sender.encode() + b"\r\n" + output + # new = b"To: " + ", ".join(self._config.recipients).encode() + b"\r\n" + new + # new = b"Subject: " + message.get("Subject", "").encode() + b"\r\n" + new + new = self._encrypt(output, message.get("Subject", "")) return new async def _send_message(