X509 Certs
Nova has an x509 cert store that it uses for the ec2 bundling image process and the cloudpipe vpn system. Currently the code runs inside the API server - which leads to issues if you want to want to run the api server on multiple boxes.
Nova creates a chain per project (tenants in the keystone world). Users can request certificates for projects (tenants) they are members of.
STATUS: DRAFT
QUESTIONS:
- what is the api for validation? Is there an admin API to download the chain (for cloudpipe?) or do we expose a validation method?
- need ability to request cloud public key (for ec2 bundling)
Overview:
move x509 into a nova-manager, run from a host that manages the CA directory
- openstack (admin-only?) extension for management - there is some (deprecated) usage in the ec2/admin.py
- use rpc to communicate between API and x509 manager
- api is a wrapper around most of the nova/crypto.py interface
[ OS API ] <=> [ x509-manager ] <=> [ crypto logic ]
Cleanup
- make generate_vpn_credentials use get_x509_cert
- key certs off of subject instead of user_id
Manager
Create a nova-x509 bin that is a nova-manager. A manager in nova is a process that: has flags, has an RPC and DB connection. (example managers are nova-scheduler)
OS API Extension
The following are users of the extension:
- the dashboard - for getting certs for users (building a novarc / nova.zip)
- CRUD around certs for a user (scoped by a tenant)
- cloudpipe
- CRUD for tenant cert works here
CALLS
- get_tenant_cert -- gets the top level tenant cert
- get_signed_cert(subject) -- (non-unique-)subject = user_id or cloudpipe_key(uuid?) returns cert signed by top level cert and private key
- revoke_certs(subject=None) -- revokes all certs for subject or all certs
- get crl -- returns certificate revocation list
REST OBJECT:
{"cert": {"x509": "text",
"tenant_id": tenant_id,
"created": "12/12/12",
"enabled": True}}
Openstack Admin API Extension
Ability to decrypt a small blob of text using the chain for a given tenant:
method name: decrypt
input: tenant_id, encrypted text
output: decrypted text
367 iv, err = utils.execute('openssl',
368 'rsautl',
369 '-decrypt',
370 '-inkey', '%s' % tenant_chain_key,
371 process_input=encrypted_iv,
372 check_exit_code=False)vishy: Cloudpipe could just request the crl on a regular basis without needing to grab all of the other files.
Old EC2 Extension
def generate_x509_for_user(self, context, name, project=None, **kwargs):
"""Generates and returns an x509 certificate for a single user.
Is usually called from a client that will wrap this with
access and secret key info, and return a zip file.
"""
if project is None:
project = name
project = manager.AuthManager().get_project(project)
user = manager.AuthManager().get_user(name)
msg = _("Getting x509 for user: %(name)s"
" on project: %(project)s") % locals()
LOG.audit(msg, context=context)
return user_dict(user, base64.b64encode(project.get_credentials(user)))