diff options
author | Fraser Tweedale <ftweedal@redhat.com> | 2016-04-19 11:47:29 +1000 |
---|---|---|
committer | Jan Cholasta <jcholast@redhat.com> | 2016-06-09 09:04:27 +0200 |
commit | 4660bb7ff0197649c8777151a3a2a5378929e842 (patch) | |
tree | d93c2194fdb1493658cbc4b6b40f286ae053568a /ipapython | |
parent | 903a90fb4e7dc7eaddc1cc4f11083dad5c16db9b (diff) | |
download | freeipa-4660bb7ff0197649c8777151a3a2a5378929e842.tar.gz freeipa-4660bb7ff0197649c8777151a3a2a5378929e842.tar.xz freeipa-4660bb7ff0197649c8777151a3a2a5378929e842.zip |
Add custodia store for lightweight CA key replication
Due to limitations in Dogtag's use of NSSDB, importing private keys
must be done by the Dogtag Java process itself. This requires a
PKIArchiveOptions format (signing key wrapped with host CA key) -
PKCS #12 cannot be used because that would require decrypting the
key in Dogtag's memory, albeit temporarily.
Add a new custodia store that executes a 'pki' command to acquire
the wrapped key.
Part of: https://fedorahosted.org/freeipa/ticket/4559
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipapython')
-rw-r--r-- | ipapython/secrets/store.py | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/ipapython/secrets/store.py b/ipapython/secrets/store.py index 26dcc4688..095da7d1f 100644 --- a/ipapython/secrets/store.py +++ b/ipapython/secrets/store.py @@ -51,6 +51,56 @@ def HTTPD_password_callback(): return password +class NSSWrappedCertDB(DBMAPHandler): + ''' + Store that extracts private keys from an NSSDB, wrapped with the + private key of the primary CA. + ''' + + def __init__(self, config, dbmap, nickname): + if 'path' not in dbmap: + raise ValueError( + 'Configuration does not provide NSSDB path') + if 'pwcallback' not in dbmap: + raise ValueError( + 'Configuration does not provide Password Calback') + if 'wrap_nick' not in dbmap: + raise ValueError( + 'Configuration does not provide nickname of wrapping key') + self.nssdb_path = dbmap['path'] + self.nssdb_password = dbmap['pwcallback']() + self.wrap_nick = dbmap['wrap_nick'] + self.target_nick = nickname + + def export_key(self): + tdir = tempfile.mkdtemp(dir=paths.TMP) + try: + nsspwfile = os.path.join(tdir, 'nsspwfile') + with open(nsspwfile, 'w+') as f: + f.write(self.nssdb_password) + wrapped_key_file = os.path.join(tdir, 'wrapped_key') + certificate_file = os.path.join(tdir, 'certificate') + ipautil.run([ + paths.PKI, '-d', self.nssdb_path, '-C', nsspwfile, + 'ca-authority-key-export', + '--wrap-nickname', self.wrap_nick, + '--target-nickname', self.target_nick, + '-o', wrapped_key_file]) + ipautil.run([ + paths.CERTUTIL, '-d', self.nssdb_path, + '-L', '-n', self.target_nick, + '-a', '-o', certificate_file]) + with open(wrapped_key_file, 'r') as f: + wrapped_key = f.read() + with open(certificate_file, 'r') as f: + certificate = f.read() + finally: + shutil.rmtree(tdir) + return json_encode({ + 'wrapped_key': b64encode(wrapped_key), + 'certificate': certificate}) + + class NSSCertDB(DBMAPHandler): def __init__(self, config, dbmap, nickname): @@ -148,6 +198,12 @@ NAME_DB_MAP = { 'handler': NSSCertDB, 'pwcallback': PKI_TOMCAT_password_callback, }, + 'ca_wrapped': { + 'handler': NSSWrappedCertDB, + 'path': paths.PKI_TOMCAT_ALIAS_DIR, + 'pwcallback': PKI_TOMCAT_password_callback, + 'wrap_nick': 'caSigningCert cert-pki-ca', + }, 'ra': { 'type': 'NSSDB', 'path': paths.HTTPD_ALIAS_DIR, |