summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-07-02 01:06:33 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-07-08 11:02:23 +0200
commit4c836008dcac27e0a8258b07270a8a529b2d9167 (patch)
tree5c6580802c62a68f5cfb75859451bce0e6f2cb94
parenta16482e4d85394314553c27afcc37c0036b6d506 (diff)
downloadouroboros-4c836008dcac27e0a8258b07270a8a529b2d9167.tar.gz
ouroboros-4c836008dcac27e0a8258b07270a8a529b2d9167.zip
irmd: Fix OAP re-key header encode
The oap_hdr_encode() function validated its own output by re-decoding with rekey hardcoded false. The case where the client signs a re-key failed its own self-check because the cert is not sent again. Now uses a flag on the encode() to signal the signed re-key without certificate. Also fixes a double free after a failed self-decode check. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
-rw-r--r--src/irmd/oap/cli.c6
-rw-r--r--src/irmd/oap/hdr.c18
-rw-r--r--src/irmd/oap/hdr.h6
-rw-r--r--src/irmd/oap/srv.c6
4 files changed, 27 insertions, 9 deletions
diff --git a/src/irmd/oap/cli.c b/src/irmd/oap/cli.c
index 689d67ca..3518b4d1 100644
--- a/src/irmd/oap/cli.c
+++ b/src/irmd/oap/cli.c
@@ -250,6 +250,7 @@ int oap_cli_prepare(void ** ctx,
void * crt = NULL;
buffer_t no_tag = BUF_INIT;
ssize_t ret;
+ int enc_flags = 0;
assert(ctx != NULL);
assert(info != NULL);
@@ -302,6 +303,9 @@ int oap_cli_prepare(void ** ctx,
crt = NULL;
}
+ if (rekey)
+ enc_flags = OAP_ENC_REKEY;
+
oap_hdr_init(&s->local_hdr, s->id, s->kex_buf, data, s->scfg.c.nid);
if (do_client_kex_prepare(info->name, s) < 0) {
@@ -310,7 +314,7 @@ int oap_cli_prepare(void ** ctx,
}
if (oap_hdr_encode(&s->local_hdr, pkp, crt, &s->scfg,
- no_tag, NID_undef, NULL)) {
+ no_tag, NID_undef, NULL, enc_flags)) {
log_err_id(s->id.data, "Failed to create OAP request header.");
goto fail_hdr;
}
diff --git a/src/irmd/oap/hdr.c b/src/irmd/oap/hdr.c
index f8400b46..6f355133 100644
--- a/src/irmd/oap/hdr.c
+++ b/src/irmd/oap/hdr.c
@@ -397,7 +397,8 @@ static int oap_hdr_encode_sealed(struct oap_hdr * hdr,
struct sec_config * scfg,
buffer_t rsp_tag,
int req_md_nid,
- const uint8_t * seal_key)
+ const uint8_t * seal_key,
+ int flags)
{
struct timespec now;
uint64_t stamp;
@@ -449,7 +450,8 @@ static int oap_hdr_encode_sealed(struct oap_hdr * hdr,
free(prefix.data);
freebuf(der);
- if (oap_hdr_decode(hdr, hdr->hdr, req_md_nid, false) < 0)
+ if (oap_hdr_decode(hdr, hdr->hdr, req_md_nid,
+ flags & OAP_ENC_REKEY) < 0)
goto fail_decode;
return 0;
@@ -472,7 +474,8 @@ int oap_hdr_encode(struct oap_hdr * hdr,
struct sec_config * scfg,
buffer_t rsp_tag,
int req_md_nid,
- const uint8_t * seal_key)
+ const uint8_t * seal_key,
+ int flags)
{
struct timespec now;
uint64_t stamp;
@@ -488,7 +491,7 @@ int oap_hdr_encode(struct oap_hdr * hdr,
if (seal_key != NULL)
return oap_hdr_encode_sealed(hdr, pkp, crt, scfg, rsp_tag,
- req_md_nid, seal_key);
+ req_md_nid, seal_key, flags);
clock_gettime(CLOCK_REALTIME, &now);
stamp = hton64(TS_TO_UINT64(now));
@@ -550,10 +553,13 @@ int oap_hdr_encode(struct oap_hdr * hdr,
goto fail_realloc;
memcpy(hdr->hdr.data + offset, sig.data, sig.len);
- clrbuf(out);
}
- if (oap_hdr_decode(hdr, hdr->hdr, req_md_nid, false) < 0)
+ /* Ownership moved to hdr->hdr; drop the alias to avoid double-free. */
+ clrbuf(out);
+
+ if (oap_hdr_decode(hdr, hdr->hdr, req_md_nid,
+ flags & OAP_ENC_REKEY) < 0)
goto fail_decode;
freebuf(der);
diff --git a/src/irmd/oap/hdr.h b/src/irmd/oap/hdr.h
index 1a599727..66fbac9a 100644
--- a/src/irmd/oap/hdr.h
+++ b/src/irmd/oap/hdr.h
@@ -168,13 +168,17 @@ void oap_hdr_init(struct oap_hdr * hdr,
void oap_hdr_fini(struct oap_hdr * oap_hdr);
+/* oap_hdr_encode option flags */
+#define OAP_ENC_REKEY (1U << 0) /* signed, cert-less re-key packet */
+
int oap_hdr_encode(struct oap_hdr * hdr,
void * pkp,
void * crt,
struct sec_config * scfg,
buffer_t rsp_tag,
int req_md_nid,
- const uint8_t * seal_key);
+ const uint8_t * seal_key,
+ int flags);
int oap_hdr_decode(struct oap_hdr * hdr,
buffer_t buf,
diff --git a/src/irmd/oap/srv.c b/src/irmd/oap/srv.c
index 5d631618..cc3dec5b 100644
--- a/src/irmd/oap/srv.c
+++ b/src/irmd/oap/srv.c
@@ -400,6 +400,7 @@ int oap_srv_process(const struct name_info * info,
void * pkp = NULL;
void * crt = NULL;
int req_md_nid;
+ int enc_flags = 0;
int ret;
assert(info != NULL);
@@ -426,6 +427,9 @@ int oap_srv_process(const struct name_info * info,
crt = NULL;
}
+ if (rekey)
+ enc_flags = OAP_ENC_REKEY;
+
if (load_srv_sec_config(info, &scfg) < 0) {
log_err("Failed to load security config for %s.", info->name);
goto fail_kex;
@@ -535,7 +539,7 @@ int oap_srv_process(const struct name_info * info,
}
ret = oap_hdr_encode(&local_hdr, pkp, crt, &scfg,
- rsp_tag, req_md_nid, seal_key);
+ rsp_tag, req_md_nid, seal_key, enc_flags);
crypt_secure_clear(hs_key, SYMMKEYSZ);