X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/0617b6e7bd26c53349e9f457cdf86ccd6a4e8fbf..00e64b67d321bf53224d546dcba58c52834a7b79:/keyexch.c diff --git a/keyexch.c b/keyexch.c index 1eb6981a..c17f4009 100644 --- a/keyexch.c +++ b/keyexch.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: keyexch.c,v 1.2 2001/02/16 21:24:27 mdw Exp $ + * $Id: keyexch.c,v 1.4 2001/06/22 19:40:36 mdw Exp $ * * Key exchange protocol * @@ -29,6 +29,12 @@ /*----- 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. + * * Revision 1.2 2001/02/16 21:24:27 mdw * Rewrite for new key exchange protocol. * @@ -163,7 +169,6 @@ static void kxc_stoptimer(kxchal *kxc) /* --- @kxc_new@ --- * * * Arguments: @keyexch *kx@ = pointer to key exchange block - * @ * * Returns: A pointer to the challenge block. * @@ -535,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); @@ -552,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); @@ -843,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++) @@ -850,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@ --- * @@ -867,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); @@ -891,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 @@ -906,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); @@ -939,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); @@ -989,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@ --- * @@ -1008,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); } } @@ -1037,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);