summaryrefslogtreecommitdiff
path: root/src/irmd/oap
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-02-15 22:31:33 +0100
committerSander Vrijders <sander@ouroboros.rocks>2026-02-18 07:53:23 +0100
commit46cc58fe1a89903f4ef928caeee1bec96ab5967b (patch)
tree36c5038ae64d5e89de627fd0ebfc338f126c5554 /src/irmd/oap
parent85cc8d28d263a8b8ff04d90622311f5d68e26e6f (diff)
downloadouroboros-46cc58fe1a89903f4ef928caeee1bec96ab5967b.tar.gz
ouroboros-46cc58fe1a89903f4ef928caeee1bec96ab5967b.zip
irmd: Fix client-side encryption request
When the server had no cipher configured, sk->nid was set to NID_undef before negotiation and never updated, causing the response header to encode NID_undef as the cipher — even though negotiate_kex() correctly populated kcfg.c.nid from the client's request. Adds a test for the KEM case where the client request encryption with nothing specified server-side. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/irmd/oap')
-rw-r--r--src/irmd/oap/srv.c3
-rw-r--r--src/irmd/oap/tests/oap_test_pqc.c84
2 files changed, 84 insertions, 3 deletions
diff --git a/src/irmd/oap/srv.c b/src/irmd/oap/srv.c
index 93270c48..a356c62e 100644
--- a/src/irmd/oap/srv.c
+++ b/src/irmd/oap/srv.c
@@ -417,8 +417,6 @@ int oap_srv_process(const struct name_info * info,
goto fail_kex;
}
- sk->nid = kcfg.c.nid;
-
/* Decode incoming header (NID_undef = request, no hash) */
if (oap_hdr_decode(&peer_hdr, req_buf, NID_undef) < 0) {
log_err("Failed to decode OAP header.");
@@ -444,7 +442,6 @@ int oap_srv_process(const struct name_info * info,
if (do_server_kex(info, &peer_hdr, &kcfg, &local_hdr.kex, sk) < 0)
goto fail_kex;
- /* Update cipher NID after negotiation */
sk->nid = kcfg.c.nid;
/* Build response header with hash of client request */
diff --git a/src/irmd/oap/tests/oap_test_pqc.c b/src/irmd/oap/tests/oap_test_pqc.c
index ed51a6b4..bbaf9f7b 100644
--- a/src/irmd/oap/tests/oap_test_pqc.c
+++ b/src/irmd/oap/tests/oap_test_pqc.c
@@ -332,6 +332,86 @@ static int test_oap_roundtrip_kem_all(void)
return ret;
}
+static int test_oap_kem_srv_uncfg(int kex)
+{
+ struct oap_test_ctx ctx;
+ const char * kex_str = kex_nid_to_str(kex);
+
+ memset(&test_cfg, 0, sizeof(test_cfg));
+
+ /* Server: auth only, no KEX configured */
+ test_cfg.srv.auth = true;
+
+ /* Client: requests KEM with server-side encapsulation */
+ test_cfg.cli.kex = kex;
+ test_cfg.cli.cipher = NID_aes_256_gcm;
+ test_cfg.cli.kdf = get_random_kdf();
+ test_cfg.cli.kem_mode = SRV_ENCAP;
+ test_cfg.cli.auth = false;
+
+ TEST_START("(%s)", kex_str);
+
+ if (oap_test_setup_kem(&ctx, root_ca_crt_ml,
+ im_ca_crt_ml) < 0)
+ goto fail;
+
+ if (oap_cli_prepare_ctx(&ctx) < 0) {
+ printf("Client prepare failed.\n");
+ goto fail_cleanup;
+ }
+
+ if (oap_srv_process_ctx(&ctx) < 0) {
+ printf("Server process failed.\n");
+ goto fail_cleanup;
+ }
+
+ if (oap_cli_complete_ctx(&ctx) < 0) {
+ printf("Client complete failed.\n");
+ goto fail_cleanup;
+ }
+
+ if (memcmp(ctx.cli.key, ctx.srv.key, SYMMKEYSZ) != 0) {
+ printf("Client and server keys do not match!\n");
+ goto fail_cleanup;
+ }
+
+ if (ctx.cli.nid == NID_undef ||
+ ctx.srv.nid == NID_undef) {
+ printf("Cipher not set in flow.\n");
+ goto fail_cleanup;
+ }
+
+ oap_test_teardown_kem(&ctx);
+
+ TEST_SUCCESS("(%s)", kex_str);
+ return TEST_RC_SUCCESS;
+
+ fail_cleanup:
+ oap_test_teardown_kem(&ctx);
+ fail:
+ TEST_FAIL("(%s)", kex_str);
+ return TEST_RC_FAIL;
+}
+
+static int test_oap_kem_srv_uncfg_all(void)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; kex_supported_nids[i] != NID_undef; i++) {
+ const char * algo;
+
+ algo = kex_nid_to_str(kex_supported_nids[i]);
+
+ if (!IS_KEM_ALGORITHM(algo))
+ continue;
+
+ ret |= test_oap_kem_srv_uncfg(kex_supported_nids[i]);
+ }
+
+ return ret;
+}
+
int oap_test_pqc(int argc,
char **argv)
{
@@ -345,6 +425,8 @@ int oap_test_pqc(int argc,
ret |= test_oap_roundtrip_kem_all();
+ ret |= test_oap_kem_srv_uncfg_all();
+
ret |= test_oap_corrupted_request();
ret |= test_oap_corrupted_response();
ret |= test_oap_truncated_request();
@@ -352,6 +434,8 @@ int oap_test_pqc(int argc,
(void) test_oap_roundtrip_auth_only;
(void) test_oap_roundtrip_kem;
(void) test_oap_roundtrip_kem_all;
+ (void) test_oap_kem_srv_uncfg;
+ (void) test_oap_kem_srv_uncfg_all;
(void) test_oap_corrupted_request;
(void) test_oap_corrupted_response;
(void) test_oap_truncated_request;