Esempio n. 1
0
    def get_subsystem_cert(self, cert_id):

        logger.info('Getting %s cert info for %s', cert_id, self.name)

        nickname = self.config.get('%s.%s.nickname' % (self.name, cert_id))
        token = self.config.get('%s.%s.tokenname' % (self.name, cert_id))

        cert = {}
        cert['id'] = cert_id
        cert['nickname'] = nickname
        cert['token'] = token
        cert['data'] = self.config.get('%s.%s.cert' % (self.name, cert_id),
                                       None)
        cert['request'] = self.config.get(
            '%s.%s.certreq' % (self.name, cert_id), None)
        cert['certusage'] = self.config.get(
            '%s.cert.%s.certusage' % (self.name, cert_id), None)

        if not nickname:
            return cert

        nssdb = self.instance.open_nssdb(token)
        try:
            cert_info = nssdb.get_cert_info(nickname)
            if cert_info:
                cert.update(cert_info)
        finally:
            nssdb.close()

        return cert
Esempio n. 2
0
    def generate_ca_signing_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_ca_signing_csr_path')
        if not csr_path:
            return

        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]

        tag = 'signing'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            deployer.generate_csr(
                nssdb,
                subsystem,
                tag,
                csr_path,
                basic_constraints_ext=basic_constraints_ext,
                key_usage_ext=key_usage_ext,
                generic_exts=generic_exts,
                subject_key_id=deployer.configuration_file.req_ski,
            )

        finally:
            nssdb.close()
Esempio n. 3
0
    def import_perm_sslserver_cert(self, instance, sslserver):

        nickname = sslserver['nickname']
        token = sslserver['token']

        config.pki_log.info(
            "importing permanent SSL server cert into %s token: %s",
            token,
            nickname,
            extra=config.PKI_INDENTATION_LEVEL_2)

        tmpdir = tempfile.mkdtemp()
        nssdb = instance.open_nssdb(token)

        try:
            pem_cert = pki.nssdb.convert_cert(sslserver['data'], 'base64',
                                              'pem')

            cert_file = os.path.join(tmpdir, 'sslserver.crt')
            with open(cert_file, 'w') as f:
                f.write(pem_cert)

            nssdb.add_cert(nickname=nickname, cert_file=cert_file)

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Esempio n. 4
0
    def remove_temp_sslserver_cert(self, instance, sslserver):

        # TODO: replace with pki-server cert-import sslserver

        nickname = sslserver['nickname']
        token = sslserver['token']

        config.pki_log.info(
            "removing temp SSL server cert from internal token: %s",
            nickname,
            extra=config.PKI_INDENTATION_LEVEL_2)

        nssdb = instance.open_nssdb()

        try:
            # Remove temp SSL server cert from internal token.
            # Remove temp key too if the perm cert uses HSM.
            if pki.nssdb.normalize_token(token):
                remove_key = True
            else:
                remove_key = False
            nssdb.remove_cert(nickname=nickname, remove_key=remove_key)

        finally:
            nssdb.close()
Esempio n. 5
0
    def remove_temp_sslserver_cert(self, deployer, instance, sslserver):

        if len(deployer.instance.tomcat_instance_subsystems()) == 1:
            # Modify contents of 'serverCertNick.conf' (if necessary)
            deployer.servercertnick_conf.modify()

        # TODO: replace with pki-server cert-import sslserver

        nickname = sslserver['nickname']
        token = deployer.mdict['pki_token_name']

        config.pki_log.info(
            "removing temp SSL server cert from internal token: %s",
            nickname,
            extra=config.PKI_INDENTATION_LEVEL_2)

        nssdb = instance.open_nssdb()

        try:
            # Remove temp SSL server cert from internal token.
            # Remove temp key too if the perm cert uses HSM.
            if not token or token == 'internal':
                remove_key = False
            else:
                remove_key = True
            nssdb.remove_cert(nickname, remove_key=remove_key)

        finally:
            nssdb.close()
Esempio n. 6
0
    def migrate_nssdb(self, instance):

        if not os.path.exists(instance.nssdb_dir):
            return

        logger.info('Migrating %s instance to NSS SQL database', instance.name)

        nssdb = instance.open_nssdb()

        try:
            # Only attempt to convert if target format is sql and DB is dbm
            if nssdb.needs_conversion():
                nssdb.convert_db()
        finally:
            nssdb.close()

        ca_path = os.path.join(instance.nssdb_dir, 'ca.crt')
        token = pki.nssdb.INTERNAL_TOKEN_NAME
        nickname = instance.get_sslserver_cert_nickname()
        if ':' in nickname:
            token = nickname.split(':', 1)[0]

        # Re-open NSS DB with correct token name
        nssdb = instance.open_nssdb(token=token)

        try:
            nssdb.extract_ca_cert(ca_path, nickname)
        finally:
            nssdb.close()
Esempio n. 7
0
    def create_nssdb(self, force=False):

        logger.info('Creating %s', self.nssdb_dir)

        if force and os.path.exists(self.nssdb_dir):
            logger.warning('NSS database already exists: %s', self.nssdb_dir)
            return

        self.makedirs(self.nssdb_dir, force=force)

        logger.info('Creating %s', self.nssdb_link)
        self.symlink(self.nssdb_dir, self.nssdb_link, force=force)

        password = self.passwords.get(pki.nssdb.INTERNAL_TOKEN_NAME)

        nssdb = pki.nssdb.NSSDatabase(
            directory=self.nssdb_dir,
            password=password)

        try:
            nssdb.create()
        finally:
            nssdb.close()

        pki.util.chown(self.nssdb_dir, self.uid, self.gid)
Esempio n. 8
0
    def import_perm_sslserver_cert(self, deployer, instance, cert):

        nickname = cert['nickname']
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        logger.info(
            'Importing permanent SSL server cert into %s token: %s',
            token, nickname)

        tmpdir = tempfile.mkdtemp()
        nssdb = instance.open_nssdb(token)

        try:
            pem_cert = pki.nssdb.convert_cert(cert['data'], 'base64', 'pem')

            cert_file = os.path.join(tmpdir, 'sslserver.crt')
            with open(cert_file, 'w') as f:
                f.write(pem_cert)

            nssdb.add_cert(
                nickname=nickname,
                cert_file=cert_file)

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Esempio n. 9
0
    def generate_audit_signing_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_audit_signing_csr_path')
        if not csr_path:
            return

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

        tag = 'audit_signing'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            self.generate_csr(deployer,
                              nssdb,
                              subsystem,
                              tag,
                              csr_path,
                              key_usage_ext=key_usage_ext)

        finally:
            nssdb.close()
Esempio n. 10
0
    def get_subsystem_cert(self, cert_id):

        logger.info('Getting %s cert info for %s', cert_id, self.name)

        nickname = self.config.get('%s.%s.nickname' % (self.name, cert_id))
        token = self.config.get('%s.%s.tokenname' % (self.name, cert_id))

        cert = {}
        cert['id'] = cert_id
        cert['nickname'] = nickname
        cert['token'] = token
        cert['data'] = self.config.get(
            '%s.%s.cert' % (self.name, cert_id), None)
        cert['request'] = self.config.get(
            '%s.%s.certreq' % (self.name, cert_id), None)
        cert['certusage'] = self.config.get(
            '%s.cert.%s.certusage' % (self.name, cert_id), None)

        if not nickname:
            return cert

        nssdb = self.instance.open_nssdb(token)
        try:
            cert_info = nssdb.get_cert_info(nickname)
            if cert_info:
                cert.update(cert_info)
        finally:
            nssdb.close()

        return cert
Esempio n. 11
0
File: keygen.py Progetto: tiran/pki
    def generate_ca_signing_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_ca_signing_csr_path')
        if not csr_path:
            return

        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]

        tag = 'signing'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            self.generate_csr(
                deployer,
                nssdb,
                subsystem,
                tag,
                csr_path,
                basic_constraints_ext=basic_constraints_ext,
                key_usage_ext=key_usage_ext,
                generic_exts=generic_exts
            )

        finally:
            nssdb.close()
Esempio n. 12
0
File: keygen.py Progetto: tiran/pki
    def generate_audit_signing_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_audit_signing_csr_path')
        if not csr_path:
            return

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

        tag = 'audit_signing'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            self.generate_csr(
                deployer,
                nssdb,
                subsystem,
                tag,
                csr_path,
                key_usage_ext=key_usage_ext
            )

        finally:
            nssdb.close()
Esempio n. 13
0
    def create_subsystem_cert_object(self, cert_id):

        nickname = self.config.get('%s.%s.nickname' % (self.name, cert_id))

        cert = {}
        cert['id'] = cert_id
        cert['nickname'] = nickname
        cert['token'] = self.config.get(
            '%s.%s.tokenname' % (self.name, cert_id), None)
        cert['data'] = self.config.get(
            '%s.%s.cert' % (self.name, cert_id), None)
        cert['request'] = self.config.get(
            '%s.%s.certreq' % (self.name, cert_id), None)
        cert['certusage'] = self.config.get(
            '%s.cert.%s.certusage' % (self.name, cert_id), None)

        if not nickname:
            return cert

        nssdb = self.instance.open_nssdb()
        try:
            cert_info = nssdb.get_cert_info(nickname)
            cert.update(cert_info)
        finally:
            nssdb.close()

        return cert
Esempio n. 14
0
File: keygen.py Progetto: tiran/pki
    def generate_ocsp_signing_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_ocsp_signing_csr_path')
        if not csr_path:
            return

        tag = 'signing'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            self.generate_csr(
                deployer,
                nssdb,
                subsystem,
                tag,
                csr_path
            )

        finally:
            nssdb.close()
Esempio n. 15
0
    def generate_ocsp_signing_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_ocsp_signing_csr_path')
        if not csr_path:
            return

        tag = 'signing'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            self.generate_csr(
                deployer,
                nssdb,
                subsystem,
                tag,
                csr_path
            )

        finally:
            nssdb.close()
Esempio n. 16
0
    def remove_temp_sslserver_cert(self, instance, sslserver):

        # TODO: replace with pki-server cert-import sslserver

        nickname = sslserver['nickname']
        token = sslserver['token']

        logger.info(
            'Removing temp SSL server cert from internal token: %s',
            nickname)

        nssdb = instance.open_nssdb()

        try:
            # Remove temp SSL server cert from internal token.
            # Remove temp key too if the perm cert uses HSM.
            if pki.nssdb.normalize_token(token):
                remove_key = True
            else:
                remove_key = False
            nssdb.remove_cert(
                nickname=nickname,
                remove_key=remove_key)

        finally:
            nssdb.close()
Esempio n. 17
0
    def cert_del(self, cert_id, remove_key=False):
        """
        Delete a cert from NSS db

        :param cert_id: Cert ID
        :type cert_id: str
        :param remove_key: Remove associate private key
        :type remove_key: bool
        """

        subsystem_name, cert_tag = pki.server.PKIServer.split_cert_id(cert_id)

        if not subsystem_name:
            subsystem_name = self.get_subsystems()[0].name

        subsystem = self.get_subsystem(subsystem_name)

        cert = subsystem.get_subsystem_cert(cert_tag)
        nssdb = self.open_nssdb()

        try:
            logger.debug('Removing %s certificate from NSS database from '
                         'subsystem %s in instance %s', cert_tag, subsystem.name, self.name)
            nssdb.remove_cert(
                nickname=cert['nickname'],
                token=cert['token'],
                remove_key=remove_key)
        finally:
            nssdb.close()
Esempio n. 18
0
 def remove_cert(self, instance, nickname, token):
     nssdb = instance.open_nssdb()
     try:
         nssdb.remove_cert(
             nickname=nickname,
             token=token)
     finally:
         nssdb.close()
Esempio n. 19
0
 def remove_cert(self, instance, nickname, token):
     nssdb = instance.open_nssdb()
     try:
         nssdb.remove_cert(
             nickname=nickname,
             token=token)
     finally:
         nssdb.close()
Esempio n. 20
0
    def get_nssdb_cert_info(self, cert_id):

        logger.info('Getting %s cert info for %s from NSS database', cert_id, self.name)

        nickname = self.config.get('%s.%s.nickname' % (self.name, cert_id))
        token = self.config.get('%s.%s.tokenname' % (self.name, cert_id))

        nssdb = self.instance.open_nssdb()
        try:
            return nssdb.get_cert_info(nickname, token=token)
        finally:
            nssdb.close()
Esempio n. 21
0
    def replace_sslserver_cert(self, deployer, instance, sslserver):

        if len(deployer.instance.tomcat_instance_subsystems()) == 1:
            # Modify contents of 'serverCertNick.conf' (if necessary)
            deployer.servercertnick_conf.modify()

        # TODO: replace with pki-server cert-import sslserver

        nickname = sslserver['nickname']

        config.pki_log.info(
            "removing temp SSL server cert from internal token: %s",
            nickname,
            extra=config.PKI_INDENTATION_LEVEL_2)

        nssdb = instance.open_nssdb()

        try:
            # remove temp SSL server cert but keep the key
            nssdb.remove_cert(nickname)

        finally:
            nssdb.close()

        token = deployer.mdict['pki_token_name']

        config.pki_log.info(
            "importing permanent SSL server cert into %s token: %s",
            token,
            nickname,
            extra=config.PKI_INDENTATION_LEVEL_2)

        tmpdir = tempfile.mkdtemp()
        nssdb = instance.open_nssdb(token)

        try:
            pem_cert = pki.nssdb.convert_cert(sslserver['cert'], 'base64',
                                              'pem')

            cert_file = os.path.join(tmpdir, 'sslserver.crt')
            with open(cert_file, 'w') as f:
                f.write(pem_cert)

            nssdb.add_cert(nickname, cert_file)

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Esempio n. 22
0
 def cert_del(self, cert_tag, remove_key=False):
     """
     Delete a cert from NSS db
     :param cert_tag: Cert Tag
     :param remove_key: Remove associate private key
     """
     cert = self.get_subsystem_cert(cert_tag)
     nssdb = self.instance.open_nssdb()
     try:
         logger.debug('Removing %s certificate from NSS database for '
                      'subsystem %s instance %s', cert_tag, self.name, self.instance)
         nssdb.remove_cert(
             nickname=cert['nickname'],
             token=cert['token'],
             remove_key=remove_key)
     finally:
         nssdb.close()
