def _csr_check(self, csr):
        """ check CSR against definied whitelists """
        self.logger.debug('CAhandler._csr_check()')

        if self.allowed_domainlist:

            result = False

            # get sans and build a list
            _san_list = csr_san_get(self.logger, csr)

            check_list = []
            san_list = []

            if _san_list:
                for san in _san_list:
                    try:
                        # SAN list must be modified/filtered)
                        (_san_type, san_value) = san.lower().split(':')
                        san_list.append(san_value)
                    except Exception:
                        # force check to fail as something went wrong during parsing
                        check_list.append(False)
                        self.logger.debug(
                            'CAhandler._csr_check(): san_list parsing failed at entry: {0}'
                            .format(san))

            # get common name and attach it to san_list
            cn_ = csr_cn_get(self.logger, csr)

            if cn_:
                cn_ = cn_.lower()
                if cn_ not in san_list:
                    # append cn to san_list
                    self.logger.debug(
                        'Ahandler._csr_check(): append cn to san_list')
                    san_list.append(cn_)

            # go over the san list and check each entry
            for san in san_list:
                check_list.append(
                    self._list_check(san, self.allowed_domainlist))

            if check_list:
                # cover a cornercase with empty checklist (no san, no cn)
                if False in check_list:
                    result = False
                else:
                    result = True
        else:
            result = True

        self.logger.debug(
            'CAhandler._csr_check() ended with: {0}'.format(result))
        return result
    def _csr_id_lookup(self, csr_cn, csr_san_list):
        """ lookup CSR based on CN """
        self.logger.debug('CAhandler._csr_id_lookup()')

        uts_n = uts_now()

        # get unused requests from NCLM
        request_list = self._unusedrequests_get()
        req_id = None
        # check every CSR
        for req in request_list:
            req_cn = None
            # check the import date and consider only csr which are less then 5min old
            csr_uts = date_to_uts_utc(req['addedAt'][:25],
                                      '%Y-%m-%dT%H:%M:%S.%f')
            if uts_n - csr_uts < 300:
                if 'subjectName' in req:
                    # split the subject and filter CN
                    subject_list = req['subjectName'].split(',')
                    for field in subject_list:
                        field = field.strip()
                        if field.startswith('CN='):
                            req_cn = field.lower().replace('cn=', '')
                            break
                # compare csr cn with request cn
                if csr_cn:
                    if req_cn == csr_cn.lower() and 'requestID' in req:
                        req_id = req['requestID']
                        break
                elif not req_cn:
                    # special certbot scenario (no CN in CSR). No better idea how to handle this, take first request
                    try:
                        req_all = requests.get(self.api_host + '/requests',
                                               headers=self.headers,
                                               verify=self.ca_bundle,
                                               proxies=self.proxy).json()
                    except BaseException as err_:
                        self.logger.error(
                            'CAhandler._csr_id_lookup() returned error: {0}'.
                            format(str(err_)))
                        req_all = []

                    for _req in reversed(req_all):
                        if 'pkcs10' in _req:
                            req_san_list = csr_san_get(self.logger,
                                                       _req['pkcs10'])
                            if sorted(csr_san_list) == sorted(
                                    req_san_list) and 'requestID' in _req:
                                req_id = _req['requestID']
                                break
        self.logger.debug(
            'CAhandler._csr_id_lookup() ended with: {0}'.format(req_id))
        return req_id
    def _requestname_get(self, csr):
        """ enroll certificate  """
        self.logger.debug('CAhandler._request_name_get()')

        # try to get cn for a name in database
        request_name = csr_cn_get(self.logger, csr)
        if not request_name:
            san_list = csr_san_get(self.logger, csr)
            try:
                (_identifiier, request_name,) = san_list[0].split(':')
            except BaseException:
                pass

        self.logger.debug('CAhandler._request_name_get() ended with: {0}'.format(request_name))
        return request_name
