Skip to content

Commit

Permalink
implement wrapper for signing certs via CLI since even *that* CFSSLs …
Browse files Browse the repository at this point in the history
…own REST API does not actually do the right way
  • Loading branch information
rambo committed Feb 10, 2024
1 parent 0d424e8 commit 0207d57
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/ocsprest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class RESTConfig(BaseSettings):
rootcakey: Path = Field(
alias="RUN_CA_KEY", description="root CA key to use in commands", default="/data/persistent/init_ca-key.pem"
)
conf: Path = Field(
alias="RUN_CA_CFSSL_CONF",
description="Path to the db config file",
default="/data/persistent/root_ca_cfssl.json",
)
dbconf: Path = Field(
alias="RUN_DB_CONFIG", description="Path to the db config file", default="/data/persistent/db.json"
)
Expand Down
57 changes: 55 additions & 2 deletions src/ocsprest/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,61 @@ async def refresh_all(request: Request) -> Dict[str, Any]:
return {"success": True}


@ROUTER.post("/sign")
async def sign_one(request: Request) -> Dict[str, Any]:
@ROUTER.post("/csr/sign")
async def csr_sign(request: Request) -> Dict[str, Any]:
"""Sign a CSR, we have to do it via CLI if we want CFSSL to add the Authority Information Access properties"""
cnf = RESTConfig().singleton()
data = await request.json()
csrtmp = Path(tempfile.gettempdir()) / f"{uuid.uuid4()}.csr"
certtmp = csrtmp.with_suffix(".crt")
try:
csrtmp.write_text(data["certificate_request"])
args_sign: List[str] = [
str(cnf.cfssl),
"sign",
f"-config {cnf.conf}",
f"-db-config {cnf.dbconf}",
f"-ca {cnf.cacrt}",
f"-ca-key {cnf.cakey}",
f"-profile {data['profile']}",
f"-csr {csrtmp}",
f"-loglevel {cfssl_loglevel()}",
]
cmd_sign = " ".join(args_sign)
ret_sign, out_sign, _ = await call_cmd(cmd_sign)
if ret_sign != 0:
raise HTTPException(
status_code=500,
detail={"success": False, "error": f"CFSSL CLI call to sign failed, code {ret_sign}. See server logs"},
)
resp_sign = json.loads(out_sign)
if not data.get("bundle", True):
return {"result": {"certificate": resp_sign["cert"].replace("\n", "\\n")}}
# Create the bundle
certtmp.write_text(resp_sign["cert"])
args_bundle: List[str] = [
str(cnf.cfssl),
"bundle",
f"-ca-bundle {cnf.rootcacrt}",
f"-int-bundle {cnf.cacrt}",
"-flavor optimal",
f"-cert {certtmp}",
f"-loglevel {cfssl_loglevel()}",
]
cmd_bundle = " ".join(args_bundle)
ret_bundle, out_bundle, _ = await call_cmd(cmd_bundle)
if ret_bundle != 0:
LOGGER.error("CFSSL CLI call to bundle failed, returning the signed cert anyway")
return {"result": {"certificate": resp_sign["cert"].replace("\n", "\\n")}}
resp_bundle = json.loads(out_bundle)
return {"result": {"certificate": resp_bundle["cert"].replace("\n", "\\n")}}
finally:
csrtmp.unlink()
certtmp.unlink()


@ROUTER.post("/ocsp/sign")
async def ocsp_sign_one(request: Request) -> Dict[str, Any]:
"""calls cfssl ocspsign"""
data = await request.json()
certtmp = Path(tempfile.gettempdir()) / f"{uuid.uuid4()}.pem"
Expand Down

0 comments on commit 0207d57

Please sign in to comment.