X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=privcache.c;h=d790c30ad07402a1325c8340a3fdd169618bcaa7;hb=564022994befb8f71b89ae015751b22c34ae3ee8;hp=c8a9a7f2a92a25fc8461e3fa5e196ce9dd3edd02;hpb=b91db65a6fc5ea2b36bfd46bd3555f4ee77f46d5;p=secnet.git diff --git a/privcache.c b/privcache.c index c8a9a7f..d790c30 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; @@ -34,14 +35,14 @@ struct privcache { struct pathprefix_template path; struct ent *ents; struct buffer_if databuf; - 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,26 +62,31 @@ 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; FILE *f=0; struct sigprivkey_if *sigpriv=0; - f = fopen(path,"rb"); + f=fopen(path,"rb"); if (!f) { if (errno == ENOENT) { slilog(log,M_DEBUG,"private key %s not found", @@ -110,22 +116,14 @@ 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", - 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); @@ -136,7 +134,7 @@ static struct sigprivkey_if *uncached_load_file( static struct sigprivkey_if *privcache_lookup(void *sst, const struct sigkeyid *id, struct log_if *log) { - struct privcache *st = sst; + struct privcache *st=sst; int was; struct ent result; @@ -148,10 +146,10 @@ static struct sigprivkey_if *privcache_lookup(void *sst, } if (st->used < st->alloc) { - was = st->used; + was=st->used; st->used++; } else { - was = st->used-1; + was=st->used-1; if (st->ents[was].sigpriv) { st->ents[was].sigpriv->dispose(st->ents[was].sigpriv->st); } @@ -162,7 +160,7 @@ static struct sigprivkey_if *privcache_lookup(void *sst, found: memmove(&st->ents[1], &st->ents[0], sizeof(st->ents[0]) * was); - st->ents[0] = result; + st->ents[0]=result; return result.sigpriv; } @@ -183,7 +181,6 @@ static list_t *privcache_apply(closure_t *self, struct cloc loc, st->ents=0; st->path.buffer=0; st->used=st->alloc=0; - st->defhash=0; item=list_elem(args,0); if (!item || item->type!=t_dict) @@ -197,18 +194,45 @@ 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); pathprefix_template_init(&st->path,path,KEYIDSZ*2); - st->defhash=find_cl_if(dict,"hash",CL_HASH,False,"site",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 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,&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); }