Exemplo n.º 1
0
    def get_ordered_certificate(self, pending_cert):
        acme_client, registration = setup_acme_client(pending_cert.authority)
        order_info = authorization_service.get(pending_cert.external_id)
        dns_provider = dns_provider_service.get(pending_cert.dns_provider_id)
        dns_provider_options = dns_provider.options
        dns_provider_type = self.get_dns_provider(dns_provider.provider_type)
        try:
            authorizations = get_authorizations(acme_client,
                                                order_info.account_number,
                                                order_info.domains,
                                                dns_provider_type,
                                                dns_provider_options)
        except ClientError:
            current_app.logger.error(
                "Unable to resolve pending cert: {}".format(pending_cert.name),
                exc_info=True)
            return False

        authorizations = finalize_authorizations(acme_client,
                                                 order_info.account_number,
                                                 dns_provider_type,
                                                 authorizations,
                                                 dns_provider_options)
        pem_certificate, pem_certificate_chain = request_certificate(
            acme_client, authorizations, pending_cert.csr)
        cert = {
            'body': "\n".join(str(pem_certificate).splitlines()),
            'chain': "\n".join(str(pem_certificate_chain).splitlines()),
            'external_id': str(pending_cert.external_id)
        }
        return cert
Exemplo n.º 2
0
    def get_ordered_certificate(self, pending_cert):
        acme_client, registration = self.acme.setup_acme_client(pending_cert.authority)
        order_info = authorization_service.get(pending_cert.external_id)
        if pending_cert.dns_provider_id:
            dns_provider = dns_provider_service.get(pending_cert.dns_provider_id)

            for domain in order_info.domains:
                # Currently, we only support specifying one DNS provider per certificate, even if that
                # certificate has multiple SANs that may belong to different providers.
                self.acme.dns_providers_for_domain[domain] = [dns_provider]
        else:
            for domain in order_info.domains:
                self.acme.autodetect_dns_providers(domain)

        try:
            order = acme_client.new_order(pending_cert.csr)
        except WildcardUnsupportedError:
            raise Exception("The currently selected ACME CA endpoint does"
                            " not support issuing wildcard certificates.")
        try:
            authorizations = self.acme.get_authorizations(acme_client, order, order_info)
        except ClientError:
            current_app.logger.error("Unable to resolve pending cert: {}".format(pending_cert.name), exc_info=True)
            return False

        authorizations = self.acme.finalize_authorizations(acme_client, authorizations)
        pem_certificate, pem_certificate_chain = self.acme.request_certificate(
            acme_client, authorizations, order)
        cert = {
            'body': "\n".join(str(pem_certificate).splitlines()),
            'chain': "\n".join(str(pem_certificate_chain).splitlines()),
            'external_id': str(pending_cert.external_id)
        }
        return cert
Exemplo n.º 3
0
    def get_ordered_certificate(self, pending_cert):
        self.acme = AcmeHandler()
        acme_client, registration = self.acme.setup_acme_client(pending_cert.authority)
        order_info = authorization_service.get(pending_cert.external_id)
        if pending_cert.dns_provider_id:
            dns_provider = dns_provider_service.get(pending_cert.dns_provider_id)

            for domain in order_info.domains:
                # Currently, we only support specifying one DNS provider per certificate, even if that
                # certificate has multiple SANs that may belong to different providers.
                self.acme.dns_providers_for_domain[domain] = [dns_provider]
        else:
            for domain in order_info.domains:
                self.acme.autodetect_dns_providers(domain)

        try:
            order = acme_client.new_order(pending_cert.csr)
        except WildcardUnsupportedError:
            raise Exception("The currently selected ACME CA endpoint does"
                            " not support issuing wildcard certificates.")
        try:
            authorizations = self.acme.get_authorizations(acme_client, order, order_info)
        except ClientError:
            current_app.logger.error("Unable to resolve pending cert: {}".format(pending_cert.name), exc_info=True)
            return False

        authorizations = self.acme.finalize_authorizations(acme_client, authorizations)
        pem_certificate, pem_certificate_chain = self.acme.request_certificate(
            acme_client, authorizations, order)
        cert = {
            'body': "\n".join(str(pem_certificate).splitlines()),
            'chain': "\n".join(str(pem_certificate_chain).splitlines()),
            'external_id': str(pending_cert.external_id)
        }
        return cert
