From 8f4a6b4dc26f11f1ea70455670ed960b45695983 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Tue, 11 Jan 2022 09:41:26 -0500 Subject: [PATCH 1/8] Update api.py enabled TLSv1_2 and TLSv1_3 enabled perfect forward secrecy ciphers --- mygeotab/api.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mygeotab/api.py b/mygeotab/api.py index bece3ab..626ca3c 100644 --- a/mygeotab/api.py +++ b/mygeotab/api.py @@ -307,13 +307,24 @@ def get_param(self): """ return dict(userName=self.username, sessionId=self.session_id, database=self.database) +#https://ciphersuite.info/ +CIPHERS = ( + 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256' + + ':ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256' +) class GeotabHTTPAdapter(HTTPAdapter): """HTTP adapter to force use of TLS 1.2 for HTTPS connections.""" + + def __init__(self, ssl_options=0, **kwargs): + self.ssl_options = ssl_options + super(TlsAdapter, self).__init__(**kwargs) def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): + ctx = ssl_.create_urllib3_context(ciphers=CIPHERS, cert_reqs=ssl.CERT_REQUIRED, options=self.ssl_options) + self.poolmanager = urllib3.poolmanager.PoolManager( - num_pools=connections, maxsize=maxsize, block=block, ssl_version=ssl.PROTOCOL_TLSv1_2, **pool_kwargs + num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx, **pool_kwargs ) @@ -343,7 +354,8 @@ def _query(server, method, parameters, timeout=DEFAULT_TIMEOUT, verify_ssl=True, params = dict(id=-1, method=method, params=parameters or {}) headers = get_headers() with requests.Session() as session: - session.mount("https://", GeotabHTTPAdapter()) + adapter = GeotabHTTPAdapter(ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 ) + session.mount("https://", adapter) if cert: session.cert = cert try: From de81973c604273ab5a881d9e7b25ae2be5fe1aa0 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:34:57 -0500 Subject: [PATCH 2/8] Update __init__.py bumped version to 0.8.8 --- mygeotab/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygeotab/__init__.py b/mygeotab/__init__.py index 947c4ce..ce6d954 100644 --- a/mygeotab/__init__.py +++ b/mygeotab/__init__.py @@ -2,7 +2,7 @@ __title__ = "mygeotab-python" __author__ = "Aaron Toth" -__version__ = "0.8.7" +__version__ = "0.8.8" import sys From 94ee6ec873cf4b476839c3c1ed6dc7a1363c3079 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:37:42 -0500 Subject: [PATCH 3/8] Update api.py Changes - Force TLS1.2+ - Force perfect forward secrecy --- mygeotab/api.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/mygeotab/api.py b/mygeotab/api.py index 626ca3c..ac0ddee 100644 --- a/mygeotab/api.py +++ b/mygeotab/api.py @@ -307,24 +307,17 @@ def get_param(self): """ return dict(userName=self.username, sessionId=self.session_id, database=self.database) -#https://ciphersuite.info/ -CIPHERS = ( - 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256' + - ':ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256' -) - class GeotabHTTPAdapter(HTTPAdapter): - """HTTP adapter to force use of TLS 1.2 for HTTPS connections.""" - - def __init__(self, ssl_options=0, **kwargs): - self.ssl_options = ssl_options - super(TlsAdapter, self).__init__(**kwargs) + """HTTP adapter to force use of TLS 1.2+ for HTTPS connections.""" def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): - ctx = ssl_.create_urllib3_context(ciphers=CIPHERS, cert_reqs=ssl.CERT_REQUIRED, options=self.ssl_options) - + ctx = create_urllib3_context() + ctx.load_default_certs() + ctx.set_ciphers('ECDHE+AESGCM:!ECDSA') + ctx.set_ecdh_curve("secp521r1:secp384r1") + self.poolmanager = urllib3.poolmanager.PoolManager( - num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx, **pool_kwargs + num_pools=connections, maxsize=maxsize, block=block, ssl_minimum_version=ssl.TLSVersion.TLSv1_2, ssl_context=ctx, **pool_kwargs ) From b6b2290f3be80cc3613d96be98cedfe4a74067a2 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:50:56 -0500 Subject: [PATCH 4/8] Update api.py removed change to _query method to simplify code review --- mygeotab/api.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mygeotab/api.py b/mygeotab/api.py index ac0ddee..c0595e0 100644 --- a/mygeotab/api.py +++ b/mygeotab/api.py @@ -347,8 +347,7 @@ def _query(server, method, parameters, timeout=DEFAULT_TIMEOUT, verify_ssl=True, params = dict(id=-1, method=method, params=parameters or {}) headers = get_headers() with requests.Session() as session: - adapter = GeotabHTTPAdapter(ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 ) - session.mount("https://", adapter) + session.mount("https://", GeotabHTTPAdapter()) if cert: session.cert = cert try: From 93f1c751645bb5c4b9c1968d23ad7433d6825670 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Fri, 14 Jan 2022 11:55:57 -0500 Subject: [PATCH 5/8] Update api.py To work around missing SSLContext.minimum_version logic. --- mygeotab/api.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mygeotab/api.py b/mygeotab/api.py index c0595e0..8dc8032 100644 --- a/mygeotab/api.py +++ b/mygeotab/api.py @@ -18,6 +18,7 @@ from requests.adapters import HTTPAdapter from requests.exceptions import Timeout from requests.packages import urllib3 +from requests.packages.urllib3.util.ssl_ import create_urllib3_context from six.moves.urllib.parse import urlparse from . import __title__, __version__ @@ -307,6 +308,7 @@ def get_param(self): """ return dict(userName=self.username, sessionId=self.session_id, database=self.database) + class GeotabHTTPAdapter(HTTPAdapter): """HTTP adapter to force use of TLS 1.2+ for HTTPS connections.""" @@ -314,10 +316,17 @@ def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): ctx = create_urllib3_context() ctx.load_default_certs() ctx.set_ciphers('ECDHE+AESGCM:!ECDSA') - ctx.set_ecdh_curve("secp521r1:secp384r1") + + ctx.options |= ssl.OP_NO_SSLv2 + ctx.options |= ssl.OP_NO_SSLv3 + ctx.options |= ssl.OP_NO_TLSv1 + ctx.options |= ssl.OP_NO_TLSv1_1 + ctx.options |= ssl.PROTOCOL_TLS + + ctx.set_ecdh_curve('secp521r1') self.poolmanager = urllib3.poolmanager.PoolManager( - num_pools=connections, maxsize=maxsize, block=block, ssl_minimum_version=ssl.TLSVersion.TLSv1_2, ssl_context=ctx, **pool_kwargs + num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx, **pool_kwargs ) From e283d60e3b9b954184d63019daaaa2edc1da4849 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Fri, 14 Jan 2022 17:00:27 -0500 Subject: [PATCH 6/8] Update __init__.py Reduced the number of touched files. --- mygeotab/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygeotab/__init__.py b/mygeotab/__init__.py index ce6d954..947c4ce 100644 --- a/mygeotab/__init__.py +++ b/mygeotab/__init__.py @@ -2,7 +2,7 @@ __title__ = "mygeotab-python" __author__ = "Aaron Toth" -__version__ = "0.8.8" +__version__ = "0.8.7" import sys From f7b83f1833d45457f60ce9d4ae7403bd7855b9a7 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Fri, 14 Jan 2022 17:06:55 -0500 Subject: [PATCH 7/8] Update api.py Downgraded from P-521 to P-384. secp521r1 : NIST/SECG curve over a 521 bit prime field secp384r1 : NIST/SECG curve over a 384 bit prime field --- mygeotab/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygeotab/api.py b/mygeotab/api.py index 8dc8032..d9a5e5c 100644 --- a/mygeotab/api.py +++ b/mygeotab/api.py @@ -323,7 +323,7 @@ def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): ctx.options |= ssl.OP_NO_TLSv1_1 ctx.options |= ssl.PROTOCOL_TLS - ctx.set_ecdh_curve('secp521r1') + ctx.set_ecdh_curve('secp384r1') self.poolmanager = urllib3.poolmanager.PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx, **pool_kwargs From ddda1656120cd1aed59563c1ee6d71ec3580b535 Mon Sep 17 00:00:00 2001 From: B3K7 <79159661+B3K7@users.noreply.github.com> Date: Sun, 16 Jan 2022 13:06:46 -0500 Subject: [PATCH 8/8] Update api.py Why what was enabled/disabled. --- mygeotab/api.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/mygeotab/api.py b/mygeotab/api.py index d9a5e5c..d16b88d 100644 --- a/mygeotab/api.py +++ b/mygeotab/api.py @@ -315,14 +315,41 @@ class GeotabHTTPAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): ctx = create_urllib3_context() ctx.load_default_certs() - ctx.set_ciphers('ECDHE+AESGCM:!ECDSA') + # disabled SSL2.0 as per: + # Sean Tuner, President, IECA + # Tim Polk, , Computer Scientist, Computer Security Division, NIST + # https://datatracker.ietf.org/doc/rfc6176/ + # rfc6176 ctx.options |= ssl.OP_NO_SSLv2 + + # disabled SSL3.0 as per: + # Richard Barnes, (former) Security Engineering, Mozilla + # Martin Thomson, Distinguished Engineer, Mozilla + # Alfredo Pironti, Cyber Security Specialist, Secure Distributed Computing, INRIA + # Adam Langley, Senior Staff Software Engineer, Google + # rfc7568 + # https://datatracker.ietf.org/doc/html/rfc7568 ctx.options |= ssl.OP_NO_SSLv3 + + # disabled TLSv1.0 and TLSv1.1 as per: + # Kathleen Moriarty, CTO, Center for Internet Security + # Stephen Farrell, Research Fellow, Computer Science, Trinity College Dublin + # RFC 8996 + # https://datatracker.ietf.org/doc/rfc8996/ ctx.options |= ssl.OP_NO_TLSv1 ctx.options |= ssl.OP_NO_TLSv1_1 + + #enabled TLS1.2 + TLS1.3 as per: + # tbd ctx.options |= ssl.PROTOCOL_TLS + #disabled ECDSA as per + # tbd + #enabled ECDHE+AESGCM as per + # tbd + ctx.set_ciphers('ECDHE+AESGCM:!ECDSA') + ctx.set_ecdh_curve('secp384r1') self.poolmanager = urllib3.poolmanager.PoolManager(