Support for SSL protocol and cipher controls

Add ability to explicitly specify SSL/TLS protocol
version and ciphers. We add 2 string options and
do not specify any default for backward compatability.
If the values are not specified explicitly we fall
back to the python defaults as we did before.

DocImpact

Closes-Bug: #1513581
Change-Id: I149cf569e1e5277f30e89203d20731d4482509d4
This commit is contained in:
Davanum Srinivas 2015-11-08 11:28:21 -05:00 committed by Davanum Srinivas (dims)
parent f4c1f1caac
commit acc9eb1e4d
3 changed files with 64 additions and 0 deletions

View File

@ -97,4 +97,14 @@ ssl_opts = [
"the server securely.",
deprecated_group='DEFAULT',
deprecated_name='ssl_key_file'),
cfg.StrOpt('version',
help='SSL version to use (valid only if SSL enabled). '
'Valid values are TLSv1 and SSLv23. SSLv2, SSLv3, '
'TLSv1_1, and TLSv1_2 may be available on some '
'distributions.'
),
cfg.StrOpt('ciphers',
help='Sets the list of available ciphers. value should be a '
'string in the OpenSSL cipher list format.'
),
]

View File

@ -22,6 +22,24 @@ from oslo_service import _options
config_section = 'ssl'
_SSL_PROTOCOLS = {
"tlsv1": ssl.PROTOCOL_TLSv1,
"sslv23": ssl.PROTOCOL_SSLv23
}
_OPTIONAL_PROTOCOLS = {
'sslv2': 'PROTOCOL_SSLv2',
'sslv3': 'PROTOCOL_SSLv3',
'tlsv1_1': 'PROTOCOL_TLSv1_1',
'tlsv1_2': 'PROTOCOL_TLSv1_2',
}
for protocol in _OPTIONAL_PROTOCOLS:
try:
_SSL_PROTOCOLS[protocol] = getattr(ssl,
_OPTIONAL_PROTOCOLS[protocol])
except AttributeError:
pass
def list_opts():
"""Entry point for oslo-config-generator."""
@ -70,4 +88,15 @@ def wrap(conf, sock):
ssl_kwargs['ca_certs'] = conf.ssl.ca_file
ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED
if conf.ssl.version:
key = conf.ssl.version.lower()
try:
ssl_kwargs['ssl_version'] = _SSL_PROTOCOLS[key]
except KeyError:
raise RuntimeError(
_("Invalid SSL version : %s") % conf.ssl.version)
if conf.ssl.ciphers:
ssl_kwargs['ciphers'] = conf.ssl.ciphers
return ssl.wrap_socket(sock, **ssl_kwargs)

View File

@ -107,3 +107,28 @@ class SslutilsTestCase(base.ServiceBaseTestCase):
'cert_reqs': ssl.CERT_REQUIRED
}
self._test_wrap(**ssl_kwargs)
def test_wrap_ciphers(self):
self.conf.set_default("ca_file", self.ca_file_name,
group=sslutils.config_section)
ciphers = (
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+'
'AES:ECDH+HIGH:DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:'
'RSA+HIGH:RSA+3DES:!aNULL:!eNULL:!MD5:!DSS:!RC4'
)
self.conf.set_default("ciphers", ciphers,
group=sslutils.config_section)
ssl_kwargs = {'ca_certs': self.conf.ssl.ca_file,
'cert_reqs': ssl.CERT_REQUIRED,
'ciphers': ciphers}
self._test_wrap(**ssl_kwargs)
def test_wrap_ssl_version(self):
self.conf.set_default("ca_file", self.ca_file_name,
group=sslutils.config_section)
self.conf.set_default("version", "tlsv1",
group=sslutils.config_section)
ssl_kwargs = {'ca_certs': self.conf.ssl.ca_file,
'cert_reqs': ssl.CERT_REQUIRED,
'ssl_version': ssl.PROTOCOL_TLSv1}
self._test_wrap(**ssl_kwargs)