X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=pubkeys.c;h=efcfa77fc31d717ab9a93d79edc312e1d16be121;hb=873f2f7629c89196a9b855e4baa8b118286a617d;hp=7ba948200f14d9f97b366184837ba632e0b0f2dc;hpb=20c35278822db437d832e47166c5936a93e891fd;p=secnet.git diff --git a/pubkeys.c b/pubkeys.c index 7ba9482..efcfa77 100644 --- a/pubkeys.c +++ b/pubkeys.c @@ -17,6 +17,8 @@ * https://www.gnu.org/licenses/gpl.html. */ +#include "util.h" +#include "base91s/base91.h" #include "pubkeys.h" #include "pubkeys.yy.h" @@ -43,3 +45,50 @@ const struct sigscheme_info *sigscheme_lookup(const char *name) return scheme; return 0; } + +static list_t *makepublic_apply(closure_t *self, struct cloc loc, + dict_t *context, list_t *args) +{ + CL_GET_STR_ARG(0,algname,"algorithm name"); + CL_GET_STR_ARG(1,b91d,"base91s-encoded public key"); + + const struct sigscheme_info *sch=sigscheme_lookup(algname); + if (!sch) cfgfatal(algname_i->loc,"make-public", + "unknown algorithm `%s'",algname); + + size_t b91l=strlen(b91d); + if (b91l > INT_MAX/4) cfgfatal(algname_i->loc,"make-public", + "base91s data unreasonably long"); + + struct buffer_if buf; + buffer_new(&buf,base91s_decode_maxlen(b91l)); + BUF_ALLOC(&buf,"make-public data buf"); + assert(buf.start == buf.base); + struct base91s b91; + base91s_init(&b91); + buf.size= base91s_decode(&b91,b91d,b91l,buf.start); + buf.size += base91s_decode_end(&b91,buf.start+buf.size); + assert(buf.size <= buf.alloclen); + + struct cfgfile_log log; + cfgfile_log_init(&log,loc,"make-public"); + + struct sigpubkey_if *pubkey; + closure_t *cl; + bool_t ok=sch->loadpub(sch,&buf,&pubkey,&cl,&log.log,loc); + if (!ok) cfgfatal(loc,"make-public","public key loading failed"); + + if (pubkey->sethash) { + struct hash_if *defhash= + find_cl_if(context,"hash",CL_HASH,True,"make-public",loc); + pubkey->sethash(pubkey->st,defhash); + } + + BUF_FREE(&buf); + buffer_destroy(&buf); + return new_closure(cl); +} + +void pubkeys_init(dict_t *dict) { + add_closure(dict,"make-public",makepublic_apply); +}