From 3c23d316d70b1ea8423e8e7bebe359c92bc183ac Mon Sep 17 00:00:00 2001 From: Ade Lee Date: Wed, 24 Sep 2014 12:09:10 -0400 Subject: [PATCH] Changes to get certificate issuance flow working Multiple changes are needed to resolve database session issues when accessing and updating order metadata, and storing the resulting certificates and intermediates. With this patch, we are able to place an order for a certificate, get the certificate immediately issued from a dogtag CA, and store the cert and intermediates correctly. Also added missing stanza in barbican-api.conf for SecretStore Closes-Bug: 1173533 Change-Id: I10785e1b6a3a73d4a9b1b2fcb1e6262e77a47b6a --- barbican/model/repositories.py | 20 +++++++++++++++++++ barbican/plugin/dogtag.py | 15 +++++++------- barbican/plugin/resources.py | 4 +++- barbican/tasks/certificate_resources.py | 13 ++++++------ barbican/tasks/resources.py | 4 +++- .../tests/tasks/test_certificate_resources.py | 17 ++++++++++------ barbican/tests/tasks/test_resources.py | 10 ++++++++-- etc/barbican/barbican-api.conf | 6 +++++- 8 files changed, 65 insertions(+), 24 deletions(-) diff --git a/barbican/model/repositories.py b/barbican/model/repositories.py index 6dfb2150c..e3243bb9f 100644 --- a/barbican/model/repositories.py +++ b/barbican/model/repositories.py @@ -855,6 +855,26 @@ class OrderPluginMetadatumRepo(BaseRepo): meta_model.order = order_model meta_model.save(session=session) + def get_metadata_for_order(self, order_id): + """Returns a dict of OrderPluginMetadatum instances.""" + + session = get_session() + with session.begin(): + try: + query = session.query(models.OrderPluginMetadatum) + query = query.filter_by(deleted=False) + + # Note: Must use '== None' below, not 'is None'. + query = query.filter( + models.OrderPluginMetadatum.order_id == order_id) + + metadata = query.all() + + except sa_orm.exc.NoResultFound: + metadata = dict() + + return dict((m.key, m.value) for m in metadata) + def _do_entity_name(self): """Sub-class hook: return entity name, such as for debugging.""" return "OrderPluginMetadatum" diff --git a/barbican/plugin/dogtag.py b/barbican/plugin/dogtag.py index a378f7055..2fdc9eeb3 100644 --- a/barbican/plugin/dogtag.py +++ b/barbican/plugin/dogtag.py @@ -480,14 +480,15 @@ class DogtagKRAPlugin(sstore.SecretStoreBase): def _store_secret_attributes(meta_dict, secret_dto): # store the following attributes for retrieval key_spec = secret_dto.key_spec - if key_spec.alg is not None: - meta_dict[DogtagKRAPlugin.ALG] = key_spec.alg - if key_spec.bit_length is not None: - meta_dict[DogtagKRAPlugin.BIT_LENGTH] = key_spec.bit_length - if key_spec.mode is not None: - meta_dict[DogtagKRAPlugin.SECRET_MODE] = key_spec.mode + if key_spec is not None: + if key_spec.alg is not None: + meta_dict[DogtagKRAPlugin.ALG] = key_spec.alg + if key_spec.bit_length is not None: + meta_dict[DogtagKRAPlugin.BIT_LENGTH] = key_spec.bit_length + if key_spec.mode is not None: + meta_dict[DogtagKRAPlugin.SECRET_MODE] = key_spec.mode if secret_dto.type is not None: - meta_dict[DogtagKRAPlugin.SECRET_TYPE] = secret_dto, type + meta_dict[DogtagKRAPlugin.SECRET_TYPE] = secret_dto.type def _get_passphrase_for_a_private_key(self, secret_metadata, key_spec): """Retrieve the passphrase for the private key which is stored diff --git a/barbican/plugin/resources.py b/barbican/plugin/resources.py index f1e3258b6..91eb60498 100644 --- a/barbican/plugin/resources.py +++ b/barbican/plugin/resources.py @@ -110,7 +110,9 @@ def store_secret(unencrypted_raw, content_type_raw, content_encoding, # Store the secret securely. # TODO(john-wood-w) Remove the SecretStoreContext once repository factory # and unit test patch work is completed. - secret_type = secret_store.KeyAlgorithm().get_secret_type(key_spec.alg) + secret_type = None + if key_spec is not None: + secret_store.KeyAlgorithm().get_secret_type(key_spec.alg) secret_dto = secret_store.SecretDTO(type=secret_type, secret=unencrypted, key_spec=key_spec, diff --git a/barbican/tasks/certificate_resources.py b/barbican/tasks/certificate_resources.py index 364ccf16c..cad1b47df 100644 --- a/barbican/tasks/certificate_resources.py +++ b/barbican/tasks/certificate_resources.py @@ -70,7 +70,8 @@ def issue_certificate_request(order_model, tenant_model, repos): the request has been completed. None otherwise """ container_model = None - plugin_meta = _get_plugin_meta(order_model) + + plugin_meta = _get_plugin_meta(order_model, repos) # Locate a suitable plugin to issue a certificate. cert_plugin = cert.CertificatePluginManager().get_plugin(order_model.meta) @@ -125,7 +126,8 @@ def check_certificate_request(order_model, tenant_model, plugin_name, repos): request has been completed. None otherwise. """ container_model = None - plugin_meta = _get_plugin_meta(order_model) + plugin_meta = _get_plugin_meta(order_model, repos) + cert_plugin = cert.CertificatePluginManager().get_plugin_by_name( plugin_name) @@ -227,11 +229,10 @@ def _schedule_retry_task(retry_object, retry_method, retry_time, args): pass -def _get_plugin_meta(order_model): +def _get_plugin_meta(order_model, repos): if order_model: - meta_dict = dict((k, v.value) for (k, v) in - order_model.order_plugin_metadata.items()) - return meta_dict + return repos.order_plugin_meta_repo.get_metadata_for_order( + order_model.id) else: return dict() diff --git a/barbican/tasks/resources.py b/barbican/tasks/resources.py index 250c82fd9..681a38ff5 100644 --- a/barbican/tasks/resources.py +++ b/barbican/tasks/resources.py @@ -217,7 +217,8 @@ class BeginTypeOrder(BaseTask): def __init__(self, tenant_repo=None, order_repo=None, secret_repo=None, tenant_secret_repo=None, datum_repo=None, kek_repo=None, container_repo=None, - container_secret_repo=None, secret_meta_repo=None): + container_secret_repo=None, secret_meta_repo=None, + order_plugin_meta_repo=None): LOG.debug('Creating BeginTypeOrder task processor') self.repos = rep.Repositories( tenant_repo=tenant_repo, @@ -227,6 +228,7 @@ class BeginTypeOrder(BaseTask): kek_repo=kek_repo, secret_meta_repo=secret_meta_repo, order_repo=order_repo, + order_plugin_meta_repo=order_plugin_meta_repo, container_repo=container_repo, container_secret_repo=container_secret_repo) diff --git a/barbican/tests/tasks/test_certificate_resources.py b/barbican/tests/tasks/test_certificate_resources.py index 894dbc406..547a0782f 100644 --- a/barbican/tests/tasks/test_certificate_resources.py +++ b/barbican/tests/tasks/test_certificate_resources.py @@ -30,21 +30,26 @@ class WhenPerformingPrivateOperations(utils.BaseTestCase): self.value = value class OrderModel(object): + id = mock.ANY order_plugin_metadata = { "foo": Value(1), "bar": Value(2), } order_model = OrderModel() - expected_dict = dict( - (k, v.value) for (k, v) in - order_model.order_plugin_metadata.items()) + repos = mock.MagicMock() + meta_repo_mock = mock.MagicMock() + repos.order_plugin_meta_repo = meta_repo_mock + meta_repo_mock.get_metadata_for_order.return_value = ( + order_model.order_plugin_metadata + ) - result = cert_res._get_plugin_meta(order_model) + result = cert_res._get_plugin_meta(order_model, repos) - self._assert_dict_equal(expected_dict, result) + self._assert_dict_equal(order_model.order_plugin_metadata, result) def test_get_plugin_meta_with_empty_dict(self): - result = cert_res._get_plugin_meta(None) + repos = mock.MagicMock() + result = cert_res._get_plugin_meta(None, repos) self._assert_dict_equal({}, result) diff --git a/barbican/tests/tasks/test_resources.py b/barbican/tests/tasks/test_resources.py index c6ade935a..e74f3b9f7 100644 --- a/barbican/tests/tasks/test_resources.py +++ b/barbican/tests/tasks/test_resources.py @@ -205,6 +205,8 @@ class WhenBeginningKeyTypeOrder(utils.BaseTestCase): self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order + self.order_plugin_meta_repo = mock.MagicMock() + self.secret = models.Secret() self.secret_repo = mock.MagicMock() @@ -236,7 +238,8 @@ class WhenBeginningKeyTypeOrder(utils.BaseTestCase): self.kek_repo, self.secret_meta_repo, self.container_repo, - self.container_secret_repo) + self.container_secret_repo, + self.order_plugin_meta_repo) @mock.patch('barbican.plugin.resources.generate_secret') def test_should_process_key_order(self, mock_generate_secret): @@ -358,6 +361,8 @@ class WhenBeginningAsymmetricTypeOrder(utils.BaseTestCase): self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order + self.order_plugin_meta_repo = mock.MagicMock() + self.secret_repo = mock.MagicMock() self.secret_repo.create_from.return_value = None @@ -386,7 +391,8 @@ class WhenBeginningAsymmetricTypeOrder(utils.BaseTestCase): self.kek_repo, self.secret_meta_repo, self.container_repo, - self.container_secret_repo) + self.container_secret_repo, + self.order_plugin_meta_repo) @mock.patch('barbican.plugin.resources.generate_asymmetric_secret') def test_should_process_asymmetric_order(self, diff --git a/etc/barbican/barbican-api.conf b/etc/barbican/barbican-api.conf index 532e46506..efb9fa83f 100644 --- a/etc/barbican/barbican-api.conf +++ b/etc/barbican/barbican-api.conf @@ -151,6 +151,11 @@ version = '1.1' # Server name for RPC service server_name = 'barbican.queue' +# ================= Secret Store Plugin =================== +[secretstore] +namespace = barbican.secretstore.plugin +enabled_secretstore_plugins = store_crypto + # ================= Crypto plugin =================== [crypto] namespace = barbican.crypto.plugin @@ -162,7 +167,6 @@ kek = 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=' [dogtag_plugin] pem_path = '/etc/barbican/kra_admin_cert.pem' -pem_password = 'password123' dogtag_host = localhost dogtag_port = 8443 nss_db_path = '/etc/barbican/alias'