ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/lib/keyset.b/
implement Keyset;
include "sys.m";
sys: Sys;
include "keyring.m";
keyring: Keyring;
include "daytime.m";
daytime: Daytime;
include "readdir.m";
include "keyset.m";
PKHASHLEN: con Keyring->SHA1dlen * 2;
init(): string
{
sys = load Sys Sys->PATH;
keyring = load Keyring Keyring->PATH;
if(keyring == nil)
return cant(Keyring->PATH);
daytime = load Daytime Daytime->PATH;
if(daytime == nil)
return cant(Daytime->PATH);
return nil;
}
cant(s: string): string
{
return sys->sprint("can't load %s: %r", s);
}
pkhash(pk: string): string
{
d := array of byte pk;
digest := array[Keyring->SHA1dlen] of byte;
keyring->sha1(d, len d, digest, nil);
s := "";
for(i := 0; i < len digest; i++)
s += sys->sprint("%2.2ux", int digest[i]);
return s;
}
keysforsigner(signername: string, spkhash: string, user: string, dir: string): (list of (string, string, string), string)
{
if(spkhash != nil && len spkhash != PKHASHLEN)
return (nil, "invalid hash string");
if(dir == nil){
if(user == nil)
user = readname("/dev/user");
if(user == nil)
dir = "/lib/keyring";
else
dir = "/usr/" + user + "/keyring";
}
readdir := load Readdir Readdir->PATH;
if(readdir == nil)
return (nil, sys->sprint("can't load Readdir: %r"));
now := daytime->now();
(a, ok) := readdir->init(dir, Readdir->COMPACT|Readdir->MTIME);
if(ok < 0)
return (nil, sys->sprint("can't open %s: %r", dir));
keys: list of (string, string, string);
for(i := 0; i < len a; i++){
if(a[i].mode & Sys->DMDIR)
continue;
f := dir + "/" + a[i].name;
info := keyring->readauthinfo(f);
if(info == nil || info.cert == nil || info.cert.exp != 0 && info.cert.exp < now)
continue;
if(signername != nil && info.cert.signer != signername)
continue;
if(spkhash != nil && pkhash(keyring->pktostr(info.spk)) != spkhash)
continue;
keys = (f, info.mypk.owner, info.cert.signer) :: keys;
}
return (keys, nil);
}
readname(f: string): string
{
fd := sys->open(f, Sys->OREAD);
if(fd == nil)
return nil;
buf := array[Sys->NAMEMAX] of byte;
n := sys->read(fd, buf, len buf);
if(n <= 0)
return nil;
return string buf[0:n];
}