diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-07-02 01:06:33 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-07-08 11:02:23 +0200 |
| commit | 4c836008dcac27e0a8258b07270a8a529b2d9167 (patch) | |
| tree | 5c6580802c62a68f5cfb75859451bce0e6f2cb94 | |
| parent | a16482e4d85394314553c27afcc37c0036b6d506 (diff) | |
| download | ouroboros-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.c | 6 | ||||
| -rw-r--r-- | src/irmd/oap/hdr.c | 18 | ||||
| -rw-r--r-- | src/irmd/oap/hdr.h | 6 | ||||
| -rw-r--r-- | src/irmd/oap/srv.c | 6 |
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); |
