0

I'm trying to programatically send an email with an S/MIME signature using a self-signed certificate, but Thunderbird keeps showing an error on the signature.

Digital signature is not valid

This message includes a digital signature, but the signature is invalid.

The certificate used to sign the message was issued by a certificate authority that you do not trust for issuing this kind of certificate.

I generated the certificate using the following command:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -addext "subjectAltName = email:${sender_email}" -keyout ${sender_private_key}.key -out ${sender_public_key}.crt -extensions v3_ca -addext  "keyUsage = digitalSignature, keyCertSign" -addext "extendedKeyUsage = emailProtection"

I then added it to Thunderbird by importing in the certificate manager and checking both boxes "This certificate can identify websites" and "This certificate can identify mail users".

Any idea what could be the issue? Is it a Thunderbird bug or am I generating the certificate improperly? I tried using Apple mail but got a similar issue so I suspect the later.

Using the command openssl smime -verify -CAfile {}.crt I get a "Verification successful" message at the end so it seems that the signature itself is correct.

Here's the summary of the output from the command openssl x509 -purpose -text -in {}.crt:

Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : No
SSL server CA : No
Netscape SSL server : No
Netscape SSL server CA : No
S/MIME signing : Yes
S/MIME signing CA : Yes
S/MIME encryption : No
S/MIME encryption CA : Yes
CRL signing : No
CRL signing CA : Yes
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : Yes
Time Stamp signing : No
Time Stamp signing CA : Yes
Code signing : No
Code signing CA : Yes
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: ...
        Validity
            Not Before: Sep 19 09:18:52 2024 GMT
            Not After : Sep 17 09:18:52 2034 GMT
        Subject: ...
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    ...
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                ...
            X509v3 Authority Key Identifier: 
                ...
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Alternative Name: 
                email:<email>
            X509v3 Key Usage: 
                Digital Signature, Certificate Sign
            X509v3 Extended Key Usage: 
                E-mail Protection
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        ...
...

Here's how I'm sending the email:

import oscrypto

oscrypto.use_openssl('/opt/homebrew/lib/libcrypto.dylib', '/opt/homebrew/lib/libssl.dylib')

from email.parser import Parser

import yagmail

class SMIME(yagmail.SMTP):

def prepare_send(
    self,
    to=None,
    subject=None,
    contents=None,
    attachments=None,
    cc=None,
    bcc=None,
    headers=None,
    newline_to_break=True
):
    recipients, msg_string = super().prepare_send(
        to, subject, contents, attachments, cc, bcc, headers, newline_to_break
    )
    parser = Parser()
    message = parser.parsestr(msg_string)

    with open('{sender_private_key}.key') as f:
        sender_private_key = f.read()
    with open('{sender_public_key}.crt') as f:
        sender_public_key = f.read()
    with open('{receiver_public_key}.crt') as f:
        receiver_public_key = f.read()

    import smail
    encrypted_message = smail.sign_and_encrypt_message(
        message,
        sender_private_key.encode(),
        sender_public_key.encode(),
        [receiver_public_key.encode()]
    )

    return recipients, encrypted_message.as_string()


Use an app password for 2FA-enabled Gmail accounts: https://myaccount.google.com/apppasswords

smtp_connection = SMIME(user='{gmail_sender_email}', password='{gmail_sender_password}', host='smtp.gmail.com') smtp_connection.send( '{receiver_email}', 'Test', 'Lorem ipsum', ) ```

0 Answers0