Example #1
0
    def new_order(self, csr_pem):
        """Request a new Order object from the server.

        :param str csr_pem: A CSR in PEM format.

        :returns: The newly created order.
        :rtype: OrderResource
        """
        csr = OpenSSL.crypto.load_certificate_request(
            OpenSSL.crypto.FILETYPE_PEM, csr_pem)
        # pylint: disable=protected-access
        dnsNames = crypto_util._pyopenssl_cert_or_req_all_names(csr)

        identifiers = []
        for name in dnsNames:
            identifiers.append(
                messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=name))
        order = messages.NewOrder(identifiers=identifiers)
        response = self._post(self.directory['newOrder'], order)
        body = messages.Order.from_json(response.json())
        authorizations = []
        for url in body.authorizations:
            authorizations.append(
                self._authzr_from_response(self._post_as_get(url), uri=url))
        return messages.OrderResource(body=body,
                                      uri=response.headers.get('Location'),
                                      authorizations=authorizations,
                                      csr_pem=csr_pem)
Example #2
0
    def new_order(self, csr_pem):
        """Request a new Order object from the server.

        If using ACMEv1, returns a dummy OrderResource with only
        the authorizations field filled in.

        :param str csr_pem: A CSR in PEM format.

        :returns: The newly created order.
        :rtype: OrderResource

        :raises errors.WildcardUnsupportedError: if a wildcard domain is
            requested but unsupported by the ACME version

        """
        if self.acme_version == 1:
            csr = OpenSSL.crypto.load_certificate_request(
                OpenSSL.crypto.FILETYPE_PEM, csr_pem)
            # pylint: disable=protected-access
            dnsNames = crypto_util._pyopenssl_cert_or_req_all_names(csr)
            authorizations = []
            for domain in dnsNames:
                authorizations.append(
                    self.client.request_domain_challenges(domain))
            return messages.OrderResource(authorizations=authorizations,
                                          csr_pem=csr_pem)
        return self.client.new_order(csr_pem)
Example #3
0
    def new_order(self, csr_pem):
        """Request a new Order object from the server.

        :param str csr_pem: A CSR in PEM format.

        :returns: The newly created order.
        :rtype: OrderResource
        """
        csr = OpenSSL.crypto.load_certificate_request(
            OpenSSL.crypto.FILETYPE_PEM, csr_pem)
        # pylint: disable=protected-access
        dnsNames = crypto_util._pyopenssl_cert_or_req_all_names(csr)
        ipNames = crypto_util._pyopenssl_cert_or_req_san_ip(csr)
        # ipNames is now []string
        identifiers = []
        for name in dnsNames:
            identifiers.append(
                messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=name))
        for ips in ipNames:
            identifiers.append(
                messages.Identifier(typ=messages.IDENTIFIER_IP, value=ips))
        order = messages.NewOrder(identifiers=identifiers)
        response = self._post(self.directory['newOrder'], order)
        body = messages.Order.from_json(response.json())
        authorizations = []
        # pylint has trouble understanding our josepy based objects which use
        # things like custom metaclass logic. body.authorizations should be a
        # list of strings containing URLs so let's disable this check here.
        for url in body.authorizations:  # pylint: disable=not-an-iterable
            authorizations.append(
                self._authzr_from_response(self._post_as_get(url), uri=url))
        return messages.OrderResource(body=body,
                                      uri=response.headers.get('Location'),
                                      authorizations=authorizations,
                                      csr_pem=csr_pem)
