Fix snakeoil_ca plugin

This fixes creation of certificates using the snakeoil_ca plugin, like
passing the configuration properly and encoding resulting data, and adds
support for stored-key requests.

Closes-Bug: #1451456
Change-Id: Ida24a192595429829e870838a487a9c100691b4c
This commit is contained in:
Thomas Herve
2015-05-01 14:25:47 +02:00
parent 01417a89ca
commit 541027b1c8
6 changed files with 86 additions and 19 deletions

View File

@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import base64
import os
import uuid
@@ -177,7 +178,8 @@ class SnakeoilCACertificatePlugin(cert_manager.CertificatePluginBase):
"""
def __init__(self, conf=CONF):
self.ca = SnakeoilCA(conf.ca_cert_path, conf.ca_cert_key_path)
self.ca = SnakeoilCA(conf.snakeoil_ca_plugin.ca_cert_path,
conf.snakeoil_ca_plugin.ca_cert_key_path)
self.cert_manager = CertManager(self.ca)
def get_default_ca_name(self):
@@ -189,14 +191,21 @@ class SnakeoilCACertificatePlugin(cert_manager.CertificatePluginBase):
def get_default_intermediates(self):
return None
def supported_request_types(self):
return [cert_manager.CertificateRequestType.CUSTOM_REQUEST,
cert_manager.CertificateRequestType.STORED_KEY_REQUEST]
def issue_certificate_request(self, order_id, order_meta, plugin_meta,
barbican_meta_dto):
try:
encoded_csr = order_meta['request_data']
except KeyError:
return cert_manager.ResultDTO(
cert_manager.CertificateStatus.CLIENT_DATA_ISSUE_SEEN,
status_message="No request_data specified")
if barbican_meta_dto.generated_csr is not None:
encoded_csr = barbican_meta_dto.generated_csr
else:
try:
encoded_csr = order_meta['request_data']
except KeyError:
return cert_manager.ResultDTO(
cert_manager.CertificateStatus.CLIENT_DATA_ISSUE_SEEN,
status_message="No request_data specified")
csr = crypto.load_certificate_request(crypto.FILETYPE_PEM, encoded_csr)
cert = self.cert_manager.make_certificate(csr)
cert_enc = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
@@ -204,8 +213,8 @@ class SnakeoilCACertificatePlugin(cert_manager.CertificatePluginBase):
return cert_manager.ResultDTO(
cert_manager.CertificateStatus.CERTIFICATE_GENERATED,
certificate=cert_enc,
intermediates=ca_enc)
certificate=base64.b64encode(cert_enc),
intermediates=base64.b64encode(ca_enc))
def modify_certificate_request(self, order_id, order_meta, plugin_meta,
barbican_meta_dto):
@@ -220,4 +229,7 @@ class SnakeoilCACertificatePlugin(cert_manager.CertificatePluginBase):
raise NotImplementedError
def supports(self, certificate_spec):
raise NotImplementedError
request_type = certificate_spec.get(
cert_manager.REQUEST_TYPE,
cert_manager.CertificateRequestType.CUSTOM_REQUEST)
return request_type in self.supported_request_types()

View File

@@ -133,8 +133,9 @@ class SnakeoilCAPluginTestCase(BaseTestCase):
self.ca_key_path = os.path.join(self.tmp_dir, 'ca.pem')
self.db_dir = self.tmp_dir
self.plugin = snakeoil_ca.SnakeoilCACertificatePlugin(
self.conf.snakeoil_ca_plugin)
self.conf)
self.order_id = mock.MagicMock()
self.barbican_meta_dto = cm.BarbicanMetaDTO()
def test_issue_certificate_request(self):
req = certificate_utils.get_valid_csr_object()
@@ -142,8 +143,10 @@ class SnakeoilCAPluginTestCase(BaseTestCase):
req_enc = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
order_meta = {'request_data': req_enc}
resp = self.plugin.issue_certificate_request(self.order_id,
order_meta, {}, {})
crypto.load_certificate(crypto.FILETYPE_PEM, resp.certificate)
order_meta, {},
self.barbican_meta_dto)
crypto.load_certificate(
crypto.FILETYPE_PEM, resp.certificate.decode('base64'))
def test_issue_certificate_request_set_subject(self):
req = certificate_utils.get_valid_csr_object()
@@ -159,8 +162,10 @@ class SnakeoilCAPluginTestCase(BaseTestCase):
req_enc = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
order_meta = {'request_data': req_enc}
resp = self.plugin.issue_certificate_request(self.order_id,
order_meta, {}, {})
cert = crypto.load_certificate(crypto.FILETYPE_PEM, resp.certificate)
order_meta, {},
self.barbican_meta_dto)
cert = crypto.load_certificate(
crypto.FILETYPE_PEM, resp.certificate.decode('base64'))
cert_subj = cert.get_subject()
self.assertEqual(cert_subj.C, 'US')
self.assertEqual(cert_subj.ST, 'OR')
@@ -169,8 +174,19 @@ class SnakeoilCAPluginTestCase(BaseTestCase):
self.assertEqual(cert_subj.OU, 'Testers OU')
self.assertEqual(cert_subj.CN, 'Testing')
def test_issue_certificate_request_stored_key(self):
req = certificate_utils.get_valid_csr_object()
req_enc = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
self.barbican_meta_dto.generated_csr = req_enc
resp = self.plugin.issue_certificate_request(
self.order_id, {}, {}, self.barbican_meta_dto)
crypto.load_certificate(
crypto.FILETYPE_PEM, resp.certificate.decode('base64'))
def test_no_request_data(self):
res = self.plugin.issue_certificate_request(self.order_id, {}, {}, {})
res = self.plugin.issue_certificate_request(
self.order_id, {}, {}, self.barbican_meta_dto)
self.assertIs(cm.CertificateStatus.CLIENT_DATA_ISSUE_SEEN,
res.status)
self.assertEqual("No request_data specified", res.status_message)
@@ -196,5 +212,20 @@ class SnakeoilCAPluginTestCase(BaseTestCase):
self.assertRaises(NotImplementedError,
self.plugin.check_certificate_status,
'', {}, {}, {})
self.assertRaises(NotImplementedError,
self.plugin.supports, '')
def test_support_request_types(self):
manager = cm.CertificatePluginManager()
manager.extensions = [mock.MagicMock(obj=self.plugin)]
cert_spec = {
cm.REQUEST_TYPE: cm.CertificateRequestType.CUSTOM_REQUEST}
self.assertEqual(self.plugin, manager.get_plugin(cert_spec))
self.assertTrue(self.plugin.supports(cert_spec))
cert_spec = {
cm.REQUEST_TYPE: cm.CertificateRequestType.STORED_KEY_REQUEST}
self.assertEqual(self.plugin, manager.get_plugin(cert_spec))
self.assertTrue(self.plugin.supports(cert_spec))
cert_spec = {
cm.REQUEST_TYPE: cm.CertificateRequestType.FULL_CMC_REQUEST}
self.assertRaises(cm.CertificatePluginNotFound,
manager.get_plugin, cert_spec)
self.assertFalse(self.plugin.supports(cert_spec))

View File

@@ -0,0 +1,19 @@
Setting up Certificate Plugins
==============================
Using the SnakeOil CA plugin
----------------------------
To evaluate Barbican certificate management, you can enable the snakeoil_ca
certificate plugin. This is not suitable for production environment, but it can
be useful as a development tool.
To do so, you simply need to set ``enabled_certificate_plugins`` in
``barbican-api.conf``.
.. code-block:: text
enabled_certificate_plugins = snakeoil_ca
And then restart your Barbican server. It will automatically generate an
in-memory CA to create certificates.

View File

@@ -7,4 +7,5 @@ Setting up Barbican
dev
keystone
devstack
certificate
troubleshooting

View File

@@ -281,3 +281,7 @@ enabled_certificate_plugins = simple_certificate
[certificate_event]
namespace = barbican.certificate.event.plugin
enabled_certificate_event_plugins = simple_certificate
#[snakeoil_ca_plugin]
#ca_cert_path = /etc/barbican/snakeoil-ca.crt
#ca_cert_key_path = /etc/barbican/snakeoil-ca.key

View File

@@ -36,7 +36,7 @@ barbican.crypto.plugin =
simple_crypto = barbican.plugin.crypto.simple_crypto:SimpleCryptoPlugin
barbican.certificate.plugin =
simple_certificate = barbican.plugin.simple_certificate_manager:SimpleCertificatePlugin
snakeoil_ca = barbican.plugin.snakeoil_ca:SnakeoilCa
snakeoil_ca = barbican.plugin.snakeoil_ca:SnakeoilCACertificatePlugin
symantec = barbican.plugin.symantec:SymantecCertificatePlugin
dogtag = barbican.plugin.dogtag:DogtagCAPlugin
barbican.certificate.event.plugin =