summaryrefslogtreecommitdiff
path: root/appl
diff options
context:
space:
mode:
Diffstat (limited to 'appl')
-rw-r--r--appl/lib/mkfile2
-rw-r--r--appl/lib/oldauth.b344
2 files changed, 346 insertions, 0 deletions
diff --git a/appl/lib/mkfile b/appl/lib/mkfile
index e681967e..279ca1ac 100644
--- a/appl/lib/mkfile
+++ b/appl/lib/mkfile
@@ -77,6 +77,8 @@ TARG=\
nametree.dis\
names.dis\
newns.dis\
+ ninep.dis\
+ oldauth.dis\
palm.dis\
palmdb.dis\
palmfile.dis\
diff --git a/appl/lib/oldauth.b b/appl/lib/oldauth.b
new file mode 100644
index 00000000..60bd9f54
--- /dev/null
+++ b/appl/lib/oldauth.b
@@ -0,0 +1,344 @@
+implement Oldauth;
+
+#
+# TO DO
+# - more error checking?
+# - details of auth error handling
+#
+
+include "sys.m";
+ sys: Sys;
+
+include "ipints.m";
+ ipints: IPints;
+ IPint: import ipints;
+
+include "crypt.m";
+ crypt: Crypt;
+ PK, SK, PKsig: import crypt;
+
+include "msgio.m";
+ msgio: Msgio;
+
+include "oldauth.m";
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ ipints = load IPints IPints->PATH;
+ crypt = load Crypt Crypt->PATH;
+ msgio = load Msgio Msgio->PATH;
+ msgio->init();
+}
+
+efmt()
+{
+ sys->werrstr("input or format error");
+}
+
+readauthinfo(filename: string): ref Authinfo
+{
+ fd := sys->open(filename, Sys->OREAD);
+ if(fd == nil)
+ return nil;
+ a := array[5] of string;
+ for(i := 0; i < len a; i++){
+ (s, err) := getstr(fd);
+ if(err != nil){
+ sys->werrstr(sys->sprint("%q: input or format error", filename));
+ return nil;
+ }
+ a[i] = s;
+ }
+ info := ref Authinfo;
+ (info.spk, nil) = strtopk(a[0]);
+ info.cert = strtocert(a[1]);
+ (info.mysk, info.owner) = strtosk(a[2]);
+ if(info.spk == nil || info.cert == nil || info.mysk == nil){
+ efmt();
+ return nil;
+ }
+ info.mypk = crypt->sktopk(info.mysk);
+ info.alpha = IPint.strtoip(a[3], 64);
+ info.p = IPint.strtoip(a[4], 64);
+ if(info.alpha == nil || info.p == nil){
+ efmt();
+ return nil;
+ }
+ return info;
+}
+
+writeauthinfo(filename: string, info: ref Authinfo): int
+{
+ if(info.alpha == nil || info.p == nil ||
+ info.spk == nil || info.mysk == nil || info.cert == nil){
+ sys->werrstr("invalid authinfo");
+ return -1;
+ }
+ a := array[5] of string;
+ a[0] = pktostr(info.spk, info.cert.signer); # signer's public key
+ a[1] = certtostr(info.cert); # certificate for my public key
+ a[2] = sktostr(info.mysk, info.owner); # my secret/public key
+ a[3] = b64(info.alpha); # diffie hellman base
+ a[4] = b64(info.p); # diffie hellman modulus
+ fd := sys->open(filename, Sys->OWRITE|Sys->OTRUNC);
+ if(fd == nil){
+ fd = sys->create(filename, Sys->OWRITE, 8r600);
+ if(fd == nil){
+ fd = sys->open(filename, Sys->OWRITE);
+ if(fd == nil)
+ return -1;
+ }
+ }
+ for(i := 0; i < len a; i++)
+ if(sendstr(fd, a[i]) <= 0)
+ return -1;
+ return 0;
+}
+
+sendstr(fd: ref Sys->FD, s: string): int
+{
+ a := array of byte s;
+ return msgio->sendmsg(fd, a, len a);
+}
+
+getstr(fd: ref Sys->FD): (string, string)
+{
+ b := msgio->getmsg(fd);
+ if(b == nil)
+ return (nil, sys->sprint("%r"));
+ return (string b, nil);
+}
+
+certtostr(c: ref Certificate): string
+{
+ s := sys->sprint("%s\n%s\n%s\n%ud\n", c.sa, c.ha, c.signer, c.exp);
+ pick r := c.sig {
+ RSA =>
+ s += b64(r.n)+"\n";
+ Elgamal =>
+ s += b64(r.r)+"\n"+b64(r.s)+"\n";
+ DSA =>
+ s += b64(r.r)+"\n"+b64(r.s)+"\n";
+ * =>
+ raise "unknown key type";
+ }
+ return s;
+}
+
+pktostr(pk: ref PK, owner: string): string
+{
+ pick k := pk {
+ RSA =>
+ s := sys->sprint("rsa\n%s\n", owner);
+ s += b64(k.n)+"\n"+b64(k.ek)+"\n";
+ return s;
+ Elgamal =>
+ s := sys->sprint("elgamal\n%s\n", owner);
+ s += b64(k.p)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n";
+ return s;
+ DSA =>
+ s := sys->sprint("dsa\n%s\n", owner);
+ s += b64(k.p)+"\n"+b64(k.q)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n";
+ return s;
+ * =>
+ raise "unknown key type";
+ }
+}
+
+sktostr(sk: ref SK, owner: string): string
+{
+ pick k := sk {
+ RSA =>
+ s := sys->sprint("rsa\n%s\n", owner);
+ s += b64(k.pk.n)+"\n"+b64(k.pk.ek)+"\n"+b64(k.dk)+"\n"+
+ b64(k.p)+"\n"+b64(k.q)+"\n"+
+ b64(k.kp)+"\n"+b64(k.kq)+"\n"+
+ k.c2.iptob64()+"\n";
+ return s;
+ Elgamal =>
+ pk := k.pk;
+ s := sys->sprint("elgamal\n%s\n", owner);
+ s += b64(pk.p)+"\n"+b64(pk.alpha)+"\n"+b64(pk.key)+"\n"+b64(k.secret)+"\n";
+ return s;
+ DSA =>
+ pk := k.pk;
+ s := sys->sprint("dsa\n%s\n", owner);
+ s += b64(pk.p)+"\n"+b64(pk.q)+"\n"+b64(pk.alpha)+"\n"+b64(k.secret)+"\n";
+ return s;
+ * =>
+ raise "unknown key type";
+ }
+}
+
+fields(s: string): array of string
+{
+ (nf, flds) := sys->tokenize(s, "\n^");
+ a := array[nf] of string;
+ for(i := 0; i < len a; i++){
+ a[i] = hd flds;
+ flds = tl flds;
+ }
+ return a;
+}
+
+bigs(a: array of string): array of ref IPint
+{
+ b := array[len a] of ref IPint;
+ for(i := 0; i < len b; i++){
+ b[i] = IPint.strtoip(a[i], 64);
+ if(b[i] == nil)
+ return nil;
+ }
+ return b;
+}
+
+need[T](a: array of T, min: int): int
+{
+ if(len a < min){
+ efmt();
+ return 1;
+ }
+ return 0;
+}
+
+strtocert(s: string): ref Certificate
+{
+ f := fields(s);
+ if(need(f, 4))
+ return nil;
+ sa := f[0];
+ ha := f[1];
+ signer := f[2];
+ exp := int big f[3]; # unsigned
+ b := bigs(f[4:]);
+ case f[0] {
+ "rsa" =>
+ if(need(b, 1))
+ return nil;
+ return ref Certificate(sa, ha, signer, exp, ref PKsig.RSA(b[0]));
+ "elgamal" =>
+ if(need(b, 2))
+ return nil;
+ return ref Certificate(sa, ha, signer, exp, ref PKsig.Elgamal(b[0], b[1]));
+ "dsa" =>
+ if(need(b, 2))
+ return nil;
+ return ref Certificate(sa, ha, signer, exp, ref PKsig.DSA(b[0], b[1]));
+ * =>
+ sys->werrstr("unknown algorithm: "+f[0]);
+ return nil;
+ }
+}
+
+strtopk(s: string): (ref PK, string)
+{
+ f := fields(s);
+ if(need(f, 3))
+ return (nil, "format error");
+ sa := f[0];
+ owner := f[1];
+ b := bigs(f[2:]);
+ case sa {
+ "rsa" =>
+ if(need(b, 2))
+ return (nil, "format error");
+ return (ref PK.RSA(b[0], b[1]), owner);
+ "elgamal" =>
+ if(need(b, 3))
+ return (nil, "format error");
+ return (ref PK.Elgamal(b[0], b[1], b[2]), owner);
+ "dsa" =>
+ if(need(b, 4))
+ return (nil, "format error");
+ return (ref PK.DSA(b[0], b[1], b[2], b[3]), owner);
+ * =>
+ return (nil, "unknown algorithm: "+f[0]);
+ }
+}
+
+strtosk(s: string): (ref SK, string)
+{
+ f := fields(s);
+ if(need(f, 3))
+ return (nil, "format error");
+ sa := f[0];
+ owner := f[1];
+ b := bigs(f[2:]);
+ case sa {
+ "rsa" =>
+ if(need(b, 8))
+ return (nil, "format error");
+ return (ref SK.RSA(ref PK.RSA(b[0], b[1]), b[2], b[3], b[4], b[5], b[6], b[7]), owner);
+ "elgamal" =>
+ if(need(b, 4))
+ return (nil, "format error");
+ return (ref SK.Elgamal(ref PK.Elgamal(b[0], b[1], b[2]), b[3]), owner);
+ "dsa" =>
+ if(need(b, 5))
+ return (nil, "format error");
+ return (ref SK.DSA(ref PK.DSA(b[0], b[1], b[2], b[3]), b[4]), owner);
+ * =>
+ return (nil, "unknown algorithm: "+f[0]);
+ }
+}
+
+skalg(sk: ref SK): string
+{
+ if(sk == nil)
+ return "nil";
+ case tagof sk {
+ tagof SK.RSA => return "rsa";
+ tagof SK.Elgamal => return "elgamal";
+ tagof SK.DSA => return "dsa";
+ * => return "gok";
+ }
+}
+
+sign(sk: ref SK, signer: string, exp: int, state: ref Crypt->DigestState, ha: string): ref Certificate
+{
+ # add signer name and expiration time to hash
+ if(state == nil)
+ return nil;
+ a := sys->aprint("%s %d", signer, exp);
+ digest := hash(ha, a, state);
+ if(digest == nil)
+ return nil;
+ b := IPint.bebytestoip(digest);
+ return ref Certificate(skalg(sk), ha, signer, exp, crypt->sign(sk, b));
+}
+
+verify(pk: ref PK, cert: ref Certificate, state: ref Crypt->DigestState): int
+{
+ if(state == nil)
+ return 0;
+ a := sys->aprint("%s %d", cert.signer, cert.exp);
+ digest := hash(cert.ha, a, state);
+ if(digest == nil)
+ return 0;
+ b := IPint.bebytestoip(digest);
+ return crypt->verify(pk, cert.sig, b);
+}
+
+hash(ha: string, a: array of byte, state: ref Crypt->DigestState): array of byte
+{
+ digest: array of byte;
+ case ha {
+ "sha" or "sha1" =>
+ digest = array[Crypt->SHA1dlen] of byte;
+ crypt->sha1(a, len a, digest, state);
+ "md5" =>
+ digest = array[Crypt->MD5dlen] of byte;
+ crypt->md5(a, len a, digest, state);
+ * =>
+ # don't bother with md4
+ sys->werrstr("unimplemented algorithm: "+ha);
+ return nil;
+ }
+ return digest;
+}
+
+b64(ip: ref IPint): string
+{
+ return ip.iptob64z();
+}