summaryrefslogtreecommitdiffstats
path: root/ipapython
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2014-10-30 11:52:14 -0400
committerJan Cholasta <jcholast@redhat.com>2014-11-24 13:09:44 +0000
commit5c0ad221e815e8c7b95c1d1095ebd6cf18e7e11c (patch)
tree1a87eeb179772b5be2db9b32474099ac8164bac8 /ipapython
parentaa9ecb253a60d9d15cd41c5c38695fe64058669a (diff)
downloadfreeipa-5c0ad221e815e8c7b95c1d1095ebd6cf18e7e11c.tar.gz
freeipa-5c0ad221e815e8c7b95c1d1095ebd6cf18e7e11c.tar.xz
freeipa-5c0ad221e815e8c7b95c1d1095ebd6cf18e7e11c.zip
Use NSS protocol range API to set available TLS protocols
Protocols are configured as an inclusive range from SSLv3 through TLSv1.2. The allowed values in the range are ssl3, tls1.0, tls1.1 and tls1.2. This is overridable per client by setting tls_version_min and/or tls_version_max. https://fedorahosted.org/freeipa/ticket/4653 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipapython')
-rw-r--r--ipapython/dogtag.py4
-rw-r--r--ipapython/nsslib.py17
2 files changed, 18 insertions, 3 deletions
diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
index bd92fe65c..67180d59b 100644
--- a/ipapython/dogtag.py
+++ b/ipapython/dogtag.py
@@ -236,7 +236,9 @@ def https_request(host, port, url, secdir, password, nickname, **kw):
"""
def connection_factory(host, port):
- conn = nsslib.NSSConnection(host, port, dbdir=secdir)
+ conn = nsslib.NSSConnection(host, port, dbdir=secdir,
+ tls_version_min=api.env.tls_version_min,
+ tls_version_max=api.env.tls_version_max)
conn.set_debuglevel(0)
conn.connect()
conn.sock.set_client_auth_data_callback(
diff --git a/ipapython/nsslib.py b/ipapython/nsslib.py
index 1452a2a58..def6b104e 100644
--- a/ipapython/nsslib.py
+++ b/ipapython/nsslib.py
@@ -174,7 +174,8 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback):
default_port = httplib.HTTPSConnection.default_port
def __init__(self, host, port=None, strict=None,
- dbdir=None, family=socket.AF_UNSPEC, no_init=False):
+ dbdir=None, family=socket.AF_UNSPEC, no_init=False,
+ tls_version_min='tls1.1', tls_version_max='tls1.2'):
"""
:param host: the server to connect to
:param port: the port to use (default is set in HTTPConnection)
@@ -183,6 +184,8 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback):
:param no_init: do not initialize the NSS database. This requires
that the database has already been initialized or
the request will fail.
+ :param tls_min_version: mininum version of SSL/TLS supported
+ :param tls_max_version: maximum version of SSL/TLS supported.
"""
httplib.HTTPConnection.__init__(self, host, port, strict)
NSSAddressFamilyFallback.__init__(self, family)
@@ -210,6 +213,8 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback):
ssl.set_domestic_policy()
nss.set_password_callback(self.password_callback)
+ self.tls_version_min = str(tls_version_min)
+ self.tls_version_max = str(tls_version_max)
def _create_socket(self):
# TODO: remove the try block once python-nss is guaranteed to contain
@@ -229,6 +234,11 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback):
self.sock = ssl.SSLSocket(family=self.family)
self.sock.set_ssl_option(ssl.SSL_SECURITY, True)
self.sock.set_ssl_option(ssl.SSL_HANDSHAKE_AS_CLIENT, True)
+ try:
+ self.sock.set_ssl_version_range(self.tls_version_min, self.tls_version_max)
+ except NSPRError, e:
+ root_logger.error('Failed to set TLS range to %s, %s' % (self.tls_version_min, self.tls_version_max))
+ raise
self.sock.set_ssl_option(ssl_require_safe_negotiation, False)
self.sock.set_ssl_option(ssl_enable_renegotiation, ssl_renegotiate_requires_xtn)
# Provide a callback which notifies us when the SSL handshake is complete
@@ -247,8 +257,11 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback):
"""
Verify callback. If we get here then the certificate is ok.
"""
+ channel = sock.get_ssl_channel_info()
+ suite = ssl.get_cipher_suite_info(channel.cipher_suite)
root_logger.debug("handshake complete, peer = %s", sock.get_peer_name())
- pass
+ root_logger.debug('Protocol: %s' % channel.protocol_version_str.upper())
+ root_logger.debug('Cipher: %s' % suite.cipher_suite_name)
def connect(self):
self.connect_socket(self.host, self.port)