Exemplo n.º 1
0
    def import_certs_and_keys(self, deployer, nssdb):

        pkcs12_file = deployer.mdict.get('pki_external_pkcs12_path')
        if not pkcs12_file or not os.path.exists(pkcs12_file):
            return

        logger.info('Importing certificates and keys from %s', pkcs12_file)

        pkcs12_password = deployer.mdict['pki_external_pkcs12_password']
        nssdb.import_pkcs12(pkcs12_file, pkcs12_password)
Exemplo n.º 2
0
    def import_certs_and_keys(self, deployer, nssdb):

        pkcs12_file = deployer.mdict.get('pki_external_pkcs12_path')
        if not pkcs12_file or not os.path.exists(pkcs12_file):
            return

        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)
Exemplo n.º 3
0
    def spawn(self, deployer):

        if config.str2bool(deployer.mdict['pki_skip_installation']):
            logger.info('Skipping NSS database creation')
            return

        logger.info('Creating NSS database')

        instance = pki.server.PKIInstance(deployer.mdict['pki_instance_name'])
        instance.load()

        subsystem = instance.get_subsystem(
            deployer.mdict['pki_subsystem'].lower())

        if config.str2bool(deployer.mdict['pki_hsm_enable']):
            deployer.password.create_hsm_password_conf(
                deployer.mdict['pki_shared_password_conf'],
                deployer.mdict['pki_server_database_password'],
                deployer.mdict['pki_token_password'])
        else:
            deployer.password.create_password_conf(
                deployer.mdict['pki_shared_password_conf'],
                deployer.mdict['pki_server_database_password'])

        # Since 'certutil' does NOT strip the 'token=' portion of
        # the 'token=password' entries, create a temporary server 'pfile'
        # which ONLY contains the 'password' for the purposes of
        # allowing 'certutil' to generate the security databases
        deployer.password.create_password_conf(
            deployer.mdict['pki_shared_pfile'],
            deployer.mdict['pki_server_database_password'],
            pin_sans_token=True)
        deployer.file.modify(deployer.mdict['pki_shared_password_conf'])

        deployer.certutil.create_security_databases(
            deployer.mdict['pki_server_database_path'],
            password_file=deployer.mdict['pki_shared_pfile'])

        if config.str2bool(deployer.mdict['pki_hsm_enable']):
            deployer.modutil.register_security_module(
                deployer.mdict['pki_server_database_path'],
                deployer.mdict['pki_hsm_modulename'],
                deployer.mdict['pki_hsm_libfile'])
        pki.util.chown(deployer.mdict['pki_server_database_path'],
                       deployer.mdict['pki_uid'], deployer.mdict['pki_uid'])
        pki.util.chmod(
            deployer.mdict['pki_server_database_path'],
            config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
        os.chmod(deployer.mdict['pki_server_database_path'],
                 config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS)

        # import system certificates before starting the server

        pki_server_pkcs12_path = deployer.mdict['pki_server_pkcs12_path']
        if pki_server_pkcs12_path:

            pki_server_pkcs12_password = deployer.mdict[
                'pki_server_pkcs12_password']
            if not pki_server_pkcs12_password:
                raise Exception('Missing pki_server_pkcs12_password property.')

            nssdb = pki.nssdb.NSSDatabase(
                directory=deployer.mdict['pki_server_database_path'],
                password_file=deployer.mdict['pki_shared_pfile'])

            try:
                nssdb.import_pkcs12(pkcs12_file=pki_server_pkcs12_path,
                                    pkcs12_password=pki_server_pkcs12_password)
            finally:
                nssdb.close()

            # update external CA file (if needed)
            external_certs_path = deployer.mdict[
                'pki_server_external_certs_path']
            if external_certs_path is not None:
                self.update_external_certs_conf(external_certs_path, deployer)

        # import CA certificates from PKCS #12 file for cloning
        pki_clone_pkcs12_path = deployer.mdict['pki_clone_pkcs12_path']

        if pki_clone_pkcs12_path:

            pki_clone_pkcs12_password = deployer.mdict[
                'pki_clone_pkcs12_password']
            if not pki_clone_pkcs12_password:
                raise Exception('Missing pki_clone_pkcs12_password property.')

            nssdb = pki.nssdb.NSSDatabase(
                directory=deployer.mdict['pki_server_database_path'],
                password_file=deployer.mdict['pki_shared_pfile'])

            try:
                print('Importing certificates from %s:' %
                      pki_clone_pkcs12_path)

                # The PKCS12 class requires an NSS database to run. For simplicity
                # it uses the NSS database that has just been created.
                pkcs12 = pki.pkcs12.PKCS12(path=pki_clone_pkcs12_path,
                                           password=pki_clone_pkcs12_password,
                                           nssdb=nssdb)

                try:
                    pkcs12.show_certs()
                finally:
                    pkcs12.close()

                # Import certificates
                nssdb.import_pkcs12(pkcs12_file=pki_clone_pkcs12_path,
                                    pkcs12_password=pki_clone_pkcs12_password)

                # Set certificate trust flags
                if subsystem.type == 'CA':
                    nssdb.modify_cert(
                        nickname=deployer.mdict['pki_ca_signing_nickname'],
                        trust_attributes='CTu,Cu,Cu')

                nssdb.modify_cert(
                    nickname=deployer.mdict['pki_audit_signing_nickname'],
                    trust_attributes='u,u,Pu')

                print('Imported certificates into %s:' %
                      deployer.mdict['pki_server_database_path'])

                nssdb.show_certs()

            finally:
                nssdb.close()

        if len(deployer.instance.tomcat_instance_subsystems()) < 2:

            # Check to see if a secure connection is being used for the DS
            if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
                # Check to see if a directory server CA certificate
                # using the same nickname already exists
                #
                # NOTE:  ALWAYS use the software DB regardless of whether
                #        the instance will utilize 'softokn' or an HSM
                #
                rv = deployer.certutil.verify_certificate_exists(
                    path=deployer.mdict['pki_server_database_path'],
                    token=deployer.mdict['pki_self_signed_token'],
                    nickname=deployer.
                    mdict['pki_ds_secure_connection_ca_nickname'],
                    password_file=deployer.mdict['pki_shared_pfile'])
                if not rv:
                    # Import the directory server CA certificate
                    rv = deployer.certutil.import_cert(
                        deployer.mdict['pki_ds_secure_connection_ca_nickname'],
                        deployer.
                        mdict['pki_ds_secure_connection_ca_trustargs'],
                        deployer.mdict['pki_ds_secure_connection_ca_pem_file'],
                        password_file=deployer.mdict['pki_shared_pfile'],
                        path=deployer.mdict['pki_server_database_path'],
                        token=deployer.mdict['pki_self_signed_token'])

        # Always delete the temporary 'pfile'
        deployer.file.delete(deployer.mdict['pki_shared_pfile'])

        # Store system cert parameters in installation step to guarantee the
        # parameters exist during configuration step and to allow customization.

        certs = subsystem.find_system_certs()
        for cert in certs:

            # get CS.cfg tag and pkispawn tag
            config_tag = cert['id']
            deploy_tag = config_tag

            if config_tag == 'signing':  # for CA and OCSP
                deploy_tag = subsystem.name + '_signing'

            # store nickname
            nickname = deployer.mdict['pki_%s_nickname' % deploy_tag]
            subsystem.config['%s.%s.nickname' %
                             (subsystem.name, config_tag)] = nickname
            subsystem.config['preop.cert.%s.nickname' % config_tag] = nickname

            # store tokenname
            tokenname = deployer.mdict['pki_%s_token' % deploy_tag]
            subsystem.config['%s.%s.tokenname' %
                             (subsystem.name, config_tag)] = tokenname

            # store subject DN
            subject_dn = deployer.mdict['pki_%s_subject_dn' % deploy_tag]
            subsystem.config['preop.cert.%s.dn' % config_tag] = subject_dn

            # TODO: move more system cert params here

        # If specified in the deployment parameter, add generic CA signing cert
        # extension parameters into the CS.cfg. Generic extension for other
        # system certs can be added directly into CS.cfg after before the
        # configuration step.

        if subsystem.type == 'CA':
            if deployer.configuration_file.add_req_ext:

                subsystem.config['preop.cert.signing.ext.oid'] = \
                    deployer.configuration_file.req_ext_oid
                subsystem.config['preop.cert.signing.ext.data'] = \
                    deployer.configuration_file.req_ext_data
                subsystem.config['preop.cert.signing.ext.critical'] = \
                    deployer.configuration_file.req_ext_critical.lower()

        subsystem.save()

        # Place 'slightly' less restrictive permissions on
        # the top-level client directory ONLY

        deployer.directory.create(
            deployer.mdict['pki_client_subsystem_dir'],
            uid=0,
            gid=0,
            perms=config.PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS)

        # Since 'certutil' does NOT strip the 'token=' portion of
        # the 'token=password' entries, create a client password file
        # which ONLY contains the 'password' for the purposes of
        # allowing 'certutil' to generate the security databases

        deployer.password.create_password_conf(
            deployer.mdict['pki_client_password_conf'],
            deployer.mdict['pki_client_database_password'],
            pin_sans_token=True)

        deployer.file.modify(deployer.mdict['pki_client_password_conf'],
                             uid=0,
                             gid=0)

        # Similarly, create a simple password file containing the
        # PKCS #12 password used when exporting the 'Admin Certificate'
        # into a PKCS #12 file

        deployer.password.create_client_pkcs12_password_conf(
            deployer.mdict['pki_client_pkcs12_password_conf'])

        deployer.file.modify(deployer.mdict['pki_client_pkcs12_password_conf'])

        deployer.directory.create(deployer.mdict['pki_client_database_dir'],
                                  uid=0,
                                  gid=0)

        deployer.certutil.create_security_databases(
            deployer.mdict['pki_client_database_dir'],
            password_file=deployer.mdict['pki_client_password_conf'])
Exemplo n.º 4
0
    def spawn(self, deployer):

        if config.str2bool(deployer.mdict['pki_skip_installation']):
            logger.info('Skipping NSS database creation')
            return

        instance = self.instance
        instance.load()

        usePSSForRSASigningAlg = \
            deployer.mdict['pki_use_pss_rsa_signing_algorithm']

        if usePSSForRSASigningAlg == "True":
            self.set_signing_algs_for_pss(deployer)

        subsystem = instance.get_subsystem(deployer.mdict['pki_subsystem'].lower())

        if config.str2bool(deployer.mdict['pki_hsm_enable']):
            hsm_token = deployer.mdict['pki_token_name']
            subsystem.config['preop.module.token'] = hsm_token

        # Since 'certutil' does NOT strip the 'token=' portion of
        # the 'token=password' entries, create a temporary server 'pfile'
        # which ONLY contains the 'password' for the purposes of
        # allowing 'certutil' to generate the security databases

        logger.info('Creating password file: %s', deployer.mdict['pki_shared_pfile'])
        deployer.password.create_password_conf(
            deployer.mdict['pki_shared_pfile'],
            deployer.mdict['pki_server_database_password'], pin_sans_token=True)
        deployer.file.modify(deployer.mdict['pki_shared_password_conf'])

        if not os.path.isdir(deployer.mdict['pki_server_database_path']):
            instance.makedirs(deployer.mdict['pki_server_database_path'], force=True)

        nssdb = pki.nssdb.NSSDatabase(
            directory=deployer.mdict['pki_server_database_path'],
            password_file=deployer.mdict['pki_shared_pfile'])

        try:
            if not nssdb.exists():
                logger.info('Creating NSS database: %s',
                            deployer.mdict['pki_server_database_path'])
                nssdb.create()
        finally:
            nssdb.close()

        if not os.path.islink(deployer.mdict['pki_instance_database_link']):
            instance.symlink(
                deployer.mdict['pki_server_database_path'],
                deployer.mdict['pki_instance_database_link'],
                force=True)

        instance.symlink(
            deployer.mdict['pki_instance_database_link'],
            deployer.mdict['pki_subsystem_database_link'],
            force=True)

        if config.str2bool(deployer.mdict['pki_hsm_enable']) and \
                not nssdb.module_exists(deployer.mdict['pki_hsm_modulename']):
            nssdb.add_module(
                deployer.mdict['pki_hsm_modulename'],
                deployer.mdict['pki_hsm_libfile'])

        # Set the initial NSS database ownership and permissions.
        pki.util.chown(
            deployer.mdict['pki_server_database_path'],
            deployer.mdict['pki_uid'],
            deployer.mdict['pki_gid'])
        pki.util.chmod(
            deployer.mdict['pki_server_database_path'],
            config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
        os.chmod(
            deployer.mdict['pki_server_database_path'],
            pki.server.DEFAULT_DIR_MODE)

        # import system certificates before starting the server

        pki_server_pkcs12_path = deployer.mdict['pki_server_pkcs12_path']
        if pki_server_pkcs12_path:

            pki_server_pkcs12_password = deployer.mdict[
                'pki_server_pkcs12_password']
            if not pki_server_pkcs12_password:
                raise Exception('Missing pki_server_pkcs12_password property.')

            nssdb = pki.nssdb.NSSDatabase(
                directory=deployer.mdict['pki_server_database_path'],
                password_file=deployer.mdict['pki_shared_pfile'])

            try:
                nssdb.import_pkcs12(
                    pkcs12_file=pki_server_pkcs12_path,
                    pkcs12_password=pki_server_pkcs12_password)
            finally:
                nssdb.close()

            # update external CA file (if needed)
            external_certs_path = deployer.mdict['pki_server_external_certs_path']
            if external_certs_path is not None:
                self.update_external_certs_conf(external_certs_path, deployer)

        # import CA certificates from PKCS #12 file for cloning
        pki_clone_pkcs12_path = deployer.mdict['pki_clone_pkcs12_path']
        pki_server_database_path = deployer.mdict['pki_server_database_path']

        if pki_clone_pkcs12_path:

            pki_clone_pkcs12_password = deployer.mdict[
                'pki_clone_pkcs12_password']
            if not pki_clone_pkcs12_password:
                raise Exception('Missing pki_clone_pkcs12_password property.')

            nssdb = pki.nssdb.NSSDatabase(
                directory=pki_server_database_path,
                password_file=deployer.mdict['pki_shared_pfile'])

            try:
                print('Importing certificates from %s:' % pki_clone_pkcs12_path)

                # The PKCS12 class requires an NSS database to run. For simplicity
                # it uses the NSS database that has just been created.
                pkcs12 = pki.pkcs12.PKCS12(
                    path=pki_clone_pkcs12_path,
                    password=pki_clone_pkcs12_password,
                    nssdb=nssdb)

                try:
                    pkcs12.show_certs()
                finally:
                    pkcs12.close()

                # Import certificates
                nssdb.import_pkcs12(
                    pkcs12_file=pki_clone_pkcs12_path,
                    pkcs12_password=pki_clone_pkcs12_password)

                print('Imported certificates into %s:' %
                      pki_server_database_path)

                nssdb.show_certs()

            finally:
                nssdb.close()

            # Export CA certificate to PEM file; same command as in
            # PKIServer.setup_cert_authentication().
            # openssl pkcs12 -in <p12_file_path> -out /tmp/auth.pem -nodes -nokeys
            pki_ca_crt_path = os.path.join(pki_server_database_path, 'ca.crt')
            cmd_export_ca = [
                'openssl', 'pkcs12',
                '-in', pki_clone_pkcs12_path,
                '-out', pki_ca_crt_path,
                '-nodes',
                '-nokeys',
                '-passin', 'pass:'******'utf-8')
            logger.debug('Result of CA certificate export: %s', res_ca)

            # At this point, we're running as root. However, the subsystem
            # will eventually start up as non-root and will attempt to do a
            # migration. If we don't fix the permissions now, migration will
            # fail and subsystem won't start up.
            pki.util.chmod(pki_ca_crt_path, 0o644)
            pki.util.chown(pki_ca_crt_path, deployer.mdict['pki_uid'],
                           deployer.mdict['pki_gid'])

        ca_cert_path = deployer.mdict.get('pki_cert_chain_path')
        if ca_cert_path and os.path.exists(ca_cert_path):
            destination = os.path.join(instance.nssdb_dir, "ca.crt")
            if not os.path.exists(destination):
                # When we're passed a CA certificate file and we don't already
                # have a CA file for some reason, we need to copy the passed
                # file as the root CA certificate to establish trust in the
                # Python code. It doesn't import it into the NSS DB for Java
                # code, but so far we haven't had any issues with certificate
                # validation there. This is only usually necessary when
                # installing a non-CA subsystem on a fresh system.
                instance.copyfile(ca_cert_path, destination)

        if len(deployer.instance.tomcat_instance_subsystems()) < 2:

            # Check to see if a secure connection is being used for the DS
            if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
                # Check to see if a directory server CA certificate
                # using the same nickname already exists
                #
                # NOTE:  ALWAYS use the software DB regardless of whether
                #        the instance will utilize 'softokn' or an HSM
                #
                rv = deployer.certutil.verify_certificate_exists(
                    path=deployer.mdict['pki_server_database_path'],
                    token=deployer.mdict['pki_self_signed_token'],
                    nickname=deployer.mdict[
                        'pki_ds_secure_connection_ca_nickname'
                    ],
                    password_file=deployer.mdict['pki_shared_pfile'])
                if not rv:
                    # Import the directory server CA certificate
                    rv = deployer.certutil.import_cert(
                        deployer.mdict['pki_ds_secure_connection_ca_nickname'],
                        deployer.mdict[
                            'pki_ds_secure_connection_ca_trustargs'],
                        deployer.mdict['pki_ds_secure_connection_ca_pem_file'],
                        password_file=deployer.mdict['pki_shared_pfile'],
                        path=deployer.mdict['pki_server_database_path'],
                        token=deployer.mdict['pki_self_signed_token'])

        # Always delete the temporary 'pfile'
        deployer.file.delete(deployer.mdict['pki_shared_pfile'])

        # Store system cert parameters in installation step to guarantee the
        # parameters exist during configuration step and to allow customization.

        certs = subsystem.find_system_certs()
        for cert in certs:

            # get CS.cfg tag and pkispawn tag
            config_tag = cert['id']
            deploy_tag = config_tag

            if config_tag == 'signing':  # for CA and OCSP
                deploy_tag = subsystem.name + '_signing'

            # store nickname
            nickname = deployer.mdict['pki_%s_nickname' % deploy_tag]
            subsystem.config['%s.%s.nickname' % (subsystem.name, config_tag)] = nickname
            subsystem.config['preop.cert.%s.nickname' % config_tag] = nickname

            # store tokenname
            tokenname = deployer.mdict['pki_%s_token' % deploy_tag]
            subsystem.config['%s.%s.tokenname' % (subsystem.name, config_tag)] = tokenname

            fullname = nickname
            if pki.nssdb.normalize_token(tokenname):
                fullname = tokenname + ':' + nickname

            subsystem.config['%s.cert.%s.nickname' % (subsystem.name, config_tag)] = fullname

            # store subject DN
            subject_dn = deployer.mdict['pki_%s_subject_dn' % deploy_tag]
            subsystem.config['preop.cert.%s.dn' % config_tag] = subject_dn

            keyalgorithm = deployer.mdict['pki_%s_key_algorithm' % deploy_tag]
            subsystem.config['preop.cert.%s.keyalgorithm' % config_tag] = keyalgorithm

            signingalgorithm = deployer.mdict.get(
                'pki_%s_signing_algorithm' % deploy_tag, keyalgorithm)
            subsystem.config['preop.cert.%s.signingalgorithm' % config_tag] = signingalgorithm

            if subsystem.name == 'ca':
                if config_tag == 'signing':
                    subsystem.config['ca.signing.defaultSigningAlgorithm'] = signingalgorithm
                    subsystem.config['ca.crl.MasterCRL.signingAlgorithm'] = signingalgorithm

                elif config_tag == 'ocsp_signing':
                    subsystem.config['ca.ocsp_signing.defaultSigningAlgorithm'] = signingalgorithm

            elif subsystem.name == 'ocsp':
                if config_tag == 'signing':
                    subsystem.config['ocsp.signing.defaultSigningAlgorithm'] = signingalgorithm

            elif subsystem.name == 'kra':
                if config_tag == 'transport':
                    subsystem.config['kra.transportUnit.signingAlgorithm'] = signingalgorithm

            # TODO: move more system cert params here

        admin_dn = deployer.mdict['pki_admin_subject_dn']
        subsystem.config['preop.cert.admin.dn'] = admin_dn

        # If specified in the deployment parameter, add generic CA signing cert
        # extension parameters into the CS.cfg. Generic extension for other
        # system certs can be added directly into CS.cfg after before the
        # configuration step.

        if subsystem.type == 'CA':

            signing_nickname = subsystem.config['ca.signing.nickname']
            subsystem.config['ca.signing.certnickname'] = signing_nickname
            subsystem.config['ca.signing.cacertnickname'] = signing_nickname

            ocsp_signing_nickname = subsystem.config['ca.ocsp_signing.nickname']
            subsystem.config['ca.ocsp_signing.certnickname'] = ocsp_signing_nickname
            subsystem.config['ca.ocsp_signing.cacertnickname'] = ocsp_signing_nickname

            if deployer.configuration_file.add_req_ext:

                subsystem.config['preop.cert.signing.ext.oid'] = \
                    deployer.configuration_file.req_ext_oid
                subsystem.config['preop.cert.signing.ext.data'] = \
                    deployer.configuration_file.req_ext_data
                subsystem.config['preop.cert.signing.ext.critical'] = \
                    deployer.configuration_file.req_ext_critical.lower()

            if deployer.configuration_file.req_ski:
                subsystem.config['preop.cert.signing.subject_key_id'] = \
                    deployer.configuration_file.req_ski

        if subsystem.type == 'KRA':

            storage_nickname = subsystem.config['kra.storage.nickname']
            storage_token = subsystem.config['kra.storage.tokenname']

            if pki.nssdb.normalize_token(storage_token):
                subsystem.config['kra.storageUnit.hardware'] = storage_token
                subsystem.config['kra.storageUnit.nickName'] = \
                    storage_token + ':' + storage_nickname
            else:
                subsystem.config['kra.storageUnit.nickName'] = \
                    storage_nickname

            transport_nickname = subsystem.config['kra.transport.nickname']
            transport_token = subsystem.config['kra.transport.tokenname']

            if pki.nssdb.normalize_token(transport_token):
                subsystem.config['kra.transportUnit.nickName'] = \
                    transport_token + ':' + transport_nickname
            else:
                subsystem.config['kra.transportUnit.nickName'] = \
                    transport_nickname

        if subsystem.type == 'OCSP':

            signing_nickname = subsystem.config['ocsp.signing.nickname']
            subsystem.config['ocsp.signing.certnickname'] = signing_nickname
            subsystem.config['ocsp.signing.cacertnickname'] = signing_nickname

        audit_nickname = subsystem.config['%s.audit_signing.nickname' % subsystem.name]
        audit_token = subsystem.config['%s.audit_signing.tokenname' % subsystem.name]

        if pki.nssdb.normalize_token(audit_token):
            audit_nickname = audit_token + ':' + audit_nickname

        subsystem.config['log.instance.SignedAudit.signedAuditCertNickname'] = audit_nickname

        san_inject = config.str2bool(deployer.mdict['pki_san_inject'])
        logger.info('Injecting SAN: %s', san_inject)

        san_for_server_cert = deployer.mdict.get('pki_san_for_server_cert')
        logger.info('SSL server cert SAN: %s', san_for_server_cert)

        if san_inject and san_for_server_cert:
            subsystem.config['service.injectSAN'] = 'true'
            subsystem.config['service.sslserver.san'] = san_for_server_cert

        subsystem.save()

        # Place 'slightly' less restrictive permissions on
        # the top-level client directory ONLY

        deployer.directory.create(
            deployer.mdict['pki_client_subsystem_dir'],
            uid=0, gid=0,
            perms=config.PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS)

        # Since 'certutil' does NOT strip the 'token=' portion of
        # the 'token=password' entries, create a client password file
        # which ONLY contains the 'password' for the purposes of
        # allowing 'certutil' to generate the security databases

        logger.info('Creating password file: %s', deployer.mdict['pki_client_password_conf'])
        deployer.password.create_password_conf(
            deployer.mdict['pki_client_password_conf'],
            deployer.mdict['pki_client_database_password'], pin_sans_token=True)

        deployer.file.modify(
            deployer.mdict['pki_client_password_conf'],
            uid=0, gid=0)

        # Similarly, create a simple password file containing the
        # PKCS #12 password used when exporting the 'Admin Certificate'
        # into a PKCS #12 file

        deployer.password.create_client_pkcs12_password_conf(
            deployer.mdict['pki_client_pkcs12_password_conf'])

        deployer.file.modify(deployer.mdict['pki_client_pkcs12_password_conf'])

        pki.util.makedirs(deployer.mdict['pki_client_database_dir'], force=True)

        nssdb = pki.nssdb.NSSDatabase(
            directory=deployer.mdict['pki_client_database_dir'],
            password_file=deployer.mdict['pki_client_password_conf'])

        try:
            if not nssdb.exists():
                nssdb.create()
        finally:
            nssdb.close()
Exemplo n.º 5
0
    def spawn(self, deployer):

        if config.str2bool(deployer.mdict['pki_skip_installation']):
            logger.info('Skipping NSS database creation')
            return

        logger.info('Creating NSS database')

        instance = pki.server.PKIInstance(deployer.mdict['pki_instance_name'])
        instance.load()

        subsystem = instance.get_subsystem(
            deployer.mdict['pki_subsystem'].lower())

        if config.str2bool(deployer.mdict['pki_hsm_enable']):
            deployer.password.create_hsm_password_conf(
                deployer.mdict['pki_shared_password_conf'],
                deployer.mdict['pki_server_database_password'],
                deployer.mdict['pki_token_password'])
        else:
            deployer.password.create_password_conf(
                deployer.mdict['pki_shared_password_conf'],
                deployer.mdict['pki_server_database_password'])

        # Since 'certutil' does NOT strip the 'token=' portion of
        # the 'token=password' entries, create a temporary server 'pfile'
        # which ONLY contains the 'password' for the purposes of
        # allowing 'certutil' to generate the security databases
        deployer.password.create_password_conf(
            deployer.mdict['pki_shared_pfile'],
            deployer.mdict['pki_server_database_password'], pin_sans_token=True)
        deployer.file.modify(deployer.mdict['pki_shared_password_conf'])

        deployer.certutil.create_security_databases(
            deployer.mdict['pki_server_database_path'],
            password_file=deployer.mdict['pki_shared_pfile'])

        if config.str2bool(deployer.mdict['pki_hsm_enable']):
            deployer.modutil.register_security_module(
                deployer.mdict['pki_server_database_path'],
                deployer.mdict['pki_hsm_modulename'],
                deployer.mdict['pki_hsm_libfile'])
        pki.util.chown(
            deployer.mdict['pki_server_database_path'],
            deployer.mdict['pki_uid'],
            deployer.mdict['pki_uid'])
        pki.util.chmod(
            deployer.mdict['pki_server_database_path'],
            config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
        os.chmod(
            deployer.mdict['pki_server_database_path'],
            config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS)

        # import system certificates before starting the server

        pki_server_pkcs12_path = deployer.mdict['pki_server_pkcs12_path']
        if pki_server_pkcs12_path:

            pki_server_pkcs12_password = deployer.mdict[
                'pki_server_pkcs12_password']
            if not pki_server_pkcs12_password:
                raise Exception('Missing pki_server_pkcs12_password property.')

            nssdb = pki.nssdb.NSSDatabase(
                directory=deployer.mdict['pki_server_database_path'],
                password_file=deployer.mdict['pki_shared_pfile'])

            try:
                nssdb.import_pkcs12(
                    pkcs12_file=pki_server_pkcs12_path,
                    pkcs12_password=pki_server_pkcs12_password)
            finally:
                nssdb.close()

            # update external CA file (if needed)
            external_certs_path = deployer.mdict['pki_server_external_certs_path']
            if external_certs_path is not None:
                self.update_external_certs_conf(external_certs_path, deployer)

        # import CA certificates from PKCS #12 file for cloning
        pki_clone_pkcs12_path = deployer.mdict['pki_clone_pkcs12_path']

        if pki_clone_pkcs12_path:

            pki_clone_pkcs12_password = deployer.mdict[
                'pki_clone_pkcs12_password']
            if not pki_clone_pkcs12_password:
                raise Exception('Missing pki_clone_pkcs12_password property.')

            nssdb = pki.nssdb.NSSDatabase(
                directory=deployer.mdict['pki_server_database_path'],
                password_file=deployer.mdict['pki_shared_pfile'])

            try:
                print('Importing certificates from %s:' % pki_clone_pkcs12_path)

                # The PKCS12 class requires an NSS database to run. For simplicity
                # it uses the NSS database that has just been created.
                pkcs12 = pki.pkcs12.PKCS12(
                    path=pki_clone_pkcs12_path,
                    password=pki_clone_pkcs12_password,
                    nssdb=nssdb)

                try:
                    pkcs12.show_certs()
                finally:
                    pkcs12.close()

                # Import certificates
                nssdb.import_pkcs12(
                    pkcs12_file=pki_clone_pkcs12_path,
                    pkcs12_password=pki_clone_pkcs12_password)

                # Set certificate trust flags
                if subsystem.type == 'CA':
                    nssdb.modify_cert(
                        nickname=deployer.mdict['pki_ca_signing_nickname'],
                        trust_attributes='CTu,Cu,Cu')

                nssdb.modify_cert(
                    nickname=deployer.mdict['pki_audit_signing_nickname'],
                    trust_attributes='u,u,Pu')

                print('Imported certificates into %s:' %
                      deployer.mdict['pki_server_database_path'])

                nssdb.show_certs()

            finally:
                nssdb.close()

        if len(deployer.instance.tomcat_instance_subsystems()) < 2:

            # Check to see if a secure connection is being used for the DS
            if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
                # Check to see if a directory server CA certificate
                # using the same nickname already exists
                #
                # NOTE:  ALWAYS use the software DB regardless of whether
                #        the instance will utilize 'softokn' or an HSM
                #
                rv = deployer.certutil.verify_certificate_exists(
                    path=deployer.mdict['pki_server_database_path'],
                    token=deployer.mdict['pki_self_signed_token'],
                    nickname=deployer.mdict[
                        'pki_ds_secure_connection_ca_nickname'
                    ],
                    password_file=deployer.mdict['pki_shared_pfile'])
                if not rv:
                    # Import the directory server CA certificate
                    rv = deployer.certutil.import_cert(
                        deployer.mdict['pki_ds_secure_connection_ca_nickname'],
                        deployer.mdict[
                            'pki_ds_secure_connection_ca_trustargs'],
                        deployer.mdict['pki_ds_secure_connection_ca_pem_file'],
                        password_file=deployer.mdict['pki_shared_pfile'],
                        path=deployer.mdict['pki_server_database_path'],
                        token=deployer.mdict['pki_self_signed_token'])

        # Always delete the temporary 'pfile'
        deployer.file.delete(deployer.mdict['pki_shared_pfile'])

        # Store system cert parameters in installation step to guarantee the
        # parameters exist during configuration step and to allow customization.

        certs = subsystem.find_system_certs()
        for cert in certs:

            # get CS.cfg tag and pkispawn tag
            config_tag = cert['id']
            deploy_tag = config_tag

            if config_tag == 'signing':  # for CA and OCSP
                deploy_tag = subsystem.name + '_signing'

            # store nickname
            nickname = deployer.mdict['pki_%s_nickname' % deploy_tag]
            subsystem.config['%s.%s.nickname' % (subsystem.name, config_tag)] = nickname
            subsystem.config['preop.cert.%s.nickname' % config_tag] = nickname

            # store tokenname
            tokenname = deployer.mdict['pki_%s_token' % deploy_tag]
            subsystem.config['%s.%s.tokenname' % (subsystem.name, config_tag)] = tokenname

            # store subject DN
            subject_dn = deployer.mdict['pki_%s_subject_dn' % deploy_tag]
            subsystem.config['preop.cert.%s.dn' % config_tag] = subject_dn

            # TODO: move more system cert params here

        # If specified in the deployment parameter, add generic CA signing cert
        # extension parameters into the CS.cfg. Generic extension for other
        # system certs can be added directly into CS.cfg after before the
        # configuration step.

        if subsystem.type == 'CA':
            if deployer.configuration_file.add_req_ext:

                subsystem.config['preop.cert.signing.ext.oid'] = \
                    deployer.configuration_file.req_ext_oid
                subsystem.config['preop.cert.signing.ext.data'] = \
                    deployer.configuration_file.req_ext_data
                subsystem.config['preop.cert.signing.ext.critical'] = \
                    deployer.configuration_file.req_ext_critical.lower()

        subsystem.save()

        # Place 'slightly' less restrictive permissions on
        # the top-level client directory ONLY

        deployer.directory.create(
            deployer.mdict['pki_client_subsystem_dir'],
            uid=0, gid=0,
            perms=config.PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS)

        # Since 'certutil' does NOT strip the 'token=' portion of
        # the 'token=password' entries, create a client password file
        # which ONLY contains the 'password' for the purposes of
        # allowing 'certutil' to generate the security databases

        deployer.password.create_password_conf(
            deployer.mdict['pki_client_password_conf'],
            deployer.mdict['pki_client_database_password'], pin_sans_token=True)

        deployer.file.modify(
            deployer.mdict['pki_client_password_conf'],
            uid=0, gid=0)

        # Similarly, create a simple password file containing the
        # PKCS #12 password used when exporting the 'Admin Certificate'
        # into a PKCS #12 file

        deployer.password.create_client_pkcs12_password_conf(
            deployer.mdict['pki_client_pkcs12_password_conf'])

        deployer.file.modify(deployer.mdict['pki_client_pkcs12_password_conf'])

        deployer.directory.create(
            deployer.mdict['pki_client_database_dir'],
            uid=0, gid=0)

        deployer.certutil.create_security_databases(
            deployer.mdict['pki_client_database_dir'],
            password_file=deployer.mdict['pki_client_password_conf'])
Exemplo n.º 6
0
    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)

        # Place "slightly" less restrictive permissions on
        # the top-level client directory ONLY
        deployer.directory.create(
            deployer.mdict['pki_client_subsystem_dir'],
            uid=0,
            gid=0,
            perms=config.PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS)
        # Since 'certutil' does NOT strip the 'token=' portion of
        # the 'token=password' entries, create a client password file
        # which ONLY contains the 'password' for the purposes of
        # allowing 'certutil' to generate the security databases
        deployer.password.create_password_conf(
            deployer.mdict['pki_client_password_conf'],
            deployer.mdict['pki_client_database_password'],
            pin_sans_token=True)
        deployer.file.modify(deployer.mdict['pki_client_password_conf'],
                             uid=0,
                             gid=0)
        # Similarly, create a simple password file containing the
        # PKCS #12 password used when exporting the "Admin Certificate"
        # into a PKCS #12 file
        deployer.password.create_client_pkcs12_password_conf(
            deployer.mdict['pki_client_pkcs12_password_conf'])
        deployer.file.modify(deployer.mdict['pki_client_pkcs12_password_conf'])
        deployer.directory.create(deployer.mdict['pki_client_database_dir'],
                                  uid=0,
                                  gid=0)
        deployer.certutil.create_security_databases(
            deployer.mdict['pki_client_database_dir'],
            deployer.mdict['pki_client_cert_database'],
            deployer.mdict['pki_client_key_database'],
            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())

        ocsp_uri = deployer.mdict.get('pki_default_ocsp_uri')
        if ocsp_uri:
            subsystem.config['ca.defaultOcspUri'] = ocsp_uri
            subsystem.save()

        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
        clone = deployer.configuration_file.clone

        try:
            if external and step_one:  # external CA step 1 only

                subject_dn = subsystem.config['preop.cert.signing.dn']

                # Determine CA signing key type and algorithm

                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.

                external_csr_path = deployer.mdict['pki_external_csr_path']
                if external_csr_path:

                    config.pki_log.info(
                        "generating CA signing certificate request in %s",
                        external_csr_path,
                        extra=config.PKI_INDENTATION_LEVEL_2)

                    basic_constraints_ext = {
                        'ca': True,
                        'path_length': None,
                        'critical': True
                    }

                    key_usage_ext = {
                        'digitalSignature': True,
                        'nonRepudiation': True,
                        'certSigning': True,
                        'crlSigning': True,
                        'critical': True
                    }

                    # if specified, add generic CSR extension
                    generic_exts = None

                    if 'preop.cert.signing.ext.oid' in subsystem.config and \
                       'preop.cert.signing.ext.data' in subsystem.config:

                        data = subsystem.config['preop.cert.signing.ext.data']
                        critical = subsystem.config[
                            'preop.cert.signing.ext.critical']

                        generic_ext = {
                            'oid':
                            subsystem.config['preop.cert.signing.ext.oid'],
                            'data': binascii.unhexlify(data),
                            'critical': config.str2bool(critical)
                        }

                        generic_exts = [generic_ext]

                    nssdb.create_request(
                        subject_dn=subject_dn,
                        request_file=external_csr_path,
                        key_type=key_type,
                        key_size=key_size,
                        curve=curve,
                        hash_alg=hash_alg,
                        basic_constraints_ext=basic_constraints_ext,
                        key_usage_ext=key_usage_ext,
                        generic_exts=generic_exts)

                    with open(external_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

                # This is needed by IPA to detect step 1 completion.
                # See is_step_one_done() in ipaserver/install/cainstance.py.

                subsystem.config['preop.ca.type'] = 'otherca'

                subsystem.save()

            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()

                # verify the signing certificate
                # raises exception on  failure
                config.pki_log.info("validating the signing certificate",
                                    extra=config.PKI_INDENTATION_LEVEL_2)
                verifier = pki.server.deployment.PKIDeployer.create_system_cert_verifier(
                    instance, 'ca')
                verifier.verify_certificate('signing')

            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

        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()

        # Construct PKI Subsystem Configuration Data
        data = None
        if deployer.mdict['pki_instance_type'] == "Tomcat":
            # CA, KRA, OCSP, TKS, or TPS
            data = deployer.config_client.construct_pki_configuration_data()

        # Configure the subsystem
        response = deployer.config_client.configure_pki_data(
            json.dumps(data, cls=pki.encoder.CustomTypeEncoder))

        config.pki_log.debug(log.PKI_CONFIG_RESPONSE_STATUS + " " +
                             str(response['status']),
                             extra=config.PKI_INDENTATION_LEVEL_2)

        try:
            certs = response['systemCerts']
        except KeyError:
            # no system certs created
            config.pki_log.debug("No new system certificates generated.",
                                 extra=config.PKI_INDENTATION_LEVEL_2)
            certs = []

        if not isinstance(certs, list):
            certs = [certs]

        for cdata in certs:

            if standalone and not step_two:

                # Stand-alone PKI (Step 1)

                if cdata['tag'].lower() == "audit_signing":
                    # Save Stand-alone PKI 'Audit Signing Certificate' CSR
                    # (Step 1)
                    deployer.config_client.save_system_csr(
                        cdata['request'],
                        log.PKI_CONFIG_EXTERNAL_CSR_SAVE_PKI_AUDIT_SIGNING_1,
                        deployer.mdict['pki_external_audit_signing_csr_path'],
                        subsystem.name)

                elif cdata['tag'].lower() == "signing":
                    # Save Stand-alone PKI OCSP 'OCSP Signing Certificate'
                    # CSR (Step 1)
                    deployer.config_client.save_system_csr(
                        cdata['request'],
                        log.PKI_CONFIG_EXTERNAL_CSR_SAVE_OCSP_SIGNING,
                        deployer.mdict['pki_external_signing_csr_path'])

                elif cdata['tag'].lower() == "sslserver":
                    # Save Stand-alone PKI 'SSL Server Certificate' CSR
                    # (Step 1)
                    deployer.config_client.save_system_csr(
                        cdata['request'],
                        log.PKI_CONFIG_EXTERNAL_CSR_SAVE_PKI_SSLSERVER_1,
                        deployer.mdict['pki_external_sslserver_csr_path'],
                        subsystem.name)

                elif cdata['tag'].lower() == "storage":
                    # Save Stand-alone PKI KRA 'Storage Certificate' CSR
                    # (Step 1)
                    deployer.config_client.save_system_csr(
                        cdata['request'],
                        log.PKI_CONFIG_EXTERNAL_CSR_SAVE_KRA_STORAGE,
                        deployer.mdict['pki_external_storage_csr_path'])

                elif cdata['tag'].lower() == "subsystem":
                    # Save Stand-alone PKI 'Subsystem Certificate' CSR
                    # (Step 1)
                    deployer.config_client.save_system_csr(
                        cdata['request'],
                        log.PKI_CONFIG_EXTERNAL_CSR_SAVE_PKI_SUBSYSTEM_1,
                        deployer.mdict['pki_external_subsystem_csr_path'],
                        subsystem.name)

                elif cdata['tag'].lower() == "transport":
                    # Save Stand-alone PKI KRA 'Transport Certificate' CSR
                    # (Step 1)
                    deployer.config_client.save_system_csr(
                        cdata['request'],
                        log.PKI_CONFIG_EXTERNAL_CSR_SAVE_KRA_TRANSPORT,
                        deployer.mdict['pki_external_transport_csr_path'])

            else:
                config.pki_log.debug(log.PKI_CONFIG_CDATA_TAG + " " +
                                     cdata['tag'],
                                     extra=config.PKI_INDENTATION_LEVEL_2)
                config.pki_log.debug(log.PKI_CONFIG_CDATA_CERT + "\n" +
                                     cdata['cert'],
                                     extra=config.PKI_INDENTATION_LEVEL_2)
                config.pki_log.debug(log.PKI_CONFIG_CDATA_REQUEST + "\n" +
                                     cdata['request'],
                                     extra=config.PKI_INDENTATION_LEVEL_2)

        # Cloned PKI subsystems do not return an Admin Certificate
        if not clone:

            if standalone:
                if not step_two:
                    # NOTE:  Do nothing for Stand-alone PKI (Step 1)
                    #        as this has already been addressed
                    #        in 'set_admin_parameters()'
                    pass
                else:
                    admin_cert = response['adminCert']['cert']
                    deployer.config_client.process_admin_cert(admin_cert)

            elif not config.str2bool(deployer.mdict['pki_import_admin_cert']):
                admin_cert = response['adminCert']['cert']
                deployer.config_client.process_admin_cert(admin_cert)

        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 not config.str2bool(
                deployer.mdict['pki_restart_configured_instance']):
            return

        deployer.systemd.restart()

        # wait for startup
        status = None

        if deployer.fips.is_fips_enabled():
            # must use 'http' protocol when FIPS mode is enabled
            status = deployer.instance.wait_for_startup(
                60, secure_connection=False)

        else:
            status = deployer.instance.wait_for_startup(60,
                                                        secure_connection=True)

        if not status:
            config.pki_log.error("server failed to restart",
                                 extra=config.PKI_INDENTATION_LEVEL_1)
            raise RuntimeError("server failed to restart")