Example #4
0
    def _csr_san_get(self, csr):
        """ get subAltNames from CSR and format them as needed """
        self.logger.debug('CAhandler._csr_san_get()')
        san_list = csr_san_get(self.logger, csr)

        o_list = []
        for san in san_list:
            try:
                (_type, value) = san.lower().split(':')
                if value:
                    o_list.append(value)
            except BaseException:
                pass

        if o_list:
            sans = '"{0}"'.format(', '.join(o_list))
        else:
            sans = None
        self.logger.debug('CAhandler._csr_san_get() ended with: {0}'.format(sans))
        return sans
    def enroll(self, csr):
        """ enroll certificate from NCLM """
        self.logger.debug('CAhandler.enroll()')
        cert_bundle = None
        error = None
        cert_raw = None

        # recode csr
        csr = b64_url_recode(self.logger, csr)

        if not self.error:
            if self.tsg_info_dic['id']:

                ca_id = self._ca_id_lookup()

                if ca_id and self.template_info_dic[
                        'name'] and not self.template_info_dic['id']:
                    self._template_id_lookup()

                # get common name of CSR
                csr_cn = csr_cn_get(self.logger, csr)
                csr_san_list = csr_san_get(self.logger, csr)

                # import csr to NCLM
                self._request_import(csr)
                # lookup csr id
                csr_id = self._csr_id_lookup(csr_cn, csr_san_list)

                if ca_id and csr_id and self.tsg_info_dic['id']:
                    data_dic = {
                        "targetSystemGroupID": self.tsg_info_dic['id'],
                        "caID": ca_id,
                        "requestID": csr_id
                    }
                    # add template if correctly configured
                    if 'id' in self.template_info_dic and self.template_info_dic[
                            'id']:
                        data_dic['templateID'] = self.template_info_dic['id']
                    self._api_post(
                        self.api_host + '/targetsystemgroups/' +
                        str(self.tsg_info_dic['id']) + '/enroll/ca/' +
                        str(ca_id), data_dic)
                    # wait for certificate enrollment to get finished
                    time.sleep(self.wait_interval)
                    cert_id = self._cert_id_lookup(csr_cn, csr_san_list)
                    if cert_id:
                        (error, cert_bundle,
                         cert_raw) = self._cert_bundle_build(cert_id)
                    else:
                        error = 'certifcate id lookup failed for:  {0}, {1}'.format(
                            csr_cn, csr_san_list)
                        self.logger.error(
                            'CAhandler.eroll(): certifcate id lookup failed for:  {0}, {1}'
                            .format(csr_cn, csr_san_list))
                else:
                    error = 'enrollment aborted. ca_id: {0}, csr_id: {1}, tsg_id: {2}'.format(
                        ca_id, csr_id, self.tsg_info_dic['id'])
                    self.logger.error(
                        'CAhandler.eroll(): enrollment aborted. ca_id: {0}, csr_id: {1}, tsg_id: {2}'
                        .format(ca_id, csr_id, self.tsg_info_dic['id']))
            else:
                error = 'CAhandler.eroll(): ID lookup for targetSystemGroup "{0}" failed.'.format(
                    self.tsg_info_dic['name'])
        else:
            self.logger.error(self.error)

        self.logger.debug('CAhandler.enroll() ended')
        return (error, cert_bundle, cert_raw, None)
Example #6
0
 def post_hook(self, certificate_name, order_name, csr, error):
     """ run after *attempting* to obtain/renew certificates """
     self.logger.debug('Hook.post_hook()')
     san_list = csr_san_get(self.logger, csr)
     self._file_append('{0}/post_hook.txt'.format(self.save_path),
                       json.dumps(san_list) + '\n')
Example #7
0
 def pre_hook(self, certificate_name, order_name, csr):
     """ run before obtaining any certificates """
     self.logger.debug('Hook.pre_hook()')
     san_list = csr_san_get(self.logger, csr)
     self._file_append('{0}/pre_hook.txt'.format(self.save_path),
                       json.dumps(san_list) + '\n')
    def _csr_check(self, certificate_name, csr):
        """ compare csr extensions against order """
        self.logger.debug('Certificate._csr_check()')

        # fetch certificate dictionary from DB
        certificate_dic = self._info(certificate_name)
        self.logger.debug(
            'Certificate._info() ended with:{0}'.format(certificate_dic))

        # empty list of statuses
        identifier_status = []

        if 'order' in certificate_dic:
            # get identifiers for order
            try:
                identifier_dic = self.dbstore.order_lookup(
                    'name', certificate_dic['order'], ['identifiers'])
            except BaseException as err_:
                self.logger.critical(
                    'acme2certifier database error in Certificate._csr_check(): {0}'
                    .format(err_))
                identifier_dic = {}

            if identifier_dic and 'identifiers' in identifier_dic:
                # load identifiers
                try:
                    identifiers = json.loads(
                        identifier_dic['identifiers'].lower())
                except BaseException:
                    identifiers = []

                # do we need to check for tnauth
                tnauthlist_identifer_in = self._tnauth_identifier_check(
                    identifiers)

                if self.tnauthlist_support and tnauthlist_identifer_in:
                    # get list of certextensions in base64 format
                    try:
                        tnauthlist = csr_extensions_get(self.logger, csr)
                        identifier_status = self._identifer_tnauth_list(
                            identifier_dic, tnauthlist)
                    except BaseException as err_:
                        identifier_status = []
                        self.logger.warning(
                            'Certificate._csr_check() error while parsing csr.\nerror: {0}'
                            .format(err_))
                else:
                    # get sans and compare identifiers against san
                    try:
                        san_list = csr_san_get(self.logger, csr)
                        identifier_status = self._identifer_status_list(
                            identifiers, san_list)
                    except BaseException as err_:
                        identifier_status = []
                        self.logger.warning(
                            'Certificate._csr_check() error while checking csr.\nerror: {0}'
                            .format(err_))

        csr_check_result = False

        if identifier_status and False not in identifier_status:
            csr_check_result = True

        self.logger.debug(
            'Certificate._csr_check() ended with {0}'.format(csr_check_result))
        return csr_check_result