add first WIP version of encryption

Signed-off-by: Florian Brandes <florian.brandes@posteo.de>
This commit is contained in:
2024-07-05 14:41:49 +02:00
parent 9cc0e2be50
commit aeb610dab9

View File

@@ -34,6 +34,7 @@ from cryptography.hazmat.primitives.serialization import (
) )
from cryptography.x509 import load_pem_x509_certificate from cryptography.x509 import load_pem_x509_certificate
from envelope import Envelope as EnvelopeEnvelope from envelope import Envelope as EnvelopeEnvelope
from M2Crypto import BIO, SMIME, X509
@dataclass(frozen=True) @dataclass(frozen=True)
@@ -163,6 +164,52 @@ class SMTPClient(SMTP):
new_message["To"] = message["To"] new_message["To"] = message["To"]
return new_message 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: def _sign(self, message: Message) -> bytes:
"""Sign the message """Sign the message
@@ -187,9 +234,10 @@ class SMTPClient(SMTP):
.sign(Encoding.SMIME, [pkcs7.PKCS7Options.DetachedSignature]) .sign(Encoding.SMIME, [pkcs7.PKCS7Options.DetachedSignature])
) )
# Add correct headers # Add correct headers
new = b"From: " + self._config.sender.encode() + b"\r\n" + output # 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"To: " + ", ".join(self._config.recipients).encode() + b"\r\n" + new
new = b"Subject: " + message.get("Subject", "").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 return new
async def _send_message( async def _send_message(