#define SITE_SENTMSG5 7
#define SITE_WAIT 8
+#define CASES_MSG3_KNOWN LABEL_MSG3: case LABEL_MSG3BIS
+
int32_t site_max_start_pad = 4*4;
static cstring_t state_name(uint32_t state)
uint64_t timeout; /* Timeout for current state */
uint8_t *dhsecret;
uint8_t *sharedsecret;
- uint32_t sharedsecretlen, sharedsecretallocd;
struct transform_inst_if *new_transform; /* For key setup/verify */
};
static _Bool type_is_msg34(uint32_t type)
{
- return
- type == LABEL_MSG3 ||
- type == LABEL_MSG3BIS ||
- type == LABEL_MSG4;
+ switch (type) {
+ case CASES_MSG3_KNOWN: case LABEL_MSG4: return True;
+ default: return False;
+ }
}
struct parsedname {
{
_Bool ok;
- /* Make room for the shared key */
- st->sharedsecretlen=st->chosen_transform->keylen?:st->dh->ceil_len;
- assert(st->sharedsecretlen);
- if (st->sharedsecretlen > st->sharedsecretallocd) {
- st->sharedsecretallocd=st->sharedsecretlen;
- st->sharedsecret=safe_realloc_ary(st->sharedsecret,1,
- st->sharedsecretallocd,
- "site:sharedsecret");
- }
-
/* Generate the shared key */
- if (!st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,pk,
- st->sharedsecret,st->sharedsecretlen))
+ if (!st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->secret_len,
+ pk, st->sharedsecret,st->dh->shared_len))
return False;
/* Set up the transform */
struct transform_if *generator=st->chosen_transform;
struct transform_inst_if *generated=generator->create(generator->st);
ok = generated->setkey(generated->st,st->sharedsecret,
- st->sharedsecretlen,st->our_name_later);
+ st->dh->shared_len,st->our_name_later);
dispose_transform(&st->new_transform);
if (!ok) return False;
void *hst;
uint8_t *hash;
string_t dhpub, sig;
+ unsigned minor;
st->retries=st->setup_retries;
BUF_ALLOC(&st->buffer,what);
if (hacky_par_mid_failnow()) return False;
- if (type==LABEL_MSG3BIS)
+ if (MSGMAJOR(type) == 3) do {
+ minor = MSGMINOR(type);
+ if (minor < 1) break;
buf_append_uint8(&st->buffer,st->chosen_transform->capab_bit);
+ } while (0);
- dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len);
+ dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->secret_len);
buf_append_string(&st->buffer,dhpub);
free(dhpub);
hash=safe_malloc(st->hash->len, "generate_msg");
static bool_t unpick_msg(struct site *st, uint32_t type,
struct buffer_if *msg, struct msg *m)
{
+ unsigned minor;
+
m->capab_transformnum=-1;
m->hashstart=msg->start;
CHECK_AVAIL(msg,4);
CHECK_EMPTY(msg);
return True;
}
- if (type==LABEL_MSG3BIS) {
- CHECK_AVAIL(msg,1);
- m->capab_transformnum = buf_unprepend_uint8(msg);
- } else {
- m->capab_transformnum = CAPAB_BIT_ANCIENTTRANSFORM;
- }
+ if (MSGMAJOR(type) == 3) do {
+ minor = MSGMINOR(type);
+#define MAYBE_READ_CAP(minminor, kind, dflt) do { \
+ if (minor < (minminor)) \
+ m->capab_##kind##num = (dflt); \
+ else { \
+ CHECK_AVAIL(msg, 1); \
+ m->capab_##kind##num = buf_unprepend_uint8(msg); \
+ } \
+} while (0)
+ MAYBE_READ_CAP(1, transform, CAPAB_BIT_ANCIENTTRANSFORM);
+#undef MAYBE_READ_CAP
+ } while (0);
CHECK_AVAIL(msg,2);
m->pklen=buf_unprepend_uint16(msg);
CHECK_AVAIL(msg,m->pklen);
}
/* MSG3 has complicated rules about capabilities, which are
* handled in process_msg3. */
- if (type==LABEL_MSG3 || type==LABEL_MSG3BIS) return True;
+ if (MSGMAJOR(type) == 3) return True;
if (m->remote_capabilities!=st->remote_capabilities) {
*error="remote capabilities changed";
return False;
{
/* Now we have our nonce and their nonce. Think of a secret key,
and create message number 3. */
- st->random->generate(st->random->st,st->dh->len,st->dhsecret);
+ st->random->generate(st->random->st,st->dh->secret_len,st->dhsecret);
return generate_msg(st,
- (st->remote_capabilities & CAPAB_TRANSFORM_MASK
- ? LABEL_MSG3BIS : LABEL_MSG3),
+ (st->remote_capabilities & CAPAB_TRANSFORM_MASK)
+ ? LABEL_MSG3BIS
+ : LABEL_MSG3,
"site:MSG3");
}
struct msg m;
cstring_t err;
- assert(msgtype==LABEL_MSG3 || msgtype==LABEL_MSG3BIS);
+ switch (msgtype) {
+ case CASES_MSG3_KNOWN: break;
+ default: assert(0);
+ }
if (!unpick_msg(st,msgtype,msg3,&m)) return False;
if (!check_msg(st,msgtype,&m,&err)) {
/* Terminate their DH public key with a '0' */
m.pk[m.pklen]=0;
/* Invent our DH secret key */
- st->random->generate(st->random->st,st->dh->len,st->dhsecret);
+ st->random->generate(st->random->st,st->dh->secret_len,st->dhsecret);
/* Generate the shared key and set up the transform */
if (!set_new_transform(st,m.pk)) return False;
FILLZERO(st->localN);
FILLZERO(st->remoteN);
dispose_transform(&st->new_transform);
- memset(st->dhsecret,0,st->dh->len);
- if (st->sharedsecret) memset(st->sharedsecret,0,st->sharedsecretlen);
+ memset(st->dhsecret,0,st->dh->secret_len);
+ memset(st->sharedsecret,0,st->dh->shared_len);
set_link_quality(st);
if (st->keepalive && !current_valid(st))
slog(st,LOG_SEC,"invalid MSG2");
}
break;
- case LABEL_MSG3:
- case LABEL_MSG3BIS:
+ case CASES_MSG3_KNOWN:
/* Setup packet: expected only in state SENTMSG2 */
if (st->state!=SITE_SENTMSG2) {
if ((st->state==SITE_SENTMSG4) &&
transport_peers_clear(st,&st->peers);
transport_peers_clear(st,&st->setup_peers);
/* XXX mlock these */
- st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
- st->sharedsecretlen=st->sharedsecretallocd=0;
- st->sharedsecret=0;
+ st->dhsecret=safe_malloc(st->dh->secret_len,"site:dhsecret");
+ st->sharedsecret=safe_malloc(st->dh->shared_len, "site:sharedsecret");
#define SET_CAPBIT(bit) do { \
uint32_t capflag = 1UL << (bit); \