X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/53a941d3f97a50964587c6e9533b1e43e74a57a8..62b5e3ecc77424add00ad4e5dc86e7248751cdf6:/server/keyexch.c diff --git a/server/keyexch.c b/server/keyexch.c index df70774d..cd6eae52 100644 --- a/server/keyexch.c +++ b/server/keyexch.c @@ -75,22 +75,25 @@ * Switch received. Committed; send data; move to @KXS_SWITCH@. */ -/*----- Tunable parameters ------------------------------------------------*/ - -#define T_VALID MIN(2) /* Challenge validity period */ -#define T_RETRY SEC(10) /* Challenge retransmit interval */ - -#define VALIDP(kx, now) ((now) < (kx)->t_valid) - /*----- 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 -------------------------------------------------*/ +/* --- @VALIDP@ --- * + * + * Arguments: @const keyexch *kx@ = key exchange state + * @time_t now@ = current time in seconds + * + * Returns: Whether the challenge in the key-exchange state is still + * valid or should be regenerated. + */ + +#define VALIDP(kx, now) ((now) < (kx)->t_valid) + /* --- @hashge@ --- * * * Arguments: @ghash *h@ = pointer to hash context @@ -604,7 +607,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); @@ -793,6 +796,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); } + if (!BOK(&bb)) return (-1); buf_init(b, BBASE(&bb), BLEN(&bb)); return (0); } @@ -909,7 +913,7 @@ static void kxfinish(keyexch *kx) { kxchal *kxc = kx->r[0]; ks_activate(kxc->ks); - settimer(kx, ks_tregen(kxc->ks)); + settimer(kx, time(0) + T_REGEN); kx->s = KXS_SWITCH; a_notify("KXDONE", "?PEER", kx->p, A_END); p_stats(kx->p)->t_kx = time(0); @@ -1065,7 +1069,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); @@ -1161,6 +1165,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; @@ -1168,7 +1178,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)); ) @@ -1231,7 +1240,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) { @@ -1248,6 +1257,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. * @@ -1256,19 +1266,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); }