From 12a26b8b34df23103d4da6d7e40705485266a4d6 Mon Sep 17 00:00:00 2001 Message-Id: <12a26b8b34df23103d4da6d7e40705485266a4d6.1714963068.git.mdw@distorted.org.uk> From: Mark Wooding Date: Mon, 27 Jun 2011 09:31:48 +0100 Subject: [PATCH] server/keyset.c: Return more informative error codes from ks_decrypt. Organization: Straylight/Edgeware From: Mark Wooding Also, do what the commentary says and return zero and break the output buffer if it's not big enough, rather than returning KSERR_DECRYPT. The new error codes allow callers to make more sensible decisions about whether to continue to search for other keys which might work better. --- server/keyexch.c | 1 + server/keyset.c | 22 ++++++++++++---------- server/tripe.h | 2 ++ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/server/keyexch.c b/server/keyexch.c index d007a434..8eaf1e88 100644 --- a/server/keyexch.c +++ b/server/keyexch.c @@ -792,6 +792,7 @@ static int decryptrest(keyexch *kx, kxchal *kxc, unsigned msg, buf *b) a_warn("KX", "?PEER", kx->p, "decrypt-failed", "%s", pkname[msg], A_END); return (-1); } + if (!BOK(&bb)) return (-1); buf_init(b, BBASE(&bb), BLEN(&bb)); return (0); } diff --git a/server/keyset.c b/server/keyset.c index 99fad2f5..1f580ff7 100644 --- a/server/keyset.c +++ b/server/keyset.c @@ -188,7 +188,7 @@ static int dodecrypt(keyset *ks, unsigned ty, buf *b, buf *bb, uint32 *seq) if (psz < ivsz + SEQSZ + tagsz) { T( trace(T_KEYSET, "keyset: block too small for keyset %u", ks->seq); ) - return (KSERR_DECRYPT); + return (KSERR_MALFORMED); } sz = psz - ivsz - SEQSZ - tagsz; pmac = BCUR(b); pseq = pmac + tagsz; piv = pseq + SEQSZ; ppk = piv + ivsz; @@ -421,7 +421,7 @@ int ks_encrypt(keyset *ks, unsigned ty, buf *b, buf *bb) * @buf *b@ = pointer to an input buffer * @buf *bb@ = pointer to an output buffer * - * Returns: Zero on success; @KSERR_DECRYPT@ on failure. Also returns + * Returns: Zero on success; @KSERR_...@ on failure. Also returns * zero if there was insufficient buffer (but the output buffer * is broken in this case). * @@ -434,12 +434,12 @@ int ks_decrypt(keyset *ks, unsigned ty, buf *b, buf *bb) { time_t now = time(0); uint32 seq; + int err; - if (!KEYOK(ks, now) || - buf_ensure(bb, BLEN(b)) || - dodecrypt(ks, ty, b, bb, &seq) || - seq_check(&ks->iseq, seq, "SYMM")) - return (KSERR_DECRYPT); + if (!KEYOK(ks, now)) return (KSERR_DECRYPT); + if (buf_ensure(bb, BLEN(b))) return (0); + if ((err = dodecrypt(ks, ty, b, bb, &seq)) != 0) return (err); + if (seq_check(&ks->iseq, seq, "SYMM")) return (KSERR_SEQ); return (0); } @@ -574,24 +574,26 @@ int ksl_decrypt(keyset **ksroot, unsigned ty, buf *b, buf *bb) time_t now = time(0); keyset *ks; uint32 seq; + int err; if (buf_ensure(bb, BLEN(b))) - return (KSERR_DECRYPT); + return (0); for (ks = *ksroot; ks; ks = ks->next) { if (!KEYOK(ks, now)) continue; - if (!dodecrypt(ks, ty, b, bb, &seq)) { + if ((err = dodecrypt(ks, ty, b, bb, &seq)) == 0) { if (ks->f & KSF_LISTEN) { T( trace(T_KEYSET, "keyset: implicitly activating keyset %u", ks->seq); ) ks->f &= ~KSF_LISTEN; } if (seq_check(&ks->iseq, seq, "SYMM")) - return (KSERR_DECRYPT); + return (KSERR_SEQ); else return (0); } + if (err != KSERR_DECRYPT) return (err); } T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); ) return (KSERR_DECRYPT); diff --git a/server/tripe.h b/server/tripe.h index c5694dc1..e382487b 100644 --- a/server/tripe.h +++ b/server/tripe.h @@ -226,6 +226,8 @@ typedef struct keyset { #define KSERR_REGEN -1 /* Regenerate keys */ #define KSERR_NOKEYS -2 /* No keys left */ #define KSERR_DECRYPT -3 /* Unable to decrypt message */ +#define KSERR_SEQ -4 /* Incorrect sequence number */ +#define KSERR_MALFORMED -5 /* Input ciphertext is broken */ /* --- Key exchange --- * * -- [mdw]