Exemplo n.º 4
0
    def get_ordered_certificates(self, pending_certs):
        self.acme = AcmeDnsHandler()
        self.acme_dns_challenge = AcmeDnsChallenge()
        pending = []
        certs = []
        for pending_cert in pending_certs:
            try:
                acme_client, registration = self.acme.setup_acme_client(
                    pending_cert.authority
                )
                order_info = authorization_service.get(pending_cert.external_id)
                if pending_cert.dns_provider_id:
                    dns_provider = dns_provider_service.get(
                        pending_cert.dns_provider_id
                    )

                    for domain in order_info.domains:
                        # Currently, we only support specifying one DNS provider per certificate, even if that
                        # certificate has multiple SANs that may belong to different providers.
                        self.acme.dns_providers_for_domain[domain] = [dns_provider]
                else:
                    for domain in order_info.domains:
                        self.acme.autodetect_dns_providers(domain)

                try:
                    order = acme_client.new_order(pending_cert.csr)
                except WildcardUnsupportedError:
                    capture_exception()
                    metrics.send(
                        "get_ordered_certificates_wildcard_unsupported_error",
                        "counter",
                        1,
                    )
                    raise Exception(
                        "The currently selected ACME CA endpoint does"
                        " not support issuing wildcard certificates."
                    )

                authorizations = self.acme.get_authorizations(
                    acme_client, order, order_info
                )

                pending.append(
                    {
                        "acme_client": acme_client,
                        "authorizations": authorizations,
                        "pending_cert": pending_cert,
                        "order": order,
                    }
                )
            except (ClientError, ValueError, Exception) as e:
                capture_exception()
                metrics.send(
                    "get_ordered_certificates_pending_creation_error", "counter", 1
                )
                current_app.logger.error(
                    f"Unable to resolve pending cert: {pending_cert}", exc_info=True
                )

                error = e
                if globals().get("order") and order:
                    error += f" Order uri: {order.uri}"
                certs.append(
                    {"cert": False, "pending_cert": pending_cert, "last_error": e}
                )

        for entry in pending:
            try:
                entry["authorizations"] = self.acme.finalize_authorizations(
                    entry["acme_client"], entry["authorizations"]
                )
                pem_certificate, pem_certificate_chain = self.acme.request_certificate(
                    entry["acme_client"], entry["authorizations"], entry["order"]
                )

                cert = {
                    "body": "\n".join(str(pem_certificate).splitlines()),
                    "chain": "\n".join(str(pem_certificate_chain).splitlines()),
                    "external_id": str(entry["pending_cert"].external_id),
                }
                certs.append({"cert": cert, "pending_cert": entry["pending_cert"]})
            except (PollError, AcmeError, Exception) as e:
                capture_exception()
                metrics.send("get_ordered_certificates_resolution_error", "counter", 1)
                order_url = order.uri
                error = f"{e}. Order URI: {order_url}"
                current_app.logger.error(
                    f"Unable to resolve pending cert: {pending_cert}. "
                    f"Check out {order_url} for more information.",
                    exc_info=True,
                )
                certs.append(
                    {
                        "cert": False,
                        "pending_cert": entry["pending_cert"],
                        "last_error": error,
                    }
                )
                # Ensure DNS records get deleted
                self.acme_dns_challenge.cleanup(
                    entry["authorizations"], entry["acme_client"]
                )
        return certs
Exemplo n.º 5
0
    def get_ordered_certificates(self, pending_certs):
        pending = []
        certs = []
        for pending_cert in pending_certs:
            try:
                acme_client, registration = setup_acme_client(
                    pending_cert.authority)
                order_info = authorization_service.get(
                    pending_cert.external_id)
                dns_provider = dns_provider_service.get(
                    pending_cert.dns_provider_id)
                dns_provider_options = dns_provider.options
                dns_provider_type = self.get_dns_provider(
                    dns_provider.provider_type)
                try:
                    order = acme_client.new_order(pending_cert.csr)
                except WildcardUnsupportedError:
                    raise Exception(
                        "The currently selected ACME CA endpoint does"
                        " not support issuing wildcard certificates.")

                authorizations = get_authorizations(acme_client, order,
                                                    order_info,
                                                    dns_provider_type,
                                                    dns_provider_options)

                pending.append({
                    "acme_client": acme_client,
                    "account_number": order_info.account_number,
                    "dns_provider_type": dns_provider_type,
                    "authorizations": authorizations,
                    "pending_cert": pending_cert,
                    "order": order,
                    "dns_provider_options": dns_provider_options,
                })
            except (ClientError, ValueError, Exception) as e:
                current_app.logger.error(
                    "Unable to resolve pending cert: {}".format(pending_cert),
                    exc_info=True)
                certs.append({
                    "cert": False,
                    "pending_cert": pending_cert,
                    "last_error": e,
                })

        for entry in pending:
            try:
                entry["authorizations"] = finalize_authorizations(
                    entry["acme_client"],
                    entry["account_number"],
                    entry["dns_provider_type"],
                    entry["authorizations"],
                    entry["dns_provider_options"],
                )
                pem_certificate, pem_certificate_chain = request_certificate(
                    entry["acme_client"], entry["authorizations"],
                    entry["pending_cert"].csr, entry["order"])

                cert = {
                    'body': "\n".join(str(pem_certificate).splitlines()),
                    'chain':
                    "\n".join(str(pem_certificate_chain).splitlines()),
                    'external_id': str(entry["pending_cert"].external_id)
                }
                certs.append({
                    "cert": cert,
                    "pending_cert": entry["pending_cert"],
                })
            except (PollError, AcmeError, Exception):
                current_app.logger.error(
                    "Unable to resolve pending cert: {}".format(pending_cert),
                    exc_info=True)
                certs.append({
                    "cert": False,
                    "pending_cert": entry["pending_cert"],
                })
        return certs
