chiark
/
gitweb
/
~mdw
/
secnet
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Introduce negotiation for Diffie--Hellman groups.
[secnet]
/
site.c
diff --git
a/site.c
b/site.c
index 4f954e61d754088b48659a61d65a8fb400bf978e..4da99e3d5be5223ec71164ebd07c07a332deacbb 100644
(file)
--- a/
site.c
+++ b/
site.c
@@
-107,7
+107,7
@@
#define SITE_SENTMSG5 7
#define SITE_WAIT 8
#define SITE_SENTMSG5 7
#define SITE_WAIT 8
-#define CASES_MSG3_KNOWN LABEL_MSG3: case LABEL_MSG3BIS
+#define CASES_MSG3_KNOWN LABEL_MSG3: case LABEL_MSG3BIS
: case LABEL_MSG3TER
int32_t site_max_start_pad = 4*4;
int32_t site_max_start_pad = 4*4;
@@
-316,7
+316,8
@@
struct site {
struct rsapubkey_if *pubkey;
struct transform_if **transforms;
int ntransforms;
struct rsapubkey_if *pubkey;
struct transform_if **transforms;
int ntransforms;
- struct dh_if *dh;
+ struct dh_if **dhs;
+ int ndhs;
struct hash_if *hash;
uint32_t index; /* Index of this site */
struct hash_if *hash;
uint32_t index; /* Index of this site */
@@
-361,6
+362,7
@@
struct site {
uint32_t remote_capabilities;
uint16_t remote_adv_mtu;
struct transform_if *chosen_transform;
uint32_t remote_capabilities;
uint16_t remote_adv_mtu;
struct transform_if *chosen_transform;
+ struct dh_if *chosen_dh;
uint32_t setup_session_id;
transport_peers setup_peers;
uint8_t localN[NONCELEN]; /* Nonces for key exchange */
uint32_t setup_session_id;
transport_peers setup_peers;
uint8_t localN[NONCELEN]; /* Nonces for key exchange */
@@
-528,6
+530,7
@@
struct msg {
uint32_t remote_capabilities;
uint16_t remote_mtu;
int capab_transformnum;
uint32_t remote_capabilities;
uint16_t remote_mtu;
int capab_transformnum;
+ int capab_dhnum;
uint8_t *nR;
uint8_t *nL;
int32_t pklen;
uint8_t *nR;
uint8_t *nL;
int32_t pklen;
@@
-553,16
+556,20
@@
static _Bool set_new_transform(struct site *st, char *pk)
/* Generate the shared key */
assert(!st->sharedsecret);
/* Generate the shared key */
assert(!st->sharedsecret);
- st->sharedsecret = safe_malloc(st->dh->shared_len, "site:sharedsecret");
- if (!st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->secret_len,
- pk, st->sharedsecret,st->dh->shared_len))
+ st->sharedsecret = safe_malloc(st->chosen_dh->shared_len,
+ "site:sharedsecret");
+ if (!st->chosen_dh->makeshared(st->chosen_dh->st,
+ st->dhsecret,st->chosen_dh->secret_len,
+ pk,
+ st->sharedsecret,
+ st->chosen_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,
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->dh->shared_len,st->our_name_later);
+ st->
chosen_
dh->shared_len,st->our_name_later);
dispose_transform(&st->new_transform);
if (!ok) return False;
dispose_transform(&st->new_transform);
if (!ok) return False;
@@
-643,9
+650,12
@@
static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what)
minor = MSGMINOR(type);
if (minor < 1) break;
buf_append_uint8(&st->buffer,st->chosen_transform->capab_bit);
minor = MSGMINOR(type);
if (minor < 1) break;
buf_append_uint8(&st->buffer,st->chosen_transform->capab_bit);
+ if (minor < 2) break;
+ buf_append_uint8(&st->buffer,st->chosen_dh->capab_bit);
} while (0);
} while (0);
- dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->secret_len);
+ dhpub=st->chosen_dh->makepublic(st->chosen_dh->st,
+ st->dhsecret,st->chosen_dh->secret_len);
buf_append_string(&st->buffer,dhpub);
free(dhpub);
hash=safe_malloc(st->hash->len, "generate_msg");
buf_append_string(&st->buffer,dhpub);
free(dhpub);
hash=safe_malloc(st->hash->len, "generate_msg");
@@
-680,7
+690,7
@@
static bool_t unpick_msg(struct site *st, uint32_t type,
{
unsigned minor;
{
unsigned minor;
- m->capab_transformnum=-1;
+ m->capab_transformnum=
m->capab_dhnum=
-1;
m->hashstart=msg->start;
CHECK_AVAIL(msg,4);
m->dest=buf_unprepend_uint32(msg);
m->hashstart=msg->start;
CHECK_AVAIL(msg,4);
m->dest=buf_unprepend_uint32(msg);
@@
-726,6
+736,7
@@
static bool_t unpick_msg(struct site *st, uint32_t type,
} \
} while (0)
MAYBE_READ_CAP(1, transform, CAPAB_BIT_ANCIENTTRANSFORM);
} \
} while (0)
MAYBE_READ_CAP(1, transform, CAPAB_BIT_ANCIENTTRANSFORM);
+ MAYBE_READ_CAP(2, dh, CAPAB_BIT_TRADZP);
#undef MAYBE_READ_CAP
} while (0);
CHECK_AVAIL(msg,2);
#undef MAYBE_READ_CAP
} while (0);
CHECK_AVAIL(msg,2);
@@
-831,12
+842,17
@@
static bool_t process_msg2(struct site *st, struct buffer_if *msg2,
st->setup_session_id=m.source;
st->remote_capabilities=m.remote_capabilities;
st->setup_session_id=m.source;
st->remote_capabilities=m.remote_capabilities;
- /* Select the transform to use */
+ /* Select the transform
and DH group
to use */
- uint32_t remote_crypto_caps = st->remote_capabilities & CAPAB_TRANSFORM_MASK;
+ uint32_t remote_crypto_caps = st->remote_capabilities;
+ if (!(remote_crypto_caps & CAPAB_EXPLICIT_TRANSFORM_DH))
+ remote_crypto_caps &= CAPAB_INEXPLICIT_TRANSFORM_MASK;
if (!remote_crypto_caps)
/* old secnets only had this one transform */
remote_crypto_caps = 1UL << CAPAB_BIT_ANCIENTTRANSFORM;
if (!remote_crypto_caps)
/* old secnets only had this one transform */
remote_crypto_caps = 1UL << CAPAB_BIT_ANCIENTTRANSFORM;
+ if (!(remote_crypto_caps & CAPAB_EXPLICIT_TRANSFORM_DH))
+ /* old secnets only had this one kind of group */
+ remote_crypto_caps |= 1UL << CAPAB_BIT_TRADZP;
#define CHOOSE_CRYPTO(kind, whats) do { \
struct kind##_if *iface; \
#define CHOOSE_CRYPTO(kind, whats) do { \
struct kind##_if *iface; \
@@
-857,6
+873,7
@@
kind##_found: \
} while (0)
CHOOSE_CRYPTO(transform, "transforms");
} while (0)
CHOOSE_CRYPTO(transform, "transforms");
+ CHOOSE_CRYPTO(dh, "Diffie--Hellman groups");
#undef CHOOSE_CRYPTO
#undef CHOOSE_CRYPTO
@@
-866,9
+883,14
@@
kind##_found: \
static void generate_dhsecret(struct site *st)
{
static void generate_dhsecret(struct site *st)
{
+ slog(st,LOG_SETUP_INIT,"key exchange negotiated DH group"
+ " %d (capabilities ours=%#"PRIx32" theirs=%#"PRIx32")",
+ st->chosen_dh->capab_bit,
+ st->local_capabilities, st->remote_capabilities);
assert(!st->dhsecret);
assert(!st->dhsecret);
- st->dhsecret = safe_malloc(st->dh->secret_len, "site:dhsecret");
- st->random->generate(st->random->st, st->dh->secret_len,st->dhsecret);
+ st->dhsecret = safe_malloc(st->chosen_dh->secret_len, "site:dhsecret");
+ st->random->generate(st->random->st,
+ st->chosen_dh->secret_len,st->dhsecret);
}
static bool_t generate_msg3(struct site *st)
}
static bool_t generate_msg3(struct site *st)
@@
-877,7
+899,11
@@
static bool_t generate_msg3(struct site *st)
and create message number 3. */
generate_dhsecret(st);
return generate_msg(st,
and create message number 3. */
generate_dhsecret(st);
return generate_msg(st,
- (st->remote_capabilities & CAPAB_TRANSFORM_MASK)
+ (st->remote_capabilities &
+ CAPAB_EXPLICIT_TRANSFORM_DH)
+ ? LABEL_MSG3TER
+ : (st->remote_capabilities &
+ CAPAB_INEXPLICIT_TRANSFORM_MASK)
? LABEL_MSG3BIS
: LABEL_MSG3,
"site:MSG3");
? LABEL_MSG3BIS
: LABEL_MSG3,
"site:MSG3");
@@
-949,6
+975,7
@@
kind##_found: \
} while (0)
CHOSE_CRYPTO(transform, "transform");
} while (0)
CHOSE_CRYPTO(transform, "transform");
+ CHOSE_CRYPTO(dh, "Diffie--Hellman group");
#undef CHOSE_CRYPTO
#undef CHOSE_CRYPTO
@@
-1520,12
+1547,12
@@
static void enter_state_run(struct site *st)
FILLZERO(st->remoteN);
dispose_transform(&st->new_transform);
if (st->dhsecret) {
FILLZERO(st->remoteN);
dispose_transform(&st->new_transform);
if (st->dhsecret) {
- memset(st->dhsecret, 0, st->dh->secret_len);
+ memset(st->dhsecret, 0, st->
chosen_
dh->secret_len);
free(st->dhsecret);
st->dhsecret = 0;
}
if (st->sharedsecret) {
free(st->dhsecret);
st->dhsecret = 0;
}
if (st->sharedsecret) {
- memset(st->sharedsecret, 0, st->dh->shared_len);
+ memset(st->sharedsecret, 0, st->
chosen_
dh->shared_len);
free(st->sharedsecret);
st->sharedsecret = 0;
}
free(st->sharedsecret);
st->sharedsecret = 0;
}
@@
-2151,7
+2178,7
@@
static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
assert(index_sequence < 0xffffffffUL);
st->index = ++index_sequence;
assert(index_sequence < 0xffffffffUL);
st->index = ++index_sequence;
- st->local_capabilities =
0
;
+ st->local_capabilities =
CAPAB_EXPLICIT_TRANSFORM_DH
;
st->early_capabilities = CAPAB_PRIORITY_MOBILE;
st->netlink=find_cl_if(dict,"link",CL_NETLINK,True,"site",loc);
st->early_capabilities = CAPAB_PRIORITY_MOBILE;
st->netlink=find_cl_if(dict,"link",CL_NETLINK,True,"site",loc);
@@
-2195,8
+2222,8
@@
static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
GET_CLOSURE_LIST("transform",transforms,ntransforms,CL_TRANSFORM);
st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
GET_CLOSURE_LIST("transform",transforms,ntransforms,CL_TRANSFORM);
+ GET_CLOSURE_LIST("dh",dhs,ndhs,CL_DH);
- st->dh=find_cl_if(dict,"dh",CL_DH,True,"site",loc);
st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
#define DEFAULT(D) (st->peer_mobile || st->local_mobile \
st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
#define DEFAULT(D) (st->peer_mobile || st->local_mobile \
@@
-2260,6
+2287,7
@@
static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
st->remote_capabilities=0;
st->chosen_transform=0;
st->remote_capabilities=0;
st->chosen_transform=0;
+ st->chosen_dh=0;
st->current.key_timeout=0;
st->auxiliary_key.key_timeout=0;
transport_peers_clear(st,&st->peers);
st->current.key_timeout=0;
st->auxiliary_key.key_timeout=0;
transport_peers_clear(st,&st->peers);
@@
-2277,6
+2305,8
@@
static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
for (i=0; i<st->ntransforms; i++)
SET_CAPBIT(st->transforms[i]->capab_bit);
for (i=0; i<st->ntransforms; i++)
SET_CAPBIT(st->transforms[i]->capab_bit);
+ for (i=0; i<st->ndhs; i++)
+ SET_CAPBIT(st->dhs[i]->capab_bit);
#undef SET_CAPBIT
#undef SET_CAPBIT