Esempio n. 23
0
    def generate_subsystem_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_subsystem_csr_path')
        if not csr_path:
            return

        key_usage_ext = {
            'digitalSignature': True,
            'nonRepudiation': True,
            'keyEncipherment': True,
            'dataEncipherment': True,
            'critical': True
        }

        extended_key_usage_ext = {
            'serverAuth': True,
            'clientAuth': True
        }

        tag = 'subsystem'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            self.generate_csr(
                deployer,
                nssdb,
                subsystem,
                tag,
                csr_path,
                key_usage_ext=key_usage_ext,
                extended_key_usage_ext=extended_key_usage_ext
            )

        finally:
            nssdb.close()
Esempio n. 24
0
File: keygen.py Progetto: tiran/pki
    def generate_subsystem_csr(self, deployer, subsystem):

        csr_path = deployer.mdict.get('pki_subsystem_csr_path')
        if not csr_path:
            return

        key_usage_ext = {
            'digitalSignature': True,
            'nonRepudiation': True,
            'keyEncipherment': True,
            'dataEncipherment': True,
            'critical': True
        }

        extended_key_usage_ext = {
            'serverAuth': True,
            'clientAuth': True
        }

        tag = 'subsystem'
        cert = subsystem.get_subsystem_cert(tag)
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        nssdb = subsystem.instance.open_nssdb(token)

        try:
            self.generate_csr(
                deployer,
                nssdb,
                subsystem,
                tag,
                csr_path,
                key_usage_ext=key_usage_ext,
                extended_key_usage_ext=extended_key_usage_ext
            )

        finally:
            nssdb.close()
Esempio n. 25
0
    def import_perm_sslserver_cert(self, deployer, instance, cert):

        nickname = cert['nickname']
        token = pki.nssdb.normalize_token(cert['token'])

        if not token:
            token = deployer.mdict['pki_token_name']

        logger.info('Importing permanent SSL server cert into %s token: %s',
                    token, nickname)

        tmpdir = tempfile.mkdtemp()
        nssdb = instance.open_nssdb(token)

        try:
            pem_cert = pki.nssdb.convert_cert(cert['data'], 'base64', 'pem')

            cert_file = os.path.join(tmpdir, 'sslserver.crt')
            with open(cert_file, 'w') as f:
                f.write(pem_cert)

            nssdb.add_cert(nickname=nickname, cert_file=cert_file)

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)

        # Reset the NSS database ownership and permissions
        # after importing the permanent SSL server cert
        # since it might create new files.
        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)
Esempio n. 26
0
    def spawn(self, deployer):

        external = deployer.configuration_file.external
        standalone = deployer.configuration_file.standalone
        step_one = deployer.configuration_file.external_step_one
        skip_configuration = deployer.configuration_file.skip_configuration

        if (external or standalone) and step_one or skip_configuration:
            logger.info('Skipping configuration')
            return

        logger.info('Configuring subsystem')

        try:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = \
                int(os.environ['PKISPAWN_STARTUP_TIMEOUT_SECONDS'])
        except (KeyError, ValueError):
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60
        if PKISPAWN_STARTUP_TIMEOUT_SECONDS <= 0:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60

        instance = self.instance
        instance.load()

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

        # configure internal database
        subsystem.config['internaldb.ldapconn.host'] = deployer.mdict['pki_ds_hostname']

        if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
            subsystem.config['internaldb.ldapconn.secureConn'] = 'true'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict['pki_ds_ldaps_port']
        else:
            subsystem.config['internaldb.ldapconn.secureConn'] = 'false'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict['pki_ds_ldap_port']

        subsystem.config['internaldb.ldapauth.bindDN'] = deployer.mdict['pki_ds_bind_dn']
        subsystem.config['internaldb.basedn'] = deployer.mdict['pki_ds_base_dn']
        subsystem.config['internaldb.database'] = deployer.mdict['pki_ds_database']

        if config.str2bool(deployer.mdict['pki_share_db']):
            subsystem.config['preop.internaldb.dbuser'] = deployer.mdict['pki_share_dbuser_dn']

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

        if subsystem.name == 'ca':
            serial_number_range_start = deployer.mdict.get('pki_serial_number_range_start')
            if serial_number_range_start:
                subsystem.config['dbs.beginSerialNumber'] = serial_number_range_start

            serial_number_range_end = deployer.mdict.get('pki_serial_number_range_end')
            if serial_number_range_end:
                subsystem.config['dbs.endSerialNumber'] = serial_number_range_end

            request_number_range_start = deployer.mdict.get('pki_request_number_range_start')
            if request_number_range_start:
                subsystem.config['dbs.beginRequestNumber'] = request_number_range_start

            request_number_range_end = deployer.mdict.get('pki_request_number_range_end')
            if request_number_range_end:
                subsystem.config['dbs.endRequestNumber'] = request_number_range_end

            replica_number_range_start = deployer.mdict.get('pki_replica_number_range_start')
            if replica_number_range_start:
                subsystem.config['dbs.beginReplicaNumber'] = replica_number_range_start

            replica_number_range_end = deployer.mdict.get('pki_replica_number_range_end')
            if replica_number_range_end:
                subsystem.config['dbs.endReplicaNumber'] = replica_number_range_end

        if subsystem.name == 'kra':
            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
                logger.debug('Setting ephemeral requests to true')
                subsystem.config['kra.ephemeralRequests'] = 'true'

        if subsystem.name == 'tps':
            baseDN = subsystem.config['internaldb.basedn']
            dsHost = subsystem.config['internaldb.ldapconn.host']
            dsPort = subsystem.config['internaldb.ldapconn.port']

            subsystem.config['tokendb.activityBaseDN'] = 'ou=Activities,' + baseDN
            subsystem.config['tokendb.baseDN'] = 'ou=Tokens,' + baseDN
            subsystem.config['tokendb.certBaseDN'] = 'ou=Certificates,' + baseDN
            subsystem.config['tokendb.userBaseDN'] = baseDN
            subsystem.config['tokendb.hostport'] = dsHost + ':' + dsPort

        subsystem.save()

        token = pki.nssdb.normalize_token(deployer.mdict['pki_token_name'])
        nssdb = instance.open_nssdb()

        existing = deployer.configuration_file.existing
        step_two = deployer.configuration_file.external_step_two
        clone = deployer.configuration_file.clone

        try:
            if existing or (external or standalone) and step_two:

                self.import_system_cert_requests(deployer, subsystem)
                self.import_system_certs(deployer, nssdb, subsystem)

                self.configure_system_certs(deployer, subsystem)
                self.update_system_certs(deployer, nssdb, subsystem)
                subsystem.save()

                self.validate_system_certs(deployer, nssdb, subsystem)

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

        create_temp_sslserver_cert = self.create_temp_sslserver_cert(deployer, instance)

        server_config = instance.get_server_config()
        unsecurePort = server_config.get_unsecure_port()
        securePort = server_config.get_secure_port()

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            logger.info('Joining existing domain')

            deployer.join_domain()

            subsystem.config['securitydomain.name'] = deployer.domain_info.id
            subsystem.config['securitydomain.select'] = 'existing'

            # hostname and ports point to security domain
            subsystem.config['securitydomain.host'] = deployer.sd_host.Hostname
            subsystem.config['securitydomain.httpport'] = deployer.sd_host.Port
            subsystem.config['securitydomain.httpseeport'] = deployer.sd_host.SecurePort
            subsystem.config['securitydomain.httpsadminport'] = deployer.sd_host.SecureAdminPort
            subsystem.config['securitydomain.httpsagentport'] = deployer.sd_host.SecureAgentPort

        elif config.str2bool(deployer.mdict['pki_subordinate']) and \
                config.str2bool(deployer.mdict['pki_subordinate_create_new_security_domain']):

            logger.info('Creating new security subdomain')

            deployer.join_domain()

            sd_name = deployer.mdict['pki_subordinate_security_domain_name']
            subsystem.config['securitydomain.name'] = sd_name
            subsystem.config['securitydomain.select'] = 'new'

            # hostname and ports point to current host
            subsystem.config['securitydomain.host'] = deployer.mdict['pki_hostname']
            subsystem.config['securitydomain.httpport'] = unsecurePort
            subsystem.config['securitydomain.httpsagentport'] = securePort
            subsystem.config['securitydomain.httpseeport'] = securePort
            subsystem.config['securitydomain.httpsadminport'] = securePort

        else:

            logger.info('Creating new security domain')

            sd_name = deployer.mdict['pki_security_domain_name']
            subsystem.config['securitydomain.name'] = sd_name
            subsystem.config['securitydomain.select'] = 'new'

            # hostname and ports point to current host
            subsystem.config['securitydomain.host'] = deployer.mdict['pki_hostname']
            subsystem.config['securitydomain.httpport'] = unsecurePort
            subsystem.config['securitydomain.httpsagentport'] = securePort
            subsystem.config['securitydomain.httpseeport'] = securePort
            subsystem.config['securitydomain.httpsadminport'] = securePort

        subsystem.config['service.securityDomainPort'] = securePort

        hierarchy = subsystem.config.get('hierarchy.select')
        issuing_ca = deployer.mdict['pki_issuing_ca']

        if not (subsystem.type == 'CA' and hierarchy == 'Root'):

            if not external and not standalone:

                logger.info('Using CA at %s', issuing_ca)

                url = urllib.parse.urlparse(issuing_ca)

                subsystem.config['preop.ca.url'] = issuing_ca
                subsystem.config['preop.ca.hostname'] = url.hostname
                subsystem.config['preop.ca.httpsport'] = str(url.port)
                subsystem.config['preop.ca.httpsadminport'] = str(url.port)

        system_certs_imported = \
            deployer.mdict['pki_server_pkcs12_path'] != '' or \
            deployer.mdict['pki_clone_pkcs12_path'] != ''

        if not (subsystem.type == 'CA' and hierarchy == 'Root'):

            if external or standalone:
                subsystem.config['preop.ca.pkcs7'] = ''

            elif not clone and not system_certs_imported:

                logger.info('Retrieving CA certificate chain from %s', issuing_ca)

                pem_chain = self.get_cert_chain(instance, issuing_ca)
                base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
                subsystem.config['preop.ca.pkcs7'] = base64_chain

                logger.info('Importing CA certificate chain')

                nssdb = instance.open_nssdb()
                try:
                    nssdb.import_pkcs7(pkcs7_data=pem_chain, trust_attributes='CT,C,C')
                finally:
                    nssdb.close()

        if subsystem.type == 'CA' and clone and not system_certs_imported:

            clone_uri = deployer.mdict['pki_clone_uri']

            logger.info('Retrieving CA certificate chain from %s', clone_uri)

            pem_chain = self.get_cert_chain(instance, clone_uri)
            base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
            subsystem.config['preop.clone.pkcs7'] = base64_chain

            logger.info('Importing CA certificate chain')

            nssdb = instance.open_nssdb()
            try:
                nssdb.import_pkcs7(pkcs7_data=pem_chain, trust_attributes='CT,C,C')
            finally:
                nssdb.close()

        subsystem.save()

        if config.str2bool(deployer.mdict['pki_ds_remove_data']):

            if config.str2bool(deployer.mdict['pki_ds_create_new_db']):
                logger.info('Removing existing database')
                subsystem.remove_database(force=True)

            elif not config.str2bool(deployer.mdict['pki_clone']) or \
                    config.str2bool(deployer.mdict['pki_clone_setup_replication']):
                logger.info('Emptying existing database')
                subsystem.empty_database(force=True)

            else:
                logger.info('Reusing replicated database')

        logger.info('Initializing database')

        # In most cases, we want to replicate the schema and therefore not add it here.
        # We provide this option though in case the clone already has schema
        # and we want to replicate back to the master.

        # On the other hand, if we are not setting up replication,
        # then we are assuming that replication is already taken care of,
        # and schema has already been replicated.

        setup_schema = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) or \
            not config.str2bool(deployer.mdict['pki_clone_replicate_schema'])

        create_database = config.str2bool(deployer.mdict['pki_ds_create_new_db'])

        # When cloning a subsystem without setting up the replication agreements,
        # the database is a subtree of an existing tree and is already replicated,
        # so there is no need to set up the base entry.

        create_base = config.str2bool(deployer.mdict['pki_ds_create_new_db']) or \
            not config.str2bool(deployer.mdict['pki_clone']) or \
            config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        create_containers = not config.str2bool(deployer.mdict['pki_clone'])

        # If the database is already replicated but not yet indexed, rebuild the indexes.

        rebuild_indexes = config.str2bool(deployer.mdict['pki_clone']) and \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) and \
            config.str2bool(deployer.mdict['pki_clone_reindex_data'])

        setup_db_manager = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        # If setting up replication, set up VLV indexes after replication.

        setup_vlv_indexes = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        subsystem.init_database(
            setup_schema=setup_schema,
            create_database=create_database,
            create_base=create_base,
            create_containers=create_containers,
            rebuild_indexes=rebuild_indexes,
            setup_db_manager=setup_db_manager,
            setup_vlv_indexes=setup_vlv_indexes)

        # 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:
            logger.info('Starting server')
            instance.start()

        elif tomcat_instance_subsystems > 1:
            logger.info('Restarting server')
            instance.restart()

        # Configure status request timeout.  This is used for each
        # status request in wait_for_startup
        value = deployer.mdict['pki_status_request_timeout']
        if len(value) == 0:
            status_request_timeout = None
        else:
            status_request_timeout = int(value)
            if status_request_timeout <= 0:
                raise ValueError("timeout must be greater than zero")

        deployer.instance.wait_for_startup(
            subsystem,
            PKISPAWN_STARTUP_TIMEOUT_SECONDS,
            request_timeout=status_request_timeout,
        )

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

        connection = pki.client.PKIConnection(
            protocol='https',
            hostname=deployer.mdict['pki_hostname'],
            port=deployer.mdict['pki_https_port'],
            trust_env=False)

        client = pki.system.SystemConfigClient(
            connection,
            subsystem=deployer.mdict['pki_subsystem_type'])

        # If pki_one_time_pin is not already defined, load from CS.cfg
        if 'pki_one_time_pin' not in deployer.mdict:
            deployer.mdict['pki_one_time_pin'] = subsystem.config['preop.pin']

        logger.info('Configuring %s subsystem', subsystem.type)

        request = deployer.config_client.create_config_request()
        client.configure(request)

        if clone:

            logger.info('Setting up clone')

            clone_setup_request = deployer.config_client.create_clone_setup_request(subsystem)
            clone_setup_request.domainInfo = deployer.domain_info
            clone_setup_request.installToken = deployer.install_token
            client.setupClone(clone_setup_request)

        logger.info('Setting up database')

        database_setup_request = deployer.config_client.create_database_setup_request()
        client.setupDatabase(database_setup_request)

        sslserver = subsystem.get_subsystem_cert('sslserver')

        for tag in subsystem.config['preop.cert.list'].split(','):

            logger.info('Setting up %s certificate', tag)
            cert = deployer.setup_cert(client, tag)

            if not cert:
                continue

            logger.debug('- cert: %s', cert['cert'])
            logger.debug('- request: %s', cert['request'])

            if tag == 'sslserver':
                sslserver['data'] = cert['cert']
                sslserver['request'] = cert['request']
                sslserver['token'] = cert['token']

        if not clone:

            logger.info('Setting up admin user')
            deployer.setup_admin(client)

        if config.str2bool(deployer.mdict['pki_backup_keys']):

            # by default store the backup file in the NSS databases directory
            if not deployer.mdict['pki_backup_file']:
                deployer.mdict['pki_backup_file'] = \
                    deployer.mdict['pki_server_database_path'] + '/' + \
                    deployer.mdict['pki_subsystem'].lower() + '_backup_keys.p12'

            logger.info('Backing up keys into %s', deployer.mdict['pki_backup_file'])
            deployer.backup_keys(instance, subsystem)

        logger.info('Setting up security domain')
        sd_setup_request = deployer.config_client.create_security_domain_setup_request()
        sd_setup_request.domainInfo = deployer.domain_info
        sd_setup_request.installToken = deployer.install_token
        client.setupSecurityDomain(sd_setup_request)

        if not config.str2bool(deployer.mdict['pki_share_db']):
            logger.info('Setting up database user')
            db_user_setup_request = deployer.config_client.create_database_user_setup_request()
            client.setupDatabaseUser(db_user_setup_request)

        logger.info('Finalizing %s configuration', subsystem.type)
        finalize_config_request = deployer.config_client.create_finalize_config_request()
        finalize_config_request.domainInfo = deployer.domain_info
        finalize_config_request.installToken = deployer.install_token
        client.finalizeConfiguration(finalize_config_request)

        if subsystem.type == 'TPS':
            logger.info('Setting up shared secret')
            deployer.setup_shared_secret(instance, subsystem)

        logger.info('%s configuration complete', subsystem.type)

        # Create an empty file that designates the fact that although
        # this server instance has been configured, it has NOT yet
        # been restarted!

        restart_server = os.path.join(instance.conf_dir, 'restart_server_after_configuration')
        logger.debug('Creating %s', restart_server)

        open(restart_server, 'a').close()
        os.chown(restart_server, instance.uid, instance.gid)
        os.chmod(restart_server, 0o660)

        # If temp SSL server cert was created and there's a new perm cert,
        # replace it with the perm cert.
        if create_temp_sslserver_cert and sslserver and sslserver['data']:
            logger.info('Stopping server')
            instance.stop()

            # Remove temp SSL server cert.
            self.remove_temp_sslserver_cert(instance, sslserver)

            # Import perm SSL server cert unless it's already imported
            # earlier in external/standalone installation.

            if not (standalone or external and subsystem.name in ['kra', 'ocsp']):

                nickname = sslserver['nickname']
                token = pki.nssdb.normalize_token(sslserver['token'])

                if not token:
                    token = deployer.mdict['pki_token_name']

                instance.set_sslserver_cert_nickname(nickname, token)

                self.import_perm_sslserver_cert(deployer, instance, sslserver)

            logger.info('Starting server')
            instance.start()

        elif config.str2bool(deployer.mdict['pki_restart_configured_instance']):
            logger.info('Restarting server')
            instance.restart()

        deployer.instance.wait_for_startup(
            subsystem,
            PKISPAWN_STARTUP_TIMEOUT_SECONDS,
            request_timeout=status_request_timeout,
        )
