Example #1
0
def get_orders_list(module, account, orders_url):
    '''
    Retrieves orders list (handles pagination).
    '''
    orders = []
    while orders_url:
        # Get part of orders list
        res, info = account.get_request(orders_url,
                                        parse_json_result=True,
                                        fail_on_error=True)
        if not res.get('orders'):
            if orders:
                module.warn(
                    'When retrieving orders list part {0}, got empty result list'
                    .format(orders_url))
            break
        # Add order URLs to result list
        orders.extend(res['orders'])
        # Extract URL of next part of results list
        new_orders_url = []

        def f(link, relation):
            if relation == 'next':
                new_orders_url.append(link)

        process_links(info, f)
        new_orders_url.append(None)
        previous_orders_url, orders_url = orders_url, new_orders_url.pop(0)
        if orders_url == previous_orders_url:
            # Prevent infinite loop
            orders_url = None
    return orders
    def _new_cert_v1(self):
        '''
        Create a new certificate based on the CSR (ACME v1 protocol).
        Return the certificate object as dict
        https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-6.5
        '''
        csr = pem_to_der(self.csr)
        new_cert = {
            "resource": "new-cert",
            "csr": nopad_b64(csr),
        }
        result, info = self.account.send_signed_request(self.directory['new-cert'], new_cert)

        chain = []

        def f(link, relation):
            if relation == 'up':
                chain_result, chain_info = self.account.get_request(link, parse_json_result=False)
                if chain_info['status'] in [200, 201]:
                    chain.clear()
                    chain.append(self._der_to_pem(chain_result))

        process_links(info, f)

        if info['status'] not in [200, 201]:
            raise ModuleFailException("Error new cert: CODE: {0} RESULT: {1}".format(info['status'], result))
        else:
            return {'cert': self._der_to_pem(result), 'uri': info['location'], 'chain': chain}
Example #3
0
    def _download_cert(self, url):
        '''
        Download and parse the certificate chain.
        https://tools.ietf.org/html/rfc8555#section-7.4.2
        '''
        content, info = self.account.get_request(
            url,
            parse_json_result=False,
            headers={'Accept': 'application/pem-certificate-chain'})

        if not content or not info['content-type'].startswith(
                'application/pem-certificate-chain'):
            raise ModuleFailException(
                "Cannot download certificate chain from {0}: {1} (headers: {2})"
                .format(url, content, info))

        cert = None
        chain = []

        # Parse data
        lines = content.decode('utf-8').splitlines(True)
        current = []
        for line in lines:
            if line.strip():
                current.append(line)
            if line.startswith('-----END CERTIFICATE-----'):
                if cert is None:
                    cert = ''.join(current)
                else:
                    chain.append(''.join(current))
                current = []

        alternates = []

        def f(link, relation):
            if relation == 'up':
                # Process link-up headers if there was no chain in reply
                if not chain:
                    chain_result, chain_info = self.account.get_request(
                        link, parse_json_result=False)
                    if chain_info['status'] in [200, 201]:
                        chain.append(self._der_to_pem(chain_result))
            elif relation == 'alternate':
                alternates.append(link)

        process_links(info, f)

        if cert is None or current:
            raise ModuleFailException(
                "Failed to parse certificate chain download from {0}: {1} (headers: {2})"
                .format(url, content, info))
        return {'cert': cert, 'chain': chain, 'alternates': alternates}