chiark / gitweb /
server/keyset.c: Return more informative error codes from ks_decrypt.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 27 Jun 2011 08:31:48 +0000 (09:31 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 21 Mar 2012 15:54:34 +0000 (15:54 +0000)
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
server/keyset.c
server/tripe.h

index d007a434ef98e5973d0882cbeeb59a203987e3ab..8eaf1e88a72ce7bc198db1d099538e0cbf706071 100644 (file)
@@ -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);
   }
     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);
 }
   buf_init(b, BBASE(&bb), BLEN(&bb));
   return (0);
 }
index 99fad2f52aa35803a592d20fd3a743b9e9d7f2a1..1f580ff7b79830ee107c6f897653e896a0b4c94b 100644 (file)
@@ -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); )
 
   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;
   }
   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
  *
  *             @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).
  *
  *             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;
 {
   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);
 }
 
   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;
   time_t now = time(0);
   keyset *ks;
   uint32 seq;
+  int err;
 
   if (buf_ensure(bb, BLEN(b)))
 
   if (buf_ensure(bb, BLEN(b)))
-    return (KSERR_DECRYPT);
+    return (0);
 
   for (ks = *ksroot; ks; ks = ks->next) {
     if (!KEYOK(ks, now))
       continue;
 
   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"))
       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);
     }
       else
        return (0);
     }
+    if (err != KSERR_DECRYPT) return (err);
   }
   T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); )
   return (KSERR_DECRYPT);
   }
   T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); )
   return (KSERR_DECRYPT);
index c5694dc13f7170d73c1fa5d9116ab501e19e09e1..e382487b8e10314af4b50971fd6866615e22ced1 100644 (file)
@@ -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_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 --- *
  *
 
 /* --- Key exchange --- *
  *