Пример #1
0
    def import_perm_sslserver_cert(self, deployer, instance, cert):

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

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

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

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

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

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

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

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Пример #2
0
    def import_perm_sslserver_cert(self, instance, sslserver):

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

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

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

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

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

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

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Пример #3
0
    def replace_sslserver_cert(self, deployer, instance, sslserver):

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

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

        nickname = sslserver['nickname']

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

        nssdb = instance.open_nssdb()

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

        finally:
            nssdb.close()

        token = deployer.mdict['pki_token_name']

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

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

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

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

            nssdb.add_cert(nickname, cert_file)

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Пример #4
0
    def import_perm_sslserver_cert(self, deployer, instance, cert):

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

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

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

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

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

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

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

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

        # Reset the NSS database ownership and permissions
        # after importing the permanent SSL server cert
        # since it might create new files.
        pki.util.chown(deployer.mdict['pki_server_database_path'],
                       deployer.mdict['pki_uid'], deployer.mdict['pki_gid'])
        pki.util.chmod(
            deployer.mdict['pki_server_database_path'],
            config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
        os.chmod(deployer.mdict['pki_server_database_path'],
                 pki.server.DEFAULT_DIR_MODE)
Пример #5
0
    def nssdb_import_cert(self, cert_id, cert_file=None):
        """
        Add cert from cert_file to NSS db with appropriate trust flags

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

        :raises pki.server.PKIServerException
        """

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

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

        subsystem = self.get_subsystem(subsystem_name)

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

        nssdb = self.open_nssdb()

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

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

            cert = subsystem.get_subsystem_cert(cert_tag)

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

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

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

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

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

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

            return cert

        finally:
            nssdb.close()
Пример #6
0
    def create_temp_sslserver_cert(self, deployer, instance):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            return True

        finally:
            nssdb.close()
            shutil.rmtree(tmpdir)
Пример #7
0
    def execute(self, argv):

        try:
            opts, args = getopt.gnu_getopt(
                argv, 'i:v', ['instance=', 'verbose', 'help', 'cert='])

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

        instance_name = 'pki-tomcat'
        cert_file = None

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

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

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

            elif o == '--cert':
                cert_file = a

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

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

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

        subsystem_name = args[0]
        cert_id = args[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 = subsystem.get_subsystem_cert(cert_id)

        if self.verbose:
            print('Retrieving certificate %s from %s' %
                  (subsystem_cert['nickname'], subsystem_cert['token']))

        token = subsystem_cert['token']
        nssdb = instance.open_nssdb(token)

        if cert_file:
            if not os.path.isfile(cert_file):
                print('ERROR: %s certificate does not exist.' % cert_file)
                self.usage()
                sys.exit(1)

            data = nssdb.get_cert(nickname=subsystem_cert['nickname'],
                                  output_format='base64')

            if data:
                if self.verbose:
                    print('Removing old %s certificate from database.' %
                          subsystem_cert['nickname'])
                nssdb.remove_cert(nickname=subsystem_cert['nickname'])
            if self.verbose:
                print('Adding new %s certificate into database.' %
                      subsystem_cert['nickname'])
            nssdb.add_cert(nickname=subsystem_cert['nickname'],
                           cert_file=cert_file)

        # Retrieve the cert info from NSSDB
        # Note: This reloads `data` object if --cert option is provided
        data = nssdb.get_cert(nickname=subsystem_cert['nickname'],
                              output_format='base64')
        subsystem_cert['data'] = data

        # format cert data for LDAP database
        lines = [data[i:i + 64] for i in range(0, len(data), 64)]
        data = '\r\n'.join(lines) + '\r\n'

        if self.verbose:
            print('Retrieving certificate request from CA database')

        # TODO: add support for remote CA
        ca = instance.get_subsystem('ca')
        if not ca:
            print('ERROR: No CA subsystem in instance %s.' % instance_name)
            sys.exit(1)

        results = ca.find_cert_requests(cert=data)

        if results:
            cert_request = results[-1]
            request = cert_request['request']

            # format cert request for CS.cfg
            lines = request.splitlines()
            if lines[0] == '-----BEGIN CERTIFICATE REQUEST-----':
                lines = lines[1:]
            if lines[-1] == '-----END CERTIFICATE REQUEST-----':
                lines = lines[:-1]
            request = ''.join(lines)
            subsystem_cert['request'] = request

        else:
            print('WARNING: Certificate request not found')

        # store cert data and request in CS.cfg
        subsystem.update_subsystem_cert(subsystem_cert)
        subsystem.save()

        self.print_message('Updated "%s" subsystem certificate' % cert_id)
Пример #8
0
    def execute(self, argv):
        try:
            opts, args = getopt.gnu_getopt(
                argv, 'i:v', ['instance=', 'verbose', 'input=', 'help'])

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

        instance_name = 'pki-tomcat'
        cert_file = None

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

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

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

            elif o == '--input':
                cert_file = a

            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]

        instance = server.PKIInstance(instance_name)

        if not instance.is_valid():
            print('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' 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

        # Get the subsystem - Eg: ca, kra, tps, tks
        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_folder = os.path.join(pki.CONF_DIR, instance_name, 'certs')
            if not cert_file:
                cert_file = os.path.join(cert_folder, cert_id + '.crt')

            if not os.path.isfile(cert_file):
                print('ERROR: No %s such file.' % cert_file)
                self.usage()
                sys.exit(1)

            cert = subsystem.get_subsystem_cert(cert_tag)

            # Import cert into NSS db
            if self.verbose:
                print('Removing old %s certificate from NSS database.' %
                      cert_id)
            nssdb.remove_cert(cert['nickname'])

            if self.verbose:
                print('Adding new %s certificate into NSS database.' % cert_id)
            nssdb.add_cert(nickname=cert['nickname'], cert_file=cert_file)

            # Update CS.cfg with the new certificate
            if self.verbose:
                print('Updating CS.cfg')

            data = nssdb.get_cert(nickname=cert['nickname'],
                                  output_format='base64')
            cert['data'] = data

            if cert_id == 'sslserver' or cert_id == 'subsystem':
                # Update all subsystem's CS.cfg
                for subsystem in instance.subsystems:
                    subsystem.update_subsystem_cert(cert)
                    subsystem.save()
            else:
                subsystem.update_subsystem_cert(cert)
                subsystem.save()

        finally:
            nssdb.close()
Пример #9
0
    def execute(self, argv):

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

        try:
            opts, args = getopt.gnu_getopt(
                argv, 'i:v',
                ['instance=', 'input=', 'verbose', 'debug', 'help'])

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

        instance_name = 'pki-tomcat'
        cert_file = None

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

            elif o == '--input':
                cert_file = a

            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)

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

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

        try:
            cert_folder = os.path.join(pki.CONF_DIR, instance_name, 'certs')
            if not cert_file:
                cert_file = os.path.join(cert_folder, cert_id + '.crt')

            if not os.path.isfile(cert_file):
                logger.error('No %s such file.', cert_file)
                self.print_help()
                sys.exit(1)

            cert = subsystem.get_subsystem_cert(cert_tag)

            logger.info('Checking existing %s certificate in NSS database',
                        cert_id)

            if nssdb.get_cert(nickname=cert['nickname'], token=cert['token']):
                logger.error('Certificate already exists: %s', cert_id)
                sys.exit(1)

            logger.info('Importing new %s certificate into NSS database',
                        cert_id)

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

            logger.info('Updating CS.cfg with the new certificate')

            data = nssdb.get_cert(nickname=cert['nickname'],
                                  token=cert['token'],
                                  output_format='base64')
            cert['data'] = data

            if cert_id == 'sslserver' or cert_id == 'subsystem':
                # Update all subsystem's CS.cfg
                for subsystem in instance.subsystems:
                    subsystem.update_subsystem_cert(cert)
                    subsystem.save()
            else:
                subsystem.update_subsystem_cert(cert)
                subsystem.save()

        finally:
            nssdb.close()
Пример #10
0
    def execute(self, argv):

        try:
            opts, _ = getopt.gnu_getopt(argv, 'v', [
                'pkcs12-file=', 'pkcs12-password='******'pkcs12-password-file=',
                'no-trust-flags', 'no-user-certs', 'no-ca-certs', 'overwrite',
                'verbose', 'debug', 'help'
            ])

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

        pkcs12_file = None
        pkcs12_password = None
        password_file = None
        no_trust_flags = False
        import_user_certs = True
        import_ca_certs = True
        overwrite = False
        debug = False

        for o, a in opts:
            if o == '--pkcs12-file':
                pkcs12_file = a

            elif o == '--pkcs12-password':
                pkcs12_password = a

            elif o == '--pkcs12-password-file':
                password_file = a

            elif o == '--no-trust-flags':
                no_trust_flags = True

            elif o == '--no-user-certs':
                import_user_certs = False

            elif o == '--no-ca-certs':
                import_ca_certs = False

            elif o == '--overwrite':
                overwrite = True

            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 PKCS #12 file')
            self.print_help()
            sys.exit(1)

        if not pkcs12_password and not password_file:
            print('ERROR: Missing PKCS #12 password')
            self.print_help()
            sys.exit(1)

        main_cli = self.parent.parent

        # Due to JSS limitation, CA certificates need to be imported
        # using certutil in order to preserve the nickname stored in
        # the PKCS #12 file.

        if main_cli.verbose:
            print('Getting certificate infos in PKCS #12 file')

        certs = []

        tmpdir = tempfile.mkdtemp()

        try:
            # find all certs in PKCS #12 file
            output_file = os.path.join(tmpdir, 'pkcs12-cert-find.txt')
            with open(output_file, 'wb') as f:

                cmd = ['pkcs12-cert-find']

                if pkcs12_file:
                    cmd.extend(['--pkcs12-file', pkcs12_file])

                if pkcs12_password:
                    cmd.extend(['--pkcs12-password', pkcs12_password])

                if password_file:
                    cmd.extend(['--pkcs12-password-file', password_file])

                if self.verbose:
                    cmd.extend(['--verbose'])

                if debug:
                    cmd.extend(['--debug'])

                main_cli.execute_java(cmd, stdout=f)

            # parse results
            with open(output_file, 'r') as f:
                cert_info = {}

                for line in f:
                    match = re.match(r'  Certificate ID: (.*)$', line)
                    if match:
                        cert_info = {}
                        cert_info['id'] = match.group(1)
                        certs.append(cert_info)
                        continue

                    match = re.match(r'  Nickname: (.*)$', line)
                    if match:
                        cert_info['nickname'] = match.group(1)
                        continue

                    match = re.match(r'  Trust Flags: (.*)$', line)
                    if match:
                        cert_info['trust_flags'] = match.group(1)
                        continue

                    match = re.match(r'  Has Key: (.*)$', line)
                    if match:
                        cert_info['has_key'] = match.group(1) == 'true'
                        continue

        finally:
            shutil.rmtree(tmpdir)

        # import CA certificates if requested
        if import_ca_certs:

            if main_cli.verbose:
                print('Importing CA certificates')

            tmpdir = tempfile.mkdtemp()

            try:
                cert_file = os.path.join(tmpdir, 'ca-cert.pem')

                nssdb = pki.nssdb.NSSDatabase(
                    main_cli.database,
                    token=main_cli.token,
                    password=main_cli.password,
                    password_file=main_cli.password_file)

                for cert_info in certs:

                    has_key = cert_info['has_key']
                    if has_key:
                        continue

                    cert_id = cert_info['id']
                    nickname = cert_info['nickname']

                    cert = nssdb.get_cert(nickname)

                    if cert:
                        if not overwrite:
                            print('WARNING: cert %s already exists' % nickname)
                            continue

                        nssdb.remove_cert(nickname)

                    if 'trust_flags' in cert_info:
                        trust_flags = cert_info['trust_flags']
                    else:
                        # default trust flags for CA certificates
                        trust_flags = 'CT,C,C'

                    if main_cli.verbose:
                        print('Exporting %s (%s) from PKCS #12 file' %
                              (nickname, cert_id))

                    cmd = ['pkcs12-cert-export']

                    if pkcs12_file:
                        cmd.extend(['--pkcs12-file', pkcs12_file])

                    if pkcs12_password:
                        cmd.extend(['--pkcs12-password', pkcs12_password])

                    if password_file:
                        cmd.extend(['--pkcs12-password-file', password_file])

                    cmd.extend(['--cert-file', cert_file])

                    cmd.extend(['--cert-id', cert_id])

                    if self.verbose:
                        cmd.extend(['--verbose'])

                    if debug:
                        cmd.extend(['--debug'])

                    main_cli.execute_java(cmd)

                    if main_cli.verbose:
                        print('Importing %s' % nickname)

                    nssdb.add_cert(nickname, cert_file, trust_flags)

            finally:
                shutil.rmtree(tmpdir)

        # import user certificates if requested
        if import_user_certs:

            if main_cli.verbose:
                print('Importing user certificates')

            nicknames = []
            for cert_info in certs:

                has_key = cert_info['has_key']
                if not has_key:
                    continue

                nickname = cert_info['nickname']
                if nickname not in nicknames:
                    nicknames.append(nickname)

            cmd = ['pkcs12-import']

            if pkcs12_file:
                cmd.extend(['--pkcs12-file', pkcs12_file])

            if pkcs12_password:
                cmd.extend(['--pkcs12-password', pkcs12_password])

            if password_file:
                cmd.extend(['--pkcs12-password-file', password_file])

            if no_trust_flags:
                cmd.extend(['--no-trust-flags'])

            if overwrite:
                cmd.extend(['--overwrite'])

            if self.verbose:
                cmd.extend(['--verbose'])

            if debug:
                cmd.extend(['--debug'])

            cmd.extend(nicknames)

            with open(os.devnull, 'w') as f:
                main_cli.execute_java(cmd, stdout=f)

        self.print_message('Import complete')
Пример #11
0
    def execute(self, argv):

        try:
            opts, args = getopt.gnu_getopt(argv, 'i:v', [
                'instance=',
                'verbose', 'help',
                'cert='])

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

        instance_name = 'pki-tomcat'
        cert_file = None

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

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

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

            elif o == '--cert':
                cert_file = a

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

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

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

        subsystem_name = args[0]
        cert_id = args[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 = subsystem.get_subsystem_cert(cert_id)

        if self.verbose:
            print('Retrieving certificate %s from %s' %
                  (subsystem_cert['nickname'], subsystem_cert['token']))

        token = subsystem_cert['token']
        nssdb = instance.open_nssdb(token)

        if cert_file:
            if not os.path.isfile(cert_file):
                print('ERROR: %s certificate does not exist.' % cert_file)
                self.usage()
                sys.exit(1)

            data = nssdb.get_cert(
                nickname=subsystem_cert['nickname'],
                output_format='base64')

            if data:
                if self.verbose:
                    print('Removing old %s certificate from database.' % subsystem_cert['nickname'])
                nssdb.remove_cert(nickname=subsystem_cert['nickname'])
            if self.verbose:
                print('Adding new %s certificate into database.' % subsystem_cert['nickname'])
            nssdb.add_cert(
                nickname=subsystem_cert['nickname'],
                cert_file=cert_file)

        # Retrieve the cert info from NSSDB
        # Note: This reloads `data` object if --cert option is provided
        data = nssdb.get_cert(
            nickname=subsystem_cert['nickname'],
            output_format='base64')
        subsystem_cert['data'] = data

        # format cert data for LDAP database
        lines = [data[i:i + 64] for i in range(0, len(data), 64)]
        data = '\r\n'.join(lines) + '\r\n'

        if self.verbose:
            print('Retrieving certificate request from CA database')

        # TODO: add support for remote CA
        ca = instance.get_subsystem('ca')
        if not ca:
            print('ERROR: No CA subsystem in instance %s.' % instance_name)
            sys.exit(1)

        results = ca.find_cert_requests(cert=data)

        if results:
            cert_request = results[-1]
            request = cert_request['request']

            # format cert request for CS.cfg
            lines = request.splitlines()
            if lines[0] == '-----BEGIN CERTIFICATE REQUEST-----':
                lines = lines[1:]
            if lines[-1] == '-----END CERTIFICATE REQUEST-----':
                lines = lines[:-1]
            request = ''.join(lines)
            subsystem_cert['request'] = request

        else:
            print('WARNING: Certificate request not found')

        # store cert data and request in CS.cfg
        subsystem.update_subsystem_cert(subsystem_cert)
        subsystem.save()

        self.print_message('Updated "%s" subsystem certificate' % cert_id)
Пример #12
0
    def execute(self, argv):

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

        try:
            opts, _ = getopt.gnu_getopt(argv, 'v', [
                'pkcs12-file=', 'pkcs12-password='******'pkcs12-password-file=',
                'no-trust-flags', 'no-user-certs', 'no-ca-certs', 'overwrite',
                'verbose', 'debug', 'help'])

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

        pkcs12_file = None
        pkcs12_password = None
        password_file = None
        no_trust_flags = False
        import_user_certs = True
        import_ca_certs = True
        overwrite = False

        for o, a in opts:
            if o == '--pkcs12-file':
                pkcs12_file = a

            elif o == '--pkcs12-password':
                pkcs12_password = a

            elif o == '--pkcs12-password-file':
                password_file = a

            elif o == '--no-trust-flags':
                no_trust_flags = True

            elif o == '--no-user-certs':
                import_user_certs = False

            elif o == '--no-ca-certs':
                import_ca_certs = False

            elif o == '--overwrite':
                overwrite = True

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

            elif o == '--debug':
                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 not pkcs12_file:
            logger.error('Missing PKCS #12 file')
            self.print_help()
            sys.exit(1)

        if not pkcs12_password and not password_file:
            logger.error('Missing PKCS #12 password')
            self.print_help()
            sys.exit(1)

        main_cli = self.parent.parent

        # Due to JSS limitation, CA certificates need to be imported
        # using certutil in order to preserve the nickname stored in
        # the PKCS #12 file.

        logger.info('Getting certificate infos in PKCS #12 file')

        certs = []

        tmpdir = tempfile.mkdtemp()

        try:
            # find all certs in PKCS #12 file
            output_file = os.path.join(tmpdir, 'pkcs12-cert-find.txt')
            with open(output_file, 'wb') as f:

                cmd = ['pkcs12-cert-find']

                if pkcs12_file:
                    cmd.extend(['--pkcs12-file', pkcs12_file])

                if pkcs12_password:
                    cmd.extend(['--pkcs12-password', pkcs12_password])

                if password_file:
                    cmd.extend(['--pkcs12-password-file', password_file])

                if self.verbose:
                    cmd.extend(['--verbose'])

                if self.debug:
                    cmd.extend(['--debug'])

                main_cli.execute_java(cmd, stdout=f)

            # parse results
            with open(output_file, 'r') as f:
                cert_info = {}

                for line in f:
                    match = re.match(r'  Certificate ID: (.*)$', line)
                    if match:
                        cert_info = {}
                        cert_info['id'] = match.group(1)
                        certs.append(cert_info)
                        continue

                    match = re.match(r'  Friendly Name: (.*)$', line)
                    if match:
                        cert_info['nickname'] = match.group(1)
                        continue

                    match = re.match(r'  Trust Flags: (.*)$', line)
                    if match:
                        cert_info['trust_flags'] = match.group(1)
                        continue

                    match = re.match(r'  Has Key: (.*)$', line)
                    if match:
                        cert_info['has_key'] = match.group(1) == 'true'
                        continue

        finally:
            shutil.rmtree(tmpdir)

        # import CA certificates if requested
        if import_ca_certs:

            logger.info('Importing CA certificates')

            tmpdir = tempfile.mkdtemp()

            try:
                cert_file = os.path.join(tmpdir, 'ca-cert.pem')

                nssdb = pki.nssdb.NSSDatabase(
                    main_cli.database,
                    token=main_cli.token,
                    password=main_cli.password,
                    password_file=main_cli.password_file)

                for cert_info in certs:

                    has_key = cert_info['has_key']
                    if has_key:
                        continue

                    cert_id = cert_info['id']
                    nickname = cert_info['nickname']

                    cert = nssdb.get_cert(
                        nickname=nickname)

                    if cert:
                        if not overwrite:
                            logger.warning('cert %s already exists', nickname)
                            continue

                        nssdb.remove_cert(
                            nickname=nickname)

                    if 'trust_flags' in cert_info:
                        trust_flags = cert_info['trust_flags']
                    else:
                        # default trust flags for CA certificates
                        trust_flags = 'CT,C,C'

                    logger.info('Exporting %s (%s) from PKCS #12 file', nickname, cert_id)

                    cmd = ['pkcs12-cert-export']

                    if pkcs12_file:
                        cmd.extend(['--pkcs12-file', pkcs12_file])

                    if pkcs12_password:
                        cmd.extend(['--pkcs12-password', pkcs12_password])

                    if password_file:
                        cmd.extend(['--pkcs12-password-file', password_file])

                    cmd.extend(['--cert-file', cert_file])

                    cmd.extend(['--cert-id', cert_id])

                    if self.verbose:
                        cmd.extend(['--verbose'])

                    if self.debug:
                        cmd.extend(['--debug'])

                    main_cli.execute_java(cmd)

                    logger.info('Importing %s', nickname)

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

            finally:
                shutil.rmtree(tmpdir)

        # import user certificates if requested
        if import_user_certs:

            logger.info('Importing user certificates')

            nicknames = []
            for cert_info in certs:

                has_key = cert_info['has_key']
                if not has_key:
                    continue

                nickname = cert_info['nickname']
                if nickname not in nicknames:
                    nicknames.append(nickname)

            cmd = ['pkcs12-import']

            if pkcs12_file:
                cmd.extend(['--pkcs12-file', pkcs12_file])

            if pkcs12_password:
                cmd.extend(['--pkcs12-password', pkcs12_password])

            if password_file:
                cmd.extend(['--pkcs12-password-file', password_file])

            if no_trust_flags:
                cmd.extend(['--no-trust-flags'])

            if overwrite:
                cmd.extend(['--overwrite'])

            if self.verbose:
                cmd.extend(['--verbose'])

            if self.debug:
                cmd.extend(['--debug'])

            cmd.extend(nicknames)

            with open(os.devnull, 'w') as f:
                main_cli.execute_java(cmd, stdout=f)

        self.print_message('Import complete')
Пример #13
0
    def execute(self, argv):

        try:
            opts, _ = getopt.gnu_getopt(argv, 'v', [
                'pkcs12=', 'password='******'password-file=', 'pkcs12-file=',
                'pkcs12-password='******'pkcs12-password-file=', 'no-trust-flags',
                'no-user-certs', 'no-ca-certs', 'overwrite', 'verbose',
                'debug', 'help'
            ])

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

        pkcs12_file = None
        pkcs12_password = None
        password_file = None
        no_trust_flags = False
        import_user_certs = True
        import_ca_certs = True
        overwrite = False

        for o, a in opts:
            if o == '--pkcs12':
                pkcs12_file = a

            elif o == '--pkcs12-file':
                pkcs12_file = a

            elif o == '--password':
                pkcs12_password = a

            elif o == '--pkcs12-password':
                pkcs12_password = a

            elif o == '--password-file':
                password_file = a

            elif o == '--pkcs12-password-file':
                password_file = a

            elif o == '--no-trust-flags':
                no_trust_flags = True

            elif o == '--no-user-certs':
                import_user_certs = False

            elif o == '--no-ca-certs':
                import_ca_certs = False

            elif o == '--overwrite':
                overwrite = True

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

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

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

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

        if not pkcs12_file:
            logger.error('Missing PKCS #12 file')
            self.print_help()
            sys.exit(1)

        if not pkcs12_password and not password_file:
            logger.error('Missing PKCS #12 password')
            self.print_help()
            sys.exit(1)

        main_cli = self.parent.parent

        # Due to JSS limitation, CA certificates need to be imported
        # using certutil in order to preserve the nickname stored in
        # the PKCS #12 file.

        logger.info('Certificates in PKCS #12 file:')

        certs = []

        tmpdir = tempfile.mkdtemp()

        try:
            # find all certs in PKCS #12 file
            output_file = os.path.join(tmpdir, 'pkcs12-cert-find.txt')
            with open(output_file, 'wb') as f:

                cmd = ['pkcs12-cert-find']

                if pkcs12_file:
                    cmd.extend(['--pkcs12', pkcs12_file])

                if pkcs12_password:
                    cmd.extend(['--password', pkcs12_password])

                if password_file:
                    cmd.extend(['--password-file', password_file])

                if logger.isEnabledFor(logging.DEBUG):
                    cmd.extend(['--debug'])

                elif logger.isEnabledFor(logging.INFO):
                    cmd.extend(['--verbose'])

                main_cli.execute_java(cmd, stdout=f)

            # parse results
            with open(output_file, 'r') as f:
                cert_info = {}

                for line in f:
                    match = re.match(r'  Certificate ID: (.*)$', line)
                    if match:
                        cert_info = {}
                        cert_info['id'] = match.group(1)
                        certs.append(cert_info)
                        continue

                    match = re.match(r'  Friendly Name: (.*)$', line)
                    if match:
                        nickname = match.group(1)
                        cert_info['nickname'] = nickname
                        logger.info('- %s', nickname)
                        continue

                    match = re.match(r'  Trust Flags: (.*)$', line)
                    if match:
                        cert_info['trust_flags'] = match.group(1)
                        continue

                    match = re.match(r'  Has Key: (.*)$', line)
                    if match:
                        cert_info['has_key'] = match.group(1) == 'true'
                        continue

        finally:
            shutil.rmtree(tmpdir)

        # import CA certificates if requested
        if import_ca_certs:

            logger.info('Importing CA certificates:')

            tmpdir = tempfile.mkdtemp()

            try:
                cert_file = os.path.join(tmpdir, 'ca-cert.pem')

                nssdb = pki.nssdb.NSSDatabase(
                    main_cli.database,
                    token=main_cli.token,
                    password=main_cli.password,
                    password_file=main_cli.password_file,
                    password_conf=main_cli.password_conf)

                for cert_info in certs:

                    has_key = cert_info['has_key']
                    if has_key:
                        continue

                    cert_id = cert_info['id']
                    nickname = cert_info['nickname']
                    logger.info('- %s', nickname)

                    cert = nssdb.get_cert(nickname=nickname)

                    if cert:
                        if not overwrite:
                            logger.warning('Certificate already exists: %s',
                                           nickname)
                            continue

                        nssdb.remove_cert(nickname=nickname)

                    if 'trust_flags' in cert_info:
                        trust_flags = cert_info['trust_flags']
                    else:
                        # default trust flags for CA certificates
                        trust_flags = 'CT,C,C'

                    logger.info('Exporting %s (%s) from PKCS #12 file',
                                nickname, cert_id)

                    cmd = ['pkcs12-cert-export']

                    if pkcs12_file:
                        cmd.extend(['--pkcs12-file', pkcs12_file])

                    if pkcs12_password:
                        cmd.extend(['--pkcs12-password', pkcs12_password])

                    if password_file:
                        cmd.extend(['--pkcs12-password-file', password_file])

                    cmd.extend(['--cert-file', cert_file])

                    cmd.extend(['--cert-id', cert_id])

                    if logger.isEnabledFor(logging.DEBUG):
                        cmd.extend(['--debug'])

                    elif logger.isEnabledFor(logging.INFO):
                        cmd.extend(['-v'])

                    main_cli.execute_java(cmd)

                    logger.info('Importing %s', nickname)

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

            finally:
                shutil.rmtree(tmpdir)

        # import user certificates if requested
        if import_user_certs:

            logger.info('Importing user certificates:')

            nicknames = []
            for cert_info in certs:

                has_key = cert_info['has_key']
                if not has_key:
                    continue

                nickname = cert_info['nickname']
                logger.info('- %s', nickname)

                if nickname not in nicknames:
                    nicknames.append(nickname)

            cmd = ['pkcs12-import']

            if pkcs12_file:
                cmd.extend(['--pkcs12', pkcs12_file])

            if pkcs12_password:
                cmd.extend(['--password', pkcs12_password])

            if password_file:
                cmd.extend(['--password-file', password_file])

            if no_trust_flags:
                cmd.extend(['--no-trust-flags'])

            if overwrite:
                cmd.extend(['--overwrite'])

            if logger.isEnabledFor(logging.DEBUG):
                cmd.extend(['--debug'])

            elif logger.isEnabledFor(logging.INFO):
                cmd.extend(['-v'])

            cmd.extend(nicknames)

            with open(os.devnull, 'w') as f:
                main_cli.execute_java(cmd, stdout=f)
Пример #14
0
    def spawn(self, deployer):

        if config.str2bool(deployer.mdict['pki_skip_configuration']):
            config.pki_log.info(log.SKIP_CONFIGURATION_SPAWN_1,
                                __name__,
                                extra=config.PKI_INDENTATION_LEVEL_1)
            return

        config.pki_log.info(log.CONFIGURATION_SPAWN_1,
                            __name__,
                            extra=config.PKI_INDENTATION_LEVEL_1)

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

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

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

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

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

        existing = deployer.configuration_file.existing
        external = deployer.configuration_file.external
        standalone = deployer.configuration_file.standalone
        step_one = deployer.configuration_file.external_step_one
        step_two = deployer.configuration_file.external_step_two
        clone = deployer.configuration_file.clone

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

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

                # Determine CA signing key type and algorithm

                key_type = deployer.mdict['pki_ca_signing_key_type']
                key_alg = deployer.mdict['pki_ca_signing_key_algorithm']

                if key_type == 'rsa':
                    key_size = int(deployer.mdict['pki_ca_signing_key_size'])
                    curve = None

                    m = re.match(r'(.*)withRSA', key_alg)
                    if not m:
                        raise Exception('Invalid key algorithm: %s' % key_alg)
                    hash_alg = m.group(1)

                elif key_type == 'ec' or key_type == 'ecc':
                    key_type = 'ec'
                    key_size = None
                    curve = deployer.mdict['pki_ca_signing_key_size']

                    m = re.match(r'(.*)withEC', key_alg)
                    if not m:
                        raise Exception('Invalid key algorithm: %s' % key_alg)
                    hash_alg = m.group(1)

                else:
                    raise Exception('Invalid key type: %s' % key_type)

                # If filename specified, generate CA cert request and
                # import it into CS.cfg.

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

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

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

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

                    # if specified, add generic CSR extension
                    generic_exts = None

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

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

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

                        generic_exts = [generic_ext]

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

                    with open(external_csr_path) as f:
                        signing_csr = f.read()

                    signing_csr = pki.nssdb.convert_csr(
                        signing_csr, 'pem', 'base64')
                    subsystem.config['ca.signing.certreq'] = signing_csr

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

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

                subsystem.save()

            if existing or external and step_two:
                # existing CA or external CA step 2

                # If specified, import CA signing CSR into CS.cfg.
                signing_csr_path = deployer.mdict['pki_external_csr_path']
                if signing_csr_path:
                    config.pki_log.info("importing CA signing CSR from %s",
                                        signing_csr_path,
                                        extra=config.PKI_INDENTATION_LEVEL_2)
                    with open(signing_csr_path) as f:
                        signing_csr = f.read()
                    signing_csr = pki.nssdb.convert_csr(
                        signing_csr, 'pem', 'base64')
                    subsystem.config['ca.signing.certreq'] = signing_csr

                # If specified, import CA signing cert into NSS database.
                signing_nickname = deployer.mdict['pki_ca_signing_nickname']
                signing_cert_file = deployer.mdict['pki_external_ca_cert_path']
                if signing_cert_file:
                    config.pki_log.info("importing %s from %s",
                                        signing_nickname,
                                        signing_cert_file,
                                        extra=config.PKI_INDENTATION_LEVEL_2)
                    nssdb.add_cert(nickname=signing_nickname,
                                   cert_file=signing_cert_file,
                                   trust_attributes='CT,C,C')

                # If specified, import certs and keys from PKCS #12 file
                # into NSS database.
                pkcs12_file = deployer.mdict['pki_external_pkcs12_path']
                if pkcs12_file:
                    config.pki_log.info(
                        "importing certificates and keys from %s",
                        pkcs12_file,
                        extra=config.PKI_INDENTATION_LEVEL_2)
                    pkcs12_password = deployer.mdict[
                        'pki_external_pkcs12_password']
                    nssdb.import_pkcs12(pkcs12_file, pkcs12_password)

                # If specified, import cert chain into NSS database.
                # Note: Cert chain must be imported after the system certs
                # to ensure that the system certs are imported with
                # the correct nicknames.
                external_ca_cert_chain_nickname = \
                    deployer.mdict['pki_external_ca_cert_chain_nickname']
                external_ca_cert_chain_file = deployer.mdict[
                    'pki_external_ca_cert_chain_path']
                if external_ca_cert_chain_file:
                    config.pki_log.info(
                        "importing certificate chain %s from %s",
                        external_ca_cert_chain_nickname,
                        external_ca_cert_chain_file,
                        extra=config.PKI_INDENTATION_LEVEL_2)
                    cert_chain, _nicks = nssdb.import_cert_chain(
                        nickname=external_ca_cert_chain_nickname,
                        cert_chain_file=external_ca_cert_chain_file,
                        trust_attributes='CT,C,C')
                    subsystem.config['ca.external_ca_chain.cert'] = cert_chain

                # Export CA signing cert from NSS database and import
                # it into CS.cfg.
                signing_cert_data = nssdb.get_cert(nickname=signing_nickname,
                                                   output_format='base64')
                subsystem.config['ca.signing.nickname'] = signing_nickname
                subsystem.config['ca.signing.tokenname'] = (
                    deployer.mdict['pki_ca_signing_token'])
                subsystem.config['ca.signing.cert'] = signing_cert_data
                subsystem.config[
                    'ca.signing.cacertnickname'] = signing_nickname
                subsystem.config['ca.signing.defaultSigningAlgorithm'] = (
                    deployer.mdict['pki_ca_signing_signing_algorithm'])

                subsystem.save()

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

            else:  # self-signed CA

                # To be implemented in ticket #1692.

                # Generate CA cert request.
                # Self sign CA cert.
                # Import self-signed CA cert into NSS database.

                pass

        finally:
            nssdb.close()

        if external and step_one:
            return

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

            deployer.password.create_password_conf(
                deployer.mdict['pki_shared_pfile'],
                deployer.mdict['pki_pin'],
                pin_sans_token=True)

            # only create a self signed cert for a new instance
            #
            # NOTE:  ALWAYS create the temporary sslserver certificate
            #        in the software DB regardless of whether the
            #        instance will utilize 'softokn' or an HSM
            #
            rv = deployer.certutil.verify_certificate_exists(
                deployer.mdict['pki_database_path'],
                deployer.mdict['pki_cert_database'],
                deployer.mdict['pki_key_database'],
                deployer.mdict['pki_secmod_database'],
                deployer.mdict['pki_self_signed_token'],
                deployer.mdict['pki_self_signed_nickname'],
                password_file=deployer.mdict['pki_shared_pfile'])

            if not rv:

                # note: in the function below, certutil is used to generate
                # the request for the self signed cert.  The keys are generated
                # by NSS, which does not actually use the data in the noise
                # file, so it does not matter what is in this file.  Certutil
                # still requires it though, otherwise it waits for keyboard
                # input
                with open(deployer.mdict['pki_self_signed_noise_file'],
                          'w') as f:
                    f.write("not_so_random_data")

                deployer.certutil.generate_self_signed_certificate(
                    deployer.mdict['pki_database_path'],
                    deployer.mdict['pki_cert_database'],
                    deployer.mdict['pki_key_database'],
                    deployer.mdict['pki_secmod_database'],
                    deployer.mdict['pki_self_signed_token'],
                    deployer.mdict['pki_self_signed_nickname'],
                    deployer.mdict['pki_self_signed_subject'],
                    deployer.mdict['pki_self_signed_serial_number'],
                    deployer.mdict['pki_self_signed_validity_period'],
                    deployer.mdict['pki_self_signed_issuer_name'],
                    deployer.mdict['pki_self_signed_trustargs'],
                    deployer.mdict['pki_self_signed_noise_file'],
                    password_file=deployer.mdict['pki_shared_pfile'])

                # Delete the temporary 'noise' file
                deployer.file.delete(
                    deployer.mdict['pki_self_signed_noise_file'])

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

        # Start/Restart this Tomcat PKI Process
        # Optionally prepare to enable a java debugger
        # (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.prepare_for_an_external_java_debugger(
                deployer.mdict['pki_target_tomcat_conf_instance_id'])
        tomcat_instance_subsystems = \
            len(deployer.instance.tomcat_instance_subsystems())
        if tomcat_instance_subsystems == 1:
            deployer.systemd.start()
        elif tomcat_instance_subsystems > 1:
            deployer.systemd.restart()

        # wait for startup
        status = deployer.instance.wait_for_startup(60)
        if status is None:
            config.pki_log.error("server failed to restart",
                                 extra=config.PKI_INDENTATION_LEVEL_2)
            raise Exception("server failed to restart")

        # Optionally wait for debugger to attach (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.wait_to_attach_an_external_java_debugger()

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

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

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

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

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

        for cdata in certs:

            if standalone and not step_two:

                # Stand-alone PKI (Step 1)

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

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

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

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

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

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

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

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

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

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

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

        # Optionally, programmatically 'restart' the configured PKI instance
        if not config.str2bool(
                deployer.mdict['pki_restart_configured_instance']):
            return

        deployer.systemd.restart()

        # wait for startup
        status = None

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

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

        if not status:
            config.pki_log.error("server failed to restart",
                                 extra=config.PKI_INDENTATION_LEVEL_1)
            raise RuntimeError("server failed to restart")
Пример #15
0
    def nssdb_import_cert(self, cert_tag, cert_file=None):
        """
        Add cert from cert_file to NSS db with appropriate trust flags

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

        nssdb = self.instance.open_nssdb()

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

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

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

            cert = self.get_subsystem_cert(cert_tag)

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

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

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

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

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

            return cert

        finally:
            nssdb.close()