Exemplo n.º 6
0
    def get_ordered_certificates(self, pending_certs):
        self.acme = AcmeHandler()
        pending = []
        certs = []
        for pending_cert in pending_certs:
            try:
                acme_client, registration = self.acme.setup_acme_client(
                    pending_cert.authority)
                order_info = authorization_service.get(
                    pending_cert.external_id)
                if pending_cert.dns_provider_id:
                    dns_provider = dns_provider_service.get(
                        pending_cert.dns_provider_id)

                    for domain in order_info.domains:
                        # Currently, we only support specifying one DNS provider per certificate, even if that
                        # certificate has multiple SANs that may belong to different providers.
                        self.acme.dns_providers_for_domain[domain] = [
                            dns_provider
                        ]
                else:
                    for domain in order_info.domains:
                        self.acme.autodetect_dns_providers(domain)

                try:
                    order = acme_client.new_order(pending_cert.csr)
                except WildcardUnsupportedError:
                    raise Exception(
                        "The currently selected ACME CA endpoint does"
                        " not support issuing wildcard certificates.")

                authorizations = self.acme.get_authorizations(
                    acme_client, order, order_info)

                pending.append({
                    "acme_client": acme_client,
                    "authorizations": authorizations,
                    "pending_cert": pending_cert,
                    "order": order,
                })
            except (ClientError, ValueError, Exception) as e:
                current_app.logger.error(
                    "Unable to resolve pending cert: {}".format(pending_cert),
                    exc_info=True)
                certs.append({
                    "cert": False,
                    "pending_cert": pending_cert,
                    "last_error": e,
                })

        for entry in pending:
            try:
                entry["authorizations"] = self.acme.finalize_authorizations(
                    entry["acme_client"],
                    entry["authorizations"],
                )
                pem_certificate, pem_certificate_chain = self.acme.request_certificate(
                    entry["acme_client"], entry["authorizations"],
                    entry["order"])

                cert = {
                    'body': "\n".join(str(pem_certificate).splitlines()),
                    'chain':
                    "\n".join(str(pem_certificate_chain).splitlines()),
                    'external_id': str(entry["pending_cert"].external_id)
                }
                certs.append({
                    "cert": cert,
                    "pending_cert": entry["pending_cert"],
                })
            except (PollError, AcmeError, Exception) as e:
                current_app.logger.error(
                    "Unable to resolve pending cert: {}".format(pending_cert),
                    exc_info=True)
                certs.append({
                    "cert": False,
                    "pending_cert": entry["pending_cert"],
                    "last_error": e,
                })
                # Ensure DNS records get deleted
                self.acme.cleanup_dns_challenges(
                    entry["acme_client"],
                    entry["authorizations"],
                )
        return certs
