diff options
Diffstat (limited to 'appl/cmd/auth/mkauthinfo.b')
| -rw-r--r-- | appl/cmd/auth/mkauthinfo.b | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/appl/cmd/auth/mkauthinfo.b b/appl/cmd/auth/mkauthinfo.b new file mode 100644 index 00000000..33feffbb --- /dev/null +++ b/appl/cmd/auth/mkauthinfo.b @@ -0,0 +1,125 @@ +implement Mkauthinfo; + +# +# sign a new key to produce a certificate +# + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "keyring.m"; + kr: Keyring; + IPint: import kr; + +include "security.m"; + auth: Auth; + +include "daytime.m"; + daytime: Daytime; + +include "arg.m"; + +Mkauthinfo: module{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +stderr: ref Sys->FD; + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + stderr = sys->open("/dev/cons", sys->OWRITE); + + kr = load Keyring Keyring->PATH; + + auth = load Auth Auth->PATH; + if(auth == nil) + nomod(Auth->PATH); + + daytime = load Daytime Daytime->PATH; + if(daytime == nil) + nomod(Daytime->PATH); + + arg := load Arg Arg->PATH; + if(arg == nil) + nomod(Arg->PATH); + arg->init(args); + arg->setusage("auth/mkauthinfo [-k keyspec] [-e ddmmyyyy] user [keyfile]"); + keyspec := "key=default"; + expiry := 0; + while((o := arg->opt()) != 0) + case o { + 'k' => + keyspec = arg->earg(); + 'e' => + expiry = parsedate(arg->earg()); + * => + arg->usage(); + } + args = arg->argv(); + if(args == nil) + arg->usage(); + user := hd args; + args = tl args; + dstfile := "/fd/1"; + if(args != nil) + dstfile = hd args; + arg = nil; + + sai := auth->key(keyspec); + if(sai == nil){ + sys->fprint(stderr, "sign: can't find key matching %q: %r\n", keyspec); + raise "fail:no key"; + } + + info := ref Keyring->Authinfo; + info.alpha = sai.alpha; + info.p = sai.p; + info.mysk = kr->genSKfromPK(sai.spk, user); + info.mypk = kr->sktopk(info.mysk); + info.spk = sai.mypk; + pkbuf := array of byte kr->pktostr(info.mypk); + state := kr->sha1(pkbuf, len pkbuf, nil, nil); + info.cert = kr->sign(sai.mysk, expiry, state, "sha1"); + if(kr->writeauthinfo("/fd/1", info) < 0){ + sys->fprint(stderr, "sign: error writing certificate: %r\n"); + raise "fail:write error"; + } +} + +parsedate(s: string): int +{ + now := daytime->now(); + tm := daytime->local(now); + if(s == "permanent") + return 0; + if(len s != 8) + fatal("bad date format "+s+" (expected DDMMYYYY)"); + tm.mday = int s[0:2]; + if(tm.mday > 31 || tm.mday < 1) + fatal(sys->sprint("bad day of month %d", tm.mday)); + tm.mon = int s[2:4] - 1; + if(tm.mon > 11 || tm.mday < 0) + fatal(sys->sprint("bad month %d\n", tm.mon + 1)); + tm.year = int s[4:8] - 1900; + if(tm.year < 70) + fatal(sys->sprint("bad year %d (year may be no earlier than 1970)", tm.year + 1900)); + expiry := daytime->tm2epoch(tm); + expiry += 60; + if(expiry <= now) + fatal("expiry date has already passed"); + return expiry; +} + +nomod(mod: string) +{ + fatal(sys->sprint("can't load %s: %r",mod)); +} + +fatal(msg: string) +{ + sys->fprint(stderr, "mkauthinfo: %s\n", msg); + raise "fail:error"; +} |
