X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=site.c;h=3b8f34d47c8ff455a0d69bf931598093cacc6a25;hb=5d903efd43518e7a4f12f7315b7cd133ac1563f1;hp=c702c7885095b009ca5bea65d259f9d778964823;hpb=c02fba3b053260d364ac3750f886dc057949ceb9;p=secnet.git diff --git a/site.c b/site.c index c702c78..3b8f34d 100644 --- a/site.c +++ b/site.c @@ -318,6 +318,7 @@ struct site { struct hash_if *hash; uint32_t index; /* Index of this site */ + uint32_t early_capabilities; uint32_t local_capabilities; int32_t setup_retries; /* How many times to send setup packets */ int32_t setup_retry_interval; /* Initial timeout for setup packets */ @@ -575,7 +576,7 @@ static _Bool set_new_transform(struct site *st, char *pk) slog(st,LOG_SETUP_INIT,"key exchange negotiated transform" " %d (capabilities ours=%#"PRIx32" theirs=%#"PRIx32")", - st->chosen_transform->capab_transformnum, + st->chosen_transform->capab_bit, st->local_capabilities, st->remote_capabilities); return True; } @@ -626,7 +627,8 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what) struct xinfoadd xia; append_string_xinfo_start(&st->buffer,&xia,st->localname); - if ((st->local_capabilities & CAPAB_EARLY) || (type != LABEL_MSG1)) { + if ((st->local_capabilities & st->early_capabilities) || + (type != LABEL_MSG1)) { buf_append_uint32(&st->buffer,st->local_capabilities); } if (type_is_msg34(type)) { @@ -643,7 +645,7 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what) if (hacky_par_mid_failnow()) return False; if (type==LABEL_MSG3BIS) - buf_append_uint8(&st->buffer,st->chosen_transform->capab_transformnum); + buf_append_uint8(&st->buffer,st->chosen_transform->capab_bit); dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len); buf_append_string(&st->buffer,dhpub); @@ -717,7 +719,7 @@ static bool_t unpick_msg(struct site *st, uint32_t type, CHECK_AVAIL(msg,1); m->capab_transformnum = buf_unprepend_uint8(msg); } else { - m->capab_transformnum = CAPAB_TRANSFORMNUM_ANCIENT; + m->capab_transformnum = CAPAB_BIT_ANCIENTTRANSFORM; } CHECK_AVAIL(msg,2); m->pklen=buf_unprepend_uint16(msg); @@ -767,7 +769,7 @@ static bool_t check_msg(struct site *st, uint32_t type, struct msg *m, return False; } if (type==LABEL_MSG2) return True; - if (!consttime_memeq(m->nR,st->remoteN,NONCELEN)!=0) { + if (!consttime_memeq(m->nR,st->remoteN,NONCELEN)) { *error="wrong remotely-generated nonce"; return False; } @@ -824,25 +826,32 @@ static bool_t process_msg2(struct site *st, struct buffer_if *msg2, /* Select the transform to use */ - uint32_t remote_transforms = st->remote_capabilities & CAPAB_TRANSFORM_MASK; - if (!remote_transforms) + uint32_t remote_crypto_caps = st->remote_capabilities & CAPAB_TRANSFORM_MASK; + if (!remote_crypto_caps) /* old secnets only had this one transform */ - remote_transforms = 1UL << CAPAB_TRANSFORMNUM_ANCIENT; + remote_crypto_caps = 1UL << CAPAB_BIT_ANCIENTTRANSFORM; + +#define CHOOSE_CRYPTO(kind, whats) do { \ + struct kind##_if *iface; \ + uint32_t bit, ours = 0; \ + int i; \ + for (i= 0; i < st->n##kind##s; i++) { \ + iface=st->kind##s[i]; \ + bit = 1UL << iface->capab_bit; \ + if (bit & remote_crypto_caps) goto kind##_found; \ + ours |= bit; \ + } \ + slog(st,LOG_ERROR,"no " whats " in common" \ + " (us %#"PRIx32"; them: %#"PRIx32")", \ + st->local_capabilities & ours, remote_crypto_caps); \ + return False; \ +kind##_found: \ + st->chosen_##kind = iface; \ +} while (0) - struct transform_if *ti; - int i; - for (i=0; intransforms; i++) { - ti=st->transforms[i]; - if ((1UL << ti->capab_transformnum) & remote_transforms) - goto transform_found; - } - slog(st,LOG_ERROR,"no transforms in common" - " (us %#"PRIx32"; them: %#"PRIx32")", - st->local_capabilities & CAPAB_TRANSFORM_MASK, - remote_transforms); - return False; - transform_found: - st->chosen_transform=ti; + CHOOSE_CRYPTO(transform, "transforms"); + +#undef CHOOSE_CRYPTO memcpy(st->remoteN,m.nR,NONCELEN); return True; @@ -897,7 +906,7 @@ static bool_t process_msg3(struct site *st, struct buffer_if *msg3, return False; } uint32_t capab_adv_late = m.remote_capabilities - & ~st->remote_capabilities & CAPAB_EARLY; + & ~st->remote_capabilities & st->early_capabilities; if (capab_adv_late) { slog(st,LOG_SEC,"msg3 impermissibly adds early capability flag(s)" " %#"PRIx32" (was %#"PRIx32", now %#"PRIx32")", @@ -906,18 +915,24 @@ static bool_t process_msg3(struct site *st, struct buffer_if *msg3, } st->remote_capabilities|=m.remote_capabilities; - struct transform_if *ti; - int i; - for (i=0; intransforms; i++) { - ti=st->transforms[i]; - if (ti->capab_transformnum == m.capab_transformnum) - goto transform_found; - } - slog(st,LOG_SEC,"peer chose unknown-to-us transform %d!", - m.capab_transformnum); - return False; - transform_found: - st->chosen_transform=ti; +#define CHOSE_CRYPTO(kind, what) do { \ + struct kind##_if *iface; \ + int i; \ + for (i=0; in##kind##s; i++) { \ + iface=st->kind##s[i]; \ + if (iface->capab_bit == m.capab_##kind##num) \ + goto kind##_found; \ + } \ + slog(st,LOG_SEC,"peer chose unknown-to-us " what " %d!", \ + m.capab_##kind##num); \ + return False; \ +kind##_found: \ + st->chosen_##kind=iface; \ +} while (0) + + CHOSE_CRYPTO(transform, "transform"); + +#undef CHOSE_CRYPTO if (!process_msg3_msg4(st,&m)) return False; @@ -1781,8 +1796,8 @@ static bool_t named_for_us(struct site *st, const struct buffer_if *buf_in, } static bool_t we_have_priority(struct site *st, const struct msg *m) { - if ((st->local_capabilities & m->remote_capabilities) - && CAPAB_PRIORITY_MOBILE) { + if (st->local_capabilities & m->remote_capabilities & + CAPAB_PRIORITY_MOBILE) { if (st->local_mobile) return True; if (st-> peer_mobile) return False; } @@ -2112,6 +2127,7 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context, assert(index_sequence < 0xffffffffUL); st->index = ++index_sequence; st->local_capabilities = 0; + st->early_capabilities = CAPAB_PRIORITY_MOBILE; st->netlink=find_cl_if(dict,"link",CL_NETLINK,True,"site",loc); #define GET_CLOSURE_LIST(dictkey,things,nthings,CL_TYPE) do{ \ @@ -2228,14 +2244,18 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context, st->sharedsecretlen=st->sharedsecretallocd=0; st->sharedsecret=0; - for (i=0; intransforms; i++) { - struct transform_if *ti=st->transforms[i]; - uint32_t capbit = 1UL << ti->capab_transformnum; - if (st->local_capabilities & capbit) - slog(st,LOG_ERROR,"transformnum capability bit" - " %d (%#"PRIx32") reused", ti->capab_transformnum, capbit); - st->local_capabilities |= capbit; - } +#define SET_CAPBIT(bit) do { \ + uint32_t capflag = 1UL << (bit); \ + if (st->local_capabilities & capflag) \ + slog(st,LOG_ERROR,"capability bit" \ + " %d (%#"PRIx32") reused", (bit), capflag); \ + st->local_capabilities |= capflag; \ +} while (0) + + for (i=0; intransforms; i++) + SET_CAPBIT(st->transforms[i]->capab_bit); + +#undef SET_CAPBIT if (st->local_mobile || st->peer_mobile) st->local_capabilities |= CAPAB_PRIORITY_MOBILE;