Dima Tisnek
Dima Tisnek

Reputation: 11779

How to set up same SSLContext in Python 3.8 through 3.13?

My code so far:

    def _ssl_context(self, ca: str | None) -> ssl.SSLContext:
        # NOTE: ssl.create_default_context() doesn't allow setting the context.protocol in a way
        # that's the same across Python 3.8 and 3.10 onwards. Whip the context up by hand.
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
        context.minimum_version = ssl.TLSVersion.TLSv1_3
        context.set_alpn_protocols(['http/1.1'])
        context.verify_flags |= ssl.VERIFY_X509_STRICT
        if (partial_chain := getattr(ssl, "VERIFY_X509_PARTIAL_CHAIN", None)):
            # Available starting from Python 3.10. The partial chain flag allows trusting the
            # intermediate CAs in the CA list without the matching root CA
            context.verify_flags |= partial_chain

        if ca is not None:
            context.load_verify_locations(cadata=ca)
        else:
            context.load_default_certs()

        return context

I'm in charge of a library (not an app) which needs to send something out over HTTPS and I'm using pure Python urllib to do so.

I want one codebase to support Python 3.8 through 3.13.

I want "Modern" settings, like the Mozilla SSL configuration generator https://ssl-config.mozilla.org/ except for the client side of the HTTPS connection.

Am I missing something?

I this the right way to go about it?

Upvotes: -1

Views: 37

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123531

Unless your application has specific requirements it is best just to use the defaults and don't set any options.

Special settings are usually only needed if one needs to work around some old or otherwise broken server setups, i.e. use of obsolete protocols, support only for unusual ciphers or broken certificate setup.

Upvotes: 1

Related Questions