From a42e35885ee21b78ca36aaee6f2e15002f6053cc Mon Sep 17 00:00:00 2001 From: Ade Lee Date: Sun, 10 May 2015 22:22:29 -0400 Subject: [PATCH] Base64 encode the cert returned from the Dogtag plugin Also, add the missing headers for the intermediates, and make the algorithm match case insensitive to make the supports() method more robust. Change-Id: I728846494e8f60ca37640d9753081deefd6cb8e4 Closes-Bug: 1453636 --- barbican/plugin/dogtag.py | 37 ++++++++++++++----- .../v1/functional/test_certificate_orders.py | 22 +++++++++++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/barbican/plugin/dogtag.py b/barbican/plugin/dogtag.py index 845588ec6..aa6a31759 100644 --- a/barbican/plugin/dogtag.py +++ b/barbican/plugin/dogtag.py @@ -66,6 +66,9 @@ dogtag_plugin_opts = [ CONF.register_group(dogtag_plugin_group) CONF.register_opts(dogtag_plugin_opts, group=dogtag_plugin_group) +CERT_HEADER = "-----BEGIN CERTIFICATE-----" +CERT_FOOTER = "-----END CERTIFICATE-----" + def setup_nss_db(conf, subsystem): crypto = None @@ -497,20 +500,23 @@ class DogtagKRAPlugin(sstore.SecretStoreBase): Note that only algorithms supported by Dogtag will be mapped. """ - if algorithm == sstore.KeyAlgorithm.AES: + if algorithm is None: + return None + + if algorithm.lower() == sstore.KeyAlgorithm.AES.lower(): return key.KeyClient.AES_ALGORITHM - elif algorithm == sstore.KeyAlgorithm.DES: + elif algorithm.lower() == sstore.KeyAlgorithm.DES.lower(): return key.KeyClient.DES_ALGORITHM - elif algorithm == sstore.KeyAlgorithm.DESEDE: + elif algorithm.lower() == sstore.KeyAlgorithm.DESEDE.lower(): return key.KeyClient.DES3_ALGORITHM - elif algorithm == sstore.KeyAlgorithm.DSA: + elif algorithm.lower() == sstore.KeyAlgorithm.DSA.lower(): return key.KeyClient.DSA_ALGORITHM - elif algorithm == sstore.KeyAlgorithm.RSA: + elif algorithm.lower() == sstore.KeyAlgorithm.RSA.lower(): return key.KeyClient.RSA_ALGORITHM - elif algorithm == sstore.KeyAlgorithm.DIFFIE_HELLMAN: + elif algorithm.lower() == sstore.KeyAlgorithm.DIFFIE_HELLMAN.lower(): # may be supported, needs to be tested return None - elif algorithm == sstore.KeyAlgorithm.EC: + elif algorithm.lower() == sstore.KeyAlgorithm.EC.lower(): # asymmetric keys not yet supported return None else: @@ -949,9 +955,22 @@ class DogtagCAPlugin(cm.CertificatePluginBase): dto = None if request_status == pki.cert.CertRequestStatus.COMPLETE: if cert is not None: + # Barbican is expecting base 64 encoded PEM, so we base64 + # encode below. + # + # Currently there is an inconsistency in what Dogtag returns + # for certificates and intermediates. For certs, we return + # PEM, whereas for intermediates, we return headerless PEM. + # This is being addressed in Dogtag ticket: + # https://fedorahosted.org/pki/ticket/1374 + # + # Until this is addressed, simply add the missing headers + cert_chain = (CERT_HEADER + "\r\n" + cert.pkcs7_cert_chain + + CERT_FOOTER) + dto = cm.ResultDTO(cm.CertificateStatus.CERTIFICATE_GENERATED, - certificate=cert.encoded, - intermediates=cert.pkcs7_cert_chain) + certificate=base64.b64encode(cert.encoded), + intermediates=base64.b64encode(cert_chain)) else: raise cm.CertificateGeneralException( u._("request_id {req_id} returns COMPLETE but no cert " diff --git a/functionaltests/api/v1/functional/test_certificate_orders.py b/functionaltests/api/v1/functional/test_certificate_orders.py index 777abca9c..40ac847bf 100644 --- a/functionaltests/api/v1/functional/test_certificate_orders.py +++ b/functionaltests/api/v1/functional/test_certificate_orders.py @@ -234,9 +234,31 @@ class CertificatesTestCase(base.TestCase): if secret.name == 'certificate': contains_cert = True self.assertIsNotNone(secret.secret_ref) + self.verify_valid_cert(secret.secret_ref) + if secret.name == 'intermediates': + self.assertIsNotNone(secret.secret_ref) + self.verify_valid_intermediates(secret.secret_ref) self.assertTrue(contains_cert) + def verify_valid_cert(self, secret_ref): + secret_resp = self.secret_behaviors.get_secret( + secret_ref, + "application/pkix-cert") + self.assertIsNotNone(secret_resp) + self.assertIsNotNone(secret_resp.content) + cert = secret_resp.content + crypto.load_certificate(crypto.FILETYPE_PEM, cert) + + def verify_valid_intermediates(self, secret_ref): + secret_resp = self.secret_behaviors.get_secret( + secret_ref, + "application/pkix-cert") + self.assertIsNotNone(secret_resp) + self.assertIsNotNone(secret_resp.content) + cert_chain = secret_resp.content + crypto.load_pkcs7_data(crypto.FILETYPE_PEM, cert_chain) + def verify_pending_waiting_for_ca(self, order_resp): self.assertEqual('PENDING', order_resp.model.status) self.assertEqual(cert_res.ORDER_STATUS_REQUEST_PENDING.id,