diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-06-12 19:34:27 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-06-29 08:32:58 +0200 |
| commit | 977bcac2d56a8793ed93b4aac7016ef36b51a07f (patch) | |
| tree | 7e26553a57cbdc75d9c33b25fe228631dea36142 /src/lib/tests/kex_test.c | |
| parent | 67c55d5869d5473e5139614637f31ea37746181d (diff) | |
| download | ouroboros-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.c | 83 |
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(); |
