summaryrefslogtreecommitdiff
path: root/src/irmd/oap
diff options
context:
space:
mode:
Diffstat (limited to 'src/irmd/oap')
-rw-r--r--src/irmd/oap/auth.c1
-rw-r--r--src/irmd/oap/srv.c23
-rw-r--r--src/irmd/oap/tests/oap_test.c7
3 files changed, 20 insertions, 11 deletions
diff --git a/src/irmd/oap/auth.c b/src/irmd/oap/auth.c
index 4b86f055..d165de73 100644
--- a/src/irmd/oap/auth.c
+++ b/src/irmd/oap/auth.c
@@ -174,6 +174,7 @@ int oap_check_hdr(const struct oap_hdr * hdr)
fail_replay:
pthread_mutex_unlock(&oap_auth.replay.mtx);
free(new);
+ return -EREPLAY;
fail_stamp:
return -EAUTH;
}
diff --git a/src/irmd/oap/srv.c b/src/irmd/oap/srv.c
index afc54acc..587a8f9f 100644
--- a/src/irmd/oap/srv.c
+++ b/src/irmd/oap/srv.c
@@ -180,11 +180,7 @@ static int negotiate_cipher(const struct oap_hdr * peer_hdr,
cli_rank = crypt_kdf_rank(peer_hdr->kdf_nid);
srv_rank = crypt_kdf_rank(kcfg->k.nid);
- /*
- * For client-encap KEM, the KDF is baked into
- * the ciphertext. The server must use the client's
- * KDF and can only verify the minimum.
- */
+ /* Client-encap KEM bakes KDF into ciphertext; verify min. */
if (OAP_KEX_ROLE(peer_hdr) == KEM_MODE_CLIENT_ENCAP) {
if (srv_rank > cli_rank) {
log_err_id(id, "Client KDF too weak.");
@@ -388,11 +384,12 @@ int oap_srv_process(const struct name_info * info,
uint8_t hash_buf[MAX_HASH_SIZE];
buffer_t req_hash = BUF_INIT;
ssize_t hash_ret;
- char cli_name[NAME_SIZE + 1]; /* TODO */
+ char cli_name[NAME_SIZE + 1];
uint8_t * id;
void * pkp = NULL;
void * crt = NULL;
int req_md_nid;
+ int ret;
assert(info != NULL);
assert(rsp_buf != NULL);
@@ -427,8 +424,13 @@ int oap_srv_process(const struct name_info * info,
id = peer_hdr.id.data; /* Logging */
- if (oap_check_hdr(&peer_hdr) < 0) {
- log_err_id(id, "OAP header failed replay check.");
+ ret = oap_check_hdr(&peer_hdr);
+ if (ret == -EREPLAY) {
+ log_warn_id(id, "OAP header failed replay check.");
+ goto fail_replay;
+ }
+ if (ret < 0) {
+ log_err_id(id, "OAP header check failed.");
goto fail_auth;
}
@@ -491,6 +493,11 @@ int oap_srv_process(const struct name_info * info,
fail_cred:
return -EAUTH;
+ fail_replay:
+ crypt_free_crt(crt);
+ crypt_free_key(pkp);
+ return -EREPLAY;
+
fail_kex:
crypt_free_crt(crt);
crypt_free_key(pkp);
diff --git a/src/irmd/oap/tests/oap_test.c b/src/irmd/oap/tests/oap_test.c
index a324b586..a525d988 100644
--- a/src/irmd/oap/tests/oap_test.c
+++ b/src/irmd/oap/tests/oap_test.c
@@ -32,6 +32,7 @@
#include <ouroboros/crypt.h>
#include <ouroboros/endian.h>
+#include <ouroboros/errno.h>
#include <ouroboros/flow.h>
#include <ouroboros/name.h>
#include <ouroboros/random.h>
@@ -1053,9 +1054,9 @@ static int test_oap_replay_packet(void)
freebuf(ctx.req_hdr);
ctx.req_hdr = saved_req;
- /* Replayed request should fail */
- if (oap_srv_process_ctx(&ctx) == 0) {
- printf("Server should reject replayed packet.\n");
+ /* Replay must return -EREPLAY so callers can drop silently. */
+ if (oap_srv_process_ctx(&ctx) != -EREPLAY) {
+ printf("Replayed packet rejection != -EREPLAY.\n");
goto fail_cleanup;
}