예제 #1
0
    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 loading 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 loading parsing 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
예제 #2
0
    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(5)
                    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)
예제 #3
0
    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
예제 #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:
            (_type, value) = san.lower().split(':')
            if value:
                o_list.append(value)

        sans = '"{0}"'.format(', '.join(o_list))
        self.logger.debug(
            'CAhandler.csr_san_get() ended with: {0}'.format(sans))
        return sans
예제 #5
0
    def _csr_check(self, csr):
        """ check CSR against definied whitelists """
        self.logger.debug('CAhandler._csr_check()')

        if self.whitelist or self.blacklist:
            result = False
            # get sans and build a list
            _san_list = csr_san_get(self.logger, csr)

            san_list = []
            check_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 BaseException:
                    # force check to fail as something went wrong during parsing
                    check_list.append(False)
                    self.logger.debug('san_list parsing failed at entry: {0}'.format(san))

            # get common name and atttach 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('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._string_wlbl_check(san, self.whitelist, self.blacklist))

            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
예제 #6
0
    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).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
예제 #7
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
예제 #8
0
    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() endet with:{0}'.format(certificate_dic))

        # empty list of statuses
        identifier_status = []

        if 'order' in certificate_dic:
            # get identifiers for order
            identifier_dic = self.dbstore.order_lookup(
                'name', certificate_dic['order'], ['identifiers'])

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

                tnauthlist_identifer_in = self.tnauth_identifier_check(
                    identifiers)

                if self.tnauthlist_support and tnauthlist_identifer_in:
                    # reload identifiers (case senetive)
                    try:
                        identifiers = json.loads(identifier_dic['identifiers'])
                    except BaseException:
                        identifiers = []

                    # get list of certextensions in base64 format
                    tnauthlist = csr_tnauthlist_get(self.logger, csr)

                    for identifier in identifiers:
                        # get the tnauthlist identifier
                        if identifier['type'].lower() == 'tnauthlist':
                            # check if tnauthlist extension is in extension list
                            if identifier['value'] in tnauthlist:
                                identifier_status.append(True)
                            else:
                                identifier_status.append(False)
                else:
                    # get sans
                    san_list = csr_san_get(self.logger, csr)
                    identifier_status = self.identifer_status_list(
                        identifiers, san_list)

        else:
            result = 'error'

        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