def enroll(self, csr):
        """ enroll certificate from NCLM """
        self.logger.debug('CAhandler.enroll()')
        cert_bundle = None
        error = None
        cert_raw = None

        # recode csr
        csr = textwrap.fill(b64_url_recode(self.logger, csr), 64) + '\n'

        if self.est_host:
            (error, ca_pem) = self._cacerts_get()
            if not error:
                if ca_pem:
                    if self.est_user or self.est_client_cert:
                        (error, cert_raw) = self._simpleenroll(csr)
                    else:
                        error = 'Authentication information missing'
                        self.logger.error('CAhandler.enroll(): {0}'.format(error))
                    if not error:
                        cert_bundle = cert_raw + ca_pem
                        cert_raw = cert_raw.replace('-----BEGIN CERTIFICATE-----\n', '')
                        cert_raw = cert_raw.replace('-----END CERTIFICATE-----\n', '')
                        cert_raw = cert_raw.replace('\n', '')
                    else:
                        self.logger.error('CAhandler.enroll(): {0}'.format(error))
                else:
                    error = 'no CA certificates found'
                    self.logger.error('CAhandler.enroll(): {0}'.format(error))
            else:
                self.logger.error('CAhandler.enroll(): {0}'.format(error))

        self.logger.debug('Certificate.enroll() ended')
        return(error, cert_bundle, cert_raw, None)
Esempio n. 2
0
    def enroll(self, csr):
        """ enroll certificate from via MS certsrv """
        self.logger.debug('CAhandler.enroll()')
        cert_bundle = None
        error = None
        cert_raw = None

        if self.openssl_bin:

            # prepare the CSR to be signed
            csr = build_pem_file(self.logger, None, b64_url_recode(self.logger, csr), None, True)
            # dump csr key
            self._file_save('{0}/csr.pem'.format(self.tmp_dir), csr)

            # build openssl command and run it
            openssl_cmd = self._opensslcmd_build()
            rcode = subprocess.call(openssl_cmd)
            if rcode:
                self.logger.error('CAhandler.enroll(): failed: {0}'.format(rcode))
                error = 'rc from enrollment not 0'

            # generate certificates we need to return
            if os.path.isfile('{0}/cert.pem'.format(self.tmp_dir)):
                (cert_bundle, cert_raw) = self._certs_bundle()
            else:
                error = 'Enrollment failed'

            # delete temporary files
            self._tmp_dir_delete()

        else:
            error = 'Config incomplete'

        self.logger.debug('Certificate.enroll() ended with error: {0}'.format(error))
        return(error, cert_bundle, cert_raw, None)
 def _account_check(self, account_name, certificate):
     """ check account """
     self.logger.debug('Certificate.issuer_check()')
     try:
         result = self.dbstore.certificate_account_check(
             account_name, b64_url_recode(self.logger, certificate))
     except BaseException as err_:
         self.logger.critical(
             'acme2certifier database error in Certificate._account_check(): {0}'
             .format(err_))
         result = None
     return result
Esempio n. 4
0
    def enroll(self, csr):
        """ enroll certificate from via MS certsrv """
        self.logger.debug('CAhandler.enroll({0})'.format(self.template))
        cert_bundle = None
        error = None
        cert_raw = None

        if self.host and self.user and self.password and self.template:
            # setup certserv
            ca_server = Certsrv(self.host, self.user, self.password, self.auth_method, self.ca_bundle, proxies=self.proxy)

            # check connection and credentials
            auth_check = self._check_credentials(ca_server)
            if auth_check:
                # recode csr
                csr = textwrap.fill(b64_url_recode(self.logger, csr), 64) + '\n'

                # get ca_chain
                try:
                    ca_pkcs7 = convert_byte_to_string(ca_server.get_chain(encoding='b64'))
                    ca_pem = self._pkcs7_to_pem(ca_pkcs7)
                    # replace crlf with lf
                    # ca_pem = ca_pem.replace('\r\n', '\n')
                except BaseException as err_:
                    ca_pem = None
                    self.logger.error('ca_server.get_chain() failed with error: {0}'.format(err_))

                try:
                    cert_raw = convert_byte_to_string(ca_server.get_cert(csr, self.template))
                    # replace crlf with lf
                    cert_raw = cert_raw.replace('\r\n', '\n')
                except BaseException as err_:
                    cert_raw = None
                    self.logger.error('ca_server.get_cert() failed with error: {0}'.format(err_))

                if ca_pem and cert_raw:
                    cert_bundle = cert_raw + ca_pem
                    cert_raw = cert_raw.replace('-----BEGIN CERTIFICATE-----\n', '')
                    cert_raw = cert_raw.replace('-----END CERTIFICATE-----\n', '')
                    cert_raw = cert_raw.replace('\n', '')
                else:
                    self.logger.error('cert bundling failed')
                    error = 'cert bundling failed'
            else:
                self.logger.error('Connection or Credentialcheck failed')
                error = 'Connection or Credentialcheck failed.'
        else:
            self.logger.error('Config incomplete')
            error = 'Config incomplete'

        self.logger.debug('Certificate.enroll() ended')
        return(error, cert_bundle, cert_raw, None)
