Cyril N.
Cyril N.

Reputation: 39889

AIOSMTPD: Unable to set TLSContext broader than 1.2

I'm trying to set up an Aiosmtpd server to accept TLS1.1 too, and I can't make it work. Regardless of how I configure TLSContext, the server only accepts TLS1.2.

Here's a reproducible code to show the issue:

# Server:

from aiosmtpd.controller import Controller
from aiosmtpd.smtp import SMTP
from aiosmtpd.handlers import Debugging
import ssl, certifi, signal


class CustomController(Controller):
    def factory(self):
        context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH, cafile=certifi.where())
        context.set_ciphers('HIGH:MEDIUM:!LOW:!DHE')
        context.set_ecdh_curve("secp384r1")
        context.options |= ssl.OP_NO_SSLv2
        context.options |= ssl.OP_NO_SSLv3
        context.options |= ssl.PROTOCOL_TLSv1
        context.options |= ssl.PROTOCOL_TLSv1_1
        context.options |= ssl.PROTOCOL_TLSv1_2
        context.options |= ssl.PROTOCOL_TLSv1_3

        context.minimum_version = ssl.TLSVersion.TLSv1
        context.maximum_version = ssl.TLSVersion.TLSv1_3

        base_path = '/etc/letsencrypt/live/smtp.server.com'
        context.load_cert_chain(
            '{}/fullchain.pem'.format(base_path),
            '{}/privkey.pem'.format(base_path)
        )  # via Let's Encrypt

        return SMTP(
            handler=self.handler,
            ident="Welcome.",
            tls_context=context,
        )


if __name__ == '__main__':
    controller = CustomController(Debugging(), hostname="localhost", port=2525)

    # Run the event loop in a separate thread.
    controller.start()
    print("Daemong started. Waiting for SIGINT or SIGQUIT to quit.")
    sig = signal.sigwait([signal.SIGINT, signal.SIGQUIT])
    print("Quitting SMTP Daemon")
    controller.stop()

The above configured context should accept TLSv1 up to TLSv1_3.

Now, here's a client, that only have TLS1.1 enabled:

import smtplib, ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.minimum_version = ssl.TLSVersion.TLSv1_1
context.maximum_version = ssl.TLSVersion.TLSv1_1

smtp = smtplib.SMTP('127.0.0.1', port='2525')
print(smtp.ehlo('client'))

try:
    print(smtp.starttls(context=context))
    print(smtp.sock.cipher())
    print(smtp.sock.version())
    print(smtp.ehlo('client'))
    print(smtp.quit())
except OSError as e:
    print(e)
    print(smtp.quit())

The exchange fails with the following SSL error:

[SSL: NO_PROTOCOLS_AVAILABLE] no protocols available (_ssl.c:1000)
Traceback (most recent call last):
  File "/home/user/st.py", line 23, in <module>
    print(smtp.starttls(context=context))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/smtplib.py", line 779, in starttls
    self.sock = context.wrap_socket(self.sock,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/ssl.py", line 1042, in _create
    self.do_handshake()
  File "/usr/lib64/python3.12/ssl.py", line 1320, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: NO_PROTOCOLS_AVAILABLE] no protocols available (_ssl.c:1000)

=> NO_PROTOCOLS_AVAILABLE

Why is that? Am I missing something? An option to enable to allow more than TLS1.2 ?

Upvotes: 1

Views: 58

Answers (0)

Related Questions