X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=site.c;h=df0ab3a46433f41f3f506a00bae751f61cbd5dae;hb=13b8fbf4548f3457b02afd36e9284d39839d6f85;hp=67227e63cbc9aba15cc88f5649dda90af8190deb;hpb=70da6a8b29d5316d1b498d766aeef15ed77e30f3;p=secnet.git diff --git a/site.c b/site.c index 67227e6..df0ab3a 100644 --- a/site.c +++ b/site.c @@ -312,12 +312,11 @@ struct site { struct resolver_if *resolver; struct log_if *log; struct random_if *random; - struct rsaprivkey_if *privkey; - struct rsapubkey_if *pubkey; + struct sigprivkey_if *privkey; + struct sigpubkey_if *pubkey; struct transform_if **transforms; int ntransforms; struct dh_if *dh; - struct hash_if *hash; uint32_t index; /* Index of this site */ uint32_t early_capabilities; @@ -534,8 +533,7 @@ struct msg { int32_t pklen; char *pk; int32_t hashlen; - int32_t siglen; - char *sig; + struct alg_msg_data sig; }; static int32_t wait_timeout(struct site *st) { @@ -615,9 +613,7 @@ static void append_string_xinfo_done(struct buffer_if *buf, out using a transform of config data supplied by netlink */ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what) { - void *hst; - uint8_t *hash; - string_t dhpub, sig; + string_t dhpub; unsigned minor; st->retries=st->setup_retries; @@ -656,15 +652,16 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what) dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len); buf_append_string(&st->buffer,dhpub); free(dhpub); - hash=safe_malloc(st->hash->len, "generate_msg"); - hst=st->hash->init(); - st->hash->update(hst,st->buffer.start,st->buffer.size); - st->hash->final(hst,hash); - sig=st->privkey->sign(st->privkey->st,hash,st->hash->len); - buf_append_string(&st->buffer,sig); - free(sig); - free(hash); + + bool_t ok=st->privkey->sign(st->privkey->st, + st->buffer.start, + st->buffer.size, + &st->buffer); + if (!ok) goto fail; return True; + + fail: + return False; } static bool_t unpick_name(struct buffer_if *msg, struct parsedname *nm) @@ -741,17 +738,12 @@ static bool_t unpick_msg(struct site *st, uint32_t type, CHECK_AVAIL(msg,m->pklen); m->pk=buf_unprepend(msg,m->pklen); m->hashlen=msg->start-m->hashstart; - CHECK_AVAIL(msg,2); - m->siglen=buf_unprepend_uint16(msg); - CHECK_AVAIL(msg,m->siglen); - m->sig=buf_unprepend(msg,m->siglen); - CHECK_EMPTY(msg); - /* In `process_msg3_msg4' below, we assume that we can write a nul - * terminator following the signature. Make sure there's enough space. - */ - if (msg->start >= msg->base + msg->alloclen) + if (!st->pubkey->unpick(st->pubkey->st,msg,&m->sig)) { return False; + } + + CHECK_EMPTY(msg); return True; } @@ -886,22 +878,13 @@ static bool_t generate_msg3(struct site *st) static bool_t process_msg3_msg4(struct site *st, struct msg *m) { - uint8_t *hash; - void *hst; - /* Check signature and store g^x mod m */ - hash=safe_malloc(st->hash->len, "process_msg3_msg4"); - hst=st->hash->init(); - st->hash->update(hst,m->hashstart,m->hashlen); - st->hash->final(hst,hash); - /* Terminate signature with a '0' - already checked that this will fit */ - m->sig[m->siglen]=0; - if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m->sig)) { + if (!st->pubkey->check(st->pubkey->st, + m->hashstart,m->hashlen, + &m->sig)) { slog(st,LOG_SEC,"msg3/msg4 signature failed check!"); - free(hash); return False; } - free(hash); st->remote_adv_mtu=m->remote_mtu; @@ -2189,17 +2172,22 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context, st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc); st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc); - st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc); + st->privkey=find_cl_if(dict,"local-key",CL_SIGPRIVKEY,True,"site",loc); st->addresses=dict_read_string_array(dict,"address",False,"site",loc,0); if (st->addresses) st->remoteport=dict_read_number(dict,"port",True,"site",loc,0); else st->remoteport=0; - st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc); + st->pubkey=find_cl_if(dict,"key",CL_SIGPUBKEY,True,"site",loc); GET_CLOSURE_LIST("transform",transforms,ntransforms,CL_TRANSFORM); st->dh=find_cl_if(dict,"dh",CL_DH,True,"site",loc); - st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc); + + if (st->privkey->sethash || st->pubkey->sethash) { + struct hash_if *hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc); + if (st->privkey->sethash) st->privkey->sethash(st->privkey->st,hash); + if (st->pubkey->sethash) st->pubkey->sethash(st->pubkey->st,hash); + } #define DEFAULT(D) (st->peer_mobile || st->local_mobile \ ? DEFAULT_MOBILE_##D : DEFAULT_##D)