Exemplo n.º 1
0
    def gen_cert(self,
                 domain: str,
                 key: Optional[crypto.PKey] = None,
                 bits: int = 2048) -> Tuple[crypto.X509, crypto.PKey]:
        """Generate tls-alpn-01 certificate.

        :param str domain: Domain verified by the challenge.
        :param OpenSSL.crypto.PKey key: Optional private key used in
            certificate generation. If not provided (``None``), then
            fresh key will be generated.
        :param int bits: Number of bits for newly generated key.

        :rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey`

        """
        if key is None:
            key = crypto.PKey()
            key.generate_key(crypto.TYPE_RSA, bits)

        der_value = b"DER:" + codecs.encode(self.h, 'hex')
        acme_extension = crypto.X509Extension(self.ID_PE_ACME_IDENTIFIER_V1,
                                              critical=True,
                                              value=der_value)

        return crypto_util.gen_ss_cert(key, [domain],
                                       force_san=True,
                                       extensions=[acme_extension]), key
Exemplo n.º 2
0
    def gen_cert(self, key=None, bits=2048):
        """Generate tls-sni-01 certificate.

        :param OpenSSL.crypto.PKey key: Optional private key used in
            certificate generation. If not provided (``None``), then
            fresh key will be generated.
        :param int bits: Number of bits for newly generated key.

        :rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey`

        """
        if key is None:
            key = OpenSSL.crypto.PKey()
            key.generate_key(OpenSSL.crypto.TYPE_RSA, bits)
        return (
            crypto_util.gen_ss_cert(
                key,
                [
                    # z_domain is too big to fit into CN, hence first dummy domain
                    "dummy",
                    self.z_domain.decode(),
                ],
                force_san=True,
            ),
            key,
        )
Exemplo n.º 3
0
def test_deploy_cert(plugin, temp_dir, domains):
    """Tests deploy_cert returning True if the tests are successful"""
    cert = crypto_util.gen_ss_cert(util.KEY, domains)
    cert_path = os.path.join(temp_dir, "cert.pem")
    with open(cert_path, "wb") as f:
        f.write(OpenSSL.crypto.dump_certificate(
            OpenSSL.crypto.FILETYPE_PEM, cert))

    for domain in domains:
        try:
            plugin.deploy_cert(domain, cert_path, util.KEY_PATH, cert_path, cert_path)
            plugin.save()  # Needed by the Apache plugin
        except le_errors.Error:
            logger.error("**** Plugin failed to deploy certificate for %s:", domain, exc_info=True)
            return False

    if not _save_and_restart(plugin, "deployed"):
        return False

    success = True
    time.sleep(3)
    for domain in domains:
        verified = validator.Validator().certificate(
            cert, domain, "127.0.0.1", plugin.https_port)
        if not verified:
            logger.error("**** Could not verify certificate for domain %s", domain)
            success = False

    if success:
        logger.info("HTTPS validation succeeded")

    return success
Exemplo n.º 4
0
    def gen_cert(self, domain, key=None, bits=2048):
        """Generate tls-alpn-01 certificate.

        :param unicode domain: Domain verified by the challenge.
        :param OpenSSL.crypto.PKey key: Optional private key used in
            certificate generation. If not provided (``None``), then
            fresh key will be generated.
        :param int bits: Number of bits for newly generated key.

        :rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey`

        """
        if key is None:
            key = crypto.PKey()
            key.generate_key(crypto.TYPE_RSA, bits)

        # Instead of using a ASN.1 encoding library just append the OCTET STRING tag (0x04)
        # and the length of the SHA256 hash (0x20) since both of these should never change
        der_value = b"DER:0420" + codecs.encode(self.h, 'hex')
        acme_extension = crypto.X509Extension(self.ID_PE_ACME_IDENTIFIER_V1,
                                              critical=True,
                                              value=der_value)

        return crypto_util.gen_ss_cert(key, [domain],
                                       force_san=True,
                                       extensions=[acme_extension]), key
Exemplo n.º 5
0
def test_deploy_cert(plugin, temp_dir, domains):
    """Tests deploy_cert returning True if the tests are successful"""
    cert = crypto_util.gen_ss_cert(util.KEY, domains)
    cert_path = os.path.join(temp_dir, "cert.pem")
    with open(cert_path, "w") as f:
        f.write(OpenSSL.crypto.dump_certificate(
            OpenSSL.crypto.FILETYPE_PEM, cert))

    for domain in domains:
        try:
            plugin.deploy_cert(domain, cert_path, util.KEY_PATH, cert_path, cert_path)
            plugin.save()  # Needed by the Apache plugin
        except le_errors.Error as error:
            logger.error("Plugin failed to deploy ceritificate for %s:", domain)
            logger.exception(error)
            return False

    if not _save_and_restart(plugin, "deployed"):
        return False

    success = True
    for domain in domains:
        verify = functools.partial(validator.Validator().certificate, cert,
                                   domain, "127.0.0.1", plugin.https_port)
        if not _try_until_true(verify):
            logger.error("Could not verify certificate for domain %s", domain)
            success = False

    if success:
        logger.info("HTTPS validation succeeded")

    return success
