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)
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)
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)
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
def cert_handler() -> CertificateHandler: args = parse_args() key, certificate = bootstrap_ca() return CertificateHandler(args, key, certificate)
def cert_handler() -> Iterator[CertificateHandler]: config = empty_config() key, certificate = bootstrap_ca() temp = TemporaryDirectory() yield CertificateHandler(config, key, certificate, Path(temp.name)) temp.cleanup()