X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/5ac9463b6365ac278641732c546a77bb61692ffe..48b845698dcf3ec4b9f8b9f1848a157f0245d7cc:/server/keyexch.c diff --git a/server/keyexch.c b/server/keyexch.c index 8577d91e..d007a434 100644 --- a/server/keyexch.c +++ b/server/keyexch.c @@ -1,13 +1,11 @@ /* -*-c-*- - * - * $Id$ * * Key exchange protocol * * (c) 2001 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Trivial IP Encryption (TrIPE). * @@ -15,12 +13,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * TrIPE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with TrIPE; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -48,14 +46,14 @@ * %$r_A = g^{\rho_A}$% Alice's challenge * %$c_A = H(\cookie{cookie}, r_A)$% Alice's cookie * %$v_A = \rho_A \xor H(\cookie{expected-reply}, a, r_A, r_B, b^{\rho_A})$% - * Alice's challenge check value + * Alice's challenge check value * %$r_B^\alpha = a^{\rho_B}$% Alice's reply * %$K = r_B^{\rho_A} = r_B^{\rho_A} = g^{\rho_A\rho_B}$% - * Alice and Bob's shared secret key + * Alice and Bob's shared secret key * %$w_A = H(\cookie{switch-request}, c_A, c_B)$% - * Alice's switch request value + * Alice's switch request value * %$u_A = H(\cookie{switch-confirm}, c_A, c_B)$% - * Alice's switch confirm value + * Alice's switch confirm value * * The messages are then: * @@ -75,11 +73,11 @@ * * %$\cookie{kx-switch-ok}, E_K(u_A))$% * Switch received. Committed; send data; move to @KXS_SWITCH@. - */ + */ /*----- Tunable parameters ------------------------------------------------*/ -#define T_VALID MIN(2) /* Challenge validity period */ +#define T_VALID SEC(20) /* Challenge validity period */ #define T_RETRY SEC(10) /* Challenge retransmit interval */ #define VALIDP(kx, now) ((now) < (kx)->t_valid) @@ -87,8 +85,7 @@ /*----- Static tables -----------------------------------------------------*/ static const char *const pkname[] = { - "pre-challenge", "cookie", "challenge", - "reply", "switch-rq", "switch-ok" + "pre-challenge", "challenge", "reply", "switch-rq", "switch-ok" }; /*----- Various utilities -------------------------------------------------*/ @@ -598,7 +595,7 @@ static kxchal *respond(keyexch *kx, unsigned msg, buf *b) goto badcheck; /* --- Fill in a new challenge block --- */ - + kxc = kxc_new(kx); G_COPY(gg, kxc->c, c); G_COPY(gg, kxc->r, r); @@ -606,7 +603,7 @@ static kxchal *respond(keyexch *kx, unsigned msg, buf *b) h = GH_INIT(algs.h); HASH_STRING(h, "tripe-check-hash"); GH_HASH(h, ck, indexsz); - GH_DONE(h, kxc->hc); + GH_DONE(h, kxc->ck); GH_DESTROY(h); h = GH_INIT(algs.h); @@ -678,7 +675,7 @@ bad: G_DESTROY(gg, cc); G_DESTROY(gg, r); mp_drop(cv); - return (0); + return (0); } /* --- @dochallenge@ --- * @@ -857,7 +854,7 @@ static void commit(keyexch *kx, kxchal *kxc) kx->r[0] = kxc; kx->nr = 1; kxc_stoptimer(kxc); - ksl_link(kx->ks, kxc->ks); + ksl_link(kx->ks, kxc->ks); } /* --- @doreply@ --- * @@ -886,7 +883,7 @@ static int doreply(keyexch *kx, buf *b) if (BLEFT(b)) { a_warn("KX", "?PEER", kx->p, "invalid", "reply", A_END); goto bad; - } + } if (kx->s == KXS_CHAL) { commit(kx, kxc); kx->s = KXS_COMMIT; @@ -1012,7 +1009,7 @@ static int doswitchok(keyexch *kx, buf *b) return (0); bad: - return (-1); + return (-1); } /*----- Main code ---------------------------------------------------------*/ @@ -1067,7 +1064,7 @@ static void start(keyexch *kx, time_t now) assert(kx->f & KXF_DEAD); - kx->f &= ~KXF_DEAD; + kx->f &= ~(KXF_DEAD | KXF_CORK); kx->nr = 0; kx->alpha = mprand_range(MP_NEW, gg->r, &rand_global, 0); kx->c = G_CREATE(gg); G_EXP(gg, kx->c, gg->g, kx->alpha); @@ -1163,6 +1160,12 @@ void kx_message(keyexch *kx, unsigned msg, buf *b) size_t sz = BSZ(b); int rc; + if (kx->f & KXF_CORK) { + start(kx, now); + settimer(kx, now + T_RETRY); + a_notify("KXSTART", A_END); + } + if (checkpub(kx)) return; @@ -1170,7 +1173,6 @@ void kx_message(keyexch *kx, unsigned msg, buf *b) stop(kx); start(kx, now); } - T( trace(T_KEYEXCH, "keyexch: processing %s packet from `%s'", msg < KX_NMSG ? pkname[msg] : "unknown", p_name(kx->p)); ) @@ -1233,7 +1235,7 @@ void kx_free(keyexch *kx) void kx_newkeys(keyexch *kx) { - if (km_getpubkey(p_name(kx->p), kx->kpub, &kx->texp_kpub)) + if (km_getpubkey(p_tag(kx->p), kx->kpub, &kx->texp_kpub)) return; kx->f |= KXF_PUBKEY; if ((kx->f & KXF_DEAD) || kx->s != KXS_SWITCH) { @@ -1250,6 +1252,7 @@ void kx_newkeys(keyexch *kx) * Arguments: @keyexch *kx@ = pointer to key exchange context * @peer *p@ = pointer to peer context * @keyset **ks@ = pointer to keyset list + * @unsigned f@ = various useful flags * * Returns: Zero if OK, nonzero if it failed. * @@ -1258,19 +1261,21 @@ void kx_newkeys(keyexch *kx) * exchange. */ -int kx_init(keyexch *kx, peer *p, keyset **ks) +int kx_init(keyexch *kx, peer *p, keyset **ks, unsigned f) { kx->ks = ks; kx->p = p; kx->kpub = G_CREATE(gg); - if (km_getpubkey(p_name(p), kx->kpub, &kx->texp_kpub)) { + if (km_getpubkey(p_tag(p), kx->kpub, &kx->texp_kpub)) { G_DESTROY(gg, kx->kpub); return (-1); } - kx->f = KXF_DEAD | KXF_PUBKEY; - start(kx, time(0)); - resend(kx); - /* Don't notify here: the ADD message hasn't gone out yet. */ + kx->f = KXF_DEAD | KXF_PUBKEY | f; + if (!(kx->f & KXF_CORK)) { + start(kx, time(0)); + resend(kx); + /* Don't notify here: the ADD message hasn't gone out yet. */ + } return (0); }