Exemplo n.º 1
0
 def test_it(self):
     host, port = self.server.socket.getsockname()[:2]
     cert = crypto_util.probe_sni(b'localhost',
                                  host=host,
                                  port=port,
                                  timeout=1)
     self.assertEqual(jose.ComparableX509(cert),
                      jose.ComparableX509(self.certs[b'localhost'][1]))
Exemplo n.º 2
0
 def test_connect(self):
     socknames = self.servers.getsocknames()
     # connect to all addresses
     for sockname in socknames:
         host, port = sockname[:2]
         cert = crypto_util.probe_sni(
             b'localhost', host=host, port=port, timeout=1)
         self.assertEqual(jose.ComparableX509(cert),
                          jose.ComparableX509(self.certs[b'localhost'][1]))
Exemplo n.º 3
0
 def test_challenge_certs(self):
     host, port = self.server.socket.getsockname()[:2]
     cert = crypto_util.probe_sni(
         b'localhost', host=host, port=port, timeout=1,
         alpn_protocols=[b"acme-tls/1"])
     #  Expect challenge cert when connecting with ALPN.
     self.assertEqual(
             jose.ComparableX509(cert),
             jose.ComparableX509(self.challenge_certs[b'localhost'][1])
     )
Exemplo n.º 4
0
def test_revoke_by_issuer():
    client = make_client(None)
    order = auth_and_issue([random_domain()], client=client)

    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                           order.fullchain_pem)
    client.revoke(jose.ComparableX509(cert), 0)
Exemplo n.º 5
0
def test_revoke_by_privkey():
    client = make_client(None)
    domains = [random_domain()]
    key = OpenSSL.crypto.PKey()
    key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
    key_pem = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key)
    csr_pem = acme_crypto_util.make_csr(key_pem, domains, False)
    order = client.new_order(csr_pem)
    cleanup = do_http_challenges(client, order.authorizations)
    try:
        order = client.poll_order_and_request_issuance(order)
    finally:
        cleanup()

    # Create a new client with the JWK as the cert private key
    jwk = jose.JWKRSA(key=key)
    net = acme_client.ClientNetwork(key,
                                    acme_version=2,
                                    user_agent="Boulder integration tester")

    new_client = acme_client.Client(os.getenv(
        'DIRECTORY', 'http://localhost:4001/directory'),
                                    key=jwk,
                                    net=net,
                                    acme_version=2)

    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                           order.fullchain_pem)
    client.revoke(jose.ComparableX509(cert), 0)
Exemplo n.º 6
0
def test_revoke_by_privkey():
    client = chisel2.make_client(None)
    domains = [random_domain()]
    key = OpenSSL.crypto.PKey()
    key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
    key_pem = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key)
    csr_pem = chisel2.make_csr(domains)
    order = client.new_order(csr_pem)
    cleanup = chisel2.do_http_challenges(client, order.authorizations)
    try:
        order = client.poll_and_finalize(order)
    finally:
        cleanup()

    # Create a new client with the JWK as the cert private key
    jwk = josepy.JWKRSA(key=key)
    net = acme_client.ClientNetwork(key,
                                    user_agent="Boulder integration tester")

    directory = Directory.from_json(net.get(chisel2.DIRECTORY_V2).json())
    new_client = acme_client.ClientV2(directory, net)

    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                           order.fullchain_pem)
    client.revoke(josepy.ComparableX509(cert), 0)
Exemplo n.º 7
0
    def finalize_order(self, orderr, deadline, fetch_alternative_chains=False):
        """Finalize an order and obtain a certificate.

        :param messages.OrderResource orderr: order to finalize
        :param datetime.datetime deadline: when to stop polling and timeout
        :param bool fetch_alternative_chains: whether to also fetch alternative
            certificate chains

        :returns: finalized order
        :rtype: messages.OrderResource

        """
        csr = OpenSSL.crypto.load_certificate_request(
            OpenSSL.crypto.FILETYPE_PEM, orderr.csr_pem)
        wrapped_csr = messages.CertificateRequest(csr=jose.ComparableX509(csr))
        self._post(orderr.body.finalize, wrapped_csr)   
        difference = 5 #set initial delay to 5sec
        while datetime.datetime.now() < deadline:
            time.sleep(difference)
            response = self._post_as_get(orderr.uri)
            body = messages.Order.from_json(response.json())
            if body.error is not None:
                raise errors.IssuanceError(body.error)
            if body.certificate is not None:
                certificate_response = self._post_as_get(body.certificate)
                orderr = orderr.update(body=body, fullchain_pem=certificate_response.text)
                if fetch_alternative_chains:
                    alt_chains_urls = self._get_links(certificate_response, 'alternate')
                    alt_chains = [self._post_as_get(url).text for url in alt_chains_urls]
                    orderr = orderr.update(alternative_fullchains_pem=alt_chains)
                return orderr
            future_date = self.retry_after(response,DEFAULT_NETWORK_TIMEOUT)
            difference = (future_date - datetime.datetime.now()).total_seconds()
        raise errors.TimeoutError()
