def revoke(self,
               cert,
               rev_reason='unspecified',
               rev_date=uts_to_date_utc(uts_now())):
        """ revoke certificate """
        self.logger.debug('CAhandler.revoke({0}: {1})'.format(
            rev_reason, rev_date))
        # lookup REST-PATH of issuing CA
        ca_dic = self._ca_get_properties('name', self.ca_name)
        if 'href' in ca_dic:
            # get serial from pem file
            serial = cert_serial_get(self.logger, cert)
            if serial:
                # get certificate information via rest by search for ca+ serial
                cert_dic = self._cert_get_properties(serial, ca_dic['href'])
                if 'certificates' in cert_dic:
                    if len(cert_dic['certificates']
                           ) > 0 and 'href' in cert_dic['certificates'][0]:
                        # revoke the cert
                        data = {
                            'newStatus': 'revoked',
                            'crlReason': rev_reason,
                            'invalidityDate': rev_date
                        }
                        cert_dic = self._api_post(
                            cert_dic['certificates'][0]['href'] + '/status',
                            data)
                        if 'status' in cert_dic:
                            # code = cert_dic['status']
                            code = 400
                            message = 'urn:ietf:params:acme:error:alreadyRevoked'
                            if 'message' in cert_dic:
                                detail = cert_dic['message']
                            else:
                                detail = 'no details'
                        else:
                            code = 200
                            message = None
                            detail = None
                    else:
                        code = 404
                        message = 'urn:ietf:params:acme:error:serverInternal'
                        detail = 'Cert path could not be found'
                else:
                    code = 404
                    message = 'urn:ietf:params:acme:error:serverInternal'
                    detail = 'Cert could not be found'
            else:
                code = 404
                message = 'urn:ietf:params:acme:error:serverInternal'
                detail = 'failed to get serial number from cert'
        else:
            code = 404
            message = 'urn:ietf:params:acme:error:serverInternal'
            detail = 'CA could not be found'

        return (code, message, detail)
예제 #2
0
    def revoke(self, cert, rev_reason, rev_date):
        """ revoke certificate """
        self.logger.debug('CAhandler.revoke()')
        # get serial from pem file and convert to formated hex
        serial = '0{:x}'.format(cert_serial_get(self.logger, cert))
        hex_serial = ':'.join(serial[i:i + 2]
                              for i in range(0, len(serial), 2))

        # search for certificate
        try:
            cert_list = requests.get(
                self.api_host + '/certificates?freeText==' + str(hex_serial) +
                '&stateCurrent=false&stateHistory=false&stateWaiting=false&stateManual=false&stateUnattached=false&expiresAfter=%22%22&expiresBefore=%22%22&sortAttribute=createdAt&sortOrder=desc&containerId='
                + str(self.tsg_info_dic['id']),
                headers=self.headers,
                verify=self.ca_bundle,
                proxies=self.proxy).json()
        except Exception as err_:
            self.logger.error(
                'CAhandler.revoke(): request get aborted with err: {0}'.format(
                    err_))
            cert_list = []

        if 'certificates' in cert_list:
            try:
                cert_id = cert_list['certificates'][0]['certificateId']
                data_dic = {'reason': rev_reason, 'time': rev_date}
                try:
                    detail = self._api_post(
                        self.api_host + '/certificates/' + str(cert_id) +
                        '/revocationrequest', data_dic)
                    code = 200
                    message = None
                except Exception as err:
                    self.logger.error(
                        'CAhandler.revoke(): _api_post got aborted with err: {0}'
                        .format(err))
                    code = 500
                    message = 'urn:ietf:params:acme:error:serverInternal'
                    detail = 'Revocation operation failed'
            except Exception:
                code = 404
                message = 'urn:ietf:params:acme:error:serverInternal'
                detail = 'CertificateID could not be found'
        else:
            code = 404
            message = 'urn:ietf:params:acme:error:serverInternal'
            detail = 'Cert could not be found'

        return (code, message, detail)