Exemplo n.º 6
0
    def test_sn_collisions(self):
        from acme.crypto_util import gen_ss_cert

        for _ in range(self.cert_count):
            cert = gen_ss_cert(self.key, ['dummy'], force_san=True)
            self.serial_num.append(cert.get_serial_number())
        self.assertTrue(len(set(self.serial_num)) > 1)
Exemplo n.º 7
0
    def test_sn_collisions(self):
        from acme.crypto_util import gen_ss_cert

        for _ in range(self.cert_count):
            cert = gen_ss_cert(self.key, ['dummy'], force_san=True)
            self.serial_num.append(cert.get_serial_number())
        self.assertTrue(len(set(self.serial_num)) > 1)
def test_deploy_cert(plugin, temp_dir, domains):
    """Tests deploy_cert returning True if the tests are successful"""
    cert = crypto_util.gen_ss_cert(util.KEY, domains)
    cert_path = os.path.join(temp_dir, "cert.pem")
    with open(cert_path, "w") as f:
        f.write(
            OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))

    for domain in domains:
        try:
            plugin.deploy_cert(domain, cert_path, util.KEY_PATH)
        except le_errors.Error as error:
            logger.error("Plugin failed to deploy ceritificate for %s:",
                         domain)
            logger.exception(error)
            return False

    if not _save_and_restart(plugin, "deployed"):
        return False

    success = True
    for domain in domains:
        verify = functools.partial(validator.Validator().certificate, cert,
                                   domain, "127.0.0.1", plugin.https_port)
        if not _try_until_true(verify):
            logger.error("Could not verify certificate for domain %s", domain)
            success = False

    if success:
        logger.info("HTTPS validation succeeded")

    return success
Exemplo n.º 9
0
 def test_sn_collisions(self):
     from acme.crypto_util import gen_ss_cert
     for _ in range(self.cert_count):
         cert = gen_ss_cert(self.key, ['dummy'],
                            force_san=True,
                            ips=[ipaddress.ip_address("10.10.10.10")])
         self.serial_num.append(cert.get_serial_number())
     self.assertGreaterEqual(len(set(self.serial_num)), self.cert_count)
Exemplo n.º 10
0
    def __init__(self, *args, **kwargs):
        super(PluginIOTestMixin, self).__init__(*args, **kwargs)

        raw_key = gen_pkey(1024)
        self.all_data = IOPlugin.Data(
            account_key=jose.JWKRSA(key=rsa.generate_private_key(
                public_exponent=65537, key_size=1024,
                backend=default_backend(),
            )),
            key=ComparablePKey(raw_key),
            cert=jose.ComparableX509(crypto_util.gen_ss_cert(raw_key, ['a'])),
            chain=[
                jose.ComparableX509(crypto_util.gen_ss_cert(raw_key, ['b'])),
                jose.ComparableX509(crypto_util.gen_ss_cert(raw_key, ['c'])),
            ],
        )
        self.key_data = IOPlugin.EMPTY_DATA._replace(key=self.all_data.key)
Exemplo n.º 11
0
    def gen_cert(self, chall, domain, key):
        """Generate DVSNI certificate.

        :param .DVSNI chall: Corresponding challenge.
        :param unicode domain:
        :param OpenSSL.crypto.PKey

        """
        return crypto_util.gen_ss_cert(key, [
            domain, chall.nonce_domain.decode(), self.z_domain(chall).decode()])
Exemplo n.º 12
0
 def _get_snakeoil_paths(self):
     # TODO: generate only once
     tmp_dir = os.path.join(self.config.work_dir, "snakeoil")
     le_key = crypto_util.init_save_key(key_size=1024, key_dir=tmp_dir, keyname="key.pem")
     key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, le_key.pem)
     cert = acme_crypto_util.gen_ss_cert(key, domains=[socket.gethostname()])
     cert_path = os.path.join(tmp_dir, "cert.pem")
     cert_pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
     with open(cert_path, "w") as cert_file:
         cert_file.write(cert_pem)
     return cert_path, le_key.file
Exemplo n.º 13
0
    def gen_cert(self, chall, domain, key):
        """Generate DVSNI certificate.

        :param .DVSNI chall: Corresponding challenge.
        :param unicode domain:
        :param OpenSSL.crypto.PKey

        """
        return crypto_util.gen_ss_cert(key, [
            domain,
            chall.nonce_domain.decode(),
            self.z_domain(chall).decode()
        ])