Exemplo n.º 8
0
    def finalize_order(self, orderr, deadline):
        """Finalize an order and obtain a certificate.

        :param messages.OrderResource orderr: order to finalize
        :param datetime.datetime deadline: when to stop polling and timeout

        :returns: finalized order
        :rtype: messages.OrderResource

        """
        csr = OpenSSL.crypto.load_certificate_request(
            OpenSSL.crypto.FILETYPE_PEM, orderr.csr_pem)
        wrapped_csr = messages.CertificateRequest(csr=jose.ComparableX509(csr))
        self._post(orderr.body.finalize, wrapped_csr)
        while datetime.datetime.now() < deadline:
            time.sleep(1)
            response = self._post_as_get(orderr.uri)
            body = messages.Order.from_json(response.json())
            if body.error is not None:
                raise errors.IssuanceError(body.error)
            if body.certificate is not None:
                certificate_response = self._post_as_get(body.certificate).text
                return orderr.update(body=body,
                                     fullchain_pem=certificate_response)
        raise errors.TimeoutError()
Exemplo n.º 9
0
def test_revoke_by_privkey():
    client = chisel2.make_client(None)
    domains = [random_domain()]
    key = OpenSSL.crypto.PKey()
    key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
    key_pem = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key)
    csr_pem = chisel2.make_csr(domains)
    order = client.new_order(csr_pem)
    cleanup = chisel2.do_http_challenges(client, order.authorizations)
    try:
        order = client.poll_and_finalize(order)
    finally:
        cleanup()

    # Create a new client with the JWK as the cert private key
    jwk = josepy.JWKRSA(key=key)
    net = acme_client.ClientNetwork(key,
                                    user_agent="Boulder integration tester")

    directory = Directory.from_json(net.get(chisel2.DIRECTORY_V2).json())
    new_client = acme_client.ClientV2(directory, net)

    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                           order.fullchain_pem)
    reset_akamai_purges()
    client.revoke(josepy.ComparableX509(cert), 0)

    cert_file_pem = os.path.join(tempdir, "revokeme.pem")
    with open(cert_file_pem, "w") as f:
        f.write(
            OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                            cert).decode())
    ee_ocsp_url = "http://localhost:4002"
    verify_ocsp(cert_file_pem, "test/test-ca2.pem", ee_ocsp_url, "revoked")
    verify_akamai_purge()
Exemplo n.º 10
0
    def _revoke_certificate(self) -> None:
        """Revoke certificate."""
        if not self.path_fullchain.exists():
            _LOGGER.warning("Can't revoke not exists certificate")
            return

        fullchain = jose.ComparableX509(
            OpenSSL.crypto.load_certificate(
                OpenSSL.crypto.FILETYPE_PEM, self.path_fullchain.read_bytes()
            )
        )

        _LOGGER.info("Revoke certificate")
        try:
            self._acme_client.revoke(fullchain, 0)
        except errors.ConflictError:
            pass
        except errors.Error as err:
            # Ignore errors where certificate did not exist
            if "No such certificate" in str(err):
                pass
            # Ignore errors where certificate has expired
            elif "Certificate is expired" in str(err):
                pass
            # Ignore errors where unrecognized issuer (happens dev/prod switch)
            elif "Certificate from unrecognized issuer" in str(err):
                pass
            else:
                _LOGGER.error("Can't revoke certificate: %s", err)
                raise AcmeClientError() from err
