def get_signed_cert( common_name: str, san_dns_names: Optional[List[str]] = None, san_ip_addresses: Optional[List[str]] = None, resotocore_uri: str = None, psk: str = None, ca_cert_path: str = None, ) -> Tuple[RSAPrivateKey, Certificate]: if resotocore_uri is None: resotocore_uri = getattr(ArgumentParser.args, "resotocore_uri", None) if psk is None: psk = getattr(ArgumentParser.args, "psk", None) cert_key = gen_rsa_key() cert_csr = gen_csr(cert_key, common_name, san_dns_names, san_ip_addresses) cert_csr_bytes = csr_to_bytes(cert_csr) headers = {} if psk is not None: encode_jwt_to_headers(headers, {}, psk) request_kwargs = {} if ca_cert_path is not None: request_kwargs["verify"] = ca_cert_path r = requests.post(f"{resotocore_uri}/ca/sign", cert_csr_bytes, headers=headers, **request_kwargs) cert_bytes = r.content cert_crt = load_cert_from_bytes(cert_bytes) return cert_key, cert_crt
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 __setstate__(self, d): d["_TLSData__load_lock"] = Lock() d["_TLSData__loaded"] = Event() d["_TLSData__exit"] = Condition() d["_TLSData__ca_cert"] = None d["_TLSData__cert"] = None d["_TLSData__key"] = None if d["__is_loaded"]: d["_TLSData__loaded"].set() d["_TLSData__ca_cert"] = load_cert_from_bytes(d["__ca_cert_bytes"]) d["_TLSData__cert"] = load_cert_from_bytes(d["__cert_bytes"]) d["_TLSData__key"] = load_key_from_bytes(d["__key_bytes"]) del d["__ca_cert_bytes"] del d["__cert_bytes"] del d["__key_bytes"] del d["__is_loaded"] d["_TLSData__watcher"] = Thread(target=self.__certificates_watcher, name="certificates_watcher") self.__dict__.update(d)
def get_ca_cert(resotocore_uri: str = None, psk: str = None) -> Certificate: if resotocore_uri is None: resotocore_uri = getattr(ArgumentParser.args, "resotocore_uri", None) if psk is None: psk = getattr(ArgumentParser.args, "psk", None) r = requests.get(f"{resotocore_uri}/ca/cert", verify=False) ca_cert = load_cert_from_bytes(r.content) if psk: jwt = decode_jwt_from_headers(r.headers, psk) if jwt["sha256_fingerprint"] != cert_fingerprint(ca_cert): raise ValueError("Invalid Root CA certificate fingerprint") return ca_cert
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 get_ca_cert(resotocore_uri: Optional[str] = None, psk: Optional[str] = None) -> Certificate: if resotocore_uri is None: resotocore_uri = resotocore.http_uri if psk is None: psk = getattr(ArgumentParser.args, "psk", None) with warnings.catch_warnings(): warnings.simplefilter("ignore") r = requests.get(f"{resotocore_uri}/ca/cert", verify=False) ca_cert = load_cert_from_bytes(r.content) if psk: # noinspection PyTypeChecker jwt = decode_jwt_from_headers(r.headers, psk) if jwt is None: raise NoJWTError("Failed to decode JWT") if jwt["sha256_fingerprint"] != cert_fingerprint(ca_cert): raise FingerprintError( "Invalid Root CA certificate fingerprint") return ca_cert
def test_sign(cert_handler: CertificateHandler) -> None: cert_bytes, fingerprint = cert_handler.sign(csr_to_bytes(gen_csr(gen_rsa_key()))) cert = load_cert_from_bytes(cert_bytes) assert cert_fingerprint(cert) == fingerprint
def test_ca_certificate(cert_handler: CertificateHandler) -> None: cert_bytes, fingerprint = cert_handler.authority_certificate cert = load_cert_from_bytes(cert_bytes) assert cert_fingerprint(cert) == fingerprint