예제 #3
0
    def revoke(self, cert, rev_reason='unspecified', rev_date=None):
        """ revoke certificate """
        self.logger.debug('CAhandler.revoke()')

        # overwrite revocation date - we ignore what has been submitted
        rev_date = uts_to_date_utc(uts_now(), '%Y%m%d%H%M%SZ')
        rev_reason = 0

        if self.xdb_file:
            # load ca cert and key
            (_ca_key, _ca_cert, ca_id) = self._ca_load()

            serial = cert_serial_get(self.logger, cert)
            if serial:
                serial = '{:X}'.format(serial)

            if ca_id and serial:
                # check if certificate has alreay been revoked:
                if not self._revocation_search('serial', serial):
                    rev_dic = {
                        'caID': ca_id,
                        'serial': serial,
                        'date': rev_date,
                        'invaldate': rev_date,
                        'reasonBit': rev_reason
                    }
                    row_id = self._revocation_insert(rev_dic)
                    if row_id:
                        code = 200
                        message = None
                        detail = None
                    else:
                        code = 500
                        message = 'urn:ietf:params:acme:error:serverInternal'
                        detail = 'database update failed'
                else:
                    code = 400
                    message = 'urn:ietf:params:acme:error:alreadyRevoked'
                    detail = 'Certificate has already been revoked'
            else:
                code = 500
                message = 'urn:ietf:params:acme:error:serverInternal'
                detail = 'certificate lookup failed'
        else:
            code = 500
            message = 'urn:ietf:params:acme:error:serverInternal'
            detail = 'configuration error'

        self.logger.debug('Certificate.revoke() ended')
        return (code, message, detail)