Esempio n. 27
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'])
Esempio n. 28
0
    def create_temp_sslserver_cert(self, deployer, instance):

        if len(deployer.instance.tomcat_instance_subsystems()) > 1:
            return False

        nickname = deployer.mdict['pki_sslserver_nickname']
        instance.set_sslserver_cert_nickname(nickname)

        tmpdir = tempfile.mkdtemp()
        nssdb = instance.open_nssdb()

        try:
            logger.info('Checking existing SSL server cert: %s', nickname)
            pem_cert = nssdb.get_cert(nickname=nickname)

            if pem_cert:
                cert = x509.load_pem_x509_certificate(pem_cert, default_backend())
                cn = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0]
                hostname = cn.value

                logger.info('Existing SSL server cert is for %s', hostname)

                # if hostname is correct, don't create temp cert
                if hostname == deployer.mdict['pki_hostname']:
                    return False

                logger.info('Removing SSL server cert for %s', hostname)

                nssdb.remove_cert(
                    nickname=nickname,
                    remove_key=True)

            logger.info('Creating temp SSL server cert for %s', deployer.mdict['pki_hostname'])

            # TODO: replace with pki-server create-cert sslserver --temp

            # NOTE:  ALWAYS create the temporary sslserver certificate
            #        in the software DB regardless of whether the
            #        instance will utilize 'softokn' or an HSM

            csr_file = os.path.join(tmpdir, 'sslserver.csr')
            cert_file = os.path.join(tmpdir, 'sslserver.crt')

            nssdb.create_request(
                subject_dn=deployer.mdict['pki_self_signed_subject'],
                request_file=csr_file,
                token=deployer.mdict['pki_self_signed_token'],
                key_type=deployer.mdict['pki_sslserver_key_type'],
                key_size=deployer.mdict['pki_sslserver_key_size']
            )

            nssdb.create_cert(
                request_file=csr_file,
                cert_file=cert_file,
                serial=deployer.mdict['pki_self_signed_serial_number'],
                validity=deployer.mdict['pki_self_signed_validity_period']
            )

            nssdb.add_cert(
                nickname=nickname,
                cert_file=cert_file,
                token=deployer.mdict['pki_self_signed_token'],
                trust_attributes=deployer.mdict['pki_self_signed_trustargs']
            )

            return True

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Esempio n. 29
0
    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=', 'append',
                'no-trust-flags', 'no-key', 'no-chain', 'verbose', 'debug',
                'help'
            ])

        except getopt.GetoptError as e:
            print('ERROR: ' + str(e))
            self.print_help()
            sys.exit(1)

        instance_name = 'pki-tomcat'
        cert_file = None
        csr_file = None
        pkcs12_file = None
        pkcs12_password = None
        pkcs12_password_file = None
        append = False
        include_trust_flags = True
        include_key = True
        include_chain = True
        debug = False

        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 == '--append':
                append = True

            elif o == '--no-trust-flags':
                include_trust_flags = False

            elif o == '--no-key':
                include_key = False

            elif o == '--no-chain':
                include_chain = False

            elif o in ('-v', '--verbose'):
                self.set_verbose(True)

            elif o == '--debug':
                debug = True

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                print('ERROR: unknown option ' + o)
                self.print_help()
                sys.exit(1)

        if len(args) < 1:
            print('ERROR: missing subsystem ID')
            self.print_help()
            sys.exit(1)

        subsystem_name = args[0]

        if not (cert_file or csr_file or pkcs12_file):
            print('ERROR: missing output file')
            self.print_help()
            sys.exit(1)

        instance = pki.server.PKIInstance(instance_name)

        if not instance.is_valid():
            print('ERROR: Invalid instance %s.' % instance_name)
            sys.exit(1)

        instance.load()

        subsystem = instance.get_subsystem(subsystem_name)
        if not subsystem:
            print('ERROR: No %s subsystem in instance '
                  '%s.' % (subsystem_name, instance_name))
            sys.exit(1)
        subsystem_cert = None

        if len(args) >= 2:
            cert_id = args[1]
            subsystem_cert = subsystem.get_subsystem_cert(cert_id)

        if (cert_file or csr_file) and not subsystem_cert:
            print('ERROR: missing cert ID')
            self.print_help()
            sys.exit(1)

        if cert_file:
            cert_data = subsystem_cert.get('data', None)
            if cert_data is None:
                print("ERROR: Unable to find certificate data for %s" %
                      cert_id)
                sys.exit(1)

            cert_data = pki.nssdb.convert_cert(cert_data, 'base64', 'pem')
            with open(cert_file, 'w') as f:
                f.write(cert_data)

        if csr_file:
            cert_request = subsystem_cert.get('request', None)
            if cert_request is None:
                print("ERROR: Unable to find certificate request for %s" %
                      cert_id)
                sys.exit(1)

            csr_data = pki.nssdb.convert_csr(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: ')

            nicknames = []

            if subsystem_cert:
                nicknames.append(subsystem_cert['nickname'])

            else:
                subsystem_certs = subsystem.find_system_certs()
                for subsystem_cert in subsystem_certs:
                    nicknames.append(subsystem_cert['nickname'])

            nssdb = instance.open_nssdb()
            try:
                nssdb.export_pkcs12(pkcs12_file=pkcs12_file,
                                    pkcs12_password=pkcs12_password,
                                    pkcs12_password_file=pkcs12_password_file,
                                    nicknames=nicknames,
                                    append=append,
                                    include_trust_flags=include_trust_flags,
                                    include_key=include_key,
                                    include_chain=include_chain,
                                    debug=debug)

            finally:
                nssdb.close()
Esempio n. 30
0
    def create_temp_sslserver_cert(self, deployer, instance, token):

        if len(deployer.instance.tomcat_instance_subsystems()) > 1:
            return False

        nssdb = instance.open_nssdb(token)

        try:
            nickname = deployer.mdict['pki_self_signed_nickname']

            config.pki_log.info("checking existing SSL server cert: %s",
                                nickname,
                                extra=config.PKI_INDENTATION_LEVEL_2)

            pem_cert = nssdb.get_cert(nickname)

            if pem_cert:
                cert = x509.load_pem_x509_certificate(pem_cert,
                                                      default_backend())
                cn = cert.subject.get_attributes_for_oid(
                    NameOID.COMMON_NAME)[0]
                hostname = cn.value

                config.pki_log.info("existing SSL server cert is for %s",
                                    hostname,
                                    extra=config.PKI_INDENTATION_LEVEL_2)

                # if hostname is correct, don't create temp cert
                if hostname == deployer.mdict['pki_hostname']:
                    return False

                config.pki_log.info("removing SSL server cert for %s",
                                    hostname,
                                    extra=config.PKI_INDENTATION_LEVEL_2)

                nssdb.remove_cert(nickname, remove_key=True)

            config.pki_log.info("creating temp SSL server cert for %s",
                                deployer.mdict['pki_hostname'],
                                extra=config.PKI_INDENTATION_LEVEL_2)

            # TODO: replace with pki-server create-cert sslserver --temp

            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
            #
            # 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'])

            return True

        finally:
            nssdb.close()
Esempio n. 31
0
    def cert_create(
            self, cert_id=None,
            username=None, password=None,
            client_cert=None, client_nssdb=None,
            client_nssdb_pass=None, client_nssdb_pass_file=None,
            serial=None, temp_cert=False, renew=False, output=None,
            secure_port='8443'):
        """
        Create a new cert for the cert_id provided

        :param cert_id: New cert's ID
        :type cert_id: str
        :param username: Username (must also supply password)
        :type username: str
        :param password: Password (must also supply username)
        :type password: str
        :param client_cert: Client cert nickname
        :type client_cert: str
        :param client_nssdb: Path to nssdb
        :type client_nssdb: str
        :param client_nssdb_pass: Password to the nssdb
        :type client_nssdb_pass: str
        :param client_nssdb_pass_file: File containing nssdb's password
        :type client_nssdb_pass_file: str
        :param serial: Serial number of the cert to be renewed.  If creating
                       a temporary certificate (temp_cert == True), the serial
                       number will be reused.  If not supplied, the cert_id is
                       used to look it up.
        :type serial: str
        :param temp_cert: Whether new cert is a temporary cert
        :type temp_cert: bool
        :param renew: Whether to place a renewal request to ca
        :type renew: bool
        :param output: Path to which new cert needs to be written to
        :type output: str
        :param secure_port: Secure port number in case of renewing a certificate
        :type secure_port: str
        :return: None
        :rtype: None
        :raises pki.server.PKIServerException

        Either supply both username and password, or supply
        client_cert and (client_nssdb_pass or client_nssdb_pass_file).

        Note that client_nssdb should be specified in either case, as it
        contains the CA Certificate.
        """
        nssdb = self.open_nssdb()
        tmpdir = tempfile.mkdtemp()
        subsystem = None  # used for system certs

        try:
            if cert_id:
                new_cert_file = output if output else self.cert_file(cert_id)

                subsystem_name, cert_tag = pki.server.PKIServer.split_cert_id(cert_id)
                if not subsystem_name:
                    subsystem_name = self.get_subsystems()[0].name
                subsystem = self.get_subsystem(subsystem_name)

                if serial is None:
                    # If admin doesn't provide a serial number, set the serial to
                    # the same serial number available in the nssdb
                    serial = subsystem.get_subsystem_cert(cert_tag)["serial_number"]

            else:
                if serial is None:
                    raise pki.server.PKIServerException(
                        "Must provide either 'cert_id' or 'serial'")
                if output is None:
                    raise pki.server.PKIServerException(
                        "Must provide 'output' when renewing by serial")
                if temp_cert:
                    raise pki.server.PKIServerException(
                        "'temp_cert' must be used with 'cert_id'")
                new_cert_file = output

            if not os.path.exists(self.cert_folder):
                os.makedirs(self.cert_folder)

            if temp_cert:
                assert subsystem is not None  # temp_cert only supported with cert_id

                logger.info('Trying to create a new temp cert for %s.', cert_id)

                # Create Temp Cert and write it to new_cert_file
                subsystem.temp_cert_create(nssdb, tmpdir, cert_tag, serial, new_cert_file)

                logger.info('Temp cert for %s is available at %s.', cert_id, new_cert_file)

            else:
                # Create permanent certificate
                if not renew:
                    # TODO: Support rekey
                    raise pki.server.PKIServerException('Rekey is not supported yet.')

                logger.info('Trying to setup a secure connection to CA subsystem.')
                if username and password:
                    connection = pki.server.PKIServer.setup_password_authentication(
                        username, password, subsystem_name='ca', secure_port=secure_port,
                        client_nssdb=client_nssdb)
                else:
                    if not client_cert:
                        raise pki.server.PKIServerException('Client cert nick name required.')
                    if not client_nssdb_pass and not client_nssdb_pass_file:
                        raise pki.server.PKIServerException('NSS db password required.')
                    connection = pki.server.PKIServer.setup_cert_authentication(
                        client_nssdb_pass=client_nssdb_pass,
                        client_cert=client_cert,
                        client_nssdb_pass_file=client_nssdb_pass_file,
                        client_nssdb=client_nssdb,
                        tmpdir=tmpdir,
                        secure_port=secure_port
                    )
                logger.info('Secure connection with CA is established.')

                logger.info('Placing cert creation request for serial: %s', serial)
                pki.server.PKIServer.renew_certificate(connection, new_cert_file, serial)
                logger.info('New cert is available at: %s', new_cert_file)

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Esempio n. 32
0
File: cert.py Progetto: tiran/pki
    def execute(self, argv):

        logging.basicConfig(format='%(levelname)s: %(message)s')

        try:
            opts, args = getopt.gnu_getopt(argv, 'i:v', [
                'instance=', 'show-all', 'pretty-print',
                'verbose', 'debug', 'help'])

        except getopt.GetoptError as e:
            logger.error(e)
            self.print_help()
            sys.exit(1)

        instance_name = 'pki-tomcat'
        show_all = False
        pretty_print = False

        for o, a in opts:
            if o in ('-i', '--instance'):
                instance_name = a

            elif o == '--show-all':
                show_all = True

            elif o == '--pretty-print':
                pretty_print = True

            elif o in ('-v', '--verbose'):
                self.set_verbose(True)
                logging.getLogger().setLevel(logging.INFO)

            elif o == '--debug':
                self.set_verbose(True)
                self.set_debug(True)
                logging.getLogger().setLevel(logging.DEBUG)

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                logger.error('option %s not recognized', o)
                self.print_help()
                sys.exit(1)

        if len(args) < 1:
            logger.error('Missing cert ID.')
            self.print_help()
            sys.exit(1)

        cert_id = args[0]

        instance = server.PKIInstance(instance_name)

        if not instance.is_valid():
            logger.error('Invalid instance %s.', instance_name)
            sys.exit(1)

        instance.load()

        subsystem_name, cert_tag = server.PKIServer.split_cert_id(cert_id)

        # If cert ID is instance specific, get it from first subsystem
        if not subsystem_name:
            subsystem_name = instance.subsystems[0].name

        subsystem = instance.get_subsystem(subsystem_name)

        if not subsystem:
            logger.error(
                'No %s subsystem in instance %s.',
                subsystem_name, instance_name)
            sys.exit(1)

        cert = subsystem.get_subsystem_cert(cert_tag)
        CertCLI.print_system_cert(cert, show_all)

        if pretty_print:
            nssdb = instance.open_nssdb()
            try:
                output = nssdb.get_cert(
                    nickname=cert['nickname'],
                    token=cert['token'],
                    output_format='pretty-print')

                print()
                print(output)

            finally:
                nssdb.close()
Esempio n. 33
0
File: cert.py Progetto: tiran/pki
    def execute(self, argv):

        logging.basicConfig(format='%(levelname)s: %(message)s')

        try:
            opts, args = getopt.gnu_getopt(argv, 'i:d:c:C:n:v', [
                'instance=', 'temp', 'serial=',
                'output=', 'renew',
                'verbose', 'debug', 'help'])

        except getopt.GetoptError as e:
            logger.error(e)
            self.print_help()
            sys.exit(1)

        instance_name = 'pki-tomcat'
        create_temp_cert = False
        serial = None
        client_nssdb_location = os.getenv('HOME') + '/.dogtag/nssdb'
        client_nssdb_password = None
        client_nssdb_pass_file = None
        client_cert = None
        output = None
        renew = False
        connection = None

        for o, a in opts:
            if o in ('-i', '--instance'):
                instance_name = a

            elif o == '-d':
                client_nssdb_location = a

            elif o == '-c':
                client_nssdb_password = a

            elif o == '-C':
                client_nssdb_pass_file = a

            elif o == '-n':
                client_cert = a

            elif o == '--temp':
                create_temp_cert = True

            elif o == '--serial':
                # string containing the dec or hex value for the identifier
                serial = str(int(a, 0))

            elif o == '--output':
                output = a

            elif o == '--renew':
                renew = True

            elif o in ('-v', '--verbose'):
                self.set_verbose(True)
                logging.getLogger().setLevel(logging.INFO)

            elif o == '--debug':
                self.set_verbose(True)
                self.set_debug(True)
                logging.getLogger().setLevel(logging.DEBUG)

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                logger.error('option %s not recognized', o)
                self.print_help()
                sys.exit(1)

        if len(args) < 1:
            logger.error('Missing cert ID.')
            self.print_help()
            sys.exit(1)

        if not create_temp_cert:
            # For permanent certificate, password of NSS db is required.
            if not client_nssdb_password and not client_nssdb_pass_file:
                logger.error('NSS database password is required.')
                self.print_help()
                sys.exit(1)

        cert_id = args[0]

        instance = server.PKIInstance(instance_name)

        if not instance.is_valid():
            logger.error('Invalid instance %s.', instance_name)
            sys.exit(1)

        # Load the instance. Default: pki-tomcat
        instance.load()

        subsystem_name = None
        cert_tag = cert_id

        if cert_id == 'sslserver' or cert_id == 'subsystem':
            subsystem_name = None
            cert_tag = cert_id

        else:
            parts = cert_id.split('_', 1)
            subsystem_name = parts[0]
            cert_tag = parts[1]

        # If cert ID is instance specific, get it from first subsystem
        if not subsystem_name:
            subsystem_name = instance.subsystems[0].name

        subsystem = instance.get_subsystem(subsystem_name)

        if not subsystem:
            logger.error(
                'No %s subsystem in instance %s.',
                subsystem_name, instance_name)
            sys.exit(1)

        nssdb = instance.open_nssdb()
        tmpdir = tempfile.mkdtemp()
        try:
            cert_folder = os.path.join(pki.CONF_DIR, instance_name, 'certs')
            if not os.path.exists(cert_folder):
                os.makedirs(cert_folder)
            new_cert_file = os.path.join(cert_folder, cert_id + '.crt')

            if output:
                new_cert_file = output

            if create_temp_cert:
                if not serial:
                    # If admin doesn't provide a serial number, find the highest in NSS db
                    # and add 1 to it
                    serial = 0
                    for sub in instance.subsystems:
                        for n_cert in sub.find_system_certs():
                            if int(n_cert['serial_number']) > serial:
                                serial = int(n_cert['serial_number'])

                    # Add 1 and then rewrap it as a string
                    serial = str(serial + 1)

            else:
                # Create permanent certificate
                if not renew:
                    # Fixme: Support rekey
                    raise Exception('Rekey is not supported yet.')

                # Create a secure connection to CA
                connection = server.PKIServer.setup_authentication(
                    c_nssdb_pass=client_nssdb_password,
                    c_cert=client_cert,
                    c_nssdb_pass_file=client_nssdb_pass_file,
                    c_nssdb=client_nssdb_location,
                    tmpdir=tmpdir,
                    subsystem_name='ca')

            if cert_tag == 'sslserver':
                self.create_ssl_cert(subsystem=subsystem,
                                     is_temp_cert=create_temp_cert,
                                     new_cert_file=new_cert_file, nssdb=nssdb, serial=serial,
                                     tmpdir=tmpdir, connection=connection)

            elif cert_tag == 'subsystem':
                self.create_subsystem_cert(is_temp_cert=create_temp_cert, serial=serial,
                                           subsystem=subsystem, new_cert_file=new_cert_file,
                                           connection=connection)

            elif cert_id in ['ca_ocsp_signing', 'ocsp_signing']:
                self.create_ocsp_cert(is_temp_cert=create_temp_cert, serial=serial,
                                      subsystem=subsystem, new_cert_file=new_cert_file,
                                      connection=connection)

            elif cert_tag == 'audit_signing':
                self.create_audit_cert(is_temp_cert=create_temp_cert, serial=serial,
                                       subsystem=subsystem, new_cert_file=new_cert_file,
                                       connection=connection)

            else:
                # renewal not yet supported
                raise Exception('Renewal for %s not yet supported.' % cert_id)

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Esempio n. 34
0
File: cert.py Progetto: tiran/pki
    def execute(self, argv):

        logging.basicConfig(format='%(levelname)s: %(message)s')

        try:
            opts, args = getopt.gnu_getopt(argv, 'i:v', [
                'instance=', 'cert-file=', 'csr-file=',
                'pkcs12-file=', 'pkcs12-password='******'pkcs12-password-file=',
                'friendly-name=',
                'cert-encryption=', 'key-encryption=',
                'append', 'no-trust-flags', 'no-key', 'no-chain',
                'verbose', 'debug', 'help'])

        except getopt.GetoptError as e:
            logger.error(e)
            self.print_help()
            sys.exit(1)

        instance_name = 'pki-tomcat'
        cert_file = None
        csr_file = None
        pkcs12_file = None
        pkcs12_password = None
        pkcs12_password_file = None
        friendly_name = None
        cert_encryption = None
        key_encryption = None
        append = False
        include_trust_flags = True
        include_key = True
        include_chain = True

        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 == '--friendly-name':
                friendly_name = a

            elif o == '--cert-encryption':
                cert_encryption = a

            elif o == '--key-encryption':
                key_encryption = a

            elif o == '--append':
                append = True

            elif o == '--no-trust-flags':
                include_trust_flags = False

            elif o == '--no-key':
                include_key = False

            elif o == '--no-chain':
                include_chain = False

            elif o in ('-v', '--verbose'):
                self.set_verbose(True)
                logging.getLogger().setLevel(logging.INFO)

            elif o == '--debug':
                self.set_verbose(True)
                self.set_debug(True)
                logging.getLogger().setLevel(logging.DEBUG)

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                logger.error('option %s not recognized', o)
                self.print_help()
                sys.exit(1)

        if len(args) < 1:
            logger.error('Missing cert ID.')
            self.print_help()
            sys.exit(1)

        cert_id = args[0]

        if not (cert_file or csr_file or pkcs12_file):
            logger.error('missing output file')
            self.print_help()
            sys.exit(1)

        instance = server.PKIInstance(instance_name)

        if not instance.is_valid():
            logger.error('Invalid instance %s.', instance_name)
            sys.exit(1)

        instance.load()

        subsystem_name, cert_tag = server.PKIServer.split_cert_id(cert_id)

        # If cert ID is instance specific, get it from first subsystem
        if not subsystem_name:
            subsystem_name = instance.subsystems[0].name

        subsystem = instance.get_subsystem(subsystem_name)

        if not subsystem:
            logger.error(
                'No %s subsystem in instance %s.',
                subsystem_name, instance_name)
            sys.exit(1)

        cert = subsystem.get_subsystem_cert(cert_tag)

        if not cert:
            logger.error('missing %s certificate', cert_id)
            self.print_help()
            sys.exit(1)

        if cert_id == 'sslserver':
            # get nickname and token from serverCertNick.conf
            full_name = instance.get_sslserver_cert_nickname()
            i = full_name.find(':')
            if i < 0:
                nickname = full_name
                token = None

            else:
                nickname = full_name[i + 1:]
                token = full_name[:i]

        else:
            # get nickname and token from CS.cfg
            nickname = cert['nickname']
            token = cert['token']

        logger.info('Nickname: %s', nickname)
        logger.info('Token: %s', token)

        nssdb = instance.open_nssdb(token)

        try:
            if cert_file:

                logger.info('Exporting %s certificate into %s.', cert_id, cert_file)

                cert_data = cert.get('data', None)
                if cert_data is None:
                    logger.error('Unable to find certificate data for %s', cert_id)
                    sys.exit(1)

                cert_data = pki.nssdb.convert_cert(cert_data, 'base64', 'pem')
                with open(cert_file, 'w') as f:
                    f.write(cert_data)

            if csr_file:

                logger.info('Exporting %s CSR into %s.', cert_id, csr_file)

                cert_request = cert.get('request', None)
                if cert_request is None:
                    logger.error('Unable to find certificate request for %s', cert_id)
                    sys.exit(1)

                csr_data = pki.nssdb.convert_csr(cert_request, 'base64', 'pem')
                with open(csr_file, 'w') as f:
                    f.write(csr_data)

            if pkcs12_file:

                logger.info('Exporting %s certificate and key into %s.', cert_id, pkcs12_file)

                if not pkcs12_password and not pkcs12_password_file:
                    pkcs12_password = getpass.getpass(prompt='Enter password for PKCS #12 file: ')

                logger.info('Friendly name: %s', friendly_name)

                nssdb.export_cert(
                    nickname=nickname,
                    pkcs12_file=pkcs12_file,
                    pkcs12_password=pkcs12_password,
                    pkcs12_password_file=pkcs12_password_file,
                    friendly_name=friendly_name,
                    cert_encryption=cert_encryption,
                    key_encryption=key_encryption,
                    append=append,
                    include_trust_flags=include_trust_flags,
                    include_key=include_key,
                    include_chain=include_chain,
                    debug=self.debug)

        finally:
            nssdb.close()
Esempio n. 35
0
    def execute(self, argv):

        try:
            opts, args = getopt.gnu_getopt(argv, 'i:v', [
                'instance=',
                'pkcs12-file=', 'pkcs12-password='******'pkcs12-password-file=',
                'append', 'no-trust-flags', 'no-key', 'no-chain',
                'verbose', 'debug', 'help'])

        except getopt.GetoptError as e:
            print('ERROR: ' + str(e))
            self.print_help()
            sys.exit(1)

        nicknames = args

        instance_name = 'pki-tomcat'
        pkcs12_file = None
        pkcs12_password = None
        pkcs12_password_file = None
        append = False
        include_trust_flags = True
        include_key = True
        include_chain = True
        debug = False

        for o, a in opts:
            if o in ('-i', '--instance'):
                instance_name = 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 == '--append':
                append = True

            elif o == '--no-trust-flags':
                include_trust_flags = False

            elif o == '--no-key':
                include_key = False

            elif o == '--no-chain':
                include_chain = False

            elif o in ('-v', '--verbose'):
                self.set_verbose(True)

            elif o == '--debug':
                debug = True

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                print('ERROR: unknown option ' + o)
                self.print_help()
                sys.exit(1)

        if not pkcs12_file:
            print('ERROR: missing output file')
            self.print_help()
            sys.exit(1)

        instance = pki.server.PKIInstance(instance_name)

        if not instance.is_valid():
            print('ERROR: Invalid instance %s.' % instance_name)
            sys.exit(1)

        instance.load()

        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,
                pkcs12_password=pkcs12_password,
                pkcs12_password_file=pkcs12_password_file,
                nicknames=nicknames,
                append=append,
                include_trust_flags=include_trust_flags,
                include_key=include_key,
                include_chain=include_chain,
                debug=debug)
        finally:
            nssdb.close()