Esempio n. 5
0
    def _certificate_chain_verify(self, cert, ca_cert):
        """ verify certificate chain """
        self.logger.debug('CAhandler._certificate_chain_verify()')

        error = None
        pem_file = build_pem_file(self.logger, None,
                                  b64_url_recode(self.logger, cert), True)

        try:
            cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_file)
        except Exception as err_:
            cert = None
            error = err_

        if not error:
            # Create a certificate store and add ca cert(s)
            try:
                store = crypto.X509Store()
                store.add_cert(ca_cert)
            except Exception:
                error = 'issuing certificate could not be added to trust-store'

            if not error:
                # add ca chain to truststore
                for cert_name in self.ca_cert_chain_list:
                    try:
                        with open(cert_name, 'r') as fso:
                            cain_cert = crypto.load_certificate(
                                crypto.FILETYPE_PEM, fso.read())
                        store.add_cert(cain_cert)
                    except Exception:
                        error = 'certificate {0} could not be added to trust store'.format(
                            cert_name)

            if not error:
                # Create a certificate context using the store and the downloaded certificate
                store_ctx = crypto.X509StoreContext(store, cert)
                # Verify the certificate, returns None if it can validate the certificate
                try:
                    # pylint: disable=E1111
                    result = store_ctx.verify_certificate()
                except Exception as err_:
                    result = str(err_)
            else:
                result = error
        else:
            result = 'certificate could not get parsed'

        self.logger.debug(
            'CAhandler._certificate_chain_verify() ended with {0}'.format(
                result))
        return result
Esempio n. 6
0
    def _csr_process(self, order_name, csr):
        """ process certificate signing request """
        self.logger.debug('Order._csr_process({0})'.format(order_name))

        order_dic = self._info(order_name)

        if order_dic:
            # change decoding from b64url to b64
            csr = b64_url_recode(self.logger, csr)

            with Certificate(self.debug, self.server_name,
                             self.logger) as certificate:
                # certificate = Certificate(self.debug, self.server_name, self.logger)
                certificate_name = certificate.store_csr(order_name, csr)
                if certificate_name:
                    (error, detail) = certificate.enroll_and_store(
                        certificate_name, csr)
                    if not error:
                        code = 200
                        message = certificate_name
                        # detail = None
                    else:
                        code = 400
                        message = error
                        if message == 'urn:ietf:params:acme:error:serverInternal':
                            code = 500
                else:
                    code = 500
                    message = 'urn:ietf:params:acme:error:serverInternal'
                    detail = 'CSR processing failed'
        else:
            code = 400
            message = 'urn:ietf:params:acme:error:unauthorized'
            detail = 'order: {0} not found'.format(order_name)

        self.logger.debug(
            'Order._csr_process() ended with order:{0} {1}:{2}:{3}'.format(
                order_name, code, message, detail))
        return (code, message, detail)