Exemplo n.º 7
0
    def get_ordered_certificates(self, pending_certs):
        self.acme = AcmeHandler()
        pending = []
        certs = []
        for pending_cert in pending_certs:
            try:
                acme_client, registration = self.acme.setup_acme_client(pending_cert.authority)
                order_info = authorization_service.get(pending_cert.external_id)
                if pending_cert.dns_provider_id:
                    dns_provider = dns_provider_service.get(pending_cert.dns_provider_id)

                    for domain in order_info.domains:
                        # Currently, we only support specifying one DNS provider per certificate, even if that
                        # certificate has multiple SANs that may belong to different providers.
                        self.acme.dns_providers_for_domain[domain] = [dns_provider]
                else:
                    for domain in order_info.domains:
                        self.acme.autodetect_dns_providers(domain)

                try:
                    order = acme_client.new_order(pending_cert.csr)
                except WildcardUnsupportedError:
                    raise Exception("The currently selected ACME CA endpoint does"
                                    " not support issuing wildcard certificates.")

                authorizations = self.acme.get_authorizations(acme_client, order, order_info)

                pending.append({
                    "acme_client": acme_client,
                    "authorizations": authorizations,
                    "pending_cert": pending_cert,
                    "order": order,
                })
            except (ClientError, ValueError, Exception) as e:
                current_app.logger.error("Unable to resolve pending cert: {}".format(pending_cert), exc_info=True)
                certs.append({
                    "cert": False,
                    "pending_cert": pending_cert,
                    "last_error": e,
                })

        for entry in pending:
            try:
                entry["authorizations"] = self.acme.finalize_authorizations(
                    entry["acme_client"],
                    entry["authorizations"],
                )
                pem_certificate, pem_certificate_chain = self.acme.request_certificate(
                    entry["acme_client"],
                    entry["authorizations"],
                    entry["order"]
                )

                cert = {
                    'body': "\n".join(str(pem_certificate).splitlines()),
                    'chain': "\n".join(str(pem_certificate_chain).splitlines()),
                    'external_id': str(entry["pending_cert"].external_id)
                }
                certs.append({
                    "cert": cert,
                    "pending_cert": entry["pending_cert"],
                })
            except (PollError, AcmeError, Exception) as e:
                current_app.logger.error("Unable to resolve pending cert: {}".format(pending_cert), exc_info=True)
                certs.append({
                    "cert": False,
                    "pending_cert": entry["pending_cert"],
                    "last_error": e,
                })
                # Ensure DNS records get deleted
                self.acme.cleanup_dns_challenges(
                    entry["acme_client"],
                    entry["authorizations"],
                )
        return certs
Exemplo n.º 8
0
    def revoke_certificate(self, certificate, comments):
        current_app.logger.debug(
            f"""Revoking certificate {type(certificate)} with auth: {certificate.authority}, comments: {comments}"""
        )
        # current_app.logger.debug(f"""Certificate body: {certificate.body}""")
        self.acme = AcmeHandler()
        acme_client, registration = self.acme.setup_acme_client(
            certificate.authority)
        order_info = authorization_service.get(certificate.external_id)
        if certificate.dns_provider_id:
            dns_provider = dns_provider_service.get(
                certificate.dns_provider_id)

            for domain in order_info.domains:
                # Currently, we only support specifying one DNS provider per certificate, even if that
                # certificate has multiple SANs that may belong to different providers.
                self.acme.dns_providers_for_domain[domain] = [dns_provider]
        else:
            for domain in order_info.domains:
                self.acme.autodetect_dns_providers(domain)

        try:
            order = acme_client.new_order(certificate.csr)
        except WildcardUnsupportedError:
            metrics.send("get_ordered_certificate_wildcard_unsupported",
                         "counter", 1)
            raise Exception("The currently selected ACME CA endpoint does"
                            " not support issuing wildcard certificates.")
        try:
            authorizations = self.acme.get_authorizations(
                acme_client, order, order_info)
        except ClientError:
            sentry.captureException()
            metrics.send("get_ordered_certificate_error", "counter", 1)
            current_app.logger.error(
                f"Unable to resolve pending cert: {certificate.name}",
                exc_info=True)
            return False

        authorizations = self.acme.finalize_authorizations(
            acme_client, authorizations)

        def from_string(key_pem, is_x509_cert=True):
            if is_x509_cert:
                pubkey = OpenSSL.crypto.load_certificate(
                    OpenSSL.crypto.FILETYPE_PEM, key_pem)
            else:
                pubkey = OpenSSL.crypto.load_privatekey(
                    OpenSSL.crypto.FILETYPE_PEM, key_pem)
            return jose.ComparableX509(pubkey)

        cert = from_string(certificate.body)
        current_app.logger.debug(f"""Certificate body import: {type(cert)}""")

        current_app.logger.debug(f"""acme client: {type(acme_client)}""")

        try:
            acme_client.revoke(cert, comments)
            metrics.send("acme_revoke_certificate_success", "counter", 1)
            certificate.status = "revoked"
        except Error as e:
            current_app.logger.error(
                f"""This certificate is already revoked before!""")