Esempio n. 36
0
    def spawn(self, deployer):

        try:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = \
                int(os.environ['PKISPAWN_STARTUP_TIMEOUT_SECONDS'])
        except (KeyError, ValueError):
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60
        if PKISPAWN_STARTUP_TIMEOUT_SECONDS <= 0:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60

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

        # set ephemeral requests if needed
        if subsystem.name == 'kra':
            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
                config.pki_log.info("setting ephemeral requests to true",
                                    extra=config.PKI_INDENTATION_LEVEL_1)
                subsystem.config['kra.ephemeralRequests'] = 'true'
                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 or standalone) and step_one:

                self.generate_system_cert_requests(deployer, nssdb, subsystem)

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

                # End of step 1.
                return

            if existing or (external or standalone) and step_two:

                self.import_system_cert_requests(deployer, subsystem)
                self.import_system_certs(deployer, nssdb, subsystem)

                self.configure_system_certs(deployer, subsystem)
                self.update_system_certs(deployer, nssdb, subsystem)
                subsystem.save()

                self.validate_system_certs(deployer, nssdb, subsystem)

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

        create_temp_sslserver_cert = self.create_temp_sslserver_cert(
            deployer, instance, token)

        # 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(
            PKISPAWN_STARTUP_TIMEOUT_SECONDS)
        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
        nssdb = instance.open_nssdb(token)
        try:
            data = deployer.config_client.construct_pki_configuration_data(
                nssdb)

        finally:
            nssdb.close()

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

        # Create an empty file that designates the fact that although
        # this server instance has been configured, it has NOT yet
        # been restarted!

        restart_server = os.path.join(instance.conf_dir,
                                      'restart_server_after_configuration')
        config.pki_log.debug('creating %s',
                             restart_server,
                             extra=config.PKI_INDENTATION_LEVEL_2)

        open(restart_server, 'a').close()
        os.chown(restart_server, instance.uid, instance.gid)
        os.chmod(restart_server, 0o660)

        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]

        sslserver = None

        for cdata in certs:

            if cdata['tag'] == 'sslserver':
                sslserver = cdata

            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_2,
                        deployer.mdict['pki_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_1,
                        deployer.mdict['pki_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_2,
                        deployer.mdict['pki_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_1,
                        deployer.mdict['pki_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_2,
                        deployer.mdict['pki_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_1,
                        deployer.mdict['pki_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 external or 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 temp SSL server cert was created and there's a new perm cert,
        # replace it with the perm cert.
        if create_temp_sslserver_cert and sslserver and sslserver['cert']:
            deployer.systemd.stop()
            self.replace_sslserver_cert(deployer, instance, sslserver)
            deployer.systemd.start()

        elif config.str2bool(
                deployer.mdict['pki_restart_configured_instance']):
            # Optionally, programmatically 'restart' the configured PKI instance
            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(
                PKISPAWN_STARTUP_TIMEOUT_SECONDS, secure_connection=False)

        else:
            status = deployer.instance.wait_for_startup(
                PKISPAWN_STARTUP_TIMEOUT_SECONDS, 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")
Esempio n. 37
0
    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=',
                'append', 'no-trust-flags', 'no-key', 'no-chain',
                'verbose', 'debug', 'help'])

        except getopt.GetoptError as e:
            print('ERROR: ' + str(e))
            self.print_help()
            sys.exit(1)

        instance_name = 'pki-tomcat'
        cert_file = None
        csr_file = None
        pkcs12_file = None
        pkcs12_password = None
        pkcs12_password_file = None
        append = False
        include_trust_flags = True
        include_key = True
        include_chain = True
        debug = False

        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 == '--append':
                append = True

            elif o == '--no-trust-flags':
                include_trust_flags = False

            elif o == '--no-key':
                include_key = False

            elif o == '--no-chain':
                include_chain = False

            elif o in ('-v', '--verbose'):
                self.set_verbose(True)

            elif o == '--debug':
                debug = True

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                print('ERROR: unknown option ' + o)
                self.print_help()
                sys.exit(1)

        if len(args) < 1:
            print('ERROR: missing subsystem ID')
            self.print_help()
            sys.exit(1)

        subsystem_name = args[0]

        if not (cert_file or csr_file or pkcs12_file):
            print('ERROR: missing output file')
            self.print_help()
            sys.exit(1)

        instance = pki.server.PKIInstance(instance_name)

        if not instance.is_valid():
            print('ERROR: Invalid instance %s.' % instance_name)
            sys.exit(1)

        instance.load()

        subsystem = instance.get_subsystem(subsystem_name)
        if not subsystem:
            print('ERROR: No %s subsystem in instance '
                  '%s.' % (subsystem_name, instance_name))
            sys.exit(1)
        subsystem_cert = None

        if len(args) >= 2:
            cert_id = args[1]
            subsystem_cert = subsystem.get_subsystem_cert(cert_id)

        if (cert_file or csr_file) and not subsystem_cert:
            print('ERROR: missing cert ID')
            self.print_help()
            sys.exit(1)

        if cert_file:
            cert_data = subsystem_cert.get('data', None)
            if cert_data is None:
                print("ERROR: Unable to find certificate data for %s" % cert_id)
                sys.exit(1)

            cert_data = pki.nssdb.convert_cert(cert_data, 'base64', 'pem')
            with open(cert_file, 'w') as f:
                f.write(cert_data)

        if csr_file:
            cert_request = subsystem_cert.get('request', None)
            if cert_request is None:
                print("ERROR: Unable to find certificate request for %s" % cert_id)
                sys.exit(1)

            csr_data = pki.nssdb.convert_csr(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: ')

            nicknames = []

            if subsystem_cert:
                nicknames.append(subsystem_cert['nickname'])

            else:
                subsystem_certs = subsystem.find_system_certs()
                for subsystem_cert in subsystem_certs:
                    nicknames.append(subsystem_cert['nickname'])

            nssdb = instance.open_nssdb()
            try:
                nssdb.export_pkcs12(
                    pkcs12_file=pkcs12_file,
                    pkcs12_password=pkcs12_password,
                    pkcs12_password_file=pkcs12_password_file,
                    nicknames=nicknames,
                    append=append,
                    include_trust_flags=include_trust_flags,
                    include_key=include_key,
                    include_chain=include_chain,
                    debug=debug)

            finally:
                nssdb.close()
Esempio n. 38
0
    def spawn(self, deployer):

        external = deployer.configuration_file.external
        standalone = deployer.configuration_file.standalone
        step_one = deployer.configuration_file.external_step_one
        skip_configuration = deployer.configuration_file.skip_configuration

        if (external or standalone) and step_one or skip_configuration:
            logger.info('Skipping configuration')
            return

        logger.info('Configuring subsystem')

        instance = self.instance
        instance.load()

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

        # configure internal database
        subsystem.config['internaldb.ldapconn.host'] = deployer.mdict['pki_ds_hostname']

        if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
            subsystem.config['internaldb.ldapconn.secureConn'] = 'true'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict['pki_ds_ldaps_port']
        else:
            subsystem.config['internaldb.ldapconn.secureConn'] = 'false'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict['pki_ds_ldap_port']

        subsystem.config['internaldb.ldapauth.bindDN'] = deployer.mdict['pki_ds_bind_dn']
        subsystem.config['internaldb.basedn'] = deployer.mdict['pki_ds_base_dn']
        subsystem.config['internaldb.database'] = deployer.mdict['pki_ds_database']

        if config.str2bool(deployer.mdict['pki_share_db']):
            subsystem.config['preop.internaldb.dbuser'] = deployer.mdict['pki_share_dbuser_dn']

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

        deployer.configure_id_generators(subsystem)

        if subsystem.name == 'ca':
            serial_number_range_start = deployer.mdict.get('pki_serial_number_range_start')
            if serial_number_range_start:
                subsystem.config['dbs.beginSerialNumber'] = serial_number_range_start

            serial_number_range_end = deployer.mdict.get('pki_serial_number_range_end')
            if serial_number_range_end:
                subsystem.config['dbs.endSerialNumber'] = serial_number_range_end

            request_number_range_start = deployer.mdict.get('pki_request_number_range_start')
            if request_number_range_start:
                subsystem.config['dbs.beginRequestNumber'] = request_number_range_start

            request_number_range_end = deployer.mdict.get('pki_request_number_range_end')
            if request_number_range_end:
                subsystem.config['dbs.endRequestNumber'] = request_number_range_end

            replica_number_range_start = deployer.mdict.get('pki_replica_number_range_start')
            if replica_number_range_start:
                subsystem.config['dbs.beginReplicaNumber'] = replica_number_range_start

            replica_number_range_end = deployer.mdict.get('pki_replica_number_range_end')
            if replica_number_range_end:
                subsystem.config['dbs.endReplicaNumber'] = replica_number_range_end

        if subsystem.name == 'kra':
            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
                logger.debug('Setting ephemeral requests to true')
                subsystem.config['kra.ephemeralRequests'] = 'true'

        if subsystem.name == 'tps':
            baseDN = subsystem.config['internaldb.basedn']
            dsHost = subsystem.config['internaldb.ldapconn.host']
            dsPort = subsystem.config['internaldb.ldapconn.port']

            subsystem.config['tokendb.activityBaseDN'] = 'ou=Activities,' + baseDN
            subsystem.config['tokendb.baseDN'] = 'ou=Tokens,' + baseDN
            subsystem.config['tokendb.certBaseDN'] = 'ou=Certificates,' + baseDN
            subsystem.config['tokendb.userBaseDN'] = baseDN
            subsystem.config['tokendb.hostport'] = dsHost + ':' + dsPort

            nickname = subsystem.config['tps.subsystem.nickname']
            token = subsystem.config['tps.subsystem.tokenname']

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

            timestamp = round(time.time() * 1000 * 1000)

            logger.info('Configuring CA connector')

            ca_url = urllib.parse.urlparse(deployer.mdict['pki_ca_uri'])
            subsystem.config['tps.connector.ca1.enable'] = 'true'
            subsystem.config['tps.connector.ca1.host'] = ca_url.hostname
            subsystem.config['tps.connector.ca1.port'] = str(ca_url.port)
            subsystem.config['tps.connector.ca1.minHttpConns'] = '1'
            subsystem.config['tps.connector.ca1.maxHttpConns'] = '15'
            subsystem.config['tps.connector.ca1.nickName'] = fullname
            subsystem.config['tps.connector.ca1.timeout'] = '30'
            subsystem.config['tps.connector.ca1.uri.enrollment'] = \
                '/ca/ee/ca/profileSubmitSSLClient'
            subsystem.config['tps.connector.ca1.uri.getcert'] = \
                '/ca/ee/ca/displayBySerial'
            subsystem.config['tps.connector.ca1.uri.renewal'] = \
                '/ca/ee/ca/profileSubmitSSLClient'
            subsystem.config['tps.connector.ca1.uri.revoke'] = \
                '/ca/ee/subsystem/ca/doRevoke'
            subsystem.config['tps.connector.ca1.uri.unrevoke'] = \
                '/ca/ee/subsystem/ca/doUnrevoke'

            subsystem.config['config.Subsystem_Connections.ca1.state'] = 'Enabled'
            subsystem.config['config.Subsystem_Connections.ca1.timestamp'] = timestamp

            logger.info('Configuring TKS connector')

            tks_url = urllib.parse.urlparse(deployer.mdict['pki_tks_uri'])
            subsystem.config['tps.connector.tks1.enable'] = 'true'
            subsystem.config['tps.connector.tks1.host'] = tks_url.hostname
            subsystem.config['tps.connector.tks1.port'] = str(tks_url.port)
            subsystem.config['tps.connector.tks1.minHttpConns'] = '1'
            subsystem.config['tps.connector.tks1.maxHttpConns'] = '15'
            subsystem.config['tps.connector.tks1.nickName'] = fullname
            subsystem.config['tps.connector.tks1.timeout'] = '30'
            subsystem.config['tps.connector.tks1.generateHostChallenge'] = 'true'
            subsystem.config['tps.connector.tks1.serverKeygen'] = 'false'
            subsystem.config['tps.connector.tks1.keySet'] = 'defKeySet'
            subsystem.config['tps.connector.tks1.tksSharedSymKeyName'] = 'sharedSecret'
            subsystem.config['tps.connector.tks1.uri.computeRandomData'] = \
                '/tks/agent/tks/computeRandomData'
            subsystem.config['tps.connector.tks1.uri.computeSessionKey'] = \
                '/tks/agent/tks/computeSessionKey'
            subsystem.config['tps.connector.tks1.uri.createKeySetData'] = \
                '/tks/agent/tks/createKeySetData'
            subsystem.config['tps.connector.tks1.uri.encryptData'] = \
                '/tks/agent/tks/encryptData'

            subsystem.config['config.Subsystem_Connections.tks1.state'] = 'Enabled'
            subsystem.config['config.Subsystem_Connections.tks1.timestamp'] = timestamp

            subsystem.config['target.Subsystem_Connections.list'] = 'ca1,tks1'

            keygen = config.str2bool(deployer.mdict['pki_enable_server_side_keygen'])

            if keygen:
                logger.info('Configuring KRA connector')

                kra_url = urllib.parse.urlparse(deployer.mdict['pki_kra_uri'])
                subsystem.config['tps.connector.kra1.enable'] = 'true'
                subsystem.config['tps.connector.kra1.host'] = kra_url.hostname
                subsystem.config['tps.connector.kra1.port'] = str(kra_url.port)
                subsystem.config['tps.connector.kra1.minHttpConns'] = '1'
                subsystem.config['tps.connector.kra1.maxHttpConns'] = '15'
                subsystem.config['tps.connector.kra1.nickName'] = fullname
                subsystem.config['tps.connector.kra1.timeout'] = '30'
                subsystem.config['tps.connector.kra1.uri.GenerateKeyPair'] = \
                    '/kra/agent/kra/GenerateKeyPair'
                subsystem.config['tps.connector.kra1.uri.TokenKeyRecovery'] = \
                    '/kra/agent/kra/TokenKeyRecovery'

                subsystem.config['config.Subsystem_Connections.kra1.state'] = 'Enabled'
                subsystem.config['config.Subsystem_Connections.kra1.timestamp'] = timestamp

                subsystem.config['target.Subsystem_Connections.list'] = 'ca1,tks1,kra1'

                subsystem.config['tps.connector.tks1.serverKeygen'] = 'true'

                # TODO: see if there are other profiles need to be configured
                subsystem.config[
                    'op.enroll.userKey.keyGen.encryption.serverKeygen.enable'] = 'true'
                subsystem.config[
                    'op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'true'
                subsystem.config[
                    'op.enroll.soKey.keyGen.encryption.serverKeygen.enable'] = 'true'
                subsystem.config[
                    'op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'true'

            else:
                # TODO: see if there are other profiles need to be configured
                subsystem.config[
                    'op.enroll.userKey.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.userKey.keyGen.encryption.recovery.destroyed.scheme'
                ] = 'GenerateNewKey'
                subsystem.config[
                    'op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.scheme'
                ] = 'GenerateNewKey'
                subsystem.config[
                    'op.enroll.soKey.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.soKey.keyGen.encryption.recovery.destroyed.scheme'
                ] = 'GenerateNewKey'
                subsystem.config[
                    'op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.scheme'
                ] = 'GenerateNewKey'

        subsystem.save()

        token = pki.nssdb.normalize_token(deployer.mdict['pki_token_name'])
        nssdb = instance.open_nssdb()

        existing = deployer.configuration_file.existing
        step_two = deployer.configuration_file.external_step_two
        clone = deployer.configuration_file.clone
        master_url = deployer.mdict['pki_clone_uri']

        try:
            if existing or (external or standalone) and step_two:

                deployer.import_system_cert_requests(subsystem)
                deployer.import_system_certs(nssdb, subsystem)

                deployer.configure_system_certs(subsystem)

                deployer.update_system_certs(nssdb, subsystem)
                subsystem.save()

                deployer.validate_system_certs(nssdb, subsystem)

            elif len(subsystems) > 1:

                for s in subsystems:

                    # find a subsystem that is already installed
                    if s.name == subsystem.name:
                        continue

                    # import cert/request data from the existing subsystem
                    # into the new subsystem being installed

                    logger.info('Importing sslserver cert data from %s', s.type)
                    subsystem.config['%s.sslserver.cert' % subsystem.name] = \
                        s.config['%s.sslserver.cert' % s.name]

                    logger.info('Importing subsystem cert data from %s', s.type)
                    subsystem.config['%s.subsystem.cert' % subsystem.name] = \
                        s.config['%s.subsystem.cert' % s.name]

                    logger.info('Importing sslserver request data from %s', s.type)
                    subsystem.config['%s.sslserver.certreq' % subsystem.name] = \
                        s.config['%s.sslserver.certreq' % s.name]

                    logger.info('Importing subsystem request data from %s', s.type)
                    subsystem.config['%s.subsystem.certreq' % subsystem.name] = \
                        s.config['%s.subsystem.certreq' % s.name]

                    break

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

        deployer.create_temp_sslserver_cert(instance)

        server_config = instance.get_server_config()
        unsecurePort = server_config.get_unsecure_port()
        securePort = server_config.get_secure_port()

        proxyUnsecurePort = subsystem.config.get('proxy.unsecurePort')
        if not proxyUnsecurePort:
            proxyUnsecurePort = unsecurePort

        proxySecurePort = subsystem.config.get('proxy.securePort')
        if not proxySecurePort:
            proxySecurePort = securePort

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            logger.info('Joining existing domain')

            deployer.join_security_domain()

            subsystem.configure_security_domain(
                'existing',
                deployer.domain_info.id,
                deployer.sd_host.Hostname,
                deployer.sd_host.Port,
                deployer.sd_host.SecurePort)

        elif config.str2bool(deployer.mdict['pki_subordinate']) and \
                config.str2bool(deployer.mdict['pki_subordinate_create_new_security_domain']):

            logger.info('Creating new subordinate security domain')

            deployer.join_security_domain()

            subsystem.configure_security_domain(
                'new',
                deployer.mdict['pki_subordinate_security_domain_name'],
                deployer.mdict['pki_hostname'],
                unsecurePort,
                securePort)

        else:

            logger.info('Creating new security domain')

            subsystem.configure_security_domain(
                'new',
                deployer.mdict['pki_security_domain_name'],
                deployer.mdict['pki_hostname'],
                unsecurePort,
                securePort)

        subsystem.config['service.securityDomainPort'] = securePort

        hierarchy = subsystem.config.get('hierarchy.select')
        issuing_ca = deployer.mdict['pki_issuing_ca']

        if external and subsystem.type == 'CA':
            # No need to use issuing CA during CA installation
            # with external certs since the certs will be provided.
            pass

        elif standalone and subsystem.type in ['KRA', 'OCSP']:
            # No need to use issuing CA during standalone KRA/OCSP
            # installation since the certs will be provided.
            pass

        else:
            # For other cases, use issuing CA to issue certs during installation.
            # KRA will also configure a connector in the issuing CA, and OCSP will
            # configure a publisher in the issuing CA.

            logger.info('Using CA at %s', issuing_ca)
            url = urllib.parse.urlparse(issuing_ca)

            subsystem.config['preop.ca.url'] = issuing_ca
            subsystem.config['preop.ca.hostname'] = url.hostname
            subsystem.config['preop.ca.httpsport'] = str(url.port)
            subsystem.config['preop.ca.httpsadminport'] = str(url.port)

        system_certs_imported = \
            deployer.mdict['pki_server_pkcs12_path'] != '' or \
            deployer.mdict['pki_clone_pkcs12_path'] != ''

        if not (subsystem.type == 'CA' and hierarchy == 'Root'):

            if external and subsystem.type == 'CA' or \
                    standalone and subsystem.type in ['KRA', 'OCSP']:
                subsystem.config['preop.ca.pkcs7'] = ''

            elif not clone and not system_certs_imported:

                logger.info('Retrieving CA certificate chain from %s', issuing_ca)

                pem_chain = deployer.get_ca_signing_cert(instance, issuing_ca)
                base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
                subsystem.config['preop.ca.pkcs7'] = base64_chain

                logger.info('Importing CA certificate chain')

                nssdb = instance.open_nssdb()
                try:
                    nssdb.import_pkcs7(pkcs7_data=pem_chain, trust_attributes='CT,C,C')
                finally:
                    nssdb.close()

        if subsystem.type == 'CA' and clone and not system_certs_imported:

            logger.info('Retrieving CA certificate chain from %s', master_url)

            pem_chain = deployer.get_ca_signing_cert(instance, master_url)
            base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
            subsystem.config['preop.clone.pkcs7'] = base64_chain

            logger.info('Importing CA certificate chain')

            nssdb = instance.open_nssdb()
            try:
                nssdb.import_pkcs7(pkcs7_data=pem_chain, trust_attributes='CT,C,C')
            finally:
                nssdb.close()

        subsystem.save()

        if clone:

            if subsystem.type in ['CA', 'KRA']:

                logger.info('Requesting ranges from %s master', subsystem.type)
                subsystem.request_ranges(master_url, session_id=deployer.install_token.token)

            logger.info('Retrieving config params from %s master', subsystem.type)

            names = [
                'internaldb.ldapauth.password',
                'internaldb.replication.password'
            ]

            substores = [
                'internaldb',
                'internaldb.ldapauth',
                'internaldb.ldapconn'
            ]

            tags = subsystem.config['preop.cert.list'].split(',')
            for tag in tags:
                if tag == 'sslserver':
                    continue
                substores.append(subsystem.name + '.' + tag)

            if subsystem.name == 'ca':
                substores.append('ca.connector.KRA')
            else:
                names.append('cloning.ca.type')

            master_config = subsystem.retrieve_config(
                master_url,
                names,
                substores,
                session_id=deployer.install_token.token)

            logger.info('Validating %s master config params', subsystem.type)

            master_properties = master_config['properties']

            master_hostname = master_properties['internaldb.ldapconn.host']
            master_port = master_properties['internaldb.ldapconn.port']

            replica_hostname = subsystem.config['internaldb.ldapconn.host']
            replica_port = subsystem.config['internaldb.ldapconn.port']

            if master_hostname == replica_hostname and master_port == replica_port:
                raise Exception('Master and replica must not share LDAP database')

            logger.info('Importing %s master config params', subsystem.type)

            subsystem.import_master_config(master_properties)

        if config.str2bool(deployer.mdict['pki_ds_remove_data']):

            if config.str2bool(deployer.mdict['pki_ds_create_new_db']):
                logger.info('Removing existing database')
                subsystem.remove_database(force=True)

            elif not config.str2bool(deployer.mdict['pki_clone']) or \
                    config.str2bool(deployer.mdict['pki_clone_setup_replication']):
                logger.info('Emptying existing database')
                subsystem.empty_database(force=True)

            else:
                logger.info('Reusing replicated database')

        logger.info('Initializing database')

        # In most cases, we want to replicate the schema and therefore not add it here.
        # We provide this option though in case the clone already has schema
        # and we want to replicate back to the master.

        # On the other hand, if we are not setting up replication,
        # then we are assuming that replication is already taken care of,
        # and schema has already been replicated.

        setup_schema = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) or \
            not config.str2bool(deployer.mdict['pki_clone_replicate_schema'])

        create_database = config.str2bool(deployer.mdict['pki_ds_create_new_db'])

        # When cloning a subsystem without setting up the replication agreements,
        # the database is a subtree of an existing tree and is already replicated,
        # so there is no need to set up the base entry.

        create_base = config.str2bool(deployer.mdict['pki_ds_create_new_db']) or \
            not config.str2bool(deployer.mdict['pki_clone']) or \
            config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        create_containers = not config.str2bool(deployer.mdict['pki_clone'])

        ds_port = subsystem.config['internaldb.ldapconn.port']
        logger.info('- internaldb.ldapconn.port: %s', ds_port)

        secure_conn = subsystem.config['internaldb.ldapconn.secureConn']
        logger.info('- internaldb.ldapconn.secureConn: %s', secure_conn)

        # If the database is already replicated but not yet indexed, rebuild the indexes.

        rebuild_indexes = config.str2bool(deployer.mdict['pki_clone']) and \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) and \
            config.str2bool(deployer.mdict['pki_clone_reindex_data'])

        subsystem.init_database(
            setup_schema=setup_schema,
            create_database=create_database,
            create_base=create_base,
            create_containers=create_containers,
            rebuild_indexes=rebuild_indexes)

        if config.str2bool(deployer.mdict['pki_clone']) and \
                config.str2bool(deployer.mdict['pki_clone_setup_replication']):

            logger.info('Setting up replication')

            master_replication_port = deployer.mdict['pki_clone_replication_master_port']
            logger.info('- master replication port: %s', master_replication_port)

            replica_replication_port = deployer.mdict['pki_clone_replication_clone_port']
            logger.info('- replica replication port: %s', replica_replication_port)

            if replica_replication_port == ds_port and secure_conn == 'true':
                replication_security = 'SSL'

            else:
                replication_security = deployer.mdict['pki_clone_replication_security']
                if not replication_security:
                    replication_security = 'None'

            logger.info('- replication security: %s', replication_security)

            subsystem.setup_replication(
                master_properties,
                master_replication_port=master_replication_port,
                replica_replication_port=replica_replication_port,
                replication_security=replication_security)

        # For security a PKI subsystem can be configured to use a database user
        # that only has a limited access to the database (instead of cn=Directory
        # Manager that has a full access to the database).
        #
        # The default database user is uid=pkidbuser,ou=people,<subsystem base DN>.
        # However, if the subsystem is configured to share the database with another
        # subsystem (pki_share_db=True), it can also be configured to use the same
        # database user (pki_share_dbuser_dn).

        if config.str2bool(deployer.mdict['pki_share_db']):
            dbuser = deployer.mdict['pki_share_dbuser_dn']
        else:
            dbuser = '******' + deployer.mdict['pki_ds_base_dn']

        subsystem.grant_database_access(dbuser)

        subsystem.add_vlv()
        subsystem.reindex_vlv()

        subsystem.load()

        if not clone and subsystem.type == 'CA':
            subsystem.import_profiles(
                input_folder='/usr/share/pki/ca/profiles/ca')

        # 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:

            logger.info('Enabling %s subsystem', subsystem.type)
            subsystem.enable()

            logger.info('Starting PKI server')
            instance.start(
                wait=True,
                max_wait=deployer.startup_timeout,
                timeout=deployer.request_timeout)

        elif tomcat_instance_subsystems > 1:

            logger.info('Enabling %s subsystem', subsystem.type)
            subsystem.enable(
                wait=True,
                max_wait=deployer.startup_timeout,
                timeout=deployer.request_timeout)

        logger.info('Waiting for %s subsystem', subsystem.type)
        subsystem.wait_for_startup(deployer.startup_timeout, deployer.request_timeout)

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

        deployer.pki_connect(subsystem)

        # If pki_one_time_pin is not already defined, load from CS.cfg
        if 'pki_one_time_pin' not in deployer.mdict:
            deployer.mdict['pki_one_time_pin'] = subsystem.config['preop.pin']

        nssdb = subsystem.instance.open_nssdb()

        try:
            system_certs = deployer.setup_system_certs(nssdb, subsystem)
        finally:
            nssdb.close()

        subsystem.save()

        if subsystem.type == 'CA':
            logger.info('Setting up subsystem user')
            deployer.setup_subsystem_user(instance, subsystem, system_certs['subsystem'])

        if not clone:
            logger.info('Getting admin certificate')
            admin_cert = deployer.get_admin_cert(subsystem)

            logger.info('Setting up admin user')
            deployer.setup_admin_user(subsystem, admin_cert)

        domain_manager = False

        if subsystem.type == 'CA':
            if clone:
                sd_hostname = subsystem.config['securitydomain.host']
                sd_port = subsystem.config['securitydomain.httpsadminport']

                sd_subsystem = deployer.domain_info.subsystems['CA']
                sd_host = sd_subsystem.get_host(sd_hostname, sd_port)

                if sd_host.DomainManager and sd_host.DomainManager.lower() == 'true':
                    domain_manager = True

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            sd_url = deployer.mdict['pki_security_domain_uri']
            logger.info('Joining security domain at %s', sd_url)
            subsystem.join_security_domain(
                sd_url,
                deployer.mdict['pki_subsystem_name'],
                deployer.mdict['pki_hostname'],
                unsecure_port=proxyUnsecurePort,
                secure_port=proxySecurePort,
                domain_manager=domain_manager,
                clone=clone,
                session_id=deployer.install_token.token)

        else:
            logger.info('Creating security domain')
            subsystem.create_security_domain()

            logger.info('Adding security domain manager')
            subsystem.add_security_domain_host(
                deployer.mdict['pki_subsystem_name'],
                deployer.mdict['pki_hostname'],
                unsecure_port=proxyUnsecurePort,
                secure_port=proxySecurePort,
                domain_manager=True)

        if not config.str2bool(deployer.mdict['pki_share_db']) and not clone:
            logger.info('Setting up database user')
            deployer.setup_database_user(instance, subsystem)

        if subsystem.type == 'CA':

            if clone:
                if sd_host.DomainManager and sd_host.DomainManager.lower() == 'true':

                    logger.info('Cloning security domain master')

                    subsystem.config['securitydomain.select'] = 'new'
                    subsystem.config['securitydomain.host'] = deployer.mdict['pki_hostname']
                    subsystem.config['securitydomain.httpport'] = unsecurePort
                    subsystem.config['securitydomain.httpsadminport'] = securePort
                    subsystem.config['securitydomain.httpsagentport'] = securePort
                    subsystem.config['securitydomain.httpseeport'] = securePort

        deployer.finalize_subsystem(instance, subsystem)

        logger.info('%s configuration complete', subsystem.type)

        # If temp SSL server cert was created and there's a new perm cert,
        # replace it with the perm cert.
        if deployer.temp_sslserver_cert_created and system_certs['sslserver']['data']:

            logger.info('Stopping PKI server')
            instance.stop(
                wait=True,
                max_wait=deployer.startup_timeout,
                timeout=deployer.request_timeout)

            # Remove temp SSL server cert.
            deployer.remove_temp_sslserver_cert(instance, system_certs['sslserver'])

            # Import perm SSL server cert unless it's already imported
            # earlier in external/standalone installation.

            if not (standalone or external and subsystem.name in ['kra', 'ocsp']):
                deployer.import_perm_sslserver_cert(instance, system_certs['sslserver'])

            # Store perm SSL server cert nickname and token
            nickname = system_certs['sslserver']['nickname']
            token = pki.nssdb.normalize_token(system_certs['sslserver']['token'])

            if not token:
                token = deployer.mdict['pki_token_name']

            instance.set_sslserver_cert_nickname(nickname, token)

            logger.info('Starting PKI server')
            instance.start(
                wait=True,
                max_wait=deployer.startup_timeout,
                timeout=deployer.request_timeout)

        elif config.str2bool(deployer.mdict['pki_restart_configured_instance']):

            logger.info('Restarting %s subsystem', subsystem.type)
            subsystem.restart(
                wait=True,
                max_wait=deployer.startup_timeout,
                timeout=deployer.request_timeout)

        logger.info('Waiting for %s subsystem', subsystem.type)
        subsystem.wait_for_startup(deployer.startup_timeout, deployer.request_timeout)
Esempio n. 39
0
    def nssdb_import_cert(self, cert_id, cert_file=None):
        """
        Add cert from cert_file to NSS db with appropriate trust flags

        :param cert_id: Cert ID
        :type cert_id: str
        :param cert_file: Cert file to be imported into NSS db
        :type cert_file: str
        :return: New cert data loaded into nssdb
        :rtype: dict

        :raises pki.server.PKIServerException
        """

        subsystem_name, cert_tag = pki.server.PKIServer.split_cert_id(cert_id)

        if not subsystem_name:
            subsystem_name = self.get_subsystems()[0].name

        subsystem = self.get_subsystem(subsystem_name)

        # audit and CA signing cert require special flags set in NSSDB
        trust_attributes = None
        if subsystem_name == 'ca' and cert_tag == 'signing':
            trust_attributes = 'CT,C,C'
        elif cert_tag == 'audit_signing':
            trust_attributes = ',,P'

        nssdb = self.open_nssdb()

        try:
            # If cert_file is not provided, load the cert from /etc/pki/certs/<cert_id>.crt
            if not cert_file:
                cert_file = self.cert_file(cert_id)

            if not os.path.isfile(cert_file):
                raise pki.server.PKIServerException('%s does not exist.' % cert_file)

            cert = subsystem.get_subsystem_cert(cert_tag)

            logger.debug('Checking existing %s certificate in NSS database'
                         ' for subsystem: %s, instance: %s',
                         cert_tag, subsystem_name, self.name)

            if nssdb.get_cert(
                    nickname=cert['nickname'],
                    token=cert['token']):
                raise pki.server.PKIServerException(
                    'Certificate already exists: %s in subsystem %s' % (cert_tag, self.name))

            logger.debug('Importing new %s certificate into NSS database'
                         ' for subsys %s, instance %s',
                         cert_tag, subsystem_name, self.name)

            nssdb.add_cert(
                nickname=cert['nickname'],
                token=cert['token'],
                cert_file=cert_file,
                trust_attributes=trust_attributes)

            logger.info('Updating CS.cfg with the new certificate')
            data = nssdb.get_cert(
                nickname=cert['nickname'],
                token=cert['token'],
                output_format='base64')

            # Store the cert data retrieved from NSS db
            cert['data'] = data

            return cert

        finally:
            nssdb.close()
Esempio n. 40
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'])
Esempio n. 41
0
    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=', 'append',
                'no-trust-flags', 'no-key', 'no-chain', 'verbose', 'debug',
                'help'
            ])

        except getopt.GetoptError as e:
            print('ERROR: ' + str(e))
            self.usage()
            sys.exit(1)

        instance_name = 'pki-tomcat'
        cert_file = None
        csr_file = None
        pkcs12_file = None
        pkcs12_password = None
        pkcs12_password_file = None
        append = False
        include_trust_flags = True
        include_key = True
        include_chain = True
        debug = False

        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 == '--append':
                append = True

            elif o == '--no-trust-flags':
                include_trust_flags = False

            elif o == '--no-key':
                include_key = False

            elif o == '--no-chain':
                include_chain = False

            elif o in ('-v', '--verbose'):
                self.set_verbose(True)

            elif o == '--debug':
                debug = True

            elif o == '--help':
                self.usage()
                sys.exit()

            else:
                self.print_message('ERROR: unknown option ' + o)
                self.usage()
                sys.exit(1)

        if len(args) < 1:
            print('ERROR: missing cert ID')
            self.usage()
            sys.exit(1)

        cert_id = args[0]

        if not (cert_file or csr_file or pkcs12_file):
            print('ERROR: missing output file')
            self.usage()
            sys.exit(1)

        instance = server.PKIInstance(instance_name)

        if not instance.is_valid():
            print('ERROR: Invalid instance %s.' % instance_name)
            sys.exit(1)

        instance.load()

        subsystem_name = None
        cert_tag = cert_id

        if cert_id != 'sslserver' and cert_id != 'subsystem':
            # To avoid ambiguity where cert ID can contain more than 1 _, we limit to one split
            temp_cert_identify = cert_id.split('_', 1)
            subsystem_name = temp_cert_identify[0]
            cert_tag = temp_cert_identify[1]

        # If cert ID is instance specific, get it from first subsystem
        if not subsystem_name:
            subsystem_name = instance.subsystems[0].name

        subsystem = instance.get_subsystem(subsystem_name)

        if not subsystem:
            print('ERROR: No %s subsystem in instance.'
                  '%s.' % (subsystem_name, instance_name))
            sys.exit(1)

        nssdb = instance.open_nssdb()

        try:
            cert = subsystem.get_subsystem_cert(cert_tag)

            if not cert:
                print('ERROR: missing %s certificate' % cert_id)
                self.usage()
                sys.exit(1)

            if cert_file:

                if self.verbose:
                    print('Exporting %s certificate into %s.' %
                          (cert_id, cert_file))

                cert_data = cert.get('data', None)
                if cert_data is None:
                    print("ERROR: Unable to find certificate data for %s" %
                          cert_id)
                    sys.exit(1)

                cert_data = pki.nssdb.convert_cert(cert_data, 'base64', 'pem')
                with open(cert_file, 'w') as f:
                    f.write(cert_data)

            if csr_file:

                if self.verbose:
                    print('Exporting %s CSR into %s.' % (cert_id, csr_file))

                cert_request = cert.get('request', None)
                if cert_request is None:
                    print("ERROR: Unable to find certificate request for %s" %
                          cert_id)
                    sys.exit(1)

                csr_data = pki.nssdb.convert_csr(cert_request, 'base64', 'pem')
                with open(csr_file, 'w') as f:
                    f.write(csr_data)

            if pkcs12_file:

                if self.verbose:
                    print('Exporting %s certificate and key into %s.' %
                          (cert_id, pkcs12_file))

                if not pkcs12_password and not pkcs12_password_file:
                    pkcs12_password = getpass.getpass(
                        prompt='Enter password for PKCS #12 file: ')

                nicknames = []
                nicknames.append(cert['nickname'])

                nssdb.export_pkcs12(pkcs12_file=pkcs12_file,
                                    pkcs12_password=pkcs12_password,
                                    pkcs12_password_file=pkcs12_password_file,
                                    nicknames=nicknames,
                                    append=append,
                                    include_trust_flags=include_trust_flags,
                                    include_key=include_key,
                                    include_chain=include_chain,
                                    debug=debug)

        finally:
            nssdb.close()
Esempio n. 42
0
    def nssdb_import_cert(self, cert_tag, cert_file=None):
        """
        Add cert from cert_file to NSS db with appropriate trust flags

        :param cert_tag: Cert Tag
        :type cert_tag: str
        :param cert_file: Cert file to be imported into NSS db
        :type cert_file: str
        :return: New cert data loaded into nssdb
        :rtype: dict
        :raises PKIServerException
        """
        # audit and CA signing cert require special flags set in NSSDB
        trust_attributes = None
        if self.name == 'ca' and cert_tag == 'signing':
            trust_attributes = 'CT,C,C'
        elif cert_tag == 'audit_signing':
            trust_attributes = ',,P'

        nssdb = self.instance.open_nssdb()

        try:
            cert_folder = os.path.join(pki.CONF_DIR, self.instance.name, 'certs')

            # If cert_file is not provided, load the cert from /etc/pki/certs/<cert_id>.crt
            if not cert_file:
                cert_file = os.path.join(cert_folder,
                                         self.name + '_' + cert_tag + '.crt')

            if not os.path.isfile(cert_file):
                raise PKIServerException('%s does not exist.' % cert_file)

            cert = self.get_subsystem_cert(cert_tag)

            logger.debug('Checking existing %s certificate in NSS database'
                         ' for subsystem: %s, instance: %s',
                         cert_tag, self.name, self.instance.name)

            if nssdb.get_cert(
                    nickname=cert['nickname'],
                    token=cert['token']):
                raise PKIServerException('Certificate already exists: %s in'
                                         'subsystem %s' % (cert_tag, self.name))

            logger.debug('Importing new %s certificate into NSS database'
                         ' for subsys %s, instance %s',
                         cert_tag, self.name, self.instance.name)
            nssdb.add_cert(
                nickname=cert['nickname'],
                token=cert['token'],
                cert_file=cert_file,
                trust_attributes=trust_attributes)

            logger.info('Updating CS.cfg with the new certificate')
            data = nssdb.get_cert(
                nickname=cert['nickname'],
                token=cert['token'],
                output_format='base64')

            # Store the cert data retrieved from NSS db
            cert['data'] = data

            return cert

        finally:
            nssdb.close()
Esempio n. 43
0
    def execute(self, argv):

        try:
            opts, args = getopt.gnu_getopt(argv, 'i:v', [
                'instance=',
                'pkcs12-file=', 'pkcs12-password='******'pkcs12-password-file=',
                'append', 'no-trust-flags', 'no-key', 'no-chain',
                'verbose', 'debug', 'help'])

        except getopt.GetoptError as e:
            logger.error(e)
            self.print_help()
            sys.exit(1)

        nicknames = args

        instance_name = 'pki-tomcat'
        pkcs12_file = None
        pkcs12_password = None
        pkcs12_password_file = None
        append = False
        include_trust_flags = True
        include_key = True
        include_chain = True

        for o, a in opts:
            if o in ('-i', '--instance'):
                instance_name = 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 == '--append':
                append = True

            elif o == '--no-trust-flags':
                include_trust_flags = False

            elif o == '--no-key':
                include_key = False

            elif o == '--no-chain':
                include_chain = False

            elif o == '--debug':
                logging.getLogger().setLevel(logging.DEBUG)

            elif o in ('-v', '--verbose'):
                logging.getLogger().setLevel(logging.INFO)

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                logger.error('Unknown option: %s', o)
                self.print_help()
                sys.exit(1)

        if not pkcs12_file:
            logger.error('missing output file')
            self.print_help()
            sys.exit(1)

        instance = pki.server.instance.PKIInstance(instance_name)

        if not instance.is_valid():
            logger.error('Invalid instance %s.', instance_name)
            sys.exit(1)

        instance.load()

        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,
                pkcs12_password=pkcs12_password,
                pkcs12_password_file=pkcs12_password_file,
                nicknames=nicknames,
                append=append,
                include_trust_flags=include_trust_flags,
                include_key=include_key,
                include_chain=include_chain)
        finally:
            nssdb.close()
Esempio n. 44
0
    def spawn(self, deployer):

        external = deployer.configuration_file.external
        standalone = deployer.configuration_file.standalone
        step_one = deployer.configuration_file.external_step_one
        skip_configuration = deployer.configuration_file.skip_configuration

        if (external or standalone) and step_one or skip_configuration:
            logger.info('Skipping configuration')
            return

        logger.info('Configuring subsystem')

        try:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = \
                int(os.environ['PKISPAWN_STARTUP_TIMEOUT_SECONDS'])
        except (KeyError, ValueError):
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60
        if PKISPAWN_STARTUP_TIMEOUT_SECONDS <= 0:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60

        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

        if subsystem.name == 'ca':
            serial_number_range_start = deployer.mdict.get(
                'pki_serial_number_range_start')
            if serial_number_range_start:
                subsystem.config[
                    'dbs.beginSerialNumber'] = serial_number_range_start

            serial_number_range_end = deployer.mdict.get(
                'pki_serial_number_range_end')
            if serial_number_range_end:
                subsystem.config[
                    'dbs.endSerialNumber'] = serial_number_range_end

            request_number_range_start = deployer.mdict.get(
                'pki_request_number_range_start')
            if request_number_range_start:
                subsystem.config[
                    'dbs.beginRequestNumber'] = request_number_range_start

            request_number_range_end = deployer.mdict.get(
                'pki_request_number_range_end')
            if request_number_range_end:
                subsystem.config[
                    'dbs.endRequestNumber'] = request_number_range_end

            replica_number_range_start = deployer.mdict.get(
                'pki_replica_number_range_start')
            if replica_number_range_start:
                subsystem.config[
                    'dbs.beginReplicaNumber'] = replica_number_range_start

            replica_number_range_end = deployer.mdict.get(
                'pki_replica_number_range_end')
            if replica_number_range_end:
                subsystem.config[
                    'dbs.endReplicaNumber'] = replica_number_range_end

        if subsystem.name == 'kra':
            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
                logger.debug('Setting ephemeral requests to true')
                subsystem.config['kra.ephemeralRequests'] = 'true'

        subsystem.save()

        token = pki.nssdb.normalize_token(deployer.mdict['pki_token_name'])
        nssdb = instance.open_nssdb()

        existing = deployer.configuration_file.existing
        step_two = deployer.configuration_file.external_step_two
        clone = deployer.configuration_file.clone

        try:
            if existing or (external or standalone) and step_two:

                self.import_system_cert_requests(deployer, subsystem)
                self.import_system_certs(deployer, nssdb, subsystem)

                self.configure_system_certs(deployer, subsystem)
                self.update_system_certs(deployer, nssdb, subsystem)
                subsystem.save()

                self.validate_system_certs(deployer, nssdb, subsystem)

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

        create_temp_sslserver_cert = self.create_temp_sslserver_cert(
            deployer, instance)

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

        # Configure status request timeout.  This is used for each
        # status request in wait_for_startup
        value = deployer.mdict['pki_status_request_timeout']
        if len(value) == 0:
            status_request_timeout = None
        else:
            status_request_timeout = int(value)
            if status_request_timeout <= 0:
                raise ValueError("timeout must be greater than zero")

        # wait for startup
        status = deployer.instance.wait_for_startup(
            PKISPAWN_STARTUP_TIMEOUT_SECONDS,
            request_timeout=status_request_timeout,
        )
        if status is None:
            logger.error('Server failed to restart')
            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
        nssdb = instance.open_nssdb(token)
        try:
            request = deployer.config_client.create_config_request(nssdb)

        finally:
            nssdb.close()

        connection = pki.client.PKIConnection(
            protocol='https',
            hostname=deployer.mdict['pki_hostname'],
            port=deployer.mdict['pki_https_port'],
            subsystem=deployer.mdict['pki_subsystem_type'],
            trust_env=False)

        client = pki.system.SystemConfigClient(connection)

        logger.info('Configuring %s subsystem', subsystem.type)
        client.configure(request)

        logger.info('Configuring certificates')
        response = client.configureCerts(request)

        if not clone:
            logger.info('Setting up admin')
            admin_setup_request = deployer.config_client.create_admin_setup_request(
            )
            admin_setup_response = client.setupAdmin(admin_setup_request)

        if config.str2bool(deployer.mdict['pki_backup_keys']):

            logger.info('Backing up keys into %s',
                        deployer.mdict['pki_backup_keys_p12'])

            key_backup_request = deployer.config_client.create_key_backup_request(
            )
            client.backupKeys(key_backup_request)

        logger.info('Setting up security domain')
        client.setupSecurityDomain(request)

        logger.info('Setting up database user')
        client.setupDatabaseUser(request)

        logger.info('Finalizing %s configuration', subsystem.type)
        client.finalizeConfiguration(request)

        logger.info('%s configuration complete', subsystem.type)

        # Create an empty file that designates the fact that although
        # this server instance has been configured, it has NOT yet
        # been restarted!

        restart_server = os.path.join(instance.conf_dir,
                                      'restart_server_after_configuration')
        logger.debug('Creating %s', restart_server)

        open(restart_server, 'a').close()
        os.chown(restart_server, instance.uid, instance.gid)
        os.chmod(restart_server, 0o660)

        try:
            certs = response['systemCerts']
        except KeyError:
            # no system certs created
            logger.debug('No new system certificates generated')
            certs = []

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

        sslserver = subsystem.get_subsystem_cert('sslserver')

        for cdata in certs:

            if cdata['tag'] == 'sslserver':
                sslserver['data'] = cdata['cert']
                sslserver['request'] = cdata['request']

            logger.debug('%s cert: %s', cdata['tag'], cdata['cert'])
            logger.debug('%s request: %s', cdata['tag'], cdata['request'])

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

            if external or standalone \
                    or not config.str2bool(deployer.mdict['pki_import_admin_cert']):
                admin_cert = admin_setup_response['adminCert']['cert']
                deployer.config_client.process_admin_cert(admin_cert)

        # If temp SSL server cert was created and there's a new perm cert,
        # replace it with the perm cert.
        if create_temp_sslserver_cert and sslserver and sslserver['data']:
            deployer.systemd.stop()

            # Remove temp SSL server cert.
            self.remove_temp_sslserver_cert(instance, sslserver)

            # Import perm SSL server cert unless it's already imported
            # earlier in external/standalone installation.

            if not (standalone
                    or external and subsystem.name in ['kra', 'ocsp']):

                nickname = sslserver['nickname']
                token = sslserver['token']
                instance.set_sslserver_cert_nickname(nickname, token)

                self.import_perm_sslserver_cert(deployer, instance, sslserver)

            deployer.systemd.start()

        elif config.str2bool(
                deployer.mdict['pki_restart_configured_instance']):
            # Optionally, programmatically 'restart' the configured PKI instance
            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(
                PKISPAWN_STARTUP_TIMEOUT_SECONDS,
                request_timeout=status_request_timeout,
                secure_connection=False,
            )

        else:
            status = deployer.instance.wait_for_startup(
                PKISPAWN_STARTUP_TIMEOUT_SECONDS,
                request_timeout=status_request_timeout,
                secure_connection=True,
            )

        if not status:
            logger.error('Server failed to restart')
            raise RuntimeError("server failed to restart")