Exemplo n.º 11
0
def revoke(config, unused_plugins):  # TODO: coop with renewal config
    """Revoke a previously obtained certificate.

    :param config: Configuration object
    :type config: interfaces.IConfig

    :param unused_plugins: List of plugins (deprecated)
    :type unused_plugins: `list` of `str`

    :returns: `None` or string indicating error in case of error
    :rtype: None or str

    """
    # For user-agent construction
    config.installer = config.authenticator = "None"
    if config.key_path is not None:  # revocation by cert key
        logger.debug("Revoking %s using cert key %s",
                     config.cert_path[0], config.key_path[0])
        crypto_util.verify_cert_matches_priv_key(config.cert_path[0], config.key_path[0])
        key = jose.JWK.load(config.key_path[1])
    else:  # revocation by account key
        logger.debug("Revoking %s using Account Key", config.cert_path[0])
        acc, _ = _determine_account(config)
        key = acc.key
    acme = client.acme_from_config_key(config, key)
    cert = crypto_util.pyopenssl_load_certificate(config.cert_path[1])[0]
    logger.debug("Reason code for revocation: %s", config.reason)

    try:
        acme.revoke(jose.ComparableX509(cert), config.reason)
        _delete_if_appropriate(config)
    except acme_errors.ClientError as e:
        return str(e)

    display_ops.success_revocation(config.cert_path[0])
Exemplo n.º 12
0
    def revoke_certificate(self, certificate, crl_reason=0):
        if not self.reuse_account(certificate.authority):
            raise InvalidConfiguration(
                "There is no ACME account saved, unable to revoke the certificate."
            )
        acme_client, _ = self.setup_acme_client(certificate.authority)

        fullchain_com = jose.ComparableX509(
            OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                            certificate.body))

        try:
            acme_client.revoke(
                fullchain_com, crl_reason
            )  # revocation reason as int (per RFC 5280 section 5.3.1)
        except (errors.ConflictError, errors.ClientError, errors.Error) as e:
            # Certificate already revoked.
            current_app.logger.error(
                "Certificate revocation failed with message: " + e.detail)
            metrics.send("acme_revoke_certificate_failure", "counter", 1)
            return False

        current_app.logger.warning("Certificate succesfully revoked: " +
                                   certificate.name)
        metrics.send("acme_revoke_certificate_success", "counter", 1)
        return True
Exemplo n.º 13
0
    def obtain_certificate_from_csr(self, domains, csr, authzr=None):
        """Obtain certificate.

        Internal function with precondition that `domains` are
        consistent with identifiers present in the `csr`.

        :param list domains: Domain names.
        :param .util.CSR csr: PEM-encoded Certificate Signing
            Request. The key used to generate this CSR can be different
            than `authkey`.
        :param list authzr: List of
            :class:`acme.messages.AuthorizationResource`

        :returns: `.CertificateResource` and certificate chain (as
            returned by `.fetch_chain`).
        :rtype: tuple

        """
        if self.auth_handler is None:
            msg = ("Unable to obtain certificate because authenticator is "
                   "not set.")
            logger.warning(msg)
            raise errors.Error(msg)
        if self.account.regr is None:
            raise errors.Error("Please register with the ACME server first.")

        logger.debug("CSR: %s, domains: %s", csr, domains)

        if authzr is None:
            authzr = self.auth_handler.get_authorizations(domains)

        certr = self.acme.request_issuance(
            jose.ComparableX509(
                OpenSSL.crypto.load_certificate_request(
                    OpenSSL.crypto.FILETYPE_PEM, csr.data)), authzr)

        notify = zope.component.getUtility(interfaces.IDisplay).notification
        retries = 0
        chain = None

        while retries <= 1:
            if retries:
                notify(
                    'Failed to fetch chain, please check your network '
                    'and continue',
                    pause=True)
            try:
                chain = self.acme.fetch_chain(certr)
                break
            except acme_errors.Error:
                logger.debug('Failed to fetch chain', exc_info=True)
                retries += 1

        if chain is None:
            raise acme_errors.Error(
                'Failed to fetch chain. You should not deploy the generated '
                'certificate, please rerun the command for a new one.')

        return certr, chain
Exemplo n.º 14
0
 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)
Exemplo n.º 15
0
 def revoke(self, fullchain: str):
     # noinspection PyTypeChecker
     certificate = OpenSSL.crypto.load_certificate(
         OpenSSL.crypto.FILETYPE_PEM, fullchain)
     certificate = josepy.ComparableX509(certificate)
     try:
         return self.acme.revoke(certificate, 0)
     except acme.errors.ConflictError:
         pass
Exemplo n.º 16
0
def test_revoke_by_authz():
    domains = [random_domain()]
    order = chisel2.auth_and_issue(domains)

    # create a new client and re-authz
    client = chisel2.make_client(None)
    chisel2.auth_and_issue(domains, client=client)

    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, order.fullchain_pem)
    client.revoke(josepy.ComparableX509(cert), 0)
