Esempio n. 1
0
def prepare(emails, config, key_path=None, usage=None):
    if key_path is not None:
        with open(key_path, "rb") as f:
            keypem = f.read()
        key = util.Key(file=key_path, pem=keypem)
    else:
        key = None
    if config.dry_run:
        key = key or util.Key(file=None,
                              pem=crypto_util.make_key(config.rsa_key_size))
        ## CSR is always used, as it MUST send "email" identifier (dns by default)
        #csr = util.CSR(file=None, form="pem", data=make_csr(key.pem, emails))
    else:
        key = key or crypto_util.generate_key(config.rsa_key_size,
                                              config.key_dir)
    csr = init_save_csr(key, emails, config, usage)
    return key, csr
Esempio n. 2
0
    def obtain_certificate(self, domains, old_keypath=None):
        """Obtains a certificate from the ACME server.

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

        :param list domains: domains to get a certificate

        :returns: certificate as PEM string, chain as PEM string,
            newly generated private key (`.util.Key`), and DER-encoded
            Certificate Signing Request (`.util.CSR`).
        :rtype: tuple

        """
        # We need to determine the key path, key PEM data, CSR path,
        # and CSR PEM data.  For a dry run, the paths are None because
        # they aren't permanently saved to disk.  For a lineage with
        # --reuse-key, the key path and PEM data are derived from an
        # existing file.

        if old_keypath is not None:
            # We've been asked to reuse a specific existing private key.
            # Therefore, we'll read it now and not generate a new one in
            # either case below.
            #
            # We read in bytes here because the type of `key.pem`
            # created below is also bytes.
            with open(old_keypath, "rb") as f:
                keypath = old_keypath
                keypem = f.read()
            key: Optional[util.Key] = util.Key(file=keypath, pem=keypem)
            logger.info("Reusing existing private key from %s.", old_keypath)
        else:
            # The key is set to None here but will be created below.
            key = None

        key_size = self.config.rsa_key_size
        elliptic_curve = "secp256r1"

        # key-type defaults to a list, but we are only handling 1 currently
        if isinstance(self.config.key_type, list):
            self.config.key_type = self.config.key_type[0]
        if self.config.elliptic_curve and self.config.key_type == 'ecdsa':
            elliptic_curve = self.config.elliptic_curve
            self.config.auth_chain_path = "./chain-ecdsa.pem"
            self.config.auth_cert_path = "./cert-ecdsa.pem"
            self.config.key_path = "./key-ecdsa.pem"
        elif self.config.rsa_key_size and self.config.key_type.lower(
        ) == 'rsa':
            key_size = self.config.rsa_key_size

        # Create CSR from names
        if self.config.dry_run:
            key = key or util.Key(
                file=None,
                pem=crypto_util.make_key(
                    bits=key_size,
                    elliptic_curve=elliptic_curve,
                    key_type=self.config.key_type,
                ),
            )
            csr = util.CSR(file=None,
                           form="pem",
                           data=acme_crypto_util.make_csr(
                               key.pem, domains, self.config.must_staple))
        else:
            key = key or crypto_util.generate_key(
                key_size=key_size,
                key_dir=self.config.key_dir,
                key_type=self.config.key_type,
                elliptic_curve=elliptic_curve,
                strict_permissions=self.config.strict_permissions,
            )
            csr = crypto_util.generate_csr(key, domains, self.config.csr_dir,
                                           self.config.must_staple,
                                           self.config.strict_permissions)

        orderr = self._get_order_and_authorizations(
            csr.data, self.config.allow_subset_of_names)
        authzr = orderr.authorizations
        auth_domains = set(a.body.identifier.value for a in authzr)
        successful_domains = [d for d in domains if d in auth_domains]

        # allow_subset_of_names is currently disabled for wildcard
        # certificates. The reason for this and checking allow_subset_of_names
        # below is because successful_domains == domains is never true if
        # domains contains a wildcard because the ACME spec forbids identifiers
        # in authzs from containing a wildcard character.
        if self.config.allow_subset_of_names and successful_domains != domains:
            if not self.config.dry_run:
                os.remove(key.file)
                os.remove(csr.file)
            return self.obtain_certificate(successful_domains)
        else:
            cert, chain = self.obtain_certificate_from_csr(csr, orderr)
            return cert, chain, key, csr
Esempio n. 3
0
 def _call(cls, key_size, key_dir):
     from certbot.crypto_util import generate_key
     return generate_key(key_size,
                         key_dir,
                         'key-certbot.pem',
                         strict_permissions=True)