Exemplo n.º 14
0
 def _get_snakeoil_paths(self):
     # TODO: generate only once
     tmp_dir = os.path.join(self.config.work_dir, "snakeoil")
     le_key = crypto_util.init_save_key(
         key_size=1024, key_dir=tmp_dir, keyname="key.pem")
     key = OpenSSL.crypto.load_privatekey(
         OpenSSL.crypto.FILETYPE_PEM, le_key.pem)
     cert = acme_crypto_util.gen_ss_cert(key, domains=[socket.gethostname()])
     cert_pem = OpenSSL.crypto.dump_certificate(
         OpenSSL.crypto.FILETYPE_PEM, cert)
     cert_file, cert_path = util.unique_file(os.path.join(tmp_dir, "cert.pem"))
     with cert_file:
         cert_file.write(cert_pem)
     return cert_path, le_key.file
Exemplo n.º 15
0
 def _get_snakeoil_paths(self):
     """Generate invalid certs that let us create ssl directives for Nginx"""
     # TODO: generate only once
     tmp_dir = os.path.join(self.config.work_dir, "snakeoil")
     le_key = crypto_util.init_save_key(
         key_size=1024, key_dir=tmp_dir, keyname="key.pem")
     key = OpenSSL.crypto.load_privatekey(
         OpenSSL.crypto.FILETYPE_PEM, le_key.pem)
     cert = acme_crypto_util.gen_ss_cert(key, domains=[socket.gethostname()])
     cert_pem = OpenSSL.crypto.dump_certificate(
         OpenSSL.crypto.FILETYPE_PEM, cert)
     cert_file, cert_path = util.unique_file(
         os.path.join(tmp_dir, "cert.pem"), mode="wb")
     with cert_file:
         cert_file.write(cert_pem)
     return cert_path, le_key.file
Exemplo n.º 16
0
 def _get_snakeoil_paths(self):
     """Generate invalid certs that let us create ssl directives for Nginx"""
     # TODO: generate only once
     tmp_dir = os.path.join(self.config.work_dir, "snakeoil")
     le_key = crypto_util.init_save_key(
        {"type": "rsa", "size": 1024}, key_dir=tmp_dir, keyname="key.pem")
     key = OpenSSL.crypto.load_privatekey(
         OpenSSL.crypto.FILETYPE_PEM, le_key.pem)
     cert = acme_crypto_util.gen_ss_cert(key, domains=[socket.gethostname()])
     cert_pem = OpenSSL.crypto.dump_certificate(
         OpenSSL.crypto.FILETYPE_PEM, cert)
     cert_file, cert_path = util.unique_file(
         os.path.join(tmp_dir, "cert.pem"), mode="wb")
     with cert_file:
         cert_file.write(cert_pem)
     return cert_path, le_key.file
Exemplo n.º 17
0
    def gen_cert(self, key=None, bits=2048):
        """Generate tls-sni-01 certificate.

        :param OpenSSL.crypto.PKey key: Optional private key used in
            certificate generation. If not provided (``None``), then
            fresh key will be generated.
        :param int bits: Number of bits for newly generated key.

        :rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey`

        """
        if key is None:
            key = OpenSSL.crypto.PKey()
            key.generate_key(OpenSSL.crypto.TYPE_RSA, bits)
        return crypto_util.gen_ss_cert(key, [
            # z_domain is too big to fit into CN, hence first dummy domain
            'dummy', self.z_domain.decode()], force_san=True), key
Exemplo n.º 18
0
    def __init__(self, *args, **kwargs):
        super(Authenticator, self).__init__(*args, **kwargs)

        # one self-signed key for all DVSNI and SimpleHTTP certificates
        self.key = OpenSSL.crypto.PKey()
        self.key.generate_key(OpenSSL.crypto.TYPE_RSA, bits=2048)
        # TODO: generate only when the first SimpleHTTP challenge is solved
        self.simple_http_cert = acme_crypto_util.gen_ss_cert(
            self.key, domains=["temp server"])

        self.served = collections.defaultdict(set)

        # Stuff below is shared across threads (i.e. servers read
        # values, main thread writes). Due to the nature of CPython's
        # GIL, the operations are safe, c.f.
        # https://docs.python.org/2/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
        self.certs = {}
        self.simple_http_resources = set()

        self.servers = ServerManager(self.certs, self.simple_http_resources)
Exemplo n.º 19
0
def test_installer(plugin, config, temp_dir):
    """Tests plugin as an installer"""
    backup = os.path.join(temp_dir, "backup")
    shutil.copytree(config, backup, symlinks=True)

    if plugin.get_all_names() != plugin.get_all_names_answer():
        raise errors.Error("get_all_names test failed")
    else:
        logging.info("get_all_names test succeeded")

    domains = list(plugin.get_testable_domain_names())
    cert = crypto_util.gen_ss_cert(util.KEY, domains)
    cert_path = os.path.join(temp_dir, "cert.pem")
    with open(cert_path, "w") as f:
        f.write(
            OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))

    for domain in domains:
        plugin.deploy_cert(domain, cert_path, util.KEY_PATH)
    plugin.save()
    plugin.restart()
Exemplo n.º 20
0
 def test_no_name(self):
     from acme.crypto_util import gen_ss_cert
     with self.assertRaises(AssertionError):
         gen_ss_cert(self.key, ips=[ipaddress.ip_address("1.1.1.1")])
         gen_ss_cert(self.key)