Exemplo n.º 17
0
    def obtain_certificate_from_csr(self, csr, orderr=None):
        """Obtain certificate.

        :param .util.CSR csr: PEM-encoded Certificate Signing
            Request. The key used to generate this CSR can be different
            than `authkey`.
        :param acme.messages.OrderResource orderr: contains authzrs

        :returns: `.CertificateResource` and certificate chain (as
            returned by `.fetch_chain`).
        :rtype: tuple

        """
        if self.auth_handler is None:
            msg = ("Unable to obtain certificate because authenticator is "
                   "not set.")
            logger.warning(msg)
            raise errors.Error(msg)
        if self.account.regr is None:
            raise errors.Error("Please register with the ACME server first.")

        logger.debug("CSR: %s", csr)

        if orderr is None:
            orderr = self.acme.new_order(csr.data)
            authzr = self.auth_handler.handle_authorizations(orderr)
            orderr = orderr.update(authorizations=authzr)
        authzr = orderr.authorizations

        certr = self.acme.request_issuance(
            jose.ComparableX509(
                OpenSSL.crypto.load_certificate_request(OpenSSL.crypto.FILETYPE_PEM, csr.data)),
                authzr)

        notify = zope.component.getUtility(interfaces.IDisplay).notification
        retries = 0
        chain = None

        while retries <= 1:
            if retries:
                notify('Failed to fetch chain, please check your network '
                       'and continue', pause=True)
            try:
                chain = self.acme.fetch_chain(certr)
                break
            except acme_errors.Error:
                logger.debug('Failed to fetch chain', exc_info=True)
                retries += 1

        if chain is None:
            raise acme_errors.Error(
                'Failed to fetch chain. You should not deploy the generated '
                'certificate, please rerun the command for a new one.')

        return certr, chain
Exemplo n.º 18
0
    def test_it(self, mock_logger):
        # Use a Queue because mock objects aren't thread safe.
        q = queue.Queue()  # type: queue.Queue[int]
        # Add port number to the queue.
        mock_logger.info.side_effect = lambda *args: q.put(args[-1])
        self.thread.start()

        # After the timeout, an exception is raised if the queue is empty.
        port = q.get(timeout=5)
        cert = crypto_util.probe_sni(b'localhost', b'0.0.0.0', port)
        self.assertEqual(jose.ComparableX509(cert),
                         test_util.load_comparable_cert('rsa2048_cert.pem'))
Exemplo n.º 19
0
    def _check_obtain_certificate(self):
        self.client.auth_handler.get_authorizations.assert_called_once_with(
            self.eg_domains, self.config.allow_subset_of_names)

        authzr = self.client.auth_handler.get_authorizations()

        self.acme.request_issuance.assert_called_once_with(
            jose.ComparableX509(
                OpenSSL.crypto.load_certificate_request(
                    OpenSSL.crypto.FILETYPE_PEM, CSR_SAN)), authzr)

        self.acme.fetch_chain.assert_called_once_with(mock.sentinel.certr)
Exemplo n.º 20
0
 def test_live(self):
     self.process.start()
     cert = None
     for _ in range(50):
         time.sleep(0.1)
         try:
             cert = crypto_util.probe_sni(b'localhost', b'127.0.0.1',
                                          self.port)
             break
         except errors.Error:  # pragma: no cover
             pass
     self.assertEqual(jose.ComparableX509(cert),
                      test_util.load_comparable_cert('rsa2048_cert.pem'))
Exemplo n.º 21
0
    def do_delete(self, job, id, force):
        """
        Delete certificate of `id`.

        If the certificate is an ACME based certificate, certificate service will try to
        revoke the certificate by updating it's status with the ACME server, if it fails an exception is raised
        and the certificate is not deleted from the system. However, if `force` is set to True, certificate is deleted
        from the system even if some error occurred while revoking the certificate with the ACME Server

        .. examples(websocket)::

          Delete certificate of `id`

            :::javascript
            {
                "id": "6841f242-840a-11e6-a437-00e04d680384",
                "msg": "method",
                "method": "certificate.delete",
                "params": [
                    1,
                    true
                ]
            }
        """
        check_dependencies(self.middleware, 'CERT', id)

        certificate = self.middleware.call_sync('certificate.get_instance', id)

        if certificate.get('acme'):
            client, key = self.middleware.call_sync(
                'acme.get_acme_client_and_key',
                certificate['acme']['directory'], True)

            try:
                client.revoke(
                    jose.ComparableX509(
                        crypto.load_certificate(crypto.FILETYPE_PEM,
                                                certificate['certificate'])),
                    0)
            except (errors.ClientError, messages.Error) as e:
                if not force:
                    raise CallError(f'Failed to revoke certificate: {e}')

        response = self.middleware.call_sync('datastore.delete',
                                             self._config.datastore, id)

        self.middleware.call_sync('service.start', 'ssl')

        job.set_progress(100)
        return response
