summaryrefslogtreecommitdiff
path: root/appl/cmd/auth/mkauthinfo.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/auth/mkauthinfo.b')
-rw-r--r--appl/cmd/auth/mkauthinfo.b125
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";
+}