From: Ian Jackson Date: Tue, 3 Dec 2019 22:57:25 +0000 (+0000) Subject: secnet: Provide `make-public' verb X-Git-Tag: v0.6.0~124 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=secnet.git;a=commitdiff_plain;h=2798941e7a1a60e385f51bde9fde6c41e6012eea secnet: Provide `make-public' verb This allows the config file to specify the use of the scheme loadpub call without having to put public keys in separate files. That will be useful for testing and perhaps in installations that just want fixed keys. There is a bug here: we use system_log for reporting errors, but that is not set up until after the configuration is read. So errors turn into segfaults. We will fix that in a moment. Signed-off-by: Ian Jackson --- diff --git a/README b/README index 1d29c55..e23701c 100644 --- a/README +++ b/README @@ -577,6 +577,15 @@ priv-cache: dict argument privkey-max (integer): optional, maximum size of private key file in bytes. [4095] +** pubkeys + +Defines: + make-public (closure => sigpubkey closure) + +make-public: ( + arg1: sigscheme name + arg2: base91s encoded public key data, according to algorithm + ** rsa Defines: diff --git a/modules.c b/modules.c index de3e699..38f1d0f 100644 --- a/modules.c +++ b/modules.c @@ -21,6 +21,7 @@ void init_builtin_modules(dict_t *dict) { + pubkeys_init(dict); resolver_module(dict); random_module(dict); udp_module(dict); diff --git a/pubkeys.c b/pubkeys.c index 7ba9482..903103f 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,54 @@ 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) +{ +#define ARG(ix,vn,what) \ + item_t *vn##_i=list_elem(args,ix); \ + if (!vn##_i) cfgfatal(loc,"make-public","need " what); \ + if (vn##_i->type!=t_string) cfgfatal(vn##_i->loc,"make-public", \ + what "must be string"); \ + const char *vn=vn##_i->data.string + + ARG(0,algname,"algorithm name"); + 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 sigpubkey_if *pubkey; + closure_t *cl; + bool_t ok=sch->loadpub(sch,&buf,&pubkey,&cl,system_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); +} diff --git a/secnet.h b/secnet.h index 057d399..dbf3341 100644 --- a/secnet.h +++ b/secnet.h @@ -377,6 +377,7 @@ typedef void init_module(dict_t *dict); extern void init_builtin_modules(dict_t *dict); +extern init_module pubkeys_init; extern init_module resolver_module; extern init_module random_module; extern init_module udp_module;