Prefer certifi provided certificates (#108)
Sets the SSL context to use the certifi provided root certificate bundle by default, unless the certifi module is older than a year. If the system-provided root certificate bundle is empty, certifi certs are always loaded.
This commit is contained in:
parent
32c4b2ca40
commit
afac304821
1 changed files with 27 additions and 14 deletions
|
@ -21,6 +21,7 @@ import ssl
|
|||
import socket
|
||||
import select
|
||||
import logging
|
||||
import datetime
|
||||
import traceback
|
||||
|
||||
from oyoyo.parse import parse_raw_irc_command
|
||||
|
@ -207,23 +208,35 @@ class IRCClient:
|
|||
|
||||
def get_ssl_context(self):
|
||||
"""Returns an SSL context for connecting over SSL/TLS.
|
||||
Loads the certifi certs instead of the system-provided certificates if
|
||||
the system certificate store is empty."""
|
||||
context = ssl.create_default_context()
|
||||
# Check if store is empty
|
||||
empty_cert_store = list(context.cert_store_stats().values()).count(0) == 3
|
||||
if empty_cert_store and "certifi" in sys.modules:
|
||||
# Can't validate certificates if store is empty,
|
||||
# load root certificates from certifi instead.
|
||||
context = ssl.create_default_context(cafile=certifi.where())
|
||||
Loads the certifi root certificate bundle if the certifi module is less
|
||||
than a year old or if the system certificate store is empty.
|
||||
|
||||
The cert store on Windows also seems to have issues, so it's better
|
||||
to use the certifi provided bundle assuming it's a recent version.
|
||||
|
||||
On MacOS the system cert store is usually empty, as Python does not use
|
||||
the system provided ones, instead relying on a bundle installed with the
|
||||
python installer."""
|
||||
default_context = ssl.create_default_context()
|
||||
if "certifi" not in sys.modules:
|
||||
return default_context
|
||||
|
||||
# Get age of certifi module
|
||||
certifi_date = datetime.datetime.strptime(certifi.__version__, "%Y.%m.%d")
|
||||
current_date = datetime.datetime.now()
|
||||
certifi_age = current_date - certifi_date
|
||||
|
||||
empty_cert_store = (
|
||||
list(default_context.cert_store_stats().values()).count(0) == 3
|
||||
)
|
||||
# 31557600 seconds is approximately 1 year
|
||||
if empty_cert_store or certifi_age.total_seconds() <= 31557600:
|
||||
PchumLog.info(
|
||||
"Using SSL/TLS context with certifi-provided root certificates."
|
||||
)
|
||||
else:
|
||||
PchumLog.info(
|
||||
"Using SSL/TLS context with system-provided root certificates."
|
||||
)
|
||||
return context
|
||||
return ssl.create_default_context(cafile=certifi.where())
|
||||
PchumLog.info("Using SSL/TLS context with system-provided root certificates.")
|
||||
return default_context
|
||||
|
||||
def connect(self, verify_hostname=True):
|
||||
"""initiates the connection to the server set in self.host:self.port
|
||||
|
|
Loading…
Reference in a new issue