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
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()
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)
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()
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()
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()
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)
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)
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()
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
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()
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()
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
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()
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()
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()
def remove_cert(self, instance, nickname, token): nssdb = instance.open_nssdb() try: nssdb.remove_cert( nickname=nickname, token=token) finally: nssdb.close()
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()
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)
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()
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()
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)
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, )
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'])
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)
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()
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()
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)
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()
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)
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()
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()
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")
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()
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)
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()
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'])
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()
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()
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()
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")