Exemplo n.º 22
0
def wildcard_revoke(cert_pem,account):

		#Check if registrar exists
		if account not in os.listdir(REG_DIRECTORY):
			print "This account does not exists, register it first with new_account.py"
			sys.exit(1)

		#Load files from disk
		with open(REG_DIRECTORY + "/" + account + "/private.key", "rb") as key_file:
			privkey = serialization.load_pem_private_key(
				key_file.read(),
				password=None,
				backend=default_backend()
			)
		with open(REG_DIRECTORY + "/" + account + "/reguri.txt", "r") as reguri_file:
			reg_uri = reguri_file.read()

		#Compose registration resource (regr)
		key = jose.JWKRSA(key=privkey)
		regr = messages.RegistrationResource(
			body=messages.Registration(
				key=key.public_key()),
			uri = reg_uri)

		#Init ACME
		net = ClientNetwork(key)
		directory = net.get(DIRECTORY_URL).json()

		acme = client.ClientV2(directory, net)


		#Check if registration is valid
		if acme.query_registration(regr).body.status == u'valid':
			print "Registration valid"
		else:
			print "Registration invalid"
			sys.exit(1)

		#Deserialize key from variable
		cert = jose.ComparableX509(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_pem))

		#Try to revoke cert, return false on error or revoked-already state
		try:
			revokation = acme.revoke(cert,1)
		except messages.Error,acme_exc:
			if str(acme_exc) == str("urn:ietf:params:acme:error:alreadyRevoked :: Certificate already revoked"):
				return ["Certificate already revoked",False]
			else:
				return [acme_exc, False]
Exemplo n.º 23
0
    def _get_cert(self, uri):
        """Returns certificate from URI.

        :param str uri: URI of certificate

        :returns: tuple of the form
            (response, :class:`josepy.util.ComparableX509`)
        :rtype: tuple

        """
        content_type = DER_CONTENT_TYPE  # TODO: make it a param
        response = self.net.get(uri, headers={'Accept': content_type},
                                content_type=content_type)
        return response, jose.ComparableX509(OpenSSL.crypto.load_certificate(
            OpenSSL.crypto.FILETYPE_ASN1, response.content))
Exemplo n.º 24
0
def test_revoke_by_issuer():
    client = chisel2.make_client(None)
    order = chisel2.auth_and_issue([random_domain()], client=client)

    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, order.fullchain_pem)
    reset_akamai_purges()
    client.revoke(josepy.ComparableX509(cert), 0)

    cert_file_pem = os.path.join(tempdir, "revokeme.pem")
    with open(cert_file_pem, "w") as f:
        f.write(OpenSSL.crypto.dump_certificate(
            OpenSSL.crypto.FILETYPE_PEM, cert).decode())
    ee_ocsp_url = "http://localhost:4002"
    verify_revocation(cert_file_pem, "test/test-ca2.pem", ee_ocsp_url)
    verify_akamai_purge()
Exemplo n.º 25
0
def revoke(config, unused_plugins):
    """Revoke a previously obtained certificate.

    :param config: Configuration object
    :type config: interfaces.IConfig

    :param unused_plugins: List of plugins (deprecated)
    :type unused_plugins: `list` of `str`

    :returns: `None` or string indicating error in case of error
    :rtype: None or str

    """
    # For user-agent construction
    config.installer = config.authenticator = None

    if config.cert_path is None and config.certname:
        config.cert_path = storage.cert_path_for_cert_name(
            config, config.certname)
    elif not config.cert_path or (config.cert_path and config.certname):
        # intentionally not supporting --cert-path & --cert-name together,
        # to avoid dealing with mismatched values
        raise errors.Error(
            "Error! Exactly one of --cert-path or --cert-name must be specified!"
        )

    if config.key_path is not None:  # revocation by cert key
        logger.debug("Revoking %s using cert key %s", config.cert_path[0],
                     config.key_path[0])
        crypto_util.verify_cert_matches_priv_key(config.cert_path[0],
                                                 config.key_path[0])
        key = jose.JWK.load(config.key_path[1])
        acme = client.acme_from_config_key(config, key)
    else:  # revocation by account key
        logger.debug("Revoking %s using Account Key", config.cert_path[0])
        acc, _ = _determine_account(config)
        acme = client.acme_from_config_key(config, acc.key, acc.regr)
    cert = crypto_util.pyopenssl_load_certificate(config.cert_path[1])[0]
    logger.debug("Reason code for revocation: %s", config.reason)
    try:
        acme.revoke(jose.ComparableX509(cert), config.reason)
        _delete_if_appropriate(config)
    except acme_errors.ClientError as e:
        return str(e)

    display_ops.success_revocation(config.cert_path[0])
    return None
