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)
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)
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)
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)
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)
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)
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), ))