예제 #4
0
    def _convert_data(self, cert_list):
        """ convert data from uts to real date """
        self.logger.debug('Housekeeping._convert_dates()')
        for cert in cert_list:
            expire_list = ('order.expires', 'authorization.expires',
                           'challenge.expires')
            for ele in expire_list:
                if ele in cert and cert[ele]:
                    cert[ele] = uts_to_date_utc(cert[ele], '%Y-%m-%d %H:%M:%S')

            # set uts to 0 if we do not have them in dictionary
            if 'certificate.issue_uts' not in cert or 'certificate.expire_uts' not in cert:
                cert['certificate.issue_uts'] = 0
                cert['certificate.expire_uts'] = 0

            # if uts is zero we try to get the dates from certificate
            if cert['certificate.issue_uts'] == 0 or cert[
                    'certificate.expire_uts'] == 0:
                # cover cases without certificate in dict
                if 'certificate.cert_raw' in cert:
                    (issue_uts,
                     expire_uts) = cert_dates_get(self.logger,
                                                  cert['certificate.cert_raw'])
                    cert['certificate.issue_uts'] = issue_uts
                    cert['certificate.expire_uts'] = expire_uts
                else:
                    cert['certificate.issue_uts'] = 0
                    cert['certificate.expire_uts'] = 0

            if cert['certificate.issue_uts'] > 0 and cert[
                    'certificate.expire_uts'] > 0:
                cert['certificate.issue_date'] = uts_to_date_utc(
                    cert['certificate.issue_uts'], '%Y-%m-%d %H:%M:%S')
                cert['certificate.expire_date'] = uts_to_date_utc(
                    cert['certificate.expire_uts'], '%Y-%m-%d %H:%M:%S')
            else:
                cert['certificate.issue_date'] = ''
                cert['certificate.expire_date'] = ''

        # add serial number
            if 'certificate.cert_raw' in cert:
                try:
                    cert['certificate.serial'] = cert_serial_get(
                        self.logger, cert['certificate.cert_raw'])
                except BaseException:
                    cert['certificate.serial'] = ''

        return cert_list
    def trigger(self, payload):
        """ process trigger message and return certificate """
        self.logger.debug('CAhandler.trigger()')

        error = None
        cert_bundle = None
        cert_raw = None

        if payload:
            # decode payload
            cert = b64_decode(self.logger, payload)
            try:
                # cert is a base64 encoded pem object
                cert_raw = b64_encode(self.logger, cert_pem2der(cert))
            except BaseException:
                # cert is a binary der encoded object
                cert_raw = b64_encode(self.logger, cert)

            # lookup REST-PATH of issuing CA
            ca_dic = self._ca_get_properties('name', self.ca_name)
            if 'href' in ca_dic:
                # get serial from pem file
                serial = cert_serial_get(self.logger, cert_raw)
                if serial:
                    # get certificate information via rest by search for ca+ serial
                    cert_list = self._cert_get_properties(
                        serial, ca_dic['href'])
                    # the first entry is the cert we are looking for
                    if 'certificates' in cert_list and len(
                            cert_list['certificates'][0]) > 0:
                        cert_dic = cert_list['certificates'][0]
                        cert_bundle = self._pem_cert_chain_generate(cert_dic)
                    else:
                        error = 'no certifcates found in rest query'
                else:
                    error = 'serial number lookup via rest failed'
            else:
                error = 'CA could not be found'
        else:
            error = 'No payload given'

        self.logger.debug(
            'CAhandler.trigger() ended with error: {0}'.format(error))
        return (error, cert_bundle, cert_raw)
    def revoke(self, cert, rev_reason='unspecified', rev_date=None):
        """ revoke certificate """
        self.logger.debug('CAhandler.revoke({0}: {1})'.format(rev_reason, rev_date))
        code = None
        message = None
        detail = None

        # overwrite revocation date - we ignore what has been submitted
        rev_date = uts_to_date_utc(uts_now(), '%y%m%d%H%M%SZ')

        if 'issuing_ca_crl' in self.issuer_dict and self.issuer_dict['issuing_ca_crl']:
            # load ca cert and key
            (ca_key, ca_cert) = self._ca_load()
            # turn of chain_check due to issues in pyopenssl (check is not working if key-usage is set)
            # result = self._certificate_chain_verify(cert, ca_cert)

            # proceed if the cert and ca-cert belong together
            # if not result:
            serial = cert_serial_get(self.logger, cert)
            # serial = serial.replace('0x', '')
            if ca_key and ca_cert and serial:
                serial = hex(serial).replace('0x', '')
                if os.path.exists(self.issuer_dict['issuing_ca_crl']):
                    # existing CRL
                    with open(self.issuer_dict['issuing_ca_crl'], 'r') as fso:
                        crl = crypto.load_crl(crypto.FILETYPE_PEM, fso.read())
                    # check CRL already contains serial
                    sn_match = self._crl_check(crl, serial)
                else:
                    # new CRL
                    crl = crypto.CRL()
                    sn_match = None

                # this is the revocation operation
                if not sn_match:
                    revoked = crypto.Revoked()
                    revoked.set_reason(convert_string_to_byte(rev_reason))
                    revoked.set_serial(convert_string_to_byte(serial))
                    revoked.set_rev_date(convert_string_to_byte(rev_date))
                    crl.add_revoked(revoked)
                    # save CRL
                    crl_text = crl.export(ca_cert, ca_key, crypto.FILETYPE_PEM, 7, convert_string_to_byte('sha256'))
                    with open(self.issuer_dict['issuing_ca_crl'], 'wb') as fso:
                        fso.write(crl_text)
                    code = 200
                else:
                    code = 400
                    message = 'urn:ietf:params:acme:error:alreadyRevoked'
                    detail = 'Certificate has already been revoked'
            else:
                code = 400
                message = 'urn:ietf:params:acme:error:serverInternal'
                detail = 'configuration error'
            #else:
            #    code = 400
            #    message = 'urn:ietf:params:acme:error:serverInternal'
            #    detail = result
        else:
            code = 400
            message = 'urn:ietf:params:acme:error:serverInternal'
            detail = 'Unsupported operation'

        self.logger.debug('CAhandler.revoke() ended')
        return(code, message, detail)