easyrsa: use env variables
This commit is contained in:
parent
b421d6f79b
commit
8079036c75
1 changed files with 68 additions and 60 deletions
|
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue