예제 #1
0
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
예제 #2
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)
예제 #3
0
 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)
예제 #4
0
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
예제 #5
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)
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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