def obtain_certificate(self, domains, csr=None):
        """Obtains a certificate from the ACME server.

        :meth:`.register` must be called before :meth:`.obtain_certificate`

        .. todo:: This function does not currently handle csr correctly...

        :param set domains: domains to get a certificate

        :param csr: CSR must contain requested domains, the key used to generate
            this CSR can be different than self.authkey
        :type csr: :class:`CSR`

        :returns: cert_key, cert_path, chain_path
        :rtype: `tuple` of (:class:`letsencrypt.client.le_util.Key`, str, str)

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

        # Perform Challenges/Get Authorizations
        authzr = self.auth_handler.get_authorizations(domains)

        # Create CSR from names
        cert_key = crypto_util.init_save_key(
            self.config.rsa_key_size, self.config.key_dir)
        csr = crypto_util.init_save_csr(
            cert_key, domains, self.config.cert_dir)

        # Retrieve certificate
        certr = self.network.request_issuance(
            jose.ComparableX509(
                M2Crypto.X509.load_request_der_string(csr.data)),
            authzr)

        # Save Certificate
        cert_path, chain_path = self.save_certificate(
            certr, self.config.cert_path, self.config.chain_path)

        revoker.Revoker.store_cert_key(
            cert_path, self.account.key.file, self.config)

        return cert_key, cert_path, chain_path
Exemple #2
0
    def _get_cert(self, uri):
        """Returns certificate from URI.

        :param str uri: URI of certificate

        :returns: tuple of the form
            (response, :class:`letsencrypt.acme.jose.ComparableX509`)
        :rtype: tuple

        """
        content_type = self.DER_CONTENT_TYPE  # TODO: make it a param
        response = self._get(uri, headers={'Accept': content_type},
                             content_type=content_type)
        return response, jose.ComparableX509(
            M2Crypto.X509.load_cert_der_string(response.content))
Exemple #3
0
    def acme_certificate(self, csr_der):
        """Handle ACME "certificate" phase.

        :param str csr_der: CSR in DER format.

        :returns: ACME "certificate" message.
        :rtype: :class:`letsencrypt.acme.message.Certificate`

        """
        logging.info("Preparing and sending CSR...")
        return self.network.send_and_receive_expected(
            messages.CertificateRequest.create(
                csr=jose.ComparableX509(
                    M2Crypto.X509.load_request_der_string(csr_der)),
                key=jose.HashableRSAKey(
                    Crypto.PublicKey.RSA.importKey(self.authkey.pem))),
            messages.Certificate)
Exemple #4
0
    def request_issuance(self, csr, authzrs):
        """Request issuance.

        :param csr: CSR
        :type csr: `M2Crypto.X509.Request` wrapped in `.ComparableX509`

        :param authzrs: `list` of `.AuthorizationResource`

        :returns: Issued certificate
        :rtype: `.messages2.CertificateResource`

        """
        assert authzrs, "Authorizations list is empty"
        logging.debug("Requesting issuance...")

        # TODO: assert len(authzrs) == number of SANs
        req = messages2.CertificateRequest(
            csr=csr, authorizations=tuple(authzr.uri for authzr in authzrs))

        content_type = self.DER_CONTENT_TYPE  # TODO: add 'cert_type 'argument
        response = self._post(
            authzrs[0].new_cert_uri,  # TODO: acme-spec #90
            self._wrap_in_jws(req),
            content_type=content_type,
            headers={'Accept': content_type})

        cert_chain_uri = response.links.get('up', {}).get('url')

        try:
            uri = response.headers['Location']
        except KeyError:
            raise errors.NetworkError('"Location" Header missing')

        return messages2.CertificateResource(
            uri=uri, authzrs=authzrs, cert_chain_uri=cert_chain_uri,
            body=jose.ComparableX509(
                M2Crypto.X509.load_cert_der_string(response.content)))
import pkg_resources
import unittest

import M2Crypto
import mock
import requests

from letsencrypt.acme import challenges
from letsencrypt.acme import jose
from letsencrypt.acme import messages2

from letsencrypt.client import account
from letsencrypt.client import errors

CERT = jose.ComparableX509(
    M2Crypto.X509.load_cert_string(
        pkg_resources.resource_string(__name__,
                                      os.path.join('testdata', 'cert.pem'))))
CERT2 = jose.ComparableX509(
    M2Crypto.X509.load_cert_string(
        pkg_resources.resource_string(__name__,
                                      os.path.join('testdata',
                                                   'cert-san.pem'))))
CSR = jose.ComparableX509(
    M2Crypto.X509.load_request_string(
        pkg_resources.resource_string(__name__,
                                      os.path.join('testdata', 'csr.pem'))))
KEY = jose.JWKRSA.load(
    pkg_resources.resource_string('letsencrypt.acme.jose',
                                  os.path.join('testdata', 'rsa512_key.pem')))
KEY2 = jose.JWKRSA.load(
    pkg_resources.resource_string('letsencrypt.acme.jose',
import pkg_resources
import unittest

import Crypto.PublicKey.RSA
import M2Crypto

from letsencrypt.acme import challenges
from letsencrypt.acme import errors
from letsencrypt.acme import jose
from letsencrypt.acme import other


KEY = Crypto.PublicKey.RSA.importKey(pkg_resources.resource_string(
    'letsencrypt.client.tests', 'testdata/rsa256_key.pem'))
CERT = jose.ComparableX509(M2Crypto.X509.load_cert(
    pkg_resources.resource_filename(
        'letsencrypt.client.tests', 'testdata/cert.pem')))
CSR = jose.ComparableX509(M2Crypto.X509.load_request(
    pkg_resources.resource_filename(
        'letsencrypt.client.tests', 'testdata/csr.pem')))
CSR2 = jose.ComparableX509(M2Crypto.X509.load_request(
    pkg_resources.resource_filename(
        'letsencrypt.acme.jose', 'testdata/csr2.pem')))


class MessageTest(unittest.TestCase):
    """Tests for letsencrypt.acme.messages.Message."""

    def setUp(self):
        # pylint: disable=missing-docstring,too-few-public-methods
        from letsencrypt.acme.messages import Message
"""Tests for letsencrypt.acme.challenges."""
import os
import pkg_resources
import unittest

import Crypto.PublicKey.RSA
import M2Crypto

from letsencrypt.acme import jose
from letsencrypt.acme import other

CERT = jose.ComparableX509(
    M2Crypto.X509.load_cert(
        pkg_resources.resource_filename('letsencrypt.client.tests',
                                        'testdata/cert.pem')))
KEY = Crypto.PublicKey.RSA.importKey(
    pkg_resources.resource_string('letsencrypt.client.tests',
                                  os.path.join('testdata', 'rsa256_key.pem')))


class SimpleHTTPSTest(unittest.TestCase):
    def setUp(self):
        from letsencrypt.acme.challenges import SimpleHTTPS
        self.msg = SimpleHTTPS(
            token='evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA')
        self.jmsg = {
            'type': 'simpleHttps',
            'token': 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA',
        }

    def test_to_json(self):
 def _get_cert(self, uri):
     content_type = self.DER_CONTENT_TYPE  # TODO: make it a param
     response = self._get(uri, headers={'Accept': content_type},
                          content_type=content_type)
     return response, jose.ComparableX509(
         M2Crypto.X509.load_cert_der_string(response.content))