From a77667339d735ec0757d1e46d80f0010b1bb3d4f Mon Sep 17 00:00:00 2001 From: Nir Magnezi Date: Sun, 14 Jul 2019 17:50:43 +0300 Subject: [PATCH] Validate server_certs_key_passphrase is 32 chars Fernet checks[1] for 32 characters long key, so Octavia should validate the value provided for server_certs_key_passphrase, to reject an invalid passphrase as early as possible. This[2] Red Hat Bug showed a case in which an invalid passphrase got configured, and as a result, Octavia was unable to create any load balancers. Related-bug: #1833942 [1] https://github.com/pyca/cryptography/blob/784676de3381f039f95f998505d45fb9d56bd300/src/cryptography/fernet.py#L36 [2] https://bugzilla.redhat.com/show_bug.cgi?id=1723051 Change-Id: I334364d4654491bc0d289472ca9ab5fe462d5139 --- octavia/certificates/common/local.py | 6 +++-- octavia/tests/unit/common/test_config.py | 23 +++++++++++++++++++ ...certs_key_passphrase-6a9dfc190c9deba8.yaml | 6 +++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/input-validation-server_certs_key_passphrase-6a9dfc190c9deba8.yaml diff --git a/octavia/certificates/common/local.py b/octavia/certificates/common/local.py index 03ffab7966..03552b9955 100644 --- a/octavia/certificates/common/local.py +++ b/octavia/certificates/common/local.py @@ -53,8 +53,10 @@ certgen_opts = [ cfg.StrOpt('server_certs_key_passphrase', default=TLS_PASS_AMPS_DEFAULT, help='Passphrase for encrypting Amphora Certificates and ' - 'Private Keys. Defaults to env[TLS_PASS_AMPS_DEFAULT] or ' - 'insecure-key-do-not-use-this-key', + 'Private Keys. Must be 32, base64(url) compatible, ' + 'characters long. Defaults to env[TLS_PASS_AMPS_DEFAULT] ' + 'or insecure-key-do-not-use-this-key', + regex=r'^[A-Za-z0-9\-_=]{32}$', required=True), cfg.StrOpt('signing_digest', default=TLS_DIGEST_DEFAULT, diff --git a/octavia/tests/unit/common/test_config.py b/octavia/tests/unit/common/test_config.py index 275599697f..2da1bb38b6 100644 --- a/octavia/tests/unit/common/test_config.py +++ b/octavia/tests/unit/common/test_config.py @@ -13,6 +13,7 @@ # under the License. from oslo_config import cfg +from oslo_config import fixture as oslo_fixture import octavia.common.config as config import octavia.tests.unit.base as base @@ -26,3 +27,25 @@ class TestConfig(base.TestCase): # Resetting because this will cause inconsistent errors when run with # other tests self.addCleanup(cfg.CONF.reset) + + def test_validate_server_certs_key_passphrase(self): + conf = self.useFixture(oslo_fixture.Config(config.cfg.CONF)) + conf.config( + group="certificates", + server_certs_key_passphrase="insecure-key-do-not-use-this-key" + ) + + # Test too short + self.assertRaises(ValueError, conf.config, + group="certificates", + server_certs_key_passphrase="short_passphrase") + + # Test too long + self.assertRaises( + ValueError, conf.config, group="certificates", + server_certs_key_passphrase="long-insecure-key-do-not-use-this") + + # Test invalid characters + self.assertRaises( + ValueError, conf.config, group="certificates", + server_certs_key_passphrase="insecure-key-do-not-u$e-this-key") diff --git a/releasenotes/notes/input-validation-server_certs_key_passphrase-6a9dfc190c9deba8.yaml b/releasenotes/notes/input-validation-server_certs_key_passphrase-6a9dfc190c9deba8.yaml new file mode 100644 index 0000000000..6a4858e130 --- /dev/null +++ b/releasenotes/notes/input-validation-server_certs_key_passphrase-6a9dfc190c9deba8.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - The passphrase for config option 'server_certs_key_passphrase' is used as + a Fernet key in Octavia and thus must be 32, base64(url) compatible, + characters long. Octavia will now validate the passphrase length and + format.