X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=privcache.c;h=5377c9049452500d36ce409cdee35fdcfc575f31;hb=686e21aa2afbd14c3e59962f02a31c4dcd62e5d8;hp=1f46eb00d033c323e84e971618acd3a4b741b810;hpb=60725608deb1940a9c60ee7da6ceec981f639088;p=secnet.git diff --git a/privcache.c b/privcache.c index 1f46eb0..5377c90 100644 --- a/privcache.c +++ b/privcache.c @@ -21,6 +21,7 @@ #include "util.h" #define DEFAULT_SIZE 5 +#define DEFAULT_MAXPRIV_BYTES 4095 struct ent { struct sigkeyid id; @@ -37,11 +38,13 @@ struct privcache { struct hash_if *defhash; }; -static struct sigprivkey_if *uncached_load_file( +static bool_t uncached_load_file( const struct sigscheme_info *scheme, const char *path, struct buffer_if *databuf, struct hash_if *defhash, + struct sigprivkey_if **sigpriv_r, + closure_t **closure_r, struct log_if *log); static struct sigprivkey_if *uncached_get(struct privcache *st, @@ -61,19 +64,26 @@ static struct sigprivkey_if *uncached_get(struct privcache *st, path); return 0; - found: - return uncached_load_file(scheme, + found:; + struct sigprivkey_if *sigpriv; + closure_t *cl; + bool_t ok=uncached_load_file(scheme, path, &st->databuf, st->defhash, + &sigpriv, + &cl, log); + return ok ? sigpriv : 0; } -static struct sigprivkey_if *uncached_load_file( +static bool_t uncached_load_file( const struct sigscheme_info *scheme, const char *path, struct buffer_if *databuf, struct hash_if *defhash, + struct sigprivkey_if **sigpriv_r, + closure_t **closure_r, struct log_if *log) { bool_t ok=False; @@ -110,22 +120,23 @@ static struct sigprivkey_if *uncached_load_file( databuf->start=databuf->base; databuf->size=got; struct cloc loc = { .file=path, .line=0 }; - ok=scheme->loadpriv(scheme, databuf, &sigpriv, log, loc); + ok=scheme->loadpriv(scheme, databuf, &sigpriv, closure_r, log, loc); if (!ok) goto error_out; /* loadpriv will have logged */ if (sigpriv->sethash) { if (!defhash) { slilog(log,M_ERR, - "private key %s requires `hash' config key for privcache to load", + "private key %s requires `hash' config key to load", path); goto error_out; } sigpriv->sethash(sigpriv->st,defhash); } + *sigpriv_r=sigpriv; out: if (f) fclose(f); - return ok ? sigpriv : 0; + return ok; error_out: if (sigpriv) sigpriv->dispose(sigpriv->st); @@ -197,7 +208,7 @@ static list_t *privcache_apply(closure_t *self, struct cloc loc, st->used=0; int32_t buflen=dict_read_number(dict,"privkey-max",False,"privcache",loc, - 4095); + DEFAULT_MAXPRIV_BYTES); buffer_new(&st->databuf,buflen+1); const char *path=dict_read_string(dict,"privkeys",True,"privcache",loc); @@ -208,7 +219,39 @@ static list_t *privcache_apply(closure_t *self, struct cloc loc, return new_closure(&st->cl); } +static list_t *loadprivate_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,path,"private key path"); + + const struct sigscheme_info *sch=sigscheme_lookup(algname); + if (!sch) cfgfatal(algname_i->loc,"load-private", + "unknown algorithm `%s'",algname); + + struct buffer_if databuf; + buffer_new(&databuf,DEFAULT_MAXPRIV_BYTES); + BUF_ALLOC(&databuf,"load-private data buf"); + + struct hash_if *defhash= + find_cl_if(context,"hash",CL_HASH,False,"load-private",loc); + + struct cfgfile_log log; + cfgfile_log_init(&log,loc,"load-private"); + + struct sigprivkey_if *sigpriv; + closure_t *cl; + bool_t ok= + uncached_load_file(sch,path,&databuf,defhash,&sigpriv,&cl,&log.log); + if (!ok) cfgfatal(loc,"load-private","private key loading failed"); + + BUF_FREE(&databuf); + buffer_destroy(&databuf); + return new_closure(cl); +} + void privcache_module(dict_t *dict) { add_closure(dict,"priv-cache",privcache_apply); + add_closure(dict,"load-private",loadprivate_apply); }