Reputation: 11779
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
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