summaryrefslogtreecommitdiff
path: root/src/lib/tests/kex_test.c
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-06-12 19:34:27 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-06-29 08:32:58 +0200
commit977bcac2d56a8793ed93b4aac7016ef36b51a07f (patch)
tree7e26553a57cbdc75d9c33b25fe228631dea36142 /src/lib/tests/kex_test.c
parent67c55d5869d5473e5139614637f31ea37746181d (diff)
downloadouroboros-977bcac2d56a8793ed93b4aac7016ef36b51a07f.tar.gz
ouroboros-977bcac2d56a8793ed93b4aac7016ef36b51a07f.zip
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 <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib/tests/kex_test.c')
-rw-r--r--src/lib/tests/kex_test.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/lib/tests/kex_test.c b/src/lib/tests/kex_test.c
index 300a0607..7a4d36d8 100644
--- a/src/lib/tests/kex_test.c
+++ b/src/lib/tests/kex_test.c
@@ -80,6 +80,12 @@
"auth=required\n" \
"digest=sha512\n"
+#define KEX_CONFIG_CACERT \
+ "cacert=/etc/ouroboros/security/cacert/ca.crt\n"
+
+#define KEX_CONFIG_UNKNOWN_KEY \
+ "autth=required\n"
+
/* Test key material for key loading tests */
#define X25519_PRIVKEY_PEM \
"-----BEGIN PRIVATE KEY-----\n" \
@@ -1055,6 +1061,81 @@ static int test_kex_parse_config_auth_no_enc(const char * config)
return TEST_RC_FAIL;
}
+static int test_kex_parse_config_cacert(void)
+{
+ struct sec_config kex;
+ FILE * fp;
+
+ TEST_START();
+
+ memset(&kex, 0, sizeof(kex));
+
+ fp = FMEMOPEN_STR(KEX_CONFIG_CACERT);
+ if (fp == NULL) {
+ printf("Failed to open memory stream.\n");
+ goto fail;
+ }
+
+ if (parse_sec_config(&kex, fp) < 0) {
+ printf("Failed to parse cacert config.\n");
+ fclose(fp);
+ goto fail;
+ }
+
+ if (strcmp(kex.cacert,
+ "/etc/ouroboros/security/cacert/ca.crt") != 0) {
+ printf("cacert not parsed correctly.\n");
+ fclose(fp);
+ goto fail;
+ }
+
+ if (kex.req_auth) {
+ printf("cacert must not imply req_auth.\n");
+ fclose(fp);
+ goto fail;
+ }
+
+ fclose(fp);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_kex_parse_config_unknown_key(void)
+{
+ struct sec_config kex;
+ FILE * fp;
+
+ TEST_START();
+
+ memset(&kex, 0, sizeof(kex));
+
+ fp = FMEMOPEN_STR(KEX_CONFIG_UNKNOWN_KEY);
+ if (fp == NULL) {
+ printf("Failed to open memory stream.\n");
+ goto fail;
+ }
+
+ if (parse_sec_config(&kex, fp) == 0) {
+ printf("Unknown key should be rejected.\n");
+ fclose(fp);
+ goto fail;
+ }
+
+ fclose(fp);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
int kex_test(int argc,
char ** argv)
{
@@ -1073,6 +1154,8 @@ int kex_test(int argc,
ret |= test_kex_parse_config_auth_optional();
ret |= test_kex_parse_config_auth_no_enc(KEX_CONFIG_AUTH_THEN_NO_ENC);
ret |= test_kex_parse_config_auth_no_enc(KEX_CONFIG_NO_ENC_THEN_AUTH);
+ ret |= test_kex_parse_config_cacert();
+ ret |= test_kex_parse_config_unknown_key();
#ifdef HAVE_OPENSSL
ret |= test_kex_parse_config_custom();
ret |= test_kex_parse_config_whitespace();