diff options
author | Endi S. Dewata <edewata@redhat.com> | 2016-03-17 15:23:34 +0100 |
---|---|---|
committer | Endi S. Dewata <edewata@redhat.com> | 2016-04-05 22:46:11 +0200 |
commit | b214755763a31545cfb8980e0625fcccb4e00300 (patch) | |
tree | 803bd4e0d81ce07da82ec7803f96a236a6bcf36c /base/common | |
parent | 2009b97646f2321a806fcebbc33c329de16793e6 (diff) | |
download | pki-b214755763a31545cfb8980e0625fcccb4e00300.tar.gz pki-b214755763a31545cfb8980e0625fcccb4e00300.tar.xz pki-b214755763a31545cfb8980e0625fcccb4e00300.zip |
Added support for cloning 3rd-party CA certificates.
The installation code has been modified such that it imports all
CA certificates from the PKCS #12 file for cloning before the
server is started using certutil. The user certificates will
continue to be imported using the existing JSS code after the
server is started. This is necessary since JSS is unable to
preserve the CA certificate nicknames.
The PKCS12Util has been modified to support multiple certificates
with the same nicknames.
The pki pkcs12-cert-find has been modified to show certificate ID
and another field indicating whether the certificate has a key.
The pki pkcs12-cert-export has been modified to accept either
certificate nickname or ID.
The pki pkcs12-import has been modified to provide options for
importing only user certificates or CA certificates.
https://fedorahosted.org/pki/ticket/1742
Diffstat (limited to 'base/common')
-rw-r--r-- | base/common/python/pki/cli/pkcs12.py | 186 | ||||
-rw-r--r-- | base/common/python/pki/nssdb.py | 13 |
2 files changed, 127 insertions, 72 deletions
diff --git a/base/common/python/pki/cli/pkcs12.py b/base/common/python/pki/cli/pkcs12.py index dc890c1a5..eaca3c6f8 100644 --- a/base/common/python/pki/cli/pkcs12.py +++ b/base/common/python/pki/cli/pkcs12.py @@ -53,6 +53,8 @@ class PKCS12ImportCLI(pki.cli.CLI): print(' --pkcs12-password <password> Password for the PKCS #12 file.') print(' --pkcs12-password-file <path> containing the PKCS #12 password.') print(' --no-trust-flags Do not include trust flags') + print(' --no-user-certs Do not import user certificates') + print(' --no-ca-certs Do not import CA certificates') print(' -v, --verbose Run in verbose mode.') print(' --debug Run in debug mode.') print(' --help Show help message.') @@ -63,7 +65,8 @@ class PKCS12ImportCLI(pki.cli.CLI): try: opts, _ = getopt.gnu_getopt(args, 'v', [ 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', - 'no-trust-flags', 'verbose', 'debug', 'help']) + 'no-trust-flags', 'no-user-certs', 'no-ca-certs', + 'verbose', 'debug', 'help']) except getopt.GetoptError as e: print('ERROR: ' + str(e)) @@ -74,6 +77,9 @@ class PKCS12ImportCLI(pki.cli.CLI): pkcs12_password = None password_file = None no_trust_flags = False + import_user_certs = True + import_ca_certs = True + debug = False for o, a in opts: if o == '--pkcs12-file': @@ -88,9 +94,18 @@ class PKCS12ImportCLI(pki.cli.CLI): elif o == '--no-trust-flags': no_trust_flags = True + elif o == '--no-user-certs': + import_user_certs = False + + elif o == '--no-ca-certs': + import_ca_certs = False + elif o in ('-v', '--verbose'): self.set_verbose(True) + elif o == '--debug': + debug = True + elif o == '--help': self.print_help() sys.exit() @@ -119,13 +134,11 @@ class PKCS12ImportCLI(pki.cli.CLI): if main_cli.verbose: print('Getting certificate infos in PKCS #12 file') - ca_certs = [] - user_certs = [] + certs = [] tmpdir = tempfile.mkdtemp() try: - # find all certs in PKCS #12 file output_file = os.path.join(tmpdir, 'pkcs12-cert-find.txt') with open(output_file, 'wb') as f: @@ -144,33 +157,28 @@ class PKCS12ImportCLI(pki.cli.CLI): if no_trust_flags: cmd.extend(['--no-trust-flags']) - main_cli.execute_java(cmd, stdout=f) + if self.verbose: + cmd.extend(['--verbose']) - # determine cert types - with open(output_file, 'r') as f: + if debug: + cmd.extend(['--debug']) - cert_info = None + main_cli.execute_java(cmd, stdout=f) - for line in f.readlines(): + # parse results + with open(output_file, 'r') as f: - match = re.match(r' Nickname: (.*)$', line) + for line in f: + match = re.match(r' Certificate ID: (.*)$', line) if match: - # store previous cert - if cert_info: - if 'key_id' in cert_info: - # if cert has key, it's a user cert - user_certs.append(cert_info) - else: - # otherwise it's a CA cert - ca_certs.append(cert_info) - cert_info = {} - cert_info['nickname'] = match.group(1) + cert_info['id'] = match.group(1) + certs.append(cert_info) continue - match = re.match(r' Key ID: (.*)$', line) + match = re.match(r' Nickname: (.*)$', line) if match: - cert_info['key_id'] = match.group(1) + cert_info['nickname'] = match.group(1) continue match = re.match(r' Trust Flags: (.*)$', line) @@ -178,74 +186,112 @@ class PKCS12ImportCLI(pki.cli.CLI): cert_info['trust_flags'] = match.group(1) continue - # store last cert - if cert_info: - if 'key_id' in cert_info: - # if cert has key, it's a user cert - user_certs.append(cert_info) - else: - # otherwise it's a CA cert - ca_certs.append(cert_info) + match = re.match(r' Has Key: (.*)$', line) + if match: + cert_info['has_key'] = match.group(1) == 'true' + continue - cert_file = os.path.join(tmpdir, 'ca-cert.pem') + finally: + shutil.rmtree(tmpdir) - nssdb = pki.nssdb.NSSDatabase( - main_cli.database, - token=main_cli.token, - password=main_cli.password, - password_file=main_cli.password_file) + # import CA certificates if requested + if import_ca_certs: - for cert_info in ca_certs: + if main_cli.verbose: + print('Importing CA certificates') - nickname = cert_info['nickname'] - trust_flags = cert_info['trust_flags'] + tmpdir = tempfile.mkdtemp() - if main_cli.verbose: - print('Exporting %s from PKCS #12 file' % nickname) + try: + cert_file = os.path.join(tmpdir, 'ca-cert.pem') - cmd = ['pkcs12-cert-export'] + nssdb = pki.nssdb.NSSDatabase( + main_cli.database, + token=main_cli.token, + password=main_cli.password, + password_file=main_cli.password_file) - if pkcs12_file: - cmd.extend(['--pkcs12-file', pkcs12_file]) + for cert_info in certs: - if pkcs12_password: - cmd.extend(['--pkcs12-password', pkcs12_password]) + has_key = cert_info['has_key'] + if has_key: + continue - if password_file: - cmd.extend(['--pkcs12-password-file', password_file]) + cert_id = cert_info['id'] + nickname = cert_info['nickname'] + trust_flags = cert_info['trust_flags'] - cmd.extend(['--cert-file', cert_file, nickname]) + if main_cli.verbose: + print('Exporting %s (%s) from PKCS #12 file' % (nickname, cert_id)) - main_cli.execute_java(cmd) + cmd = ['pkcs12-cert-export'] - if main_cli.verbose: - print('Importing %s' % nickname) + if pkcs12_file: + cmd.extend(['--pkcs12-file', pkcs12_file]) - nssdb.add_cert(nickname, cert_file, trust_flags) + if pkcs12_password: + cmd.extend(['--pkcs12-password', pkcs12_password]) - finally: - shutil.rmtree(tmpdir) + if password_file: + cmd.extend(['--pkcs12-password-file', password_file]) + + cmd.extend(['--cert-file', cert_file]) + + cmd.extend(['--cert-id', cert_id]) + + if self.verbose: + cmd.extend(['--verbose']) + + if debug: + cmd.extend(['--debug']) + + main_cli.execute_java(cmd) + + if main_cli.verbose: + print('Importing %s' % nickname) + + nssdb.add_cert(nickname, cert_file, trust_flags) + + finally: + shutil.rmtree(tmpdir) + + # import user certificates if requested + if import_user_certs: + + if main_cli.verbose: + print('Importing user certificates') + + nicknames = [] + for cert_info in certs: + + has_key = cert_info['has_key'] + if not has_key: + continue + + nickname = cert_info['nickname'] + if nickname not in nicknames: + nicknames.append(nickname) - # importing user certs + cmd = ['pkcs12-import'] - nicknames = [] - for cert_info in user_certs: - nicknames.append(cert_info['nickname']) + if pkcs12_file: + cmd.extend(['--pkcs12-file', pkcs12_file]) - cmd = ['pkcs12-import'] + if pkcs12_password: + cmd.extend(['--pkcs12-password', pkcs12_password]) - if pkcs12_file: - cmd.extend(['--pkcs12-file', pkcs12_file]) + if password_file: + cmd.extend(['--pkcs12-password-file', password_file]) - if pkcs12_password: - cmd.extend(['--pkcs12-password', pkcs12_password]) + if no_trust_flags: + cmd.extend(['--no-trust-flags']) - if password_file: - cmd.extend(['--pkcs12-password-file', password_file]) + if self.verbose: + cmd.extend(['--verbose']) - if no_trust_flags: - cmd.extend(['--no-trust-flags']) + if debug: + cmd.extend(['--debug']) - cmd.extend(nicknames) + cmd.extend(nicknames) - main_cli.execute_java(cmd) + main_cli.execute_java(cmd) diff --git a/base/common/python/pki/nssdb.py b/base/common/python/pki/nssdb.py index e6aa0a6c2..f4ce1f240 100644 --- a/base/common/python/pki/nssdb.py +++ b/base/common/python/pki/nssdb.py @@ -512,8 +512,11 @@ class NSSDatabase(object): finally: shutil.rmtree(tmpdir) - def import_pkcs12(self, pkcs12_file, pkcs12_password=None, - pkcs12_password_file=None): + def import_pkcs12(self, pkcs12_file, + pkcs12_password=None, + pkcs12_password_file=None, + no_user_certs=False, + no_ca_certs=False): tmpdir = tempfile.mkdtemp() @@ -544,6 +547,12 @@ class NSSDatabase(object): '--pkcs12-password-file', password_file ]) + if no_user_certs: + cmd.extend(['--no-user-certs']) + + if no_ca_certs: + cmd.extend(['--no-ca-certs']) + subprocess.check_call(cmd) finally: |