Esempio n. 7
0
    def revoke(self, _cert, _rev_reason, _rev_date):
        """ revoke certificate """
        self.logger.debug('CAhandler.revoke()')

        user_key = None
        code = 500
        message = 'urn:ietf:params:acme:error:serverInternal'
        detail = None

        try:
            certpem = '-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n'.format(
                textwrap.fill(str(b64_url_recode(self.logger, _cert)), 64))
            cert = josepy.ComparableX509(
                crypto.load_certificate(crypto.FILETYPE_PEM, certpem))

            if os.path.exists(self.keyfile):
                user_key = self._user_key_load()
            net = client.ClientNetwork(user_key)

            if user_key:
                directory = messages.Directory.from_json(
                    net.get('{0}{1}'.format(
                        self.url, self.path_dic['directory_path'])).json())
                acmeclient = client.ClientV2(directory, net=net)
                reg = messages.NewRegistration.from_data(
                    key=user_key,
                    email=self.email,
                    terms_of_service_agreed=True,
                    only_return_existing=True)

                if not self.account:
                    self._account_lookup(acmeclient, reg, directory)

                if self.account:
                    regr = messages.RegistrationResource(
                        uri="{0}{1}{2}".format(self.url,
                                               self.path_dic['acct_path'],
                                               self.account),
                        body=reg)
                    self.logger.debug(
                        'CAhandler.revoke() checking remote registration status'
                    )
                    regr = acmeclient.query_registration(regr)

                    if regr.body.status == "valid":
                        self.logger.debug(
                            'CAhandler.revoke() issuing revocation order')
                        acmeclient.revoke(cert, 1)
                        self.logger.debug('CAhandler.revoke() successfull')
                        code = 200
                        message = None
                    else:
                        self.logger.error(
                            'CAhandler.enroll: Bad ACME account: {0}'.format(
                                regr.body.error))
                        detail = 'Bad ACME account: {0}'.format(
                            regr.body.error)

                else:
                    self.logger.error(
                        'CAhandler.revoke(): could not find account key and lookup at acme-endpoint failed.'
                    )
                    detail = 'account lookup failed'
            else:
                self.logger.error(
                    'CAhandler.revoke(): could not load user_key {0}'.format(
                        self.keyfile))
                detail = 'Internal Error'

        except Exception as err:
            self.logger.error('CAhandler.enroll: error: {0}'.format(err))
            detail = str(err)

        finally:
            del user_key

        self.logger.debug('Certificate.revoke() ended')
        return (code, message, detail)
