1*25b96b1dSforsythimplement Oldauth; 2*25b96b1dSforsyth 3*25b96b1dSforsyth# 4*25b96b1dSforsyth# TO DO 5*25b96b1dSforsyth# - more error checking? 6*25b96b1dSforsyth# - details of auth error handling 7*25b96b1dSforsyth# 8*25b96b1dSforsyth 9*25b96b1dSforsythinclude "sys.m"; 10*25b96b1dSforsyth sys: Sys; 11*25b96b1dSforsyth 12*25b96b1dSforsythinclude "ipints.m"; 13*25b96b1dSforsyth ipints: IPints; 14*25b96b1dSforsyth IPint: import ipints; 15*25b96b1dSforsyth 16*25b96b1dSforsythinclude "crypt.m"; 17*25b96b1dSforsyth crypt: Crypt; 18*25b96b1dSforsyth PK, SK, PKsig: import crypt; 19*25b96b1dSforsyth 20*25b96b1dSforsythinclude "msgio.m"; 21*25b96b1dSforsyth msgio: Msgio; 22*25b96b1dSforsyth 23*25b96b1dSforsythinclude "oldauth.m"; 24*25b96b1dSforsyth 25*25b96b1dSforsythinit() 26*25b96b1dSforsyth{ 27*25b96b1dSforsyth sys = load Sys Sys->PATH; 28*25b96b1dSforsyth ipints = load IPints IPints->PATH; 29*25b96b1dSforsyth crypt = load Crypt Crypt->PATH; 30*25b96b1dSforsyth msgio = load Msgio Msgio->PATH; 31*25b96b1dSforsyth msgio->init(); 32*25b96b1dSforsyth} 33*25b96b1dSforsyth 34*25b96b1dSforsythefmt() 35*25b96b1dSforsyth{ 36*25b96b1dSforsyth sys->werrstr("input or format error"); 37*25b96b1dSforsyth} 38*25b96b1dSforsyth 39*25b96b1dSforsythreadauthinfo(filename: string): ref Authinfo 40*25b96b1dSforsyth{ 41*25b96b1dSforsyth fd := sys->open(filename, Sys->OREAD); 42*25b96b1dSforsyth if(fd == nil) 43*25b96b1dSforsyth return nil; 44*25b96b1dSforsyth a := array[5] of string; 45*25b96b1dSforsyth for(i := 0; i < len a; i++){ 46*25b96b1dSforsyth (s, err) := getstr(fd); 47*25b96b1dSforsyth if(err != nil){ 48*25b96b1dSforsyth sys->werrstr(sys->sprint("%q: input or format error", filename)); 49*25b96b1dSforsyth return nil; 50*25b96b1dSforsyth } 51*25b96b1dSforsyth a[i] = s; 52*25b96b1dSforsyth } 53*25b96b1dSforsyth info := ref Authinfo; 54*25b96b1dSforsyth (info.spk, nil) = strtopk(a[0]); 55*25b96b1dSforsyth info.cert = strtocert(a[1]); 56*25b96b1dSforsyth (info.mysk, info.owner) = strtosk(a[2]); 57*25b96b1dSforsyth if(info.spk == nil || info.cert == nil || info.mysk == nil){ 58*25b96b1dSforsyth efmt(); 59*25b96b1dSforsyth return nil; 60*25b96b1dSforsyth } 61*25b96b1dSforsyth info.mypk = crypt->sktopk(info.mysk); 62*25b96b1dSforsyth info.alpha = IPint.strtoip(a[3], 64); 63*25b96b1dSforsyth info.p = IPint.strtoip(a[4], 64); 64*25b96b1dSforsyth if(info.alpha == nil || info.p == nil){ 65*25b96b1dSforsyth efmt(); 66*25b96b1dSforsyth return nil; 67*25b96b1dSforsyth } 68*25b96b1dSforsyth return info; 69*25b96b1dSforsyth} 70*25b96b1dSforsyth 71*25b96b1dSforsythwriteauthinfo(filename: string, info: ref Authinfo): int 72*25b96b1dSforsyth{ 73*25b96b1dSforsyth if(info.alpha == nil || info.p == nil || 74*25b96b1dSforsyth info.spk == nil || info.mysk == nil || info.cert == nil){ 75*25b96b1dSforsyth sys->werrstr("invalid authinfo"); 76*25b96b1dSforsyth return -1; 77*25b96b1dSforsyth } 78*25b96b1dSforsyth a := array[5] of string; 79*25b96b1dSforsyth a[0] = pktostr(info.spk, info.cert.signer); # signer's public key 80*25b96b1dSforsyth a[1] = certtostr(info.cert); # certificate for my public key 81*25b96b1dSforsyth a[2] = sktostr(info.mysk, info.owner); # my secret/public key 82*25b96b1dSforsyth a[3] = b64(info.alpha); # diffie hellman base 83*25b96b1dSforsyth a[4] = b64(info.p); # diffie hellman modulus 84*25b96b1dSforsyth fd := sys->open(filename, Sys->OWRITE|Sys->OTRUNC); 85*25b96b1dSforsyth if(fd == nil){ 86*25b96b1dSforsyth fd = sys->create(filename, Sys->OWRITE, 8r600); 87*25b96b1dSforsyth if(fd == nil){ 88*25b96b1dSforsyth fd = sys->open(filename, Sys->OWRITE); 89*25b96b1dSforsyth if(fd == nil) 90*25b96b1dSforsyth return -1; 91*25b96b1dSforsyth } 92*25b96b1dSforsyth } 93*25b96b1dSforsyth for(i := 0; i < len a; i++) 94*25b96b1dSforsyth if(sendstr(fd, a[i]) <= 0) 95*25b96b1dSforsyth return -1; 96*25b96b1dSforsyth return 0; 97*25b96b1dSforsyth} 98*25b96b1dSforsyth 99*25b96b1dSforsythsendstr(fd: ref Sys->FD, s: string): int 100*25b96b1dSforsyth{ 101*25b96b1dSforsyth a := array of byte s; 102*25b96b1dSforsyth return msgio->sendmsg(fd, a, len a); 103*25b96b1dSforsyth} 104*25b96b1dSforsyth 105*25b96b1dSforsythgetstr(fd: ref Sys->FD): (string, string) 106*25b96b1dSforsyth{ 107*25b96b1dSforsyth b := msgio->getmsg(fd); 108*25b96b1dSforsyth if(b == nil) 109*25b96b1dSforsyth return (nil, sys->sprint("%r")); 110*25b96b1dSforsyth return (string b, nil); 111*25b96b1dSforsyth} 112*25b96b1dSforsyth 113*25b96b1dSforsythcerttostr(c: ref Certificate): string 114*25b96b1dSforsyth{ 115*25b96b1dSforsyth s := sys->sprint("%s\n%s\n%s\n%ud\n", c.sa, c.ha, c.signer, c.exp); 116*25b96b1dSforsyth pick r := c.sig { 117*25b96b1dSforsyth RSA => 118*25b96b1dSforsyth s += b64(r.n)+"\n"; 119*25b96b1dSforsyth Elgamal => 120*25b96b1dSforsyth s += b64(r.r)+"\n"+b64(r.s)+"\n"; 121*25b96b1dSforsyth DSA => 122*25b96b1dSforsyth s += b64(r.r)+"\n"+b64(r.s)+"\n"; 123*25b96b1dSforsyth * => 124*25b96b1dSforsyth raise "unknown key type"; 125*25b96b1dSforsyth } 126*25b96b1dSforsyth return s; 127*25b96b1dSforsyth} 128*25b96b1dSforsyth 129*25b96b1dSforsythpktostr(pk: ref PK, owner: string): string 130*25b96b1dSforsyth{ 131*25b96b1dSforsyth pick k := pk { 132*25b96b1dSforsyth RSA => 133*25b96b1dSforsyth s := sys->sprint("rsa\n%s\n", owner); 134*25b96b1dSforsyth s += b64(k.n)+"\n"+b64(k.ek)+"\n"; 135*25b96b1dSforsyth return s; 136*25b96b1dSforsyth Elgamal => 137*25b96b1dSforsyth s := sys->sprint("elgamal\n%s\n", owner); 138*25b96b1dSforsyth s += b64(k.p)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n"; 139*25b96b1dSforsyth return s; 140*25b96b1dSforsyth DSA => 141*25b96b1dSforsyth s := sys->sprint("dsa\n%s\n", owner); 142*25b96b1dSforsyth s += b64(k.p)+"\n"+b64(k.q)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n"; 143*25b96b1dSforsyth return s; 144*25b96b1dSforsyth * => 145*25b96b1dSforsyth raise "unknown key type"; 146*25b96b1dSforsyth } 147*25b96b1dSforsyth} 148*25b96b1dSforsyth 149*25b96b1dSforsythsktostr(sk: ref SK, owner: string): string 150*25b96b1dSforsyth{ 151*25b96b1dSforsyth pick k := sk { 152*25b96b1dSforsyth RSA => 153*25b96b1dSforsyth s := sys->sprint("rsa\n%s\n", owner); 154*25b96b1dSforsyth s += b64(k.pk.n)+"\n"+b64(k.pk.ek)+"\n"+b64(k.dk)+"\n"+ 155*25b96b1dSforsyth b64(k.p)+"\n"+b64(k.q)+"\n"+ 156*25b96b1dSforsyth b64(k.kp)+"\n"+b64(k.kq)+"\n"+ 157*25b96b1dSforsyth k.c2.iptob64()+"\n"; 158*25b96b1dSforsyth return s; 159*25b96b1dSforsyth Elgamal => 160*25b96b1dSforsyth pk := k.pk; 161*25b96b1dSforsyth s := sys->sprint("elgamal\n%s\n", owner); 162*25b96b1dSforsyth s += b64(pk.p)+"\n"+b64(pk.alpha)+"\n"+b64(pk.key)+"\n"+b64(k.secret)+"\n"; 163*25b96b1dSforsyth return s; 164*25b96b1dSforsyth DSA => 165*25b96b1dSforsyth pk := k.pk; 166*25b96b1dSforsyth s := sys->sprint("dsa\n%s\n", owner); 167*25b96b1dSforsyth s += b64(pk.p)+"\n"+b64(pk.q)+"\n"+b64(pk.alpha)+"\n"+b64(k.secret)+"\n"; 168*25b96b1dSforsyth return s; 169*25b96b1dSforsyth * => 170*25b96b1dSforsyth raise "unknown key type"; 171*25b96b1dSforsyth } 172*25b96b1dSforsyth} 173*25b96b1dSforsyth 174*25b96b1dSforsythfields(s: string): array of string 175*25b96b1dSforsyth{ 176*25b96b1dSforsyth (nf, flds) := sys->tokenize(s, "\n^"); 177*25b96b1dSforsyth a := array[nf] of string; 178*25b96b1dSforsyth for(i := 0; i < len a; i++){ 179*25b96b1dSforsyth a[i] = hd flds; 180*25b96b1dSforsyth flds = tl flds; 181*25b96b1dSforsyth } 182*25b96b1dSforsyth return a; 183*25b96b1dSforsyth} 184*25b96b1dSforsyth 185*25b96b1dSforsythbigs(a: array of string): array of ref IPint 186*25b96b1dSforsyth{ 187*25b96b1dSforsyth b := array[len a] of ref IPint; 188*25b96b1dSforsyth for(i := 0; i < len b; i++){ 189*25b96b1dSforsyth b[i] = IPint.strtoip(a[i], 64); 190*25b96b1dSforsyth if(b[i] == nil) 191*25b96b1dSforsyth return nil; 192*25b96b1dSforsyth } 193*25b96b1dSforsyth return b; 194*25b96b1dSforsyth} 195*25b96b1dSforsyth 196*25b96b1dSforsythneed[T](a: array of T, min: int): int 197*25b96b1dSforsyth{ 198*25b96b1dSforsyth if(len a < min){ 199*25b96b1dSforsyth efmt(); 200*25b96b1dSforsyth return 1; 201*25b96b1dSforsyth } 202*25b96b1dSforsyth return 0; 203*25b96b1dSforsyth} 204*25b96b1dSforsyth 205*25b96b1dSforsythstrtocert(s: string): ref Certificate 206*25b96b1dSforsyth{ 207*25b96b1dSforsyth f := fields(s); 208*25b96b1dSforsyth if(need(f, 4)) 209*25b96b1dSforsyth return nil; 210*25b96b1dSforsyth sa := f[0]; 211*25b96b1dSforsyth ha := f[1]; 212*25b96b1dSforsyth signer := f[2]; 213*25b96b1dSforsyth exp := int big f[3]; # unsigned 214*25b96b1dSforsyth b := bigs(f[4:]); 215*25b96b1dSforsyth case f[0] { 216*25b96b1dSforsyth "rsa" => 217*25b96b1dSforsyth if(need(b, 1)) 218*25b96b1dSforsyth return nil; 219*25b96b1dSforsyth return ref Certificate(sa, ha, signer, exp, ref PKsig.RSA(b[0])); 220*25b96b1dSforsyth "elgamal" => 221*25b96b1dSforsyth if(need(b, 2)) 222*25b96b1dSforsyth return nil; 223*25b96b1dSforsyth return ref Certificate(sa, ha, signer, exp, ref PKsig.Elgamal(b[0], b[1])); 224*25b96b1dSforsyth "dsa" => 225*25b96b1dSforsyth if(need(b, 2)) 226*25b96b1dSforsyth return nil; 227*25b96b1dSforsyth return ref Certificate(sa, ha, signer, exp, ref PKsig.DSA(b[0], b[1])); 228*25b96b1dSforsyth * => 229*25b96b1dSforsyth sys->werrstr("unknown algorithm: "+f[0]); 230*25b96b1dSforsyth return nil; 231*25b96b1dSforsyth } 232*25b96b1dSforsyth} 233*25b96b1dSforsyth 234*25b96b1dSforsythstrtopk(s: string): (ref PK, string) 235*25b96b1dSforsyth{ 236*25b96b1dSforsyth f := fields(s); 237*25b96b1dSforsyth if(need(f, 3)) 238*25b96b1dSforsyth return (nil, "format error"); 239*25b96b1dSforsyth sa := f[0]; 240*25b96b1dSforsyth owner := f[1]; 241*25b96b1dSforsyth b := bigs(f[2:]); 242*25b96b1dSforsyth case sa { 243*25b96b1dSforsyth "rsa" => 244*25b96b1dSforsyth if(need(b, 2)) 245*25b96b1dSforsyth return (nil, "format error"); 246*25b96b1dSforsyth return (ref PK.RSA(b[0], b[1]), owner); 247*25b96b1dSforsyth "elgamal" => 248*25b96b1dSforsyth if(need(b, 3)) 249*25b96b1dSforsyth return (nil, "format error"); 250*25b96b1dSforsyth return (ref PK.Elgamal(b[0], b[1], b[2]), owner); 251*25b96b1dSforsyth "dsa" => 252*25b96b1dSforsyth if(need(b, 4)) 253*25b96b1dSforsyth return (nil, "format error"); 254*25b96b1dSforsyth return (ref PK.DSA(b[0], b[1], b[2], b[3]), owner); 255*25b96b1dSforsyth * => 256*25b96b1dSforsyth return (nil, "unknown algorithm: "+f[0]); 257*25b96b1dSforsyth } 258*25b96b1dSforsyth} 259*25b96b1dSforsyth 260*25b96b1dSforsythstrtosk(s: string): (ref SK, string) 261*25b96b1dSforsyth{ 262*25b96b1dSforsyth f := fields(s); 263*25b96b1dSforsyth if(need(f, 3)) 264*25b96b1dSforsyth return (nil, "format error"); 265*25b96b1dSforsyth sa := f[0]; 266*25b96b1dSforsyth owner := f[1]; 267*25b96b1dSforsyth b := bigs(f[2:]); 268*25b96b1dSforsyth case sa { 269*25b96b1dSforsyth "rsa" => 270*25b96b1dSforsyth if(need(b, 8)) 271*25b96b1dSforsyth return (nil, "format error"); 272*25b96b1dSforsyth return (ref SK.RSA(ref PK.RSA(b[0], b[1]), b[2], b[3], b[4], b[5], b[6], b[7]), owner); 273*25b96b1dSforsyth "elgamal" => 274*25b96b1dSforsyth if(need(b, 4)) 275*25b96b1dSforsyth return (nil, "format error"); 276*25b96b1dSforsyth return (ref SK.Elgamal(ref PK.Elgamal(b[0], b[1], b[2]), b[3]), owner); 277*25b96b1dSforsyth "dsa" => 278*25b96b1dSforsyth if(need(b, 5)) 279*25b96b1dSforsyth return (nil, "format error"); 280*25b96b1dSforsyth return (ref SK.DSA(ref PK.DSA(b[0], b[1], b[2], b[3]), b[4]), owner); 281*25b96b1dSforsyth * => 282*25b96b1dSforsyth return (nil, "unknown algorithm: "+f[0]); 283*25b96b1dSforsyth } 284*25b96b1dSforsyth} 285*25b96b1dSforsyth 286*25b96b1dSforsythskalg(sk: ref SK): string 287*25b96b1dSforsyth{ 288*25b96b1dSforsyth if(sk == nil) 289*25b96b1dSforsyth return "nil"; 290*25b96b1dSforsyth case tagof sk { 291*25b96b1dSforsyth tagof SK.RSA => return "rsa"; 292*25b96b1dSforsyth tagof SK.Elgamal => return "elgamal"; 293*25b96b1dSforsyth tagof SK.DSA => return "dsa"; 294*25b96b1dSforsyth * => return "gok"; 295*25b96b1dSforsyth } 296*25b96b1dSforsyth} 297*25b96b1dSforsyth 298*25b96b1dSforsythsign(sk: ref SK, signer: string, exp: int, state: ref Crypt->DigestState, ha: string): ref Certificate 299*25b96b1dSforsyth{ 300*25b96b1dSforsyth # add signer name and expiration time to hash 301*25b96b1dSforsyth if(state == nil) 302*25b96b1dSforsyth return nil; 303*25b96b1dSforsyth a := sys->aprint("%s %d", signer, exp); 304*25b96b1dSforsyth digest := hash(ha, a, state); 305*25b96b1dSforsyth if(digest == nil) 306*25b96b1dSforsyth return nil; 307*25b96b1dSforsyth b := IPint.bebytestoip(digest); 308*25b96b1dSforsyth return ref Certificate(skalg(sk), ha, signer, exp, crypt->sign(sk, b)); 309*25b96b1dSforsyth} 310*25b96b1dSforsyth 311*25b96b1dSforsythverify(pk: ref PK, cert: ref Certificate, state: ref Crypt->DigestState): int 312*25b96b1dSforsyth{ 313*25b96b1dSforsyth if(state == nil) 314*25b96b1dSforsyth return 0; 315*25b96b1dSforsyth a := sys->aprint("%s %d", cert.signer, cert.exp); 316*25b96b1dSforsyth digest := hash(cert.ha, a, state); 317*25b96b1dSforsyth if(digest == nil) 318*25b96b1dSforsyth return 0; 319*25b96b1dSforsyth b := IPint.bebytestoip(digest); 320*25b96b1dSforsyth return crypt->verify(pk, cert.sig, b); 321*25b96b1dSforsyth} 322*25b96b1dSforsyth 323*25b96b1dSforsythhash(ha: string, a: array of byte, state: ref Crypt->DigestState): array of byte 324*25b96b1dSforsyth{ 325*25b96b1dSforsyth digest: array of byte; 326*25b96b1dSforsyth case ha { 327*25b96b1dSforsyth "sha" or "sha1" => 328*25b96b1dSforsyth digest = array[Crypt->SHA1dlen] of byte; 329*25b96b1dSforsyth crypt->sha1(a, len a, digest, state); 330*25b96b1dSforsyth "md5" => 331*25b96b1dSforsyth digest = array[Crypt->MD5dlen] of byte; 332*25b96b1dSforsyth crypt->md5(a, len a, digest, state); 333*25b96b1dSforsyth * => 334*25b96b1dSforsyth # don't bother with md4 335*25b96b1dSforsyth sys->werrstr("unimplemented algorithm: "+ha); 336*25b96b1dSforsyth return nil; 337*25b96b1dSforsyth } 338*25b96b1dSforsyth return digest; 339*25b96b1dSforsyth} 340*25b96b1dSforsyth 341*25b96b1dSforsythb64(ip: ref IPint): string 342*25b96b1dSforsyth{ 343*25b96b1dSforsyth return ip.iptob64z(); 344*25b96b1dSforsyth} 345