Support expiry of other peers' public keys.
authormdw <mdw>
Fri, 22 Jun 2001 19:40:36 +0000 (19:40 +0000)
committermdw <mdw>
Fri, 22 Jun 2001 19:40:36 +0000 (19:40 +0000)
keyexch.c
keymgmt.c
tripe.h

index 55e302c..c17f400 100644 (file)
--- a/keyexch.c
+++ b/keyexch.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: keyexch.c,v 1.3 2001/06/19 22:07:09 mdw Exp $
+ * $Id: keyexch.c,v 1.4 2001/06/22 19:40:36 mdw Exp $
  *
  * Key exchange protocol
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: keyexch.c,v $
+ * Revision 1.4  2001/06/22 19:40:36  mdw
+ * Support expiry of other peers' public keys.
+ *
  * Revision 1.3  2001/06/19 22:07:09  mdw
  * Cosmetic fixes.
  *
@@ -537,12 +540,14 @@ static void resend(keyexch *kx)
 
   switch (kx->s) {
     case KXS_CHAL:
-      T( trace(T_KEYEXCH, "sending prechallenge to `%s'", p_name(kx->p)); )
+      T( trace(T_KEYEXCH, "keyexch: sending prechallenge to `%s'",
+              p_name(kx->p)); )
       b = p_txstart(kx->p, MSG_KEYEXCH | KX_PRECHAL);
       buf_putmp(b, kx->c);
       break;
     case KXS_COMMIT:
-      T( trace(T_KEYEXCH, "sending switch request to `%s'", p_name(kx->p)); )
+      T( trace(T_KEYEXCH, "keyexch: sending switch request to `%s'",
+              p_name(kx->p)); )
       kxc = kx->r[0];
       b = p_txstart(kx->p, MSG_KEYEXCH | KX_SWITCH);
       buf_put(b, kx->hc, HASHSZ);
@@ -554,7 +559,7 @@ static void resend(keyexch *kx)
       ks_encrypt(kxc->ks, &bb, b);
       break;
     case KXS_SWITCH:
-      T( trace(T_KEYEXCH, "sending switch confirmation to `%s'",
+      T( trace(T_KEYEXCH, "keyexch: sending switch confirmation to `%s'",
               p_name(kx->p)); )
       kxc = kx->r[0];
       b = p_txstart(kx->p, MSG_KEYEXCH | KX_SWITCHOK);
@@ -845,6 +850,9 @@ static void stop(keyexch *kx)
 {
   unsigned i;
 
+  if (kx->f & KXF_DEAD)
+    return;
+
   if (kx->f & KXF_TIMER)
     sel_rmtimer(&kx->t);
   for (i = 0; i < kx->nr; i++)
@@ -852,6 +860,9 @@ static void stop(keyexch *kx)
   mp_drop(kx->alpha);
   mp_drop(kx->c);
   mp_drop(kx->rx);
+  kx->t_valid = 0;
+  kx->f |= KXF_DEAD;
+  kx->f &= ~KXF_TIMER;
 }
 
 /* --- @start@ --- *
@@ -869,8 +880,10 @@ static void start(keyexch *kx, time_t now)
 {
   HASH_CTX h;
 
+  assert(kx->f & KXF_DEAD);
+
+  kx->f &= ~KXF_DEAD;
   kx->nr = 0;
-  kx->f = 0;
   kx->alpha = mprand_range(MP_NEW, kpriv.dp.q, &rand_global, 0);
   kx->c = mpmont_exp(&mg, MP_NEW, kpriv.dp.g, kx->alpha);
   kx->rx = mpmont_exp(&mg, MP_NEW, kx->kpub.y, kx->alpha);
@@ -893,6 +906,32 @@ static void start(keyexch *kx, time_t now)
   })
 }
 
+/* --- @checkpub@ --- *
+ *
+ * Arguments:  @keyexch *kx@ = pointer to key exchange context
+ *
+ * Returns:    Zero if OK, nonzero if the peer's public key has expired.
+ *
+ * Use:                Deactivates the key-exchange until the peer acquires a new
+ *             public key.
+ */
+
+static int checkpub(keyexch *kx)
+{
+  time_t now;
+  if (kx->f & KXF_DEAD)
+    return (-1);
+  now = time(0);
+  if (KEY_EXPIRED(now, kx->texp_kpub)) {
+    stop(kx);
+    a_warn("public key for `%s' has expired", p_name(kx->p));
+    dh_pubfree(&kx->kpub);
+    kx->f &= ~KXF_PUBKEY;
+    return (-1);
+  }
+  return (0);
+}
+
 /* --- @kx_start@ --- *
  *
  * Arguments:  @keyexch *kx@ = pointer to key exchange context
@@ -908,6 +947,8 @@ void kx_start(keyexch *kx)
 {
   time_t now = time(0);
 
+  if (checkpub(kx))
+    return;
   if (!ISVALID(kx, now)) {
     stop(kx);
     start(kx, now);
@@ -941,6 +982,9 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
   };
 #endif
 
+  if (checkpub(kx))
+    return;
+
   if (!ISVALID(kx, now)) {
     stop(kx);
     start(kx, now);
@@ -991,7 +1035,8 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
 void kx_free(keyexch *kx)
 {
   stop(kx);
-  dh_pubfree(&kx->kpub);
+  if (kx->f & KXF_PUBKEY)
+    dh_pubfree(&kx->kpub);
 }
 
 /* --- @kx_newkeys@ --- *
@@ -1010,15 +1055,18 @@ void kx_newkeys(keyexch *kx)
 {
   dh_pub dp;
 
-  if (km_getpubkey(p_name(kx->p), &dp))
+  if (km_getpubkey(p_name(kx->p), &dp, &kx->texp_kpub))
     return;
-  dh_pubfree(&kx->kpub);
+  if (kx->f & KXF_PUBKEY)
+    dh_pubfree(&kx->kpub);
   kx->kpub = dp;
-  if (kx->s != KXS_SWITCH) {
+  kx->f |= KXF_PUBKEY;
+  if ((kx->f & KXF_DEAD) || kx->s != KXS_SWITCH) {
     T( trace(T_KEYEXCH, "keyexch: restarting key negotiation with `%s'",
             p_name(kx->p)); )
-    kx->t_valid = 0;
-    kx_start(kx);
+    stop(kx);
+    start(kx, time(0));
+    resend(kx);
   }
 }
 
@@ -1039,8 +1087,9 @@ int kx_init(keyexch *kx, peer *p, keyset **ks)
 {
   kx->ks = ks;
   kx->p = p;
-  if (km_getpubkey(p_name(p), &kx->kpub))
+  if (km_getpubkey(p_name(p), &kx->kpub, &kx->texp_kpub))
     return (-1);
+  kx->f = KXF_DEAD | KXF_PUBKEY;
   start(kx, time(0));
   resend(kx);
   return (0);
index 55a188b..54a31b0 100644 (file)
--- a/keymgmt.c
+++ b/keymgmt.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: keymgmt.c,v 1.2 2001/06/19 22:07:09 mdw Exp $
+ * $Id: keymgmt.c,v 1.3 2001/06/22 19:40:36 mdw Exp $
  *
  * Key loading and storing
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: keymgmt.c,v $
+ * Revision 1.3  2001/06/22 19:40:36  mdw
+ * Support expiry of other peers' public keys.
+ *
  * Revision 1.2  2001/06/19 22:07:09  mdw
  * Cosmetic fixes.
  *
@@ -233,21 +236,26 @@ void km_init(const char *priv, const char *pub, const char *tag)
  *
  * Arguments:  @const char *tag@ = public key tag to load
  *             @dh_pub *kpub@ = where to put the public key
+ *             @time_t *t_exp@ = where to put the expiry time
  *
  * Returns:    Zero if OK, nonzero if it failed.
  *
  * Use:                Fetches a public key from the keyring.
  */
 
-int km_getpubkey(const char *tag, dh_pub *kpub)
+int km_getpubkey(const char *tag, dh_pub *kpub, time_t *t_exp)
 {
   key_packstruct kps[DH_PUBFETCHSZ];
   key_packdef *kp;
+  key *k;
   dh_pub dp;
   int e;
 
   kp = key_fetchinit(dh_pubfetch, kps, &dp);
-  e = key_fetchbyname(kp, kf_pub, tag);
+  if ((k = key_bytag(kf_pub, tag)) == 0)
+    e = KERR_NOTFOUND;
+  else
+    e = key_fetch(kp, k);
   key_fetchdone(kp);
   if (e) {
     a_warn("error loading public key `%s': %s", tag, key_strerror(e));
@@ -272,6 +280,7 @@ int km_getpubkey(const char *tag, dh_pub *kpub)
   kpub->dp.q = MP_COPY(dp.dp.q);
   kpub->dp.g = MP_COPY(dp.dp.g);
   kpub->y = MP_COPY(dp.y);
+  *t_exp = k->exp;
   return (0);
 }
 
diff --git a/tripe.h b/tripe.h
index 9a18032..06fbf8f 100644 (file)
--- a/tripe.h
+++ b/tripe.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: tripe.h,v 1.8 2001/06/19 22:10:57 mdw Exp $
+ * $Id: tripe.h,v 1.9 2001/06/22 19:40:36 mdw Exp $
  *
  * Main header file for TrIPE
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: tripe.h,v $
+ * Revision 1.9  2001/06/22 19:40:36  mdw
+ * Support expiry of other peers' public keys.
+ *
  * Revision 1.8  2001/06/19 22:10:57  mdw
  * Some more constants for the algorithms.  Document the packet format
  * change for non-malleability.  Moved @buf@ definitions to separate header
@@ -335,6 +338,7 @@ typedef struct keyexch {
   unsigned s;                          /* Current state in exchange */
   sel_timer t;                         /* Timer for next exchange */
   dh_pub kpub;                         /* Peer's public key */
+  time_t texp_kpub;                    /* Expiry time for public key */
   mp *alpha;                           /* My temporary secret */
   mp *c;                               /* My challenge */
   mp *rx;                              /* The expected response */
@@ -345,6 +349,8 @@ typedef struct keyexch {
 } keyexch;
 
 #define KXF_TIMER 1u                   /* Waiting for a timer to go off */
+#define KXF_DEAD 2u                    /* The key-exchanger isn't up */
+#define KXF_PUBKEY 4u                  /* Key exchanger has a public key */
 
 enum {
   KXS_DEAD,                            /* Uninitialized state (magical) */
@@ -484,13 +490,15 @@ extern void km_init(const char */*kr_priv*/, const char */*kr_pub*/,
  *
  * Arguments:  @const char *tag@ = public key tag to load
  *             @dh_pub *kpub@ = where to put the public key
+ *             @time_t *t_exp@ = where to put the expiry time
  *
  * Returns:    Zero if OK, nonzero if it failed.
  *
  * Use:                Fetches a public key from the keyring.
  */
 
-extern int km_getpubkey(const char */*tag*/, dh_pub */*kpub*/);
+extern int km_getpubkey(const char */*tag*/, dh_pub */*kpub*/,
+                       time_t */*t_exp*/);
 
 /*----- Key exchange ------------------------------------------------------*/