Exemplo n.º 26
0
    def _check_obtain_certificate(self, auth_count=1):
        if auth_count == 1:
            self.client.auth_handler.handle_authorizations.assert_called_once_with(
                self.eg_order, self.config.allow_subset_of_names)
        else:
            self.assertEqual(
                self.client.auth_handler.handle_authorizations.call_count,
                auth_count)

        authzr = self.client.auth_handler.handle_authorizations()

        self.acme.request_issuance.assert_called_once_with(
            jose.ComparableX509(
                OpenSSL.crypto.load_certificate_request(
                    OpenSSL.crypto.FILETYPE_PEM, CSR_SAN)), authzr)

        self.acme.fetch_chain.assert_called_once_with(mock.sentinel.certr)
Exemplo n.º 27
0
    def revoke_certificate(self, reason=0):
        """
        Attempts to revoke the existing certificate from the issuing ACME server.\n
        - :param `reason` [`int`]: the numeric reason for revocation identifier.\n
        - :return [`none`]:\n
        - :raises `InvalidCertificate`: if this object does not contain a certificate.\n
        - :raises `acme.errors.ConflictError`: if the certificate is already revoked.\n\n

        ## Example\n
        ```python
        >>> client.revoke_certificate()
        ```
        """
        self.__validate_certificate__()

        # Load the certificate crypto object and request revocation from the ACME server
        cert_obj = jose.ComparableX509(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, self.certificate))
        self.__client__.revoke(cert_obj, reason)
Exemplo n.º 28
0
def issue(client, authzs, cert_output=None):
    """Given a list of authzs that are being processed by the server,
       wait for them to be ready, then request issuance of a cert with a random
       key for the given domains.

       If cert_output is provided, write the cert as a PEM file to that path."""
    domains = [authz.body.identifier.value for authz in authzs]
    pkey = OpenSSL.crypto.PKey()
    pkey.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
    csr = OpenSSL.crypto.X509Req()
    csr.add_extensions([
        OpenSSL.crypto.X509Extension(
            'subjectAltName'.encode(),
            critical=False,
            value=(', '.join('DNS:' + d for d in domains)).encode()
        ),
    ])
    csr.set_pubkey(pkey)
    csr.set_version(2)
    csr.sign(pkey, 'sha256')

    cert_resource = None
    try:
        cert_resource, _ = client.poll_and_request_issuance(josepy.ComparableX509(csr), authzs)
    except acme_errors.PollError as error:
        # If we get a PollError, pick the first failed authz and turn it into a more
        # useful ValidationError that contains details we can look for in tests.
        for authz in error.updated:
            r = requests.get(authz.uri)
            r.raise_for_status()
            updated_authz = r.json()
            domain = authz.body.identifier.value,
            for c in updated_authz['challenges']:
                if 'error' in c:
                    err = c['error']
                    raise(ValidationError(domain, err['type'], err['detail']))
        # If none of the authz's had an error, just re-raise.
        raise
    if cert_output is not None:
        pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                              cert_resource.body)
        with open(cert_output, 'w') as f:
            f.write(pem.decode())
    return cert_resource
    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)
Exemplo n.º 30
0
    def test_it(self):
        max_attempts = 5
        for attempt in range(max_attempts):
            try:
                cert = crypto_util.probe_sni(
                    b'localhost', b'0.0.0.0', self.port)
            except errors.Error:
                self.assertTrue(attempt + 1 < max_attempts, "Timeout!")
                time.sleep(1)  # wait until thread starts
            else:
                self.assertEqual(jose.ComparableX509(cert),
                                 test_util.load_comparable_cert(
                                     'rsa2048_cert.pem'))
                break

            if attempt == 0:
                # the first attempt is always meant to fail, so we can test
                # the socket failure code-path for probe_sni, as well
                self.thread.start()