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