From 9dce4a497f7c977a3c453972706eeb325bd33275 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Thu, 12 Nov 2015 00:23:26 +0100 Subject: Added pki-server subsystem-cert-export command. A new command has been added to export a system certificate, the CSR, and the key. This command can be used to migrate a system certificate into another instance. https://fedorahosted.org/pki/ticket/456 --- base/server/python/pki/server/__init__.py | 6 ++ base/server/python/pki/server/cli/subsystem.py | 126 +++++++++++++++++++++++++ 2 files changed, 132 insertions(+) (limited to 'base/server/python/pki') diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py index 0d522084c..d55a3691d 100644 --- a/base/server/python/pki/server/__init__.py +++ b/base/server/python/pki/server/__init__.py @@ -34,6 +34,7 @@ import subprocess import tempfile import pki +import pki.nss INSTANCE_BASE_DIR = '/var/lib/pki' REGISTRY_DIR = '/etc/sysconfig/pki' @@ -327,6 +328,11 @@ class PKIInstance(object): return password + def open_nssdb(self): + return pki.nss.NSSDatabase( + directory=self.nssdb_dir, + password=self.get_password('internal')) + def get_subsystem(self, name): for subsystem in self.subsystems: if name == subsystem.name: diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py index 3b9f9860f..14b5be2f5 100644 --- a/base/server/python/pki/server/cli/subsystem.py +++ b/base/server/python/pki/server/cli/subsystem.py @@ -23,11 +23,13 @@ from __future__ import absolute_import from __future__ import print_function import base64 import getopt +import getpass import nss.nss as nss import string import sys import pki.cli +import pki.nss import pki.server @@ -296,6 +298,7 @@ class SubsystemCertCLI(pki.cli.CLI): self.add_module(SubsystemCertFindCLI()) self.add_module(SubsystemCertShowCLI()) + self.add_module(SubsystemCertExportCLI()) self.add_module(SubsystemCertUpdateCLI()) @staticmethod @@ -440,6 +443,129 @@ class SubsystemCertShowCLI(pki.cli.CLI): SubsystemCertCLI.print_subsystem_cert(subsystem_cert) +class SubsystemCertExportCLI(pki.cli.CLI): + + def __init__(self): + super(SubsystemCertExportCLI, self).__init__( + 'export', 'Export subsystem certificate') + + def usage(self): + print('Usage: pki-server subsystem-cert-export [OPTIONS] ') + print() + print(' -i, --instance Instance ID (default: pki-tomcat).') + print(' --cert-file Output file to store the exported certificate in PEM format.') + print(' --csr-file Output file to store the exported CSR in PEM format.') + print(' --pkcs12-file Output file to store the exported certificate and key in PKCS #12 format.') + print(' --pkcs12-password Password for the PKCS #12 file.') + print(' --pkcs12-password-file Input file containing the password for the PKCS #12 file.') + print(' -v, --verbose Run in verbose mode.') + print(' --help Show help message.') + print() + + def execute(self, argv): + + try: + opts, args = getopt.gnu_getopt(argv, 'i:v', [ + 'instance=', 'cert-file=', 'csr-file=', + 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', + 'verbose', 'help']) + + except getopt.GetoptError as e: + print('ERROR: ' + str(e)) + self.usage() + sys.exit(1) + + if len(args) < 1: + print('ERROR: missing subsystem ID') + self.usage() + sys.exit(1) + + if len(args) < 2: + print('ERROR: missing cert ID') + self.usage() + sys.exit(1) + + subsystem_name = args[0] + cert_id = args[1] + instance_name = 'pki-tomcat' + cert_file = None + csr_file = None + pkcs12_file = None + pkcs12_password = None + pkcs12_password_file = None + + for o, a in opts: + if o in ('-i', '--instance'): + instance_name = a + + elif o == '--cert-file': + cert_file = a + + elif o == '--csr-file': + csr_file = a + + elif o == '--pkcs12-file': + pkcs12_file = a + + elif o == '--pkcs12-password': + pkcs12_password = a + + elif o == '--pkcs12-password-file': + pkcs12_password_file = a + + elif o in ('-v', '--verbose'): + self.set_verbose(True) + + elif o == '--help': + self.print_help() + sys.exit() + + else: + print('ERROR: unknown option ' + o) + self.usage() + sys.exit(1) + + if not cert_file and not csr_file and not pkcs12_file: + print('ERROR: missing output file') + self.usage() + sys.exit(1) + + instance = pki.server.PKIInstance(instance_name) + instance.load() + + subsystem = instance.get_subsystem(subsystem_name) + subsystem_cert = subsystem.get_subsystem_cert(cert_id) + + if cert_file: + + cert_data = pki.nss.convert_cert(subsystem_cert['data'], 'base64', 'pem') + with open(cert_file, 'w') as f: + f.write(cert_data) + + if csr_file: + + csr_data = pki.nss.convert_csr(subsystem_cert['request'], 'base64', 'pem') + with open(csr_file, 'w') as f: + f.write(csr_data) + + if pkcs12_file: + + if not pkcs12_password and not pkcs12_password_file: + pkcs12_password = getpass.getpass(prompt='Enter password for PKCS #12 file: ') + + nssdb = instance.open_nssdb() + try: + nssdb.export_pkcs12( + pkcs12_file=pkcs12_file, + nickname=subsystem_cert['nickname'], + pkcs12_password=pkcs12_password, + pkcs12_password_file=pkcs12_password_file) + finally: + nssdb.close() + + self.print_message('Exported %s certificate' % cert_id) + + class SubsystemCertUpdateCLI(pki.cli.CLI): def __init__(self): -- cgit