Merge "Improve the error message for bad pkcs12 bundles" into stable/queens

This commit is contained in:
Zuul 2019-10-18 03:06:17 +00:00 committed by Gerrit Code Review
commit 7148cf63ad
5 changed files with 34 additions and 1 deletions

View File

@ -142,6 +142,8 @@ class ListenersController(base.BaseController):
try: try:
cert_parser.load_certificate_data( cert_parser.load_certificate_data(
self.cert_manager, ref, context) self.cert_manager, ref, context)
except exceptions.UnreadablePKCS12:
raise
except Exception: except Exception:
bad_refs.append(ref) bad_refs.append(ref)

View File

@ -21,12 +21,16 @@ from cryptography.hazmat.primitives import serialization
from OpenSSL import crypto from OpenSSL import crypto
from octavia.certificates.common import cert from octavia.certificates.common import cert
from octavia.common import exceptions
class PKCS12Cert(cert.Cert): class PKCS12Cert(cert.Cert):
"""Representation of a Cert for local storage.""" """Representation of a Cert for local storage."""
def __init__(self, certbag): def __init__(self, certbag):
p12 = crypto.load_pkcs12(certbag) try:
p12 = crypto.load_pkcs12(certbag)
except crypto.Error as e:
raise exceptions.UnreadablePKCS12(error=str(e))
self.certificate = p12.get_certificate() self.certificate = p12.get_certificate()
self.intermediates = p12.get_ca_certificates() self.intermediates = p12.get_ca_certificates()
self.private_key = p12.get_privatekey() self.private_key = p12.get_privatekey()

View File

@ -112,6 +112,8 @@ class BarbicanCertManager(cert_mgr.CertManager):
try: try:
cert_secret = connection.secrets.get(secret_ref=cert_ref) cert_secret = connection.secrets.get(secret_ref=cert_ref)
return pkcs12.PKCS12Cert(cert_secret.payload) return pkcs12.PKCS12Cert(cert_secret.payload)
except exceptions.UnreadablePKCS12:
raise
except Exception: except Exception:
# If our get fails, try with the legacy driver. # If our get fails, try with the legacy driver.
# TODO(rm_work): Remove this code when the deprecation cycle for # TODO(rm_work): Remove this code when the deprecation cycle for

View File

@ -128,6 +128,13 @@ class UnreadableCert(OctaviaException):
message = _("Could not read X509 from PEM") message = _("Could not read X509 from PEM")
class UnreadablePKCS12(APIException):
msg = _("The PKCS12 bundle is unreadable. Please check the PKCS12 bundle "
"validity. In addition, make sure it does not require a pass "
"phrase. Error: %(error)s")
code = 400
class MisMatchedKey(OctaviaException): class MisMatchedKey(OctaviaException):
message = _("Key and x509 certificate do not match") message = _("Key and x509 certificate do not match")

View File

@ -16,10 +16,12 @@ import uuid
from barbicanclient.v1 import secrets from barbicanclient.v1 import secrets
import mock import mock
from OpenSSL import crypto
import octavia.certificates.common.barbican as barbican_common import octavia.certificates.common.barbican as barbican_common
import octavia.certificates.common.cert as cert import octavia.certificates.common.cert as cert
import octavia.certificates.manager.barbican as barbican_cert_mgr import octavia.certificates.manager.barbican as barbican_cert_mgr
from octavia.common import exceptions
import octavia.tests.unit.base as base import octavia.tests.unit.base as base
import octavia.tests.unit.common.sample_configs.sample_certs as sample import octavia.tests.unit.common.sample_configs.sample_certs as sample
@ -133,6 +135,22 @@ class TestBarbicanManager(base.TestCase):
self.assertItemsEqual(sample.X509_IMDS_LIST, data.get_intermediates()) self.assertItemsEqual(sample.X509_IMDS_LIST, data.get_intermediates())
self.assertIsNone(data.get_private_key_passphrase()) self.assertIsNone(data.get_private_key_passphrase())
@mock.patch('OpenSSL.crypto.load_pkcs12')
def test_get_cert_bad_pkcs12(self, mock_load_pkcs12):
mock_load_pkcs12.side_effect = [crypto.Error]
# Mock out the client
self.bc.secrets.get.return_value = self.secret
# Test bad pkcs12 bundle re-raises UnreadablePKCS12
self.assertRaises(exceptions.UnreadablePKCS12,
self.cert_manager.get_cert,
context=self.context,
cert_ref=self.secret_ref,
resource_ref=self.secret_ref,
service_name='Octavia')
def test_delete_cert_legacy(self): def test_delete_cert_legacy(self):
# Attempt to deregister as a consumer # Attempt to deregister as a consumer
self.cert_manager.delete_cert( self.cert_manager.delete_cert(