summaryrefslogtreecommitdiffstats
path: root/base/server/python
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2015-11-07 00:09:19 +0100
committerEndi S. Dewata <edewata@redhat.com>2015-11-25 00:26:21 +0100
commit20c985ae773b26f653cac6d22bd9d93923e18c8e (patch)
treed10cf2d40b0434e35c0214700f26d4998db6778c /base/server/python
parentec9c68d68eabff3784fcf6dabf2c6745734b3c9c (diff)
downloadpki-20c985ae773b26f653cac6d22bd9d93923e18c8e.tar.gz
pki-20c985ae773b26f653cac6d22bd9d93923e18c8e.tar.xz
pki-20c985ae773b26f653cac6d22bd9d93923e18c8e.zip
Added mechanism to import existing CA certificate.
The deployment procedure for external CA has been modified such that it generates the CA CSR before starting the server. This allows the same procedure to be used to import CA certificate from an existing server. It also removes the requirement to keep the server running while waiting to get the CSR signed by an external CA. https://fedorahosted.org/pki/ticket/456
Diffstat (limited to 'base/server/python')
-rw-r--r--base/server/python/pki/server/__init__.py5
-rw-r--r--base/server/python/pki/server/deployment/pkihelper.py70
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/configuration.py128
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/finalization.py12
4 files changed, 183 insertions, 32 deletions
diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py
index d55a3691d..bf592dcd5 100644
--- a/base/server/python/pki/server/__init__.py
+++ b/base/server/python/pki/server/__init__.py
@@ -328,10 +328,11 @@ class PKIInstance(object):
return password
- def open_nssdb(self):
+ def open_nssdb(self, token='internal'):
return pki.nss.NSSDatabase(
directory=self.nssdb_dir,
- password=self.get_password('internal'))
+ token=token,
+ password=self.get_password(token))
def get_subsystem(self, name):
for subsystem in self.subsystems:
diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index 61f04d215..9c9b40454 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -757,8 +757,7 @@ class ConfigurationFile:
# External CA
if not self.external_step_two:
# External CA (Step 1)
- self.confirm_data_exists("pki_external_csr_path")
- self.confirm_missing_file("pki_external_csr_path")
+ # The pki_external_csr_path is optional.
# generic extension support in CSR - for external CA
if self.add_req_ext:
self.confirm_data_exists("pki_req_ext_oid")
@@ -766,10 +765,9 @@ class ConfigurationFile:
self.confirm_data_exists("pki_req_ext_data")
else:
# External CA (Step 2)
- self.confirm_data_exists("pki_external_ca_cert_chain_path")
- self.confirm_file_exists("pki_external_ca_cert_chain_path")
- self.confirm_data_exists("pki_external_ca_cert_path")
- self.confirm_file_exists("pki_external_ca_cert_path")
+ # The pki_external_ca_cert_chain_path and
+ # pki_external_ca_cert_path are optional.
+ pass
elif not self.skip_configuration and self.standalone:
if not self.external_step_two:
# Stand-alone PKI Admin CSR (Step 1)
@@ -3813,17 +3811,7 @@ class ConfigClient:
if not isinstance(certs, list):
certs = [certs]
for cdata in certs:
- if (self.subsystem == "CA" and self.external and
- not self.external_step_two):
- # External CA (Step 1)
- if cdata['tag'].lower() == "signing":
- # Save 'External CA Signing Certificate' CSR (Step 1)
- self.save_system_csr(
- cdata['request'],
- log.PKI_CONFIG_EXTERNAL_CSR_SAVE,
- self.mdict['pki_external_csr_path'])
- return
- elif self.standalone and not self.external_step_two:
+ if self.standalone and not self.external_step_two:
# Stand-alone PKI (Step 1)
if cdata['tag'].lower() == "audit_signing":
# Save Stand-alone PKI 'Audit Signing Certificate' CSR
@@ -3991,8 +3979,17 @@ class ConfigClient:
data.token = self.mdict['pki_token_name']
data.tokenPassword = self.mdict['pki_token_password']
data.subsystemName = self.mdict['pki_subsystem_name']
+
+ data.external = self.external
data.standAlone = self.standalone
- data.stepTwo = self.external_step_two
+
+ if self.standalone:
+ # standalone installation uses two-step process (ticket #1698)
+ data.stepTwo = self.external_step_two
+
+ else:
+ # other installations use only one step in the configuration servlet
+ data.stepTwo = False
# Cloning parameters
if self.mdict['pki_instance_type'] == "Tomcat":
@@ -4122,25 +4119,46 @@ class ConfigClient:
self.mdict['pki_req_ext_critical']
cert1.req_ext_data = \
self.mdict['pki_req_ext_data']
- if self.external_step_two:
- # External CA (Step 2) or Stand-alone PKI (Step 2)
- if not self.subsystem == "CA":
- # Stand-alone PKI (Step 2)
- cert1 = pki.system.SystemCertData()
- cert1.tag = self.mdict['pki_ca_signing_tag']
- # Load the External CA or Stand-alone PKI
+
+ if self.external and self.external_step_two: # external/existing CA step 2
+
+ # If specified, load the externally-signed CA cert
+ if self.mdict['pki_external_ca_cert_path']:
+ self.load_system_cert(
+ cert1,
+ log.PKI_CONFIG_EXTERNAL_CA_LOAD,
+ self.mdict['pki_external_ca_cert_path'])
+
+ # If specified, load the external CA cert chain
+ if self.mdict['pki_external_ca_cert_chain_path']:
+ self.load_system_cert_chain(
+ cert1,
+ log.PKI_CONFIG_EXTERNAL_CA_CHAIN_LOAD,
+ self.mdict['pki_external_ca_cert_chain_path'])
+
+ systemCerts.append(cert1)
+
+ elif self.standalone and self.external_step_two: # standalone KRA/OCSP step 2
+
+ cert1 = pki.system.SystemCertData()
+ cert1.tag = self.mdict['pki_ca_signing_tag']
+
+ # Load the stand-alone PKI
# 'External CA Signing Certificate' (Step 2)
self.load_system_cert(
cert1,
log.PKI_CONFIG_EXTERNAL_CA_LOAD,
self.mdict['pki_external_ca_cert_path'])
- # Load the External CA or Stand-alone PKI
+
+ # Load the stand-alone PKI
# 'External CA Signing Certificate Chain' (Step 2)
self.load_system_cert_chain(
cert1,
log.PKI_CONFIG_EXTERNAL_CA_CHAIN_LOAD,
self.mdict['pki_external_ca_cert_chain_path'])
+
systemCerts.append(cert1)
+
elif self.subsystem == "CA":
# PKI CA or Subordinate CA
systemCerts.append(cert1)
diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py
index c6e890235..b8b8fc691 100644
--- a/base/server/python/pki/server/deployment/scriptlets/configuration.py
+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py
@@ -21,13 +21,18 @@
from __future__ import absolute_import
import json
+import re
# PKI Deployment Imports
from .. import pkiconfig as config
from .. import pkimessages as log
from .. import pkiscriptlet
-import pki.system
+
import pki.encoder
+import pki.nss
+import pki.server
+import pki.system
+import pki.util
# PKI Deployment Configuration Scriptlet
@@ -81,6 +86,127 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
deployer.mdict['pki_client_secmod_database'],
password_file=deployer.mdict['pki_client_password_conf'])
+ instance = pki.server.PKIInstance(deployer.mdict['pki_instance_name'])
+ instance.load()
+
+ subsystem = instance.get_subsystem(deployer.mdict['pki_subsystem'].lower())
+
+ token = deployer.mdict['pki_token_name']
+ nssdb = instance.open_nssdb(token)
+
+ external = config.str2bool(deployer.mdict['pki_external'])
+ step_one = not config.str2bool(deployer.mdict['pki_external_step_two'])
+ step_two = not step_one
+
+ try:
+ if external and step_one: # external/existing CA step 1
+
+ key_type = deployer.mdict['pki_ca_signing_key_type']
+ key_alg = deployer.mdict['pki_ca_signing_key_algorithm']
+
+ if key_type == 'rsa':
+ key_size = int(deployer.mdict['pki_ca_signing_key_size'])
+ curve = None
+
+ m = re.match(r'(.*)withRSA', key_alg)
+ if not m:
+ raise Exception('Invalid key algorithm: %s' % key_alg)
+ hash_alg = m.group(1)
+
+ elif key_type == 'ec' or key_type == 'ecc':
+ key_type = 'ec'
+ key_size = None
+ curve = deployer.mdict['pki_ca_signing_key_size']
+
+ m = re.match(r'(.*)withEC', key_alg)
+ if not m:
+ raise Exception('Invalid key algorithm: %s' % key_alg)
+ hash_alg = m.group(1)
+
+ else:
+ raise Exception('Invalid key type: %s' % key_type)
+
+ # If filename specified, generate CA cert request and
+ # import it into CS.cfg.
+ request_file = deployer.mdict['pki_external_csr_path']
+ if request_file:
+ nssdb.create_request(
+ subject_dn=deployer.mdict['pki_ca_signing_subject_dn'],
+ request_file=request_file,
+ key_type=key_type,
+ key_size=key_size,
+ curve=curve,
+ hash_alg=hash_alg)
+ with open(request_file) as f:
+ signing_csr = f.read()
+ signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64')
+ subsystem.config['ca.signing.certreq'] = signing_csr
+
+ subsystem.save()
+
+ elif external and step_two: # external/existing CA step 2
+
+ # If specified, import existing CA cert request into CS.cfg.
+ request_file = deployer.mdict['pki_external_csr_path']
+ if request_file:
+ with open(request_file) as f:
+ signing_csr = f.read()
+ signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64')
+ subsystem.config['ca.signing.certreq'] = signing_csr
+
+ # If specified, import external CA cert into NSS database.
+ external_ca_cert_chain_nickname = deployer.mdict['pki_external_ca_cert_chain_nickname']
+ external_ca_cert_chain_file = deployer.mdict['pki_external_ca_cert_chain_path']
+ if external_ca_cert_chain_file:
+ cert_chain = nssdb.import_cert_chain(
+ nickname=external_ca_cert_chain_nickname,
+ cert_chain_file=external_ca_cert_chain_file,
+ trust_attributes='CT,C,C')
+ subsystem.config['ca.external_ca_chain.cert'] = cert_chain
+
+ # If specified, import externally-signed CA cert into NSS database.
+ signing_nickname = deployer.mdict['pki_ca_signing_nickname']
+ signing_cert_file = deployer.mdict['pki_external_ca_cert_path']
+ if signing_cert_file:
+ nssdb.add_cert(
+ nickname=signing_nickname,
+ cert_file=signing_cert_file,
+ trust_attributes='CT,C,C')
+
+ # If specified, import CA cert and key from PKCS #12 file into NSS database.
+ pkcs12_file = deployer.mdict['pki_external_pkcs12_path']
+ if pkcs12_file:
+ pkcs12_password = deployer.mdict['pki_external_pkcs12_password']
+ nssdb.import_pkcs12(pkcs12_file, pkcs12_password)
+
+ # Export CA cert from NSS database and import it into CS.cfg.
+ signing_cert_data = nssdb.get_cert(
+ nickname=signing_nickname,
+ output_format='base64')
+ subsystem.config['ca.signing.nickname'] = signing_nickname
+ subsystem.config['ca.signing.tokenname'] = deployer.mdict['pki_ca_signing_token']
+ subsystem.config['ca.signing.cert'] = signing_cert_data
+ subsystem.config['ca.signing.cacertnickname'] = signing_nickname
+ subsystem.config['ca.signing.defaultSigningAlgorithm'] = deployer.mdict['pki_ca_signing_signing_algorithm']
+
+ subsystem.save()
+
+ else: # self-signed CA
+
+ # To be implemented in ticket #1692.
+
+ # Generate CA cert request.
+ # Self sign CA cert.
+ # Import self-signed CA cert into NSS database.
+
+ pass
+
+ finally:
+ nssdb.close()
+
+ if external and step_one:
+ return self.rv
+
# Start/Restart this Tomcat PKI Process
# Optionally prepare to enable a java debugger
# (e. g. - 'eclipse'):
diff --git a/base/server/python/pki/server/deployment/scriptlets/finalization.py b/base/server/python/pki/server/deployment/scriptlets/finalization.py
index 56ddf0219..3c4f469ac 100644
--- a/base/server/python/pki/server/deployment/scriptlets/finalization.py
+++ b/base/server/python/pki/server/deployment/scriptlets/finalization.py
@@ -67,9 +67,15 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
if len(deployer.instance.tomcat_instance_subsystems()) == 1:
# Modify contents of 'serverCertNick.conf' (if necessary)
deployer.servercertnick_conf.modify()
- # Optionally, programmatically 'restart' the configured PKI instance
- if config.str2bool(deployer.mdict['pki_restart_configured_instance']):
- deployer.systemd.restart()
+
+ external = config.str2bool(deployer.mdict['pki_external'])
+ step_one = not config.str2bool(deployer.mdict['pki_external_step_two'])
+
+ if not (external and step_one):
+ # Optionally, programmatically 'restart' the configured PKI instance
+ if config.str2bool(deployer.mdict['pki_restart_configured_instance']):
+ deployer.systemd.restart()
+
# Optionally, 'purge' the entire temporary client infrastructure
# including the client NSS security databases and password files
#