# Authors: # Matthew Harmsen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # from __future__ import absolute_import # PKI Deployment Imports from .. import pkiconfig as config from .. import pkimessages as log from .. import pkiscriptlet import pki.encoder import pki.nssdb import pki.server import pki.system import pki.util # PKI Deployment Configuration Scriptlet class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): def spawn(self, deployer): if config.str2bool(deployer.mdict['pki_skip_configuration']): config.pki_log.info(log.SKIP_CONFIGURATION_SPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) return config.pki_log.info(log.CONFIGURATION_SPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) deployer.instance.verify_subsystem_exists() 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) existing = deployer.configuration_file.existing external = deployer.configuration_file.external standalone = deployer.configuration_file.standalone step_one = deployer.configuration_file.external_step_one step_two = deployer.configuration_file.external_step_two try: if existing or external and step_two: # existing CA or external CA step 2 # If specified, import CA signing CSR into CS.cfg. signing_csr_path = deployer.mdict['pki_external_csr_path'] if signing_csr_path: config.pki_log.info( "importing CA signing CSR from %s", signing_csr_path, extra=config.PKI_INDENTATION_LEVEL_2) with open(signing_csr_path) as f: signing_csr = f.read() signing_csr = pki.nssdb.convert_csr( signing_csr, 'pem', 'base64') subsystem.config['ca.signing.certreq'] = signing_csr # If specified, import CA signing 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: config.pki_log.info( "importing %s from %s", signing_nickname, signing_cert_file, extra=config.PKI_INDENTATION_LEVEL_2) nssdb.add_cert( nickname=signing_nickname, cert_file=signing_cert_file, trust_attributes='CT,C,C') # If specified, import certs and keys from PKCS #12 file # into NSS database. pkcs12_file = deployer.mdict['pki_external_pkcs12_path'] if pkcs12_file: config.pki_log.info( "importing certificates and keys from %s", pkcs12_file, extra=config.PKI_INDENTATION_LEVEL_2) pkcs12_password = deployer.mdict[ 'pki_external_pkcs12_password'] nssdb.import_pkcs12(pkcs12_file, pkcs12_password) # If specified, import cert chain into NSS database. # Note: Cert chain must be imported after the system certs # to ensure that the system certs are imported with # the correct nicknames. 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: config.pki_log.info( "importing certificate chain %s from %s", external_ca_cert_chain_nickname, external_ca_cert_chain_file, extra=config.PKI_INDENTATION_LEVEL_2) cert_chain, _nicks = 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 # Export CA signing 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() elif standalone and step_two: # To be implemented in ticket #1692. # Import standalone system certificates into NSS database. pass else: # self-signed CA # To be implemented in ticket #1692. # Generate self-signed CA cert. # Import self-signed CA cert into NSS database. pass finally: nssdb.close() if external and step_one: return if len(deployer.instance.tomcat_instance_subsystems()) < 2: deployer.password.create_password_conf( deployer.mdict['pki_shared_pfile'], deployer.mdict['pki_pin'], pin_sans_token=True) # only create a self signed cert for a new instance # # NOTE: ALWAYS create the temporary sslserver certificate # in the software DB regardless of whether the # instance will utilize 'softokn' or an HSM # rv = deployer.certutil.verify_certificate_exists( deployer.mdict['pki_database_path'], deployer.mdict['pki_cert_database'], deployer.mdict['pki_key_database'], deployer.mdict['pki_secmod_database'], deployer.mdict['pki_self_signed_token'], deployer.mdict['pki_self_signed_nickname'], password_file=deployer.mdict['pki_shared_pfile']) if not rv: # note: in the function below, certutil is used to generate # the request for the self signed cert. The keys are generated # by NSS, which does not actually use the data in the noise # file, so it does not matter what is in this file. Certutil # still requires it though, otherwise it waits for keyboard # input with open( deployer.mdict['pki_self_signed_noise_file'], 'w') as f: f.write("not_so_random_data") deployer.certutil.generate_self_signed_certificate( deployer.mdict['pki_database_path'], deployer.mdict['pki_cert_database'], deployer.mdict['pki_key_database'], deployer.mdict['pki_secmod_database'], deployer.mdict['pki_self_signed_token'], deployer.mdict['pki_self_signed_nickname'], deployer.mdict['pki_self_signed_subject'], deployer.mdict['pki_self_signed_serial_number'], deployer.mdict['pki_self_signed_validity_period'], deployer.mdict['pki_self_signed_issuer_name'], deployer.mdict['pki_self_signed_trustargs'], deployer.mdict['pki_self_signed_noise_file'], password_file=deployer.mdict['pki_shared_pfile']) # Delete the temporary 'noise' file deployer.file.delete( deployer.mdict['pki_self_signed_noise_file']) # Always delete the temporary 'pfile' deployer.file.delete(deployer.mdict['pki_shared_pfile']) # Start/Restart this Tomcat PKI Process # Optionally prepare to enable a java debugger # (e. g. - 'eclipse'): if config.str2bool(deployer.mdict['pki_enable_java_debugger']): config.prepare_for_an_external_java_debugger( deployer.mdict['pki_target_tomcat_conf_instance_id']) tomcat_instance_subsystems = \ len(deployer.instance.tomcat_instance_subsystems()) if tomcat_instance_subsystems == 1: deployer.systemd.start() elif tomcat_instance_subsystems > 1: deployer.systemd.restart() # wait for startup status = deployer.instance.wait_for_startup(60) if status is None: config.pki_log.error( "server failed to restart", extra=config.PKI_INDENTATION_LEVEL_2) raise Exception("server failed to restart") # Optionally wait for debugger to attach (e. g. - 'eclipse'): if config.str2bool(deployer.mdict['pki_enable_java_debugger']): config.wait_to_attach_an_external_java_debugger() def destroy(self, deployer): config.pki_log.info(log.CONFIGURATION_DESTROY_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) if len(deployer.instance.tomcat_instance_subsystems()) == 1: if deployer.directory.exists(deployer.mdict['pki_client_dir']): deployer.directory.delete(deployer.mdict['pki_client_dir'])