예제 #1
0
    def lookup(config: CoreConfig, db: StandardDatabase, temp_dir: Path) -> CertificateHandler:
        args = config.args
        # if we get a ca certificate from the command line, use it
        if args.ca_cert and args.ca_cert_key:
            ca_key = load_key_from_file(args.ca_cert_key, args.ca_cert_key_pass)
            ca_cert = load_cert_from_file(args.ca_cert_cert)
            log.info(f"Using CA certificate from command line. fingerprint:{cert_fingerprint(ca_cert)}")
            return CertificateHandler(config, ca_key, ca_cert, temp_dir)

        # otherwise, load from database or create it
        sd = db.collection("system_data")
        maybe_ca = sd.get("ca")
        if maybe_ca and isinstance(maybe_ca.get("key"), str) and isinstance(maybe_ca.get("certificate"), str):
            log.debug("Found existing certificate in data store.")
            key = load_key_from_bytes(maybe_ca["key"].encode("utf-8"))
            certificate = load_cert_from_bytes(maybe_ca["certificate"].encode("utf-8"))
            log.info(f"Using CA certificate from database. fingerprint:{cert_fingerprint(certificate)}")
            return CertificateHandler(config, key, certificate, temp_dir)
        else:
            wo = "with" if args.ca_cert_key_pass else "without"
            key, certificate = bootstrap_ca()
            log.info(
                f"No ca certificate found - create new one {wo} passphrase. fingerprint:{cert_fingerprint(certificate)}"
            )
            key_string = key_to_bytes(key, args.ca_cert_key_pass).decode("utf-8")
            certificate_string = cert_to_bytes(certificate).decode("utf-8")
            sd.insert({"_key": "ca", "key": key_string, "certificate": certificate_string})
            return CertificateHandler(config, key, certificate, temp_dir)
예제 #2
0
 def lookup(args: Namespace, db: StandardDatabase, passphrase: Optional[str] = None) -> CertificateHandler:
     sd = db.collection("system_data")
     maybe_ca = sd.get("ca")
     if maybe_ca and isinstance(maybe_ca.get("key"), str) and isinstance(maybe_ca.get("certificate"), str):
         log.debug("Found existing certificate in data store.")
         key = load_key_from_bytes(maybe_ca["key"].encode("utf-8"))
         certificate = load_cert_from_bytes(maybe_ca["certificate"].encode("utf-8"))
         return CertificateHandler(args, key, certificate)
     else:
         wo = "with" if passphrase else "without"
         log.info(f"No ca certificate found - create a new one {wo} passphrase.")
         key, certificate = bootstrap_ca()
         key_string = key_to_bytes(key, passphrase).decode("utf-8")
         certificate_string = cert_to_bytes(certificate).decode("utf-8")
         sd.insert({"_key": "ca", "key": key_string, "certificate": certificate_string})
         return CertificateHandler(args, key, certificate)
예제 #3
0
def test_x509():
    with tempfile.TemporaryDirectory() as tmp:
        ca_key, ca_cert = bootstrap_ca()
        cert_key = gen_rsa_key()
        gen_csr(cert_key)  # dummy call to generate CSR without SANs
        cert_csr = gen_csr(
            cert_key,
            san_dns_names=["example.com"],
            san_ip_addresses=["10.0.1.1", "10.0.0.0/24"],
        )
        cert_crt = sign_csr(cert_csr, ca_key, ca_cert)
        ca_key_path = os.path.join(tmp, "ca.key")
        ca_cert_path = os.path.join(tmp, "ca.crt")

        cert_key_path = os.path.join(tmp, "cert.key")
        cert_key_passphrase = "foobar"
        cert_csr_path = os.path.join(tmp, "cert.csr")
        cert_crt_path = os.path.join(tmp, "cert.crt")

        write_key_to_file(ca_key, key_path=ca_key_path)
        write_cert_to_file(ca_cert, cert_path=ca_cert_path)

        write_key_to_file(cert_key,
                          key_path=cert_key_path,
                          passphrase=cert_key_passphrase)
        write_csr_to_file(cert_csr, csr_path=cert_csr_path)
        write_cert_to_file(cert_crt, cert_path=cert_crt_path)

        loaded_ca_key = load_key_from_file(ca_key_path)
        loaded_ca_cert = load_cert_from_file(ca_cert_path)
        loaded_cert_key = load_key_from_file(cert_key_path,
                                             passphrase=cert_key_passphrase)
        loaded_cert_csr = load_csr_from_file(cert_csr_path)
        loaded_cert_crt = load_cert_from_file(cert_crt_path)

        assert loaded_ca_cert == ca_cert
        assert loaded_cert_csr == cert_csr
        assert loaded_cert_crt == cert_crt
        assert cert_fingerprint(loaded_ca_cert) == cert_fingerprint(ca_cert)
        assert cert_fingerprint(loaded_cert_crt) == cert_fingerprint(cert_crt)
        assert key_to_bytes(ca_key) == key_to_bytes(loaded_ca_key)
        assert key_to_bytes(cert_key) == key_to_bytes(loaded_cert_key)
예제 #4
0
def disabled_test_secure_web():
    with tempfile.TemporaryDirectory() as tmp:
        ca_key, ca_cert = bootstrap_ca()
        cert_key = gen_rsa_key()
        cert_csr = gen_csr(cert_key, common_name="localhost")
        cert_crt = sign_csr(cert_csr, ca_key, ca_cert)
        ca_cert_path = os.path.join(tmp, "ca.crt")
        cert_key_path = os.path.join(tmp, "cert.key")
        cert_crt_path = os.path.join(tmp, "cert.crt")

        write_cert_to_file(ca_cert, cert_path=ca_cert_path)
        write_key_to_file(cert_key, key_path=cert_key_path)
        write_cert_to_file(cert_crt, cert_path=cert_crt_path)

        free_port = get_free_port()
        print(f"Starting https webserver on port {free_port}")
        web_server = WebServer(WebApp(),
                               web_port=free_port,
                               ssl_cert=cert_crt_path,
                               ssl_key=cert_key_path)
        web_server.daemon = True
        web_server.start()
        start_time = time.time()
        while not web_server.serving:
            if time.time() - start_time > 10:
                raise RuntimeError("timeout waiting for web server start")
            time.sleep(0.1)

        endpoint = f"https://localhost:{free_port}"
        r = requests.get(f"{endpoint}/health", verify=ca_cert_path)
        assert r.text == "ok\r\n"
        web_server.shutdown()
        while web_server.is_alive():
            print("Waiting for web server to shutdown")
            time.sleep(1)
        cherrypy.engine
예제 #5
0
def cert_handler() -> CertificateHandler:
    args = parse_args()
    key, certificate = bootstrap_ca()
    return CertificateHandler(args, key, certificate)
예제 #6
0
def cert_handler() -> Iterator[CertificateHandler]:
    config = empty_config()
    key, certificate = bootstrap_ca()
    temp = TemporaryDirectory()
    yield CertificateHandler(config, key, certificate, Path(temp.name))
    temp.cleanup()