/* -*-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
*
/*----- 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.
*
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);
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);
{
unsigned i;
+ if (kx->f & KXF_DEAD)
+ return;
+
if (kx->f & KXF_TIMER)
sel_rmtimer(&kx->t);
for (i = 0; i < kx->nr; i++)
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@ --- *
{
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);
})
}
+/* --- @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
{
time_t now = time(0);
+ if (checkpub(kx))
+ return;
if (!ISVALID(kx, now)) {
stop(kx);
start(kx, now);
};
#endif
+ if (checkpub(kx))
+ return;
+
if (!ISVALID(kx, now)) {
stop(kx);
start(kx, now);
void kx_free(keyexch *kx)
{
stop(kx);
- dh_pubfree(&kx->kpub);
+ if (kx->f & KXF_PUBKEY)
+ dh_pubfree(&kx->kpub);
}
/* --- @kx_newkeys@ --- *
{
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);
}
}
{
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);
/* -*-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
*
/*----- 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.
*
*
* 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));
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);
}
/* -*-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
*
/*----- 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
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 */
} 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) */
*
* 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 ------------------------------------------------------*/