Return CA for a given instance

Return the signing CA certificate.

Closes bug: 1409037
Change-Id: I57ec9b657dd2bedf4b13a45703f7fd0c6d1d4a0b
This commit is contained in:
Stanisław Pitucha 2015-07-03 15:07:35 +10:00
parent 222684e825
commit 7623347163
4 changed files with 65 additions and 6 deletions

View File

@ -133,6 +133,17 @@ def certificate_fingerprint(cert_pem, hash_name):
return cert.get_fingerprint(hash_name)
def get_ca(ra_name):
ca_conf = jsonloader.signing_ca_for_registration_authority(ra_name)
ca_path = ca_conf.get('cert_path')
if not ca_path:
pecan.abort(404, "CA certificate not available")
with open(ca_path) as f:
return f.read()
def dispatch_sign(ra_name, csr):
"""Dispatch the sign call to the configured backend.

View File

@ -32,12 +32,14 @@ class RobotsController(rest.RestController):
return "User-agent: *\nDisallow: /\n"
class SignInstanceController(rest.RestController):
"""Handles POST requests to /v1/sign/ra_name."""
class GenericInstanceController(rest.RestController):
"""Handles requests to /xxx/ra_name."""
def __init__(self, ra_name):
self.ra_name = ra_name
class SignInstanceController(GenericInstanceController):
"""Handles POST requests to /sign/instance."""
@pecan.expose(content_type="text/plain")
def post(self):
ra_name = self.ra_name
@ -54,16 +56,29 @@ class SignInstanceController(rest.RestController):
return certificate_ops.dispatch_sign(ra_name, csr)
class SignController(rest.RestController):
class CAInstanceController(GenericInstanceController):
"""Handles POST requests to /ca/ra_name."""
@pecan.expose(content_type="text/plain")
def get(self):
ra_name = self.ra_name
return certificate_ops.get_ca(ra_name)
class RAController(rest.RestController):
def __init__(self, subcontroller):
self._subcontroller = subcontroller
@pecan.expose()
def _lookup(self, ra_name, *remaining):
if ra_name in jsonloader.registration_authority_names():
return SignInstanceController(ra_name), remaining
return self._subcontroller(ra_name), remaining
pecan.abort(404)
class V1Controller(rest.RestController):
sign = SignController()
sign = RAController(SignInstanceController)
ca = RAController(CAInstanceController)
class RootController(object):

View File

@ -26,3 +26,23 @@ Result
~~~~~~
Signed certificate
/v1/ca/<registration_authority> (GET)
----------------------------------------
Requests the CA which would be used to sign the request made to this
registration authority.
Do *NOT* use this to retrieve the certificate needed to trust communication
with Anchor. Connection to Anchor *MUST* be fully trusted before using this
endpoint for further configuration.
Request parameters
~~~~~~~~~~~~~~~~~~
* ``encoding``: request encoding - currently supported: "pem"
Result
~~~~~~
CA certificate used to sign for this RA.

View File

@ -173,3 +173,16 @@ class TestFunctional(tests.DefaultConfigMixin, unittest.TestCase):
"'broken_validator' for registration authority "
"'default_ra'") in str(resp))
self.assertTrue(derp.called)
def test_get_ca(self):
data = {'encoding': 'pem'}
resp = self.app.get('/v1/ca/default_ra', data, expect_errors=False)
self.assertEqual(200, resp.status_int)
cert = X509_cert.X509Certificate.from_buffer(resp.text)
# make sure the cert is what we asked for
self.assertEqual("/C=AU/ST=Some-State/O=Herp Derp plc/OU"
"=herp.derp.plc/CN=herp.derp.plc",
str(cert.get_subject()))