From 977bcac2d56a8793ed93b4aac7016ef36b51a07f Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Fri, 12 Jun 2026 19:34:27 +0200 Subject: irmd: Add issuer and digest pinning to OAP A peer certificate that verifies against the CA store could have been issued by any trusted CA, and a peer could pick any supported digest for its signature. Tighten the authentication contract with two local policies. cacert= pins the issuing CA: a peer certificate, if presented, must chain through the pinned CA. Whether a certificate is mandatory at all remains controlled by auth= alone. digest= now also pins the signature digest: a classical peer must sign with the locally configured digest, and may not omit the digest NID to fall back to the key's default digest. PQC signatures (ML-DSA, SLH-DSA) have an intrinsic digest and may be NID_undef. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/irmd/oap/io.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/irmd/oap/io.c') diff --git a/src/irmd/oap/io.c b/src/irmd/oap/io.c index 24d33e60..5c560ea5 100644 --- a/src/irmd/oap/io.c +++ b/src/irmd/oap/io.c @@ -100,6 +100,8 @@ int load_kex_config(const char * name, const char * path, struct sec_config * cfg) { + void * pin; + assert(name != NULL); assert(cfg != NULL); @@ -112,6 +114,15 @@ int load_kex_config(const char * name, return -1; } + if (cfg->cacert[0] != '\0') { + if (crypt_load_crt_file(cfg->cacert, &pin) < 0) { + log_err("Failed to load pinned CA %s for %s.", + cfg->cacert, name); + return -EAUTH; + } + crypt_free_crt(pin); + } + if (!IS_KEX_ALGO_SET(cfg)) { log_info("Key exchange not configured for %s.", name); return 0; -- cgit v1.2.3