easyrsa: use env variables

This commit is contained in:
Jörn-Michael Miehe 2022-04-02 00:08:27 +00:00
parent b421d6f79b
commit 8079036c75

View file

@ -80,22 +80,22 @@ class DistinguishedName(BaseModel):
return result
@property
def easyrsa_args(self) -> list[str]:
def easyrsa_env(self) -> dict[str, str]:
"""
Pass this DN as arguments to easyrsa
"""
return [
"--dn-mode=org",
return {
"EASYRSA_DN": "org",
f"--req-c={self.country}",
f"--req-st={self.state}",
f"--req-city={self.city}",
f"--req-org={self.organization}",
f"--req-ou={self.organizational_unit}",
f"--req-email={self.email}",
f"--req-cn={self.common_name}",
]
"EASYRSA_REQ_COUNTRY": self.country,
"EASYRSA_REQ_PROVINCE": self.state,
"EASYRSA_REQ_CITY": self.city,
"EASYRSA_REQ_ORG": self.organization,
"EASYRSA_REQ_OU": self.organizational_unit,
"EASYRSA_REQ_EMAIL": self.email,
"EASYRSA_REQ_CN": self.common_name,
}
class CertificateType(Enum):
@ -116,6 +116,30 @@ class EasyRSA:
Represents an EasyRSA PKI.
"""
__mapKeyAlgorithm = {
KeyAlgorithm.rsa2048: {
"EASYRSA_ALGO": "rsa",
"EASYRSA_KEY_SIZE": "2048",
},
KeyAlgorithm.rsa4096: {
"EASYRSA_ALGO": "rsa",
"EASYRSA_KEY_SIZE": "2048",
},
KeyAlgorithm.secp256r1: {
"EASYRSA_ALGO": "ec",
"EASYRSA_CURVE": "secp256r1",
},
KeyAlgorithm.secp384r1: {
"EASYRSA_ALGO": "ec",
"EASYRSA_CURVE": "secp384r1",
},
KeyAlgorithm.ed25519: {
"EASYRSA_ALGO": "ed",
"EASYRSA_CURVE": "ed25519",
},
None: {},
}
@property
def output_directory(self) -> Path:
"""
@ -146,7 +170,8 @@ class EasyRSA:
def __easyrsa(
self,
*easyrsa_args: str,
*easyrsa_cmd: str,
**easyrsa_env: str,
) -> subprocess.CompletedProcess:
"""
Call the `easyrsa` executable
@ -154,10 +179,14 @@ class EasyRSA:
return subprocess.run(
[
"easyrsa", "--batch",
f"--pki-dir={self.output_directory}",
*easyrsa_args,
"/usr/local/bin/easyrsa",
*easyrsa_cmd,
],
env={
"EASYRSA_BATCH": "1",
"EASYRSA_PKI": str(self.output_directory),
**easyrsa_env,
},
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
check=True,
)
@ -165,8 +194,8 @@ class EasyRSA:
def __build_cert(
self,
cert_filename: Path,
expiry_days: int | None,
*easyrsa_args: str,
*easyrsa_cmd: str,
**easyrsa_env: str,
) -> crypto.X509:
"""
Create an X.509 certificate
@ -174,45 +203,28 @@ class EasyRSA:
config = Config._
# always include password options
extra_args: list[str] = [
f"--passout=pass:{self.ca_password}",
f"--passin=pass:{self.ca_password}",
]
# if given, include expiry option
if expiry_days is not None:
extra_args += [f"--days={expiry_days}"]
# if configured, include algorithm option
if (algorithm := config.crypto.key_algorithm) is not None:
args_map = {
KeyAlgorithm.rsa2048: [
"--use-algo=rsa", "--keysize=2048"
],
KeyAlgorithm.rsa2048: [
"--use-algo=rsa", "--keysize=2048"
],
KeyAlgorithm.secp256r1: [
"--use-algo=ec", "--curve=secp256r1"
],
KeyAlgorithm.secp384r1: [
"--use-algo=ec", "--curve=secp384r1"
],
KeyAlgorithm.ed25519: [
"--use-algo=ed", "--curve=ed25519"
]
}
if algorithm not in args_map:
if ((algorithm := config.crypto.key_algorithm)
not in EasyRSA.__mapKeyAlgorithm):
raise ValueError(f"Unexpected algorithm: {algorithm}")
extra_args += args_map[algorithm]
# include expiry options
if (ca_expiry_days := config.crypto.ca_expiry_days) is not None:
easyrsa_env["EASYRSA_CA_EXPIRE"] = str(ca_expiry_days)
if (cert_expiry_days := config.crypto.cert_expiry_days) is not None:
easyrsa_env["EASYRSA_CERT_EXPIRE"] = str(cert_expiry_days)
# call easyrsa
self.__easyrsa(
*extra_args,
*easyrsa_args
*easyrsa_cmd,
# include CA password
EASYRSA_PASSOUT=f"pass:{self.ca_password}",
EASYRSA_PASSIN=f"pass:{self.ca_password}",
# include algorithm options
**EasyRSA.__mapKeyAlgorithm[algorithm],
**easyrsa_env,
)
# parse the new certificate
@ -237,12 +249,10 @@ class EasyRSA:
cert = self.__build_cert(
Path("ca.crt"),
Config._.crypto.ca_expiry_days,
"--dn-mode=cn_only",
"--req-cn=kiwi-vpn-ca",
"build-ca",
EASYRSA_DN="cn_only",
EASYRSA_REQ_CN="kiwi-vpn-ca",
)
# # this takes long!
@ -267,13 +277,11 @@ class EasyRSA:
return self.__build_cert(
Path(f"issued/{dn.common_name}.crt"),
Config._.crypto.cert_expiry_days,
*dn.easyrsa_args,
f"build-{cert_type}-full",
dn.common_name,
"nopass",
**dn.easyrsa_env,
)