Esempio n. 8
0
    def enroll(self, csr):
        """ enroll certificate  """
        # pylint: disable=R0915
        self.logger.debug('CAhandler.enroll()')

        csr_pem = '-----BEGIN CERTIFICATE REQUEST-----\n{0}\n-----END CERTIFICATE REQUEST-----\n'.format(
            textwrap.fill(str(b64_url_recode(self.logger, csr)), 64))

        cert_bundle = None
        error = None
        cert_raw = None
        poll_indentifier = None
        user_key = None

        # check CN and SAN against black/whitlist
        result = self._csr_check(csr)

        if result:
            try:
                user_key = self._user_key_load()
                net = client.ClientNetwork(user_key)

                directory = messages.Directory.from_json(
                    net.get('{0}{1}'.format(
                        self.url, self.path_dic['directory_path'])).json())
                acmeclient = client.ClientV2(directory, net=net)
                reg = messages.Registration.from_data(
                    key=user_key, terms_of_service_agreed=True)

                if self.account:
                    regr = messages.RegistrationResource(
                        uri="{0}{1}{2}".format(self.url,
                                               self.path_dic['acct_path'],
                                               self.account),
                        body=reg)
                    self.logger.debug(
                        'CAhandler.enroll(): checking remote registration status'
                    )
                    regr = acmeclient.query_registration(regr)
                else:
                    # new account or existing account with missing account id
                    regr = self._account_register(acmeclient, user_key,
                                                  directory)

                if regr.body.status == "valid":
                    self.logger.debug(
                        'CAhandler.enroll() issuing signing order')
                    self.logger.debug('CAhandler.enroll() CSR: ' +
                                      str(csr_pem))
                    order = acmeclient.new_order(csr_pem)

                    # query challenges
                    for authzr in list(order.authorizations):
                        (challenge_name, challenge_content,
                         challenge) = self._http_challenge_info(
                             authzr, user_key)
                        if challenge_name and challenge_content:
                            # store challenge in database to allow challenge validation
                            self._challenge_store(challenge_name,
                                                  challenge_content)
                            _auth_response = acmeclient.answer_challenge(
                                challenge, challenge.chall.response(user_key)
                            )  # lgtm [py/unused-local-variable]

                    self.logger.debug(
                        'CAhandler.enroll() polling for certificate')
                    order = acmeclient.poll_and_finalize(order)

                    if order.fullchain_pem:
                        self.logger.debug('CAhandler.enroll() successful')
                        cert_bundle = str(order.fullchain_pem)
                        cert_raw = str(
                            base64.b64encode(
                                crypto.dump_certificate(
                                    crypto.FILETYPE_ASN1,
                                    crypto.load_certificate(
                                        crypto.FILETYPE_PEM, cert_bundle))),
                            'utf-8')
                    else:
                        # raise Exception("Error getting certificate: " + str(order.error))
                        self.logger.error(
                            'CAhandler.enroll: Error getting certificate: {0}'.
                            format(order.error))
                        error = 'Error getting certificate: {0}'.format(
                            order.error)
                else:
                    self.logger.error(
                        'CAhandler.enroll: Bad ACME account: {0}'.format(
                            regr.body.error))
                    error = 'Bad ACME account: {0}'.format(regr.body.error)
                    # raise Exception("Bad ACME account: " + str(regr.body.error))

            except Exception as err:
                self.logger.error('CAhandler.enroll: error: {0}'.format(err))
                error = str(err)
            finally:
                del user_key

        else:
            error = 'CSR rejected. Either CN or SANs are not allowed by policy'
            self.logger.error(
                'CAhandler.enroll: CSR rejected. Either CN or SANs are not allowed by policy.'
            )

        self.logger.debug('Certificate.enroll() ended')
        return (error, cert_bundle, cert_raw, poll_indentifier)
    def enroll(self, csr):
        """ enroll certificate """
        self.logger.debug('CAhandler.enroll()')

        cert_bundle = None
        cert_raw = None

        error = self._config_check()

        if not error:
            try:
                # check CN and SAN against black/whitlist
                (result, enforce_cn) = self._csr_check(csr)

                if result:
                    # prepare the CSR
                    csr = build_pem_file(self.logger, None, b64_url_recode(self.logger, csr), None, True)

                    # load ca cert and key
                    (ca_key, ca_cert) = self._ca_load()

                    # load certificate_profile (if applicable)
                    if self.openssl_conf:
                        cert_extension_dic = self._certificate_extensions_load()
                    else:
                        cert_extension_dic = []

                    # creating a rest form CSR
                    req = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr)
                    subject = req.get_subject()
                    if self.cn_enforce and enforce_cn:
                        self.logger.info('CAhandler.enroll(): overwrite CN with {0}'.format(enforce_cn))
                        setattr(subject, 'CN', enforce_cn)

                    # sign csr
                    cert = crypto.X509()
                    cert.gmtime_adj_notBefore(0)
                    cert.gmtime_adj_notAfter(self.cert_validity_days * 86400)
                    cert.set_issuer(ca_cert.get_subject())
                    cert.set_subject(subject)
                    cert.set_pubkey(req.get_pubkey())
                    cert.set_serial_number(uuid.uuid4().int)
                    cert.set_version(2)
                    cert.add_extensions(req.get_extensions())

                    default_extension_list = [
                        crypto.X509Extension(convert_string_to_byte('subjectKeyIdentifier'), False, convert_string_to_byte('hash'), subject=cert),
                        crypto.X509Extension(convert_string_to_byte('authorityKeyIdentifier'), False, convert_string_to_byte('keyid:always'), issuer=ca_cert),
                        crypto.X509Extension(convert_string_to_byte('basicConstraints'), True, convert_string_to_byte('CA:FALSE')),
                        crypto.X509Extension(convert_string_to_byte('extendedKeyUsage'), False, convert_string_to_byte('clientAuth,serverAuth')),
                    ]

                    if cert_extension_dic:
                        try:
                            cert.add_extensions(self._certificate_extensions_add(cert_extension_dic, cert, ca_cert))
                        except BaseException as err_:
                            self.logger.error('CAhandler.enroll() error while loading extensions form file. Use default set.\nerror: {0}'.format(err_))
                            cert.add_extensions(default_extension_list)
                    else:
                        # add keyUsage if it does not exist in CSR
                        ku_is_in = False
                        for ext in req.get_extensions():
                            if convert_byte_to_string(ext.get_short_name()) == 'keyUsage':
                                ku_is_in = True
                        if not ku_is_in:
                            default_extension_list.append(crypto.X509Extension(convert_string_to_byte('keyUsage'), True, convert_string_to_byte('digitalSignature,keyEncipherment')))

                        # add default extensions
                        cert.add_extensions(default_extension_list)

                    cert.sign(ca_key, 'sha256')

                    # store certifiate
                    self._certificate_store(cert)
                    # create bundle and raw cert
                    cert_bundle = self._pemcertchain_generate(convert_byte_to_string(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)), open(self.issuer_dict['issuing_ca_cert']).read())
                    cert_raw = convert_byte_to_string(base64.b64encode(crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)))
                else:
                    error = 'urn:ietf:params:acme:badCSR'

            except BaseException as err:
                self.logger.error('CAhandler.enroll() error: {0}'.format(err))
                error = 'Unknown exception'

        self.logger.debug('CAhandler.enroll() ended')
        return(error, cert_bundle, cert_raw, None)
    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)
    def enroll(self, csr):
        """ enroll certificate  """
        # pylint: disable=R0914
        self.logger.debug('CAhandler.enroll()')

        cert_bundle = None
        cert_raw = None
        error = self._config_check()

        if not error:
            request_name = self._requestname_get(csr)
            if request_name:
                # import CSR to database
                _csr_info = self._csr_import(csr, request_name)

                # prepare the CSR to be signed
                csr = build_pem_file(self.logger, None, b64_url_recode(self.logger, csr), None, True)

                # load ca cert and key
                (ca_key, ca_cert, ca_id) = self._ca_load()

                if ca_key and ca_cert and ca_id:
                    # load request
                    req = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr)

                    # copy cn of request
                    subject = req.get_subject()
                    # rewrite CN if required
                    if not subject.CN:
                        self.logger.info('rewrite CN to {0}'.format(request_name))
                        subject.CN = request_name

                    # create certificate object
                    cert = crypto.X509()
                    cert.set_pubkey(req.get_pubkey())
                    cert.set_version(2)
                    cert.set_serial_number(uuid.uuid4().int & (1<<63)-1)
                    cert.set_issuer(ca_cert.get_subject())

                    # load template if configured
                    if self.template_name:
                        (dn_dic, template_dic) = self._template_load()
                    else:
                        dn_dic = {}
                        template_dic = {}

                    # set cert_validity
                    if 'validity' in template_dic:
                        self.logger.info('take validity from template: {0}'.format(template_dic['validity']))
                        # take validity from template
                        cert_validity = template_dic['validity']
                    else:
                        cert_validity = self.cert_validity_days
                    cert.gmtime_adj_notBefore(0)
                    cert.gmtime_adj_notAfter(cert_validity * 86400)

                    # get extension list from CSR
                    csr_extensions_list = req.get_extensions()
                    extension_list = self._extension_list_generate(template_dic, cert, ca_cert, csr_extensions_list)

                    # add extensions (copy from CSR and take the ones we constructed)
                    # cert.add_extensions(csr_extensions_list)
                    cert.add_extensions(extension_list)

                    if dn_dic:
                        self.logger.info('modify subject with template data')
                        subject = self._subject_modify(subject, dn_dic)
                    cert.set_subject(subject)

                    # sign csr
                    cert.sign(ca_key, 'sha256')
                    serial = cert.get_serial_number()

                    # get hsshes
                    issuer_hash = ca_cert.subject_name_hash() & 0x7fffffff
                    name_hash = cert.subject_name_hash() & 0x7fffffff

                    # store certificate
                    self._store_cert(ca_id, request_name, '{:X}'.format(serial), convert_byte_to_string(b64_encode(self.logger, crypto.dump_certificate(crypto.FILETYPE_ASN1, cert))), name_hash, issuer_hash)

                    cert_bundle = self._pemcertchain_generate(convert_byte_to_string(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)), convert_byte_to_string(crypto.dump_certificate(crypto.FILETYPE_PEM, ca_cert)))
                    cert_raw = convert_byte_to_string(b64_encode(self.logger, crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)))
                else:
                    error = 'ca lookup failed'
            else:
                error = 'request_name lookup failed'
        self.logger.debug('Certificate.enroll() ended')
        return(error, cert_bundle, cert_raw, None)
    def enroll(self, csr):
        """ enroll certificate  """
        self.logger.debug('CAhandler.enroll()')

        csr_pem = '-----BEGIN CERTIFICATE REQUEST-----\n{0}\n-----END CERTIFICATE REQUEST-----\n'.format(textwrap.fill(str(b64_url_recode(self.logger, csr)), 64))

        cert_bundle = None
        error = None
        cert_raw = None
        poll_indentifier = None
        key = None

        try:
            self.logger.debug('CAhandler.enroll() opening key')
            with open(self.keyfile, "r") as keyf:
                key = josepy.JWKRSA.json_loads(keyf.read())

            net = client.ClientNetwork(key)
            directory = messages.Directory.from_json(net.get(self.url).json())
            acmeclient = client.ClientV2(directory, net=net)
            reg = messages.Registration.from_data(key=key, terms_of_service_agreed=True)
            regr = messages.RegistrationResource(uri="{}/account/{}".format(self.url, self.account), body=reg)
            self.logger.debug('CAhandler.enroll() checking remote registration status')
            regr = acmeclient.query_registration(regr)

            if regr.body.status != "valid":
                raise Exception("Bad ACME account: " + str(regr.body.error))

            self.logger.debug('CAhandler.enroll() issuing signing order')
            self.logger.debug('CAhandler.enroll() CSR: ' + str(csr_pem))
            order = acmeclient.new_order(csr_pem)

            self.logger.debug('CAhandler.enroll() polling for certificate')
            order = acmeclient.poll_and_finalize(order)

            if not order.fullchain_pem:
                raise Exception("Error getting certificate: " + str(order.error))

            self.logger.debug('CAhandler.enroll() successful')
            cert_bundle = str(order.fullchain_pem)
            cert_raw = str(base64.b64encode(crypto.dump_certificate(crypto.FILETYPE_ASN1, crypto.load_certificate(crypto.FILETYPE_PEM, cert_bundle))), 'utf-8')

        except Exception as e:
            self.logger.error(str(e))
            error = str(e)

        finally:
            del key

        self.logger.debug('Certificate.enroll() ended')
        return(error, cert_bundle, cert_raw, poll_indentifier)
    def revoke(self, _cert, _rev_reason, _rev_date):
        """ revoke certificate """
        self.logger.debug('CAhandler.revoke()')

        certpem = '-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n'.format(textwrap.fill(str(b64_url_recode(self.logger, _cert)), 64))
        cert = josepy.ComparableX509(crypto.load_certificate(crypto.FILETYPE_PEM, certpem))

        code = 200
        message = None
        detail = None

        try:
            self.logger.debug('CAhandler.revoke() opening key')
            with open(self.keyfile, "r") as keyf:
                key = josepy.JWKRSA.json_loads(keyf.read())

            net = client.ClientNetwork(key)
            directory = messages.Directory.from_json(net.get(self.url).json())
            acmeclient = client.ClientV2(directory, net=net)
            reg = messages.Registration.from_data(key=key, terms_of_service_agreed=True)
            regr = messages.RegistrationResource(uri="{}/account/{}".format(self.url, self.account), body=reg)
            self.logger.debug('CAhandler.revoke() checking remote registration status')
            regr = acmeclient.query_registration(regr)

            if regr.body.status != "valid":
                raise Exception("Bad ACME account: " + str(regr.body.error))

            self.logger.debug('CAhandler.revoke() issuing revocation order')
            acmeclient.revoke(cert, 1)
            self.logger.debug('CAhandler.revoke() successfull')


        except Exception as e:
            self.logger.error(str(e))
            code = 500
            message = 'urn:ietf:params:acme:error:serverInternal'
            detail = str(e)

        finally:
            del key

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