Example #4
0
    def setUp(self):
        super(ClientV2Test, self).setUp()

        self.directory = DIRECTORY_V2

        from acme.client import ClientV2
        self.client = ClientV2(self.directory, self.net)

        self.new_reg = self.new_reg.update(terms_of_service_agreed=True)

        self.authzr_uri2 = 'https://www.letsencrypt-demo.org/acme/authz/2'
        self.authz2 = self.authz.update(identifier=messages.Identifier(
            typ=messages.IDENTIFIER_FQDN, value='www.example.com'),
            status=messages.STATUS_PENDING)
        self.authzr2 = messages.AuthorizationResource(
            body=self.authz2, uri=self.authzr_uri2)

        self.order = messages.Order(
            identifiers=(self.authz.identifier, self.authz2.identifier),
            status=messages.STATUS_PENDING,
            authorizations=(self.authzr.uri, self.authzr_uri2),
            finalize='https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize')
        self.orderr = messages.OrderResource(
            body=self.order,
            uri='https://www.letsencrypt-demo.org/acme/acct/1/order/1',
            authorizations=[self.authzr, self.authzr2], csr_pem=CSR_SAN_PEM)
Example #5
0
    def new_order(self, csr_pem):
        """Request a new Order object from the server.

        :param str csr_pem: A CSR in PEM format.

        :returns: The newly created order.
        :rtype: OrderResource
        """
        csr = cryptography.x509.load_pem_x509_csr(
            csr_pem, cryptography.hazmat.backends.default_backend())
        san_extension = next(
            ext for ext in csr.extensions if ext.oid ==
            cryptography.x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
        dnsNames = san_extension.value.get_values_for_type(
            cryptography.x509.DNSName)

        identifiers = []
        for name in dnsNames:
            identifiers.append(
                messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=name))
        order = messages.NewOrder(identifiers=identifiers)
        response = self.net.post(self.directory['newOrder'], order)
        body = messages.Order.from_json(response.json())
        authorizations = []
        for url in body.authorizations:
            authorizations.append(self._authzr_from_response(
                self.net.get(url)))
        return messages.OrderResource(body=body,
                                      uri=response.headers.get('Location'),
                                      authorizations=authorizations,
                                      csr_pem=csr_pem)
Example #6
0
    def submit_order(self, key, names):
        """
        Create a new order and return the OrderResource for that order with
        all the authorizations resolved.

        It will automatically create a new private key and CSR for the
        domain 'names'.

        :param key: Key for the future certificate.
        :param list of str names: Sequence of DNS names for which to request
            a new certificate.

        :return: The new authorization resource.
        :rtype: Deferred[`~acme.messages.Order`]
        """
        # certbot helper API needs PEM.
        pem_key = key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption(),
        )
        csr_pem = make_csr(pem_key, names)
        identifiers = [fqdn_identifier(name) for name in names]

        message = messages.NewOrder(identifiers=identifiers)
        response = yield self._client.post(self.directory.newOrder, message)
        self._expect_response(response, [http.CREATED])

        order_uri = self._maybe_location(response)

        authorizations = []
        order_body = yield response.json()
        for uri in order_body['authorizations']:
            # We do a POST-as-GET
            respose = yield self._client.post(uri, obj=None)
            self._expect_response(response, [http.CREATED])
            body = yield respose.json()
            authorizations.append(
                messages.AuthorizationResource(
                    body=messages.Authorization.from_json(body),
                    uri=uri,
                ))

        order = messages.OrderResource(
            body=messages.Order.from_json(order_body),
            uri=order_uri,
            authorizations=authorizations,
            csr_pem=csr_pem,
        )

        # TODO: Not sure if all these sanity checks are required.
        for identifier in order.body.identifiers:
            if identifier not in identifiers:
                raise errors.UnexpectedUpdate(order)
        defer.returnValue(order)
Example #7
0
    def finalize(self, order):
        """
        Request order finalization.

        Authorizations should have already been completed for all of the names
        requested in the order.

        :param ~acme.messages.Order order: The order for which the certificate
            is requested.

        :rtype: Deferred[`acme.messages.OrderResource`]
        :return: The issued certificate.
        """
        csr = OpenSSL.crypto.load_certificate_request(
            OpenSSL.crypto.FILETYPE_PEM, order.csr_pem)
        request = Finalize(csr=jose.ComparableX509(csr))
        response = yield self._client.post(order.body.finalize, obj=request)
        self._expect_response(response, [http.OK])
        body = yield response.json()
        defer.returnValue(
            messages.OrderResource(
                uri=order.uri,
                body=messages.Order.from_json(body),
            ))