diff options
28 files changed, 1414 insertions, 99 deletions
@@ -1,3 +1,9 @@ +20080116 + add rsa to factotum +20080115 + add blowfish to keyring (not yet documented) + add explicit public and private key types to keyring (in development: not yet documented) + add IPint.mod, IPint.iptob64z 20080111 add newuser to newns(2) 20080109 diff --git a/appl/cmd/auth/factotum/authio.m b/appl/cmd/auth/factotum/authio.m index 7c0565b5..a156daba 100644 --- a/appl/cmd/auth/factotum/authio.m +++ b/appl/cmd/auth/factotum/authio.m @@ -47,12 +47,15 @@ Authio: module rpc: ref Rpc; findkey: fn(io: self ref IO, attrs: list of ref Attr, extra: string): (ref Key, string); + findkeys: fn(io: self ref IO, attrs: list of ref Attr, extra: string): (list of ref Key, string); needkey: fn(io: self ref IO, attrs: list of ref Attr, extra: string): (ref Key, string); read: fn(io: self ref IO): array of byte; readn: fn(io: self ref IO, n: int): array of byte; write: fn(io: self ref IO, buf: array of byte, n: int): int; toosmall: fn(io: self ref IO, n: int); error: fn(io: self ref IO, s: string); + rdwr: fn(io: self ref IO): array of byte; + reply2read: fn(io: self ref IO, a: array of byte, n: int): int; ok: fn(io: self ref IO); done: fn(io: self ref IO, ai: ref Authinfo); }; @@ -71,10 +74,12 @@ Authio: module user: fn(): string; lookattrval: fn(a: list of ref Attr, n: string): string; parseline: fn(s: string): list of ref Attr; + attrtext: fn(a: list of ref Attr): string; }; Authproto: module { init: fn(f: Authio): string; interaction: fn(attrs: list of ref Authio->Attr, io: ref Authio->IO): string; + keycheck: fn(k: ref Authio->Key): string; }; diff --git a/appl/cmd/auth/factotum/factotum.b b/appl/cmd/auth/factotum/factotum.b index 07169747..0baf9c0c 100644 --- a/appl/cmd/auth/factotum/factotum.b +++ b/appl/cmd/auth/factotum/factotum.b @@ -19,6 +19,8 @@ include "authio.m"; include "arg.m"; +include "readdir.m"; + Factotum: module { init: fn(nil: ref Draw->Context, nil: list of string); @@ -39,7 +41,7 @@ debug := Debug; files: Files; authio: Authio; -keymanc: chan of (list of ref Attr, int, chan of (ref Key, string)); +keymanc: chan of (list of ref Attr, int, chan of (list of ref Key, string)); init(nil: ref Draw->Context, args: list of string) { @@ -55,7 +57,7 @@ init(nil: ref Draw->Context, args: list of string) arg->setusage("auth/factotum [-d] [-m /mnt/factotum] [-s factotum]"); while((o := arg->opt()) != 0) case o { - 'd' => debug = 1; + 'd' => debug++; 'm' => mntpt = arg->earg(); 's' => svcname = "#s"+arg->earg(); * => arg->usage(); @@ -74,7 +76,7 @@ init(nil: ref Draw->Context, args: list of string) files.needkey = sys->file2chan(mntpt, "needkey"); if(files.ctl == nil || files.rpc == nil || files.proto == nil || files.needkey == nil) err(sys->sprint("can't create %s/*: %r", mntpt)); - keymanc = chan of (list of ref Attr, int, chan of (ref Key, string)); + keymanc = chan of (list of ref Attr, int, chan of (list of ref Key, string)); spawn factotumsrv(); } @@ -101,14 +103,14 @@ rlist: list of ref Fid; factotumsrv() { sys->pctl(Sys->NEWPGRP|Sys->FORKFD|Sys->FORKENV, nil); - if(!Debug) + if(debug == 0) privacy(); allkeys := array[0] of ref Key; pidc := chan of int; donec := chan of ref Fid; # keyc := chan of (list of ref Attr, chan of (ref Key, string)); needfid := -1; - needed, needy: list of (int, list of ref Attr, chan of (ref Key, string)); + needed, needy: list of (int, list of ref Attr, chan of (list of ref Key, string)); needread: Sys->Rread; needtag := 0; for(;;) X: alt{ @@ -216,7 +218,7 @@ factotumsrv() (off, nbytes, nil, rc) := <-files.proto.read => if(rc == nil) break; - rc <-= reads("pass\np9any\n", off, nbytes); # TO DO + rc <-= reads(readprotos(), off, nbytes); (nil, nil, nil, wc) := <-files.proto.write => if(wc != nil) wc <-= (0, "illegal operation"); @@ -260,7 +262,7 @@ factotumsrv() break; } tag := int t; - nl: list of (int, list of ref Attr, chan of (ref Key, string)); + nl: list of (int, list of ref Attr, chan of (list of ref Key, string)); found := 0; for(l := needed; l != nil; l = tl l){ (ntag, attrs, kc) := hd l; @@ -268,7 +270,7 @@ factotumsrv() found = 1; k := findkey(allkeys, attrs); if(k != nil) - kc <-= (k, nil); + kc <-= (k :: nil, nil); else kc <-= (nil, "needkey "+attrtext(attrs)); while((l = tl l) != nil) @@ -284,9 +286,9 @@ factotumsrv() (attrs, required, kc) := <-keymanc => # look for key and reply - k := findkey(allkeys, attrs); - if(k != nil){ - kc <-= (k, nil); + kl := findkeys(allkeys, attrs); + if(kl != nil){ + kc <-= (kl, nil); break; }else if(!required || needfid == -1){ kc <-= (nil, "needkey "+attrtext(attrs)); @@ -353,6 +355,21 @@ reads(str: string, off, nbytes: int): (array of byte, string) return (bstr[off:off+nbytes], nil); } +readprotos(): string +{ + readdir := load Readdir Readdir->PATH; + if(readdir == nil) + return "unknown\n"; + (dirs, nil) := readdir->init("/dis/auth/proto", Readdir->NAME|Readdir->COMPACT); + s := ""; + for(i := 0; i < len dirs; i++){ + n := dirs[i].name; + if(len n > 4 && n[len n-4:] == ".dis") + s += n[0: len n-4]+"\n"; + } + return s; +} + Ogok, Ostart, Oread, Owrite, Oauthinfo, Oattr: con iota; ops := array[] of { @@ -406,19 +423,19 @@ request(r: ref Fid, pidc: chan of int, donec: chan of ref Fid) startproto(request: string): (Authproto, list of ref Attr, string) { attrs := parseline(request); - if(Debug) + if(debug > 1) sys->print("-> %s <-\n", attrtext(attrs)); p := lookattrval(attrs, "proto"); if(p == nil) return (nil, nil, "did not specify protocol"); - if(Debug) + if(debug > 1) sys->print("proto=%s\n", p); if(any(p, "./")) # avoid unpleasantness return (nil, nil, "illegal protocol: "+p); proto := load Authproto "/dis/auth/proto/"+p+".dis"; if(proto == nil) return (nil, nil, sys->sprint("protocol %s: %r", p)); - if(Debug) + if(debug) sys->print("start %s\n", p); e: string; { @@ -708,9 +725,15 @@ delattrs(lv: list of ref Attr, rv: list of ref Attr): list of ref Attr return reverse(nl); } +ignored(s: string): int +{ + return s == "role" || s == "disabled"; +} + matchattr(attrs: list of ref Attr, pat: ref Attr): int { - return (b := lookattr(attrs, pat.name)) != nil && (pat.tag == Aquery || b.val == pat.val); + return (b := lookattr(attrs, pat.name)) != nil && (pat.tag == Aquery || b.val == pat.val) || + ignored(pat.name); } matchattrs(pub: list of ref Attr, secret: list of ref Attr, pats: list of ref Attr): int @@ -756,7 +779,7 @@ shellsort(a: array of ref Attr) findkey(keys: array of ref Key, attrs: list of ref Attr): ref Key { - if(Debug) + if(debug) sys->print("findkey %q\n", attrtext(attrs)); for(i := 0; i < len keys; i++) if((k := keys[i]) != nil && matchattrs(k.attrs, k.secrets, attrs)) @@ -764,6 +787,17 @@ findkey(keys: array of ref Key, attrs: list of ref Attr): ref Key return nil; } +findkeys(keys: array of ref Key, attrs: list of ref Attr): list of ref Key +{ + if(debug) + sys->print("findkey %q\n", attrtext(attrs)); + kl: list of ref Key; + for(i := 0; i < len keys; i++) + if((k := keys[i]) != nil && matchattrs(k.attrs, k.secrets, attrs)) + kl = k :: kl; + return reverse(kl); +} + delkey(keys: array of ref Key, attrs: list of ref Attr): int { nk := 0; @@ -835,12 +869,20 @@ any(s: string, t: string): int return 0; } -IO.findkey(nil: self ref IO, attrs: list of ref Attr, extra: string): (ref Key, string) +IO.findkey(io: self ref IO, attrs: list of ref Attr, extra: string): (ref Key, string) +{ + (kl, err) := io.findkeys(attrs, extra); + if(kl != nil) + return (hd kl, err); + return (nil, err); +} + +IO.findkeys(nil: self ref IO, attrs: list of ref Attr, extra: string): (list of ref Key, string) { ea := parseline(extra); for(; ea != nil; ea = tl ea) attrs = hd ea :: attrs; - kc := chan of (ref Key, string); + kc := chan of (list of ref Key, string); keymanc <-= (attrs, 1, kc); # TO DO: 1 => 0 for not needed return <-kc; } @@ -850,9 +892,12 @@ IO.needkey(nil: self ref IO, attrs: list of ref Attr, extra: string): (ref Key, ea := parseline(extra); for(; ea != nil; ea = tl ea) attrs = hd ea :: attrs; - kc := chan of (ref Key, string); + kc := chan of (list of ref Key, string); keymanc <-= (attrs, 1, kc); - return <-kc; + (kl, err) := <-kc; + if(kl != nil) + return (hd kl, err); + return (nil, err); } IO.read(io: self ref IO): array of byte @@ -890,6 +935,7 @@ IO.write(io: self ref IO, buf: array of byte, n: int): int okdata(rpc, buf[0:n]); return n; } + io.rpc = rpc; io.toosmall(n+3); Oauthinfo => reply(rpc, "error authentication unfinished"); @@ -899,6 +945,48 @@ IO.write(io: self ref IO, buf: array of byte, n: int): int exit; } +IO.rdwr(io: self ref IO): array of byte +{ + io.ok(); + while((rpc := rio(io.f)) != nil) + case rpc.cmd { + Oread => + io.rpc = rpc; + if(rpc.nbytes >= 3) + return nil; + io.toosmall(128+3); # make them read something + Owrite => + io.rpc = rpc; + if(rpc.arg == nil) + rpc.arg = array[0] of byte; + return rpc.arg; + Oauthinfo => + reply(rpc, "error authentication unfinished"); + * => + phase(rpc, "protocol phase error"); + } + exit; +} + +IO.reply2read(io: self ref IO, buf: array of byte, n: int): int +{ + if(io.rpc == nil) + return 0; + rpc := io.rpc; + if(rpc.cmd != Oread){ + io.rpc = nil; + phase(rpc, "internal phase error"); + return 0; + } + if(rpc.nbytes-3 < n){ + io.toosmall(n+3); + return 0; + } + io.rpc = nil; + okdata(rpc, buf[0:n]); + return 1; +} + IO.ok(io: self ref IO) { if(io.rpc != nil){ diff --git a/appl/cmd/auth/factotum/proto/infauth.b b/appl/cmd/auth/factotum/proto/infauth.b index 0b3505d6..cfc847eb 100644 --- a/appl/cmd/auth/factotum/proto/infauth.b +++ b/appl/cmd/auth/factotum/proto/infauth.b @@ -382,3 +382,8 @@ sl(l: list of ref Sexp): ref Sexp { return ref Sexp.List(l); } + +keycheck(nil: ref Authio->Key): string +{ + return nil; +} diff --git a/appl/cmd/auth/factotum/proto/p9any.b b/appl/cmd/auth/factotum/proto/p9any.b index 1668a701..3d0b0d12 100644 --- a/appl/cmd/auth/factotum/proto/p9any.b +++ b/appl/cmd/auth/factotum/proto/p9any.b @@ -230,3 +230,8 @@ authdial(netroot: string, dom: string): ref Sys->FD (nil, conn) := sys->dial(netmkaddr(p, netroot, "ticket"), nil); return conn.dfd; } + +keycheck(nil: ref Authio->Key): string +{ + return nil; +} diff --git a/appl/cmd/auth/factotum/proto/pass.b b/appl/cmd/auth/factotum/proto/pass.b index 9c4462b3..aea5b00e 100644 --- a/appl/cmd/auth/factotum/proto/pass.b +++ b/appl/cmd/auth/factotum/proto/pass.b @@ -27,3 +27,8 @@ interaction(attrs: list of ref Attr, io: ref Authio->IO): string io.write(a, len a); return nil; } + +keycheck(nil: ref Authio->Key): string +{ + return nil; +} diff --git a/appl/cmd/auth/factotum/proto/rsa.b b/appl/cmd/auth/factotum/proto/rsa.b new file mode 100644 index 00000000..24dcef43 --- /dev/null +++ b/appl/cmd/auth/factotum/proto/rsa.b @@ -0,0 +1,126 @@ +implement Authproto; + +# SSH RSA authentication. +# +# Client protocol: +# read public key +# if you don't like it, read another, repeat +# write challenge +# read response +# all numbers are hexadecimal biginits parsable with strtomp. +# + +include "sys.m"; + sys: Sys; + Rread, Rwrite: import Sys; + +include "draw.m"; + +include "keyring.m"; + kr: Keyring; + IPint, RSAsk, RSApk: import kr; + +include "../authio.m"; + authio: Authio; + Aattr, Aval, Aquery: import Authio; + Attr, IO, Key, Authinfo: import authio; + eqbytes, memrandom: import authio; + lookattrval: import authio; + + +init(f: Authio): string +{ + authio = f; + sys = load Sys Sys->PATH; + kr = load Keyring Keyring->PATH; +# base16 = load Encoding Encoding->BASE16PATH; + return nil; +} + +interaction(attrs: list of ref Attr, io: ref IO): string +{ + role := lookattrval(attrs, "role"); + if(role == nil) + return "role not specified"; + if(role != "client") + return "only client role supported"; + sk: ref RSAsk; + keys: list of ref Key; + err: string; + for(;;){ + waitread(io); + (keys, err) = io.findkeys(attrs, ""); + if(keys != nil) + break; + io.error(err); + } + for(; keys != nil; keys = tl keys){ + (sk, err) = keytorsa(hd keys); + if(sk != nil){ + r := array of byte sk.pk.n.iptostr(16); + while(!io.reply2read(r, len r)) + waitread(io); + data := io.rdwr(); + if(data != nil){ + chal := IPint.strtoip(string data, 16); + if(chal == nil){ + io.error("invalid challenge value"); + continue; + } + m := sk.decrypt(chal); + b := array of byte m.iptostr(16); + io.write(b, len b); + io.done(nil); + return nil; + } + } + } + for(;;){ + io.error("no key matches "+authio->attrtext(attrs)); + waitread(io); + } +} + +waitread(io: ref IO) +{ + while(io.rdwr() != nil) + io.error("no current key"); +} + +Badkey: exception(string); + +ipint(attrs: list of ref Attr, name: string): ref IPint raises Badkey +{ + s := lookattrval(attrs, name); + if(s == nil) + raise Badkey("missing attribute "+name); + m := IPint.strtoip(s, 16); + if(m == nil) + raise Badkey("invalid value for "+name); + return m; +} + +keytorsa(k: ref Key): (ref RSAsk, string) +{ + sk := ref RSAsk; + sk.pk = ref RSApk; + { + sk.pk.ek = ipint(k.attrs, "ek"); + sk.pk.n = ipint(k.attrs, "n"); + sk.dk = ipint(k.secrets, "!dk"); + sk.p = ipint(k.secrets, "!p"); + sk.q = ipint(k.secrets, "!q"); + sk.kp = ipint(k.secrets, "!kp"); + sk.kq = ipint(k.secrets, "!kq"); + sk.c2 = ipint(k.secrets, "!c2"); + }exception e{ + Badkey => + return (nil, "rsa key "+e); + } + return (sk, nil); +} + +keycheck(k: ref Authio->Key): string +{ + return keytorsa(k).t1; +} diff --git a/appl/cmd/auth/factotum/rpc.b b/appl/cmd/auth/factotum/rpc.b index 220980a8..5d76c2be 100644 --- a/appl/cmd/auth/factotum/rpc.b +++ b/appl/cmd/auth/factotum/rpc.b @@ -58,7 +58,7 @@ rpc(f: ref Sys->FD, addr: string) b := array of byte addr; if(sys->write(f, b, len b) > 0){ sys->seek(f, big 0, Sys->SEEKSTART); - buf := array[256] of byte; + buf := array[4096+3] of byte; if((n := sys->read(f, buf, len buf)) > 0) sys->print("%s\n", string buf[0:n]); if(n >= 0) diff --git a/appl/cmd/diff.b b/appl/cmd/diff.b index 4ef3ab32..3847e9e9 100644 --- a/appl/cmd/diff.b +++ b/appl/cmd/diff.b @@ -203,7 +203,6 @@ init(nil: ref Draw->Context, args: list of string) sort(a : array of line, n : int) { w : line; - j1:=0; m := 0; for (i := 1; i <= n; i *= 2) m = 2*i - 1; @@ -791,12 +790,9 @@ statfile(file : string) : (string,Sys->Dir) { (ret,sb):=sys->stat(file); if (ret==-1) { - if (file == "-") { - (ret,sb)= sys->fstat(sys->fildes(0)); - if (ret == -1) { - error(sys->sprint("cannot stat %s: %r", file)); - return (nil,sb); - } + if (file != "-" || sys->fstat(sys->fildes(0)).t0 == -1){ + error(sys->sprint("cannot stat %s: %r", file)); + return (nil,sb); } (file, sb) = mktmpfile(sys->fildes(0)); } diff --git a/appl/lib/factotum.b b/appl/lib/factotum.b index a2cec879..0b3ff1a8 100644 --- a/appl/lib/factotum.b +++ b/appl/lib/factotum.b @@ -306,3 +306,123 @@ getuserpasswd(keyspec: string): (string, string) } return (hd flds, hd tl flds); } + +parseattrs(s: string): list of ref Attr +{ + str := load String String->PATH; + fld := str->unquoted(s); + rfld := fld; + for(fld = nil; rfld != nil; rfld = tl rfld) + fld = (hd rfld) :: fld; + attrs: list of ref Attr; + for(; fld != nil; fld = tl fld){ + n := hd fld; + a := ""; + tag := Aattr; + for(i:=0; i<len n; i++) + if(n[i] == '='){ + a = n[i+1:]; + n = n[0:i]; + tag = Aval; + } + if(len n == 0) + continue; + if(tag == Aattr && len n > 1 && n[len n-1] == '?'){ + tag = Aquery; + n = n[0:len n-1]; + } + attrs = ref Attr(tag, n, a) :: attrs; + } + # TO DO: eliminate answered queries + return attrs; +} + +Attr.text(a: self ref Attr): string +{ + case a.tag { + Aattr => + return a.name; + Aval => + return sys->sprint("%q=%q", a.name, a.val); + Aquery => + return sys->sprint("%q?", a.name); + * => + return "??"; + } +} + +attrtext(attrs: list of ref Attr): string +{ + s := ""; + for(; attrs != nil; attrs = tl attrs){ + if(s != nil) + s[len s] = ' '; + s += (hd attrs).text(); + } + return s; +} + +findattr(attrs: list of ref Attr, n: string): ref Attr +{ + for(; attrs != nil; attrs = tl attrs) + if((a := hd attrs).tag != Aquery && a.name == n) + return a; + return nil; +} + +findattrval(attrs: list of ref Attr, n: string): string +{ + if((a := findattr(attrs, n)) != nil) + return a.val; + return nil; +} + +delattr(l: list of ref Attr, n: string): list of ref Attr +{ + rl: list of ref Attr; + for(; l != nil; l = tl l) + if((hd l).name != n) + rl = hd l :: rl; + return rev(rl); +} + +copyattrs(l: list of ref Attr): list of ref Attr +{ + rl: list of ref Attr; + for(; l != nil; l = tl l) + rl = hd l :: rl; + return rev(rl); +} + +takeattrs(l: list of ref Attr, names: list of string): list of ref Attr +{ + rl: list of ref Attr; + for(; l != nil; l = tl l){ + n := (hd l).name; + for(nl := names; nl != nil; nl = tl nl) + if((hd nl) == n){ + rl = hd l :: rl; + break; + } + } + return rev(rl); +} + +publicattrs(l: list of ref Attr): list of ref Attr +{ + rl: list of ref Attr; + for(; l != nil; l = tl l){ + a := hd l; + if(a.tag != Aquery || a.val == nil) + rl = a :: rl; + } + return rev(rl); +} + +rev[T](l: list of T): list of T +{ + rl: list of T; + for(; l != nil; l = tl l) + rl = hd l :: rl; + return rl; +} diff --git a/appl/lib/spki/spki.b b/appl/lib/spki/spki.b index 18a2d68a..615aa48e 100644 --- a/appl/lib/spki/spki.b +++ b/appl/lib/spki/spki.b @@ -629,7 +629,7 @@ signbytes(data: array of byte, sigalg: string, key: ref Key): (ref Signature, st l: list of (string, array of byte); for(; vals != nil; vals = tl vals){ (n, v) := hd vals; - l = (f2s(n), v) :: l; + l = (f2s("rsa", n), v) :: l; } sig.sig = revt(l); return (sig, nil); @@ -1095,7 +1095,7 @@ Key.sexp(k: self ref Key): ref Sexp for(; els != nil; els = tl els){ (n, v) := hd els; a := pre0(v.iptobebytes()); - rl = ref Sexp.List(ref Sexp.String(f2s(n),nil) :: ref Sexp.Binary(a,nil) :: nil) :: rl; + rl = ref Sexp.List(ref Sexp.String(f2s("rsa", n),nil) :: ref Sexp.Binary(a,nil) :: nil) :: rl; } return ref Sexp.List(ref Sexp.String(sort, nil) :: ref Sexp.List(ref Sexp.String(k.sigalg(),nil) :: rev(rl)) :: nil); @@ -2093,9 +2093,12 @@ Keyrep.pk(pk: ref Keyring->PK): ref Keyrep.PK "rsa" => return ref Keyrep.PK(hd flds, hd tl flds, keyextract(tl tl flds, list of {("ek",1), ("n",0)})); - "elgamal" or "dsa" => + "elgamal" => return ref Keyrep.PK(hd flds, hd tl flds, keyextract(tl tl flds, list of {("p",0), ("alpha",1), ("key",2)})); + "dsa" => + return ref Keyrep.PK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",2), ("q",1), ("key",3)})); * => return nil; } @@ -2112,9 +2115,12 @@ Keyrep.sk(pk: ref Keyring->SK): ref Keyrep.SK "rsa" => return ref Keyrep.SK(hd flds, hd tl flds, keyextract(tl tl flds,list of {("ek",1), ("n",0), ("!dk",2), ("!q",4), ("!p",3), ("!kq",6), ("!kp",5), ("!c2",7)})); # see comment elsewhere about p, q - "elgamal" or "dsa" => + "elgamal" => return ref Keyrep.SK(hd flds, hd tl flds, keyextract(tl tl flds, list of {("p",0), ("alpha",1), ("key",2), ("!secret",3)})); + "dsa" => + return ref Keyrep.SK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",2), ("q",1), ("key",3), ("!secret",4)})); * => return nil; } @@ -2122,7 +2128,7 @@ Keyrep.sk(pk: ref Keyring->SK): ref Keyrep.SK Keyrep.get(k: self ref Keyrep, n: string): ref IPint { - n1 := f2s(n); + n1 := f2s("rsa", n); for(el := k.els; el != nil; el = tl el) if((hd el).t0 == n || (hd el).t0 == n1) return (hd el).t1; @@ -2191,21 +2197,31 @@ s2f(s: string): string } } -f2s(s: string): string +f2s(alg: string, s: string): string { - case s { - "ek" => return "e"; - "!p" => return "q"; # see above - "!q" => return "p"; - "!dk" => return "d"; - "!kp" => return "b"; - "!kq" => return "a"; - "!c2" => return "c"; + case alg { + "rsa" => + case s { + "ek" => return "e"; + "!p" => return "q"; # see above + "!q" => return "p"; + "!dk" => return "d"; + "!kp" => return "b"; + "!kq" => return "a"; + "!c2" => return "c"; + } + "dsa" => + case s { + "p" or "q" => return s; + "alpha" => return "g"; + "key" => return "y"; + } * => - if(s != nil && s[0] == '!') - return s[1:]; - return s; + ; } + if(s != nil && s[0] == '!') + return s[1:]; + return s; } Keyrep.eq(k1: self ref Keyrep, k2: ref Keyrep): int diff --git a/dis/auth/factotum.dis b/dis/auth/factotum.dis Binary files differindex 47cedcca..fb04eca7 100644 --- a/dis/auth/factotum.dis +++ b/dis/auth/factotum.dis diff --git a/dis/auth/proto/p9any.dis b/dis/auth/proto/p9any.dis Binary files differindex 4a3057c8..4371874a 100644 --- a/dis/auth/proto/p9any.dis +++ b/dis/auth/proto/p9any.dis diff --git a/dis/auth/proto/pass.dis b/dis/auth/proto/pass.dis Binary files differindex 6bd14645..7ee7d36c 100644 --- a/dis/auth/proto/pass.dis +++ b/dis/auth/proto/pass.dis diff --git a/dis/auth/proto/rsa.dis b/dis/auth/proto/rsa.dis Binary files differnew file mode 100644 index 00000000..bfddb804 --- /dev/null +++ b/dis/auth/proto/rsa.dis diff --git a/dis/auth/rpc.dis b/dis/auth/rpc.dis Binary files differindex b929d5f8..31dd709e 100644 --- a/dis/auth/rpc.dis +++ b/dis/auth/rpc.dis diff --git a/dis/diff.dis b/dis/diff.dis Binary files differindex 311f7e4e..5f8f5c3a 100644 --- a/dis/diff.dis +++ b/dis/diff.dis diff --git a/dis/lib/factotum.dis b/dis/lib/factotum.dis Binary files differindex 0fb35884..27722fc8 100644 --- a/dis/lib/factotum.dis +++ b/dis/lib/factotum.dis diff --git a/dis/lib/spki/spki.dis b/dis/lib/spki/spki.dis Binary files differindex 07f9f4a8..d6b89a34 100644 --- a/dis/lib/spki/spki.dis +++ b/dis/lib/spki/spki.dis diff --git a/emu/Nt/devfs.c b/emu/Nt/devfs.c index 43517829..f5185799 100644 --- a/emu/Nt/devfs.c +++ b/emu/Nt/devfs.c @@ -1867,8 +1867,10 @@ secsdstat(SECURITY_DESCRIPTOR *sd, Stat *st, Rune *srv) gsid = osid; owner = sidtouser(srv, osid); + if(owner == nil) + return 0; group = sidtouser(srv, gsid); - if(owner == 0 || group == 0) + if(group == nil) return 0; /* no acl means full access */ @@ -2065,7 +2067,7 @@ sidtouser(Rune *srv, SID *s) ndname = sizeof(dname); if(!LookupAccountSidW(srv, s, aname, &naname, dname, &ndname, &type)) - return nil; + return mkuser(s, SidTypeUnknown, L"unknown", L"unknown") ; /* was return nil; */ return mkuser(s, type, aname, dname); } diff --git a/include/version.h b/include/version.h index d5b076bf..80a4bcbd 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define VERSION "Fourth Edition (20080111)" +#define VERSION "Fourth Edition (20080116)" diff --git a/libinterp/ipint.c b/libinterp/ipint.c index b7cb8af2..d81fccf4 100644 --- a/libinterp/ipint.c +++ b/libinterp/ipint.c @@ -46,6 +46,44 @@ freeIPint(Heap *h, int swept) } void +IPint_iptob64z(void *fp) +{ + F_IPint_iptob64 *f; + BigInt b; + char buf[MaxBigBytes]; /* TO DO: should allocate these */ + uchar *p; + int n, o; + + f = fp; + destroy(*f->ret); + *f->ret = H; + + if(f->i == H) + error(exNilref); + + b = MP(f->i); + n = (b->top+1)*Dbytes; + p = malloc(n+1); + if(p == nil) + error(exHeap); + n = mptobe(b, p+1, n, nil); + if(n < 0){ + free(p); + return; + } + p[0] = 0; + if(n != 0 && (p[1]&0x80)){ + /* force leading 0 byte for compatibility with older representation */ + o = 0; + n++; + }else + o = 1; + enc64(buf, sizeof(buf), p+o, n); + retstr(buf, f->ret); + free(p); +} + +void IPint_iptob64(void *fp) { F_IPint_iptob64 *f; @@ -112,21 +150,33 @@ IPint_iptostr(void *fp) retstr(buf, f->ret); } +static Keyring_IPint* +strtoipint(String *s, int base) +{ + char *p, *q; + BigInt b; + + p = string2c(s); + b = strtomp(p, &q, base, nil); + if(b == nil) + return H; + if(q == p || *q != 0){ + mpfree(b); + return H; + } + return newIPint(b); +} + void IPint_b64toip(void *fp) { F_IPint_b64toip *f; - BigInt b; f = fp; destroy(*f->ret); *f->ret = H; - if(f->str == H) - error(exNilref); - - b = strtomp(string2c(f->str), nil, 64, nil); - *f->ret = newIPint(b); + *f->ret = strtoipint(f->str, 64); } void @@ -167,17 +217,12 @@ void IPint_strtoip(void *fp) { F_IPint_strtoip *f; - BigInt b; f = fp; destroy(*f->ret); *f->ret = H; - if(f->str == H) - return; - - b = strtomp(string2c(f->str), nil, f->base, nil); - *f->ret = newIPint(b); + *f->ret = strtoipint(f->str, f->base); } /* create a random integer */ @@ -384,6 +429,27 @@ IPint_div(void *fp) f->ret->t1 = newIPint(rem); } void +IPint_mod(void *fp) +{ + F_IPint_mod *f; + BigInt i1, i2, ret; + + f = fp; + destroy(*f->ret); + *f->ret = H; + + if(f->i1 == H || f->i2 == H) + error(exNilref); + + i1 = ((IPint*)f->i1)->b; + i2 = ((IPint*)f->i2)->b; + ret = mpnew(0); + if(ret != nil) + mpmod(i1, i2, ret); + + *f->ret = newIPint(ret); +} +void IPint_neg(void *fp) { F_IPint_neg *f; @@ -669,6 +735,7 @@ if(0)print("1"); two = itomp(2, nil); if(mpcmp(diff, two) < 0){ + mpfree(one); mpfree(two); itomp(0, result); return; diff --git a/libinterp/keyring.c b/libinterp/keyring.c index 20ce610c..57a2095d 100644 --- a/libinterp/keyring.c +++ b/libinterp/keyring.c @@ -26,8 +26,18 @@ Type *TAuthinfo; Type *TAESstate; Type *TDESstate; Type *TIDEAstate; +Type *TBFstate; Type *TRC4state; Type *TIPint; +Type *TDSAsk; +Type *TDSApk; +Type *TDSAsig; +Type *TEGsk; +Type *TEGpk; +Type *TEGsig; +Type *TRSAsk; +Type *TRSApk; +Type *TRSAsig; enum { Maxmsg= 4096 @@ -43,7 +53,17 @@ uchar Authinfomap[] = Keyring_Authinfo_map; uchar AESstatemap[] = Keyring_AESstate_map; uchar DESstatemap[] = Keyring_DESstate_map; uchar IDEAstatemap[] = Keyring_IDEAstate_map; +uchar BFstatemap[] = Keyring_BFstate_map; uchar RC4statemap[] = Keyring_RC4state_map; +uchar DSAskmap[] = Keyring_DSAsk_map; +uchar DSApkmap[] = Keyring_DSApk_map; +uchar DSAsigmap[] = Keyring_DSAsig_map; +uchar EGskmap[] = Keyring_EGsk_map; +uchar EGpkmap[] = Keyring_EGpk_map; +uchar EGsigmap[] = Keyring_EGsig_map; +uchar RSAskmap[] = Keyring_RSAsk_map; +uchar RSApkmap[] = Keyring_RSApk_map; +uchar RSAsigmap[] = Keyring_RSAsig_map; PK* checkPK(Keyring_PK *k); @@ -57,6 +77,15 @@ static char exBadSK[] = "bad secret key"; static char exBadPK[] = "bad public key"; static char exBadCert[] = "bad certificate"; +typedef struct XBFstate XBFstate; + +/* BF state */ +struct XBFstate +{ + Keyring_BFstate x; + BFstate state; +}; + /* * Infinite (actually kind of big) precision integers */ @@ -114,6 +143,38 @@ big64conv(Fmt *f) return n; } +static BigInt +checkIPint(Keyring_IPint *v) +{ + IPint *ip; + + ip = (IPint*)v; + if(ip == H || ip == nil) + error(exNilref); + if(D2H(ip)->t != TIPint) + error(exType); + return ip->b; +} + +static void* +newthing(Type *t, int add) +{ + Heap *h; + + h = heap(t); + if(add) + ptradd(h); + return H2D(void*, h); +} + +static Keyring_IPint* +ipcopymp(BigInt b) +{ + if(b == nil) + return H; + return newIPint(mpcopy(b)); +} + /* convert a base64 string to a big */ BigInt base64tobig(char *str, char **strp) @@ -949,17 +1010,6 @@ Keyring_sign(void *fp) mpfree(b); } -static BigInt -checkIPint(Keyring_IPint *v) -{ - IPint *ip; - - ip = (IPint*)v; - if(ip == H || ip == nil || D2H(ip)->t != TIPint) - error(exType); - return ip->b; -} - void Keyring_signm(void *fp) { @@ -2003,9 +2053,20 @@ keyringmodinit(void) sizeof(DESstatemap)); TIDEAstate = dtype(freeheap, sizeof(XIDEAstate), IDEAstatemap, sizeof(IDEAstatemap)); + TBFstate = dtype(freeheap, sizeof(XBFstate), BFstatemap, + sizeof(BFstatemap)); TRC4state = dtype(freeheap, sizeof(XRC4state), RC4statemap, sizeof(RC4statemap)); TAuthinfo = dtype(freeheap, sizeof(Keyring_Authinfo), Authinfomap, sizeof(Authinfomap)); + TDSAsk = dtype(freeheap, sizeof(Keyring_DSAsk), DSAskmap, sizeof(DSAskmap)); + TDSApk = dtype(freeheap, sizeof(Keyring_DSApk), DSApkmap, sizeof(DSApkmap)); + TDSAsig = dtype(freeheap, sizeof(Keyring_DSAsig), DSAsigmap, sizeof(DSAsigmap)); + TEGsk = dtype(freeheap, sizeof(Keyring_EGsk), EGskmap, sizeof(EGskmap)); + TEGpk = dtype(freeheap, sizeof(Keyring_EGpk), EGpkmap, sizeof(EGpkmap)); + TEGsig = dtype(freeheap, sizeof(Keyring_EGsig), EGsigmap, sizeof(EGsigmap)); + TRSAsk = dtype(freeheap, sizeof(Keyring_RSAsk), RSAskmap, sizeof(RSAskmap)); + TRSApk = dtype(freeheap, sizeof(Keyring_RSApk), RSApkmap, sizeof(RSApkmap)); + TRSAsig = dtype(freeheap, sizeof(Keyring_RSAsig), RSAsigmap, sizeof(RSAsigmap)); if((sav = elgamalinit()) != nil) algs[nalg++] = sav; @@ -2201,9 +2262,9 @@ Keyring_dessetup(void *fp) destroy(*f->ret); *f->ret = H; - if(f->key == (Array*)H) + if(f->key == H) return; - if(f->ivec == (Array*)H) + if(f->ivec == H) ivec = 0; else ivec = f->ivec->data; @@ -2231,7 +2292,7 @@ Keyring_desecb(void *fp) if(f->state == (Keyring_DESstate*)H) return; - if(f->buf == (Array*)H) + if(f->buf == H) return; if(f->buf->len < f->n) f->n = f->buf->len; @@ -2255,9 +2316,9 @@ Keyring_descbc(void *fp) f = fp; - if(f->state == (Keyring_DESstate*)H) + if(f->state == H) return; - if(f->buf == (Array*)H) + if(f->buf == H) return; if(f->buf->len < f->n) f->n = f->buf->len; @@ -2450,6 +2511,63 @@ Keyring_aescbc(void *fp) } void +Keyring_blowfishsetup(void *fp) +{ + F_Keyring_blowfishsetup *f; + Heap *h; + XBFstate *is; + uchar *ivec; + + f = fp; + destroy(*f->ret); + *f->ret = H; + + if(f->key == (Array*)H) + return; + if(f->ivec == (Array*)H) + ivec = nil; + else + ivec = f->ivec->data; + + if(f->key->len <= 0) + return; + if(ivec && f->ivec->len != BFbsize) + return; + + h = heap(TBFstate); + is = H2D(XBFstate*, h); + + setupBFstate(&is->state, f->key->data, f->key->len, ivec); + + *f->ret = (Keyring_BFstate*)is; +} + +void +Keyring_blowfishcbc(void *fp) +{ + F_Keyring_blowfishcbc *f; + XBFstate *is; + uchar *p; + + f = fp; + + if(f->state == (Keyring_BFstate*)H) + return; + if(f->buf == (Array*)H) + return; + if(f->buf->len < f->n) + f->n = f->buf->len; + + is = (XBFstate*)f->state; + p = f->buf->data; + + if(f->direction == 0) + bfCBCencrypt(p, f->n, &is->state); + else + bfCBCdecrypt(p, f->n, &is->state); +} + +void Keyring_rc4setup(void *fp) { F_Keyring_rc4setup *f; @@ -2515,3 +2633,397 @@ Keyring_rc4back(void *fp) is = (XRC4state*)f->state; rc4back(&is->state, f->n); } + +/* + * public/secret keys, signing and verifying + */ + +static void +dsapk2pub(DSApub* p, Keyring_DSApk* pk) +{ + if(pk == H) + error(exNilref); + p->p = checkIPint(pk->p); + p->q = checkIPint(pk->q); + p->alpha = checkIPint(pk->alpha); + p->key = checkIPint(pk->key); +} + +static void +dsask2priv(DSApriv* p, Keyring_DSAsk* sk) +{ + if(sk == H || sk->pk == H) + error(exNilref); + dsapk2pub(&p->pub, sk->pk); + p->secret = checkIPint(sk->secret); +} + +static void +dsapriv2sk(Keyring_DSAsk* sk, DSApriv* p) +{ + Keyring_DSApk* pk; + + pk = sk->pk; + pk->p = ipcopymp(p->pub.p); + pk->q = ipcopymp(p->pub.q); + pk->alpha = ipcopymp(p->pub.alpha); + pk->key = ipcopymp(p->pub.key); + sk->secret = ipcopymp(p->secret); +} + +void +DSAsk_gen(void *fp) +{ + F_DSAsk_gen *f; + Keyring_DSAsk *sk; + DSApriv *p; + DSApub pub, *oldpk; + void *v; + + f = fp; + v = *f->ret; + sk = newthing(TDSAsk, 0); + sk->pk = newthing(TDSApk, 0); + *f->ret = sk; + destroy(v); + oldpk = nil; + if(f->oldpk != H){ + dsapk2pub(&pub, f->oldpk); + oldpk = &pub; + } + release(); + p = dsagen(oldpk); + acquire(); + dsapriv2sk(sk, p); + dsaprivfree(p); +} + +void +DSAsk_sign(void *fp) +{ + F_DSAsk_sign *f; + Keyring_DSAsig *sig; + DSApriv p; + BigInt m; + DSAsig *s; + void *v; + + f = fp; + v = *f->ret; + sig = newthing(TDSAsig, 0); + *f->ret = sig; + destroy(v); + + dsask2priv(&p, f->k); + m = checkIPint(f->m); + release(); + s = dsasign(&p, m); + acquire(); + sig->r = ipcopymp(s->r); + sig->s = ipcopymp(s->s); + dsasigfree(s); +} + +void +DSApk_verify(void *fp) +{ + F_DSApk_verify *f; + DSApub p; + DSAsig sig; + BigInt m; + + f = fp; + *f->ret = 0; + if(f->m == H || f->sig == H) + return; + dsapk2pub(&p, f->k); + sig.r = checkIPint(f->sig->r); + sig.s = checkIPint(f->sig->s); + m = checkIPint(f->m); + release(); + *f->ret = dsaverify(&p, &sig, m) == 0; + acquire(); +} + +static void +egpk2pub(EGpub* p, Keyring_EGpk* pk) +{ + if(pk == H) + error(exNilref); + p->p = checkIPint(pk->p); + p->alpha = checkIPint(pk->alpha); + p->key = checkIPint(pk->key); +} + +static void +egsk2priv(EGpriv* p, Keyring_EGsk* sk) +{ + if(sk == H || sk->pk == H) + error(exNilref); + egpk2pub(&p->pub, sk->pk); + p->secret = checkIPint(sk->secret); +} + +static void +egpriv2sk(Keyring_EGsk* sk, EGpriv* p) +{ + Keyring_EGpk* pk; + + pk = sk->pk; + pk->p = ipcopymp(p->pub.p); + pk->alpha = ipcopymp(p->pub.alpha); + pk->key = ipcopymp(p->pub.key); + sk->secret = ipcopymp(p->secret); +} + +void +EGsk_gen(void *fp) +{ + F_EGsk_gen *f; + Keyring_EGsk *sk; + EGpriv *p; + void *v; + + f = fp; + v = *f->ret; + sk = newthing(TEGsk, 0); + sk->pk = newthing(TEGpk, 0); + *f->ret = sk; + destroy(v); + release(); + for(;;){ + p = eggen(f->nlen, f->nrep); + if(mpsignif(p->pub.p) == f->nlen) + break; + egprivfree(p); + } + acquire(); + egpriv2sk(sk, p); + egprivfree(p); +} + +void +EGsk_sign(void *fp) +{ + F_EGsk_sign *f; + Keyring_EGsig *sig; + EGpriv p; + BigInt m; + EGsig *s; + void *v; + + f = fp; + v = *f->ret; + sig = newthing(TEGsig, 0); + *f->ret = sig; + destroy(v); + + egsk2priv(&p, f->k); + m = checkIPint(f->m); + release(); + s = egsign(&p, m); + acquire(); + sig->r = ipcopymp(s->r); + sig->s = ipcopymp(s->s); + egsigfree(s); +} + +void +EGpk_verify(void *fp) +{ + F_EGpk_verify *f; + EGpub p; + EGsig sig; + BigInt m; + + f = fp; + *f->ret = 0; + if(f->m == H || f->sig == H) + return; + egpk2pub(&p, f->k); + sig.r = checkIPint(f->sig->r); + sig.s = checkIPint(f->sig->s); + m = checkIPint(f->m); + release(); + *f->ret = egverify(&p, &sig, m) == 0; + acquire(); +} + +static void +rsapk2pub(RSApub* p, Keyring_RSApk* pk) +{ + if(pk == H) + error(exNilref); + memset(p, 0, sizeof(*p)); + p->n = checkIPint(pk->n); + p->ek = checkIPint(pk->ek); +} + +static void +rsask2priv(RSApriv* p, Keyring_RSAsk* sk) +{ + if(sk == H || sk->pk == H) + error(exNilref); + rsapk2pub(&p->pub, sk->pk); + p->dk = checkIPint(sk->dk); + p->p = checkIPint(sk->p); + p->q = checkIPint(sk->q); + p->kp = checkIPint(sk->kp); + p->kq = checkIPint(sk->kq); + p->c2 = checkIPint(sk->c2); +} + +static void +rsapriv2sk(Keyring_RSAsk* sk, RSApriv* p) +{ + Keyring_RSApk* pk; + + pk = sk->pk; + pk->n = ipcopymp(p->pub.n); + pk->ek = ipcopymp(p->pub.ek); + sk->dk = ipcopymp(p->dk); + sk->p = ipcopymp(p->p); + sk->q = ipcopymp(p->q); + sk->kp = ipcopymp(p->kp); + sk->kq = ipcopymp(p->kq); + sk->c2 = ipcopymp(p->c2); +} + +void +RSApk_encrypt(void *fp) +{ + F_RSApk_encrypt *f; + RSApub p; + BigInt m, o; + void *v; + + f = fp; + v = *f->ret; + *f->ret = H; + destroy(v); + + rsapk2pub(&p, f->k); + m = checkIPint(f->m); + release(); + o = rsaencrypt(&p, m, nil); + acquire(); + *f->ret = newIPint(o); +} + +void +RSAsk_gen(void *fp) +{ + F_RSAsk_gen *f; + Keyring_RSAsk *sk; + RSApriv *p; + void *v; + + f = fp; + v = *f->ret; + sk = newthing(TRSAsk, 0); + sk->pk = newthing(TRSApk, 0); + *f->ret = sk; + destroy(v); + release(); + for(;;){ + p = rsagen(f->nlen, f->elen, f->nrep); + if(mpsignif(p->pub.n) == f->nlen) + break; + rsaprivfree(p); + } + acquire(); + rsapriv2sk(sk, p); + rsaprivfree(p); +} + +void +RSAsk_fill(void *fp) +{ + F_RSAsk_fill *f; + Keyring_RSAsk *sk; + RSApriv *p; + void *v; + + f = fp; + v = *f->ret; + sk = newthing(TRSAsk, 0); + sk->pk = newthing(TRSApk, 0); + *f->ret = sk; + destroy(v); + release(); + p = rsafill(checkIPint(f->n), checkIPint(f->e), checkIPint(f->d), + checkIPint(f->p), checkIPint(f->q)); + acquire(); + if(p == nil) { + *f->ret = H; + destroy(sk); + }else{ + rsapriv2sk(sk, p); + rsaprivfree(p); + } +} + +void +RSAsk_decrypt(void *fp) +{ + F_RSAsk_decrypt *f; + RSApriv p; + BigInt m, o; + void *v; + + f = fp; + v = *f->ret; + *f->ret = H; + destroy(v); + + rsask2priv(&p, f->k); + m = checkIPint(f->m); + release(); + o = rsadecrypt(&p, m, nil); + acquire(); + *f->ret = newIPint(o); +} + +void +RSAsk_sign(void *fp) +{ + F_RSAsk_sign *f; + Keyring_RSAsig *sig; + RSApriv p; + BigInt m, s; + void *v; + + f = fp; + v = *f->ret; + sig = newthing(TRSAsig, 0); + *f->ret = sig; + destroy(v); + + rsask2priv(&p, f->k); + m = checkIPint(f->m); + release(); + s = rsadecrypt(&p, m, nil); + acquire(); + sig->n = newIPint(s); +} + +void +RSApk_verify(void *fp) +{ + F_RSApk_verify *f; + RSApub p; + BigInt sig, m, t; + + f = fp; + *f->ret = 0; + if(f->m == H || f->sig == H) + return; + rsapk2pub(&p, f->k); + sig = checkIPint(f->sig->n); + m = checkIPint(f->m); + release(); + t = rsaencrypt(&p, sig, nil); + *f->ret = mpcmp(t, m) == 0; + mpfree(t); + acquire(); +} diff --git a/libinterp/keyring.h b/libinterp/keyring.h index 0bea5171..0aa4185a 100644 --- a/libinterp/keyring.h +++ b/libinterp/keyring.h @@ -8,19 +8,27 @@ Runtab Keyringmodtab[]={ "IPint.b64toip",0xa803ee03,IPint_b64toip,40,2,{0x0,0x80,}, "IPint.bebytestoip",0x6fa90725,IPint_bebytestoip,40,2,{0x0,0x80,}, "IPint.bits",0xeb4c9bad,IPint_bits,40,2,{0x0,0x80,}, + "blowfishcbc",0xac616ba,Keyring_blowfishcbc,48,2,{0x0,0xc0,}, + "blowfishsetup",0x44452583,Keyring_blowfishsetup,40,2,{0x0,0xc0,}, "IPint.bytestoip",0x6fa90725,IPint_bytestoip,40,2,{0x0,0x80,}, "certtoattr",0xbc65254a,Keyring_certtoattr,40,2,{0x0,0x80,}, "certtostr",0xbc65254a,Keyring_certtostr,40,2,{0x0,0x80,}, "IPint.cmp",0x79774f9e,IPint_cmp,40,2,{0x0,0xc0,}, "IPint.copy",0x491fbd11,IPint_copy,40,2,{0x0,0x80,}, "DigestState.copy",0x491fbd11,DigestState_copy,40,2,{0x0,0x80,}, + "RSAsk.decrypt",0xf3b51b95,RSAsk_decrypt,40,2,{0x0,0xc0,}, "descbc",0xac616ba,Keyring_descbc,48,2,{0x0,0xc0,}, "desecb",0xac616ba,Keyring_desecb,48,2,{0x0,0xc0,}, "dessetup",0x44452583,Keyring_dessetup,40,2,{0x0,0xc0,}, "dhparams",0x6abb2418,Keyring_dhparams,40,0,{0}, "IPint.div",0x4672bf61,IPint_div,40,2,{0x0,0xc0,}, + "RSApk.encrypt",0xdc0ec366,RSApk_encrypt,40,2,{0x0,0xc0,}, "IPint.eq",0x79774f9e,IPint_eq,40,2,{0x0,0xc0,}, "IPint.expmod",0xe6105024,IPint_expmod,48,2,{0x0,0xe0,}, + "RSAsk.fill",0x2ab0d50a,RSAsk_fill,56,2,{0x0,0xf8,}, + "RSAsk.gen",0xc197fd0,RSAsk_gen,48,0,{0}, + "DSAsk.gen",0x46f0eb94,DSAsk_gen,40,2,{0x0,0x80,}, + "EGsk.gen",0x4a59c528,EGsk_gen,40,0,{0}, "genSK",0xadd8cbd9,Keyring_genSK,48,2,{0x0,0xc0,}, "genSKfromPK",0x5416d1ee,Keyring_genSKfromPK,40,2,{0x0,0xc0,}, "getbytearray",0x4e02ce80,Keyring_getbytearray,40,2,{0x0,0x80,}, @@ -34,12 +42,14 @@ Runtab Keyringmodtab[]={ "IPint.inttoip",0x95dc8b6d,IPint_inttoip,40,0,{0}, "IPint.invert",0xa47c1b24,IPint_invert,40,2,{0x0,0xc0,}, "IPint.iptob64",0xfab4eb8a,IPint_iptob64,40,2,{0x0,0x80,}, + "IPint.iptob64z",0xfab4eb8a,IPint_iptob64z,40,2,{0x0,0x80,}, "IPint.iptobebytes",0xc8e5162d,IPint_iptobebytes,40,2,{0x0,0x80,}, "IPint.iptobytes",0xc8e5162d,IPint_iptobytes,40,2,{0x0,0x80,}, "IPint.iptoint",0xeb4c9bad,IPint_iptoint,40,2,{0x0,0x80,}, "IPint.iptostr",0xf9fdc03d,IPint_iptostr,40,2,{0x0,0x80,}, "md4",0x7656377,Keyring_md4,48,2,{0x0,0xb0,}, "md5",0x7656377,Keyring_md5,48,2,{0x0,0xb0,}, + "IPint.mod",0xa47c1b24,IPint_mod,40,2,{0x0,0xc0,}, "IPint.mul",0xa47c1b24,IPint_mul,40,2,{0x0,0xc0,}, "IPint.neg",0x491fbd11,IPint_neg,40,2,{0x0,0x80,}, "IPint.not",0x491fbd11,IPint_not,40,2,{0x0,0x80,}, @@ -61,6 +71,9 @@ Runtab Keyringmodtab[]={ "IPint.shl",0xc7b0bc01,IPint_shl,40,2,{0x0,0x80,}, "IPint.shr",0xc7b0bc01,IPint_shr,40,2,{0x0,0x80,}, "sign",0xdacb7a7e,Keyring_sign,48,2,{0x0,0xb0,}, + "RSAsk.sign",0x5dbdc2fe,RSAsk_sign,40,2,{0x0,0xc0,}, + "DSAsk.sign",0x6e51e1b3,DSAsk_sign,40,2,{0x0,0xc0,}, + "EGsk.sign",0xca053e70,EGsk_sign,40,2,{0x0,0xc0,}, "signm",0xba5bd10f,Keyring_signm,48,2,{0x0,0xe0,}, "sktoattr",0xfb4e61ba,Keyring_sktoattr,40,2,{0x0,0x80,}, "sktopk",0x6f74c7c9,Keyring_sktopk,40,2,{0x0,0x80,}, @@ -71,9 +84,12 @@ Runtab Keyringmodtab[]={ "strtosk",0xcc511522,Keyring_strtosk,40,2,{0x0,0x80,}, "IPint.sub",0xa47c1b24,IPint_sub,40,2,{0x0,0xc0,}, "verify",0x8b5b9f76,Keyring_verify,48,2,{0x0,0xe0,}, + "RSApk.verify",0x1857beff,RSApk_verify,48,2,{0x0,0xe0,}, + "DSApk.verify",0xeca448ff,DSApk_verify,48,2,{0x0,0xe0,}, + "EGpk.verify",0xfb1e256c,EGpk_verify,48,2,{0x0,0xe0,}, "verifym",0x8b5b9f76,Keyring_verifym,48,2,{0x0,0xe0,}, "writeauthinfo",0x5ba03002,Keyring_writeauthinfo,40,2,{0x0,0xc0,}, "IPint.xor",0xa47c1b24,IPint_xor,40,2,{0x0,0xc0,}, 0 }; -#define Keyringmodlen 74 +#define Keyringmodlen 90 diff --git a/libinterp/runt.h b/libinterp/runt.h index e9342d08..75144e0c 100644 --- a/libinterp/runt.h +++ b/libinterp/runt.h @@ -31,7 +31,17 @@ typedef struct Keyring_AESstate Keyring_AESstate; typedef struct Keyring_DESstate Keyring_DESstate; typedef struct Keyring_IDEAstate Keyring_IDEAstate; typedef struct Keyring_RC4state Keyring_RC4state; +typedef struct Keyring_BFstate Keyring_BFstate; typedef struct Keyring_Authinfo Keyring_Authinfo; +typedef struct Keyring_RSApk Keyring_RSApk; +typedef struct Keyring_RSAsk Keyring_RSAsk; +typedef struct Keyring_RSAsig Keyring_RSAsig; +typedef struct Keyring_DSApk Keyring_DSApk; +typedef struct Keyring_DSAsk Keyring_DSAsk; +typedef struct Keyring_DSAsig Keyring_DSAsig; +typedef struct Keyring_EGpk Keyring_EGpk; +typedef struct Keyring_EGsk Keyring_EGsk; +typedef struct Keyring_EGsig Keyring_EGsig; typedef struct Loader_Inst Loader_Inst; typedef struct Loader_Typedesc Loader_Typedesc; typedef struct Loader_Link Loader_Link; @@ -337,6 +347,12 @@ struct Keyring_RC4state }; #define Keyring_RC4state_size 4 #define Keyring_RC4state_map {0} +struct Keyring_BFstate +{ + WORD x; +}; +#define Keyring_BFstate_size 4 +#define Keyring_BFstate_map {0} struct Keyring_Authinfo { Keyring_SK* mysk; @@ -348,6 +364,76 @@ struct Keyring_Authinfo }; #define Keyring_Authinfo_size 24 #define Keyring_Authinfo_map {0xfc,} +struct Keyring_RSApk +{ + Keyring_IPint* n; + Keyring_IPint* ek; +}; +#define Keyring_RSApk_size 8 +#define Keyring_RSApk_map {0xc0,} +struct Keyring_RSAsk +{ + Keyring_RSApk* pk; + Keyring_IPint* dk; + Keyring_IPint* p; + Keyring_IPint* q; + Keyring_IPint* kp; + Keyring_IPint* kq; + Keyring_IPint* c2; +}; +#define Keyring_RSAsk_size 28 +#define Keyring_RSAsk_map {0xfe,} +struct Keyring_RSAsig +{ + Keyring_IPint* n; +}; +#define Keyring_RSAsig_size 4 +#define Keyring_RSAsig_map {0x80,} +struct Keyring_DSApk +{ + Keyring_IPint* p; + Keyring_IPint* q; + Keyring_IPint* alpha; + Keyring_IPint* key; +}; +#define Keyring_DSApk_size 16 +#define Keyring_DSApk_map {0xf0,} +struct Keyring_DSAsk +{ + Keyring_DSApk* pk; + Keyring_IPint* secret; +}; +#define Keyring_DSAsk_size 8 +#define Keyring_DSAsk_map {0xc0,} +struct Keyring_DSAsig +{ + Keyring_IPint* r; + Keyring_IPint* s; +}; +#define Keyring_DSAsig_size 8 +#define Keyring_DSAsig_map {0xc0,} +struct Keyring_EGpk +{ + Keyring_IPint* p; + Keyring_IPint* alpha; + Keyring_IPint* key; +}; +#define Keyring_EGpk_size 12 +#define Keyring_EGpk_map {0xe0,} +struct Keyring_EGsk +{ + Keyring_EGpk* pk; + Keyring_IPint* secret; +}; +#define Keyring_EGsk_size 8 +#define Keyring_EGsk_map {0xc0,} +struct Keyring_EGsig +{ + Keyring_IPint* r; + Keyring_IPint* s; +}; +#define Keyring_EGsig_size 8 +#define Keyring_EGsig_map {0xc0,} struct Loader_Inst { BYTE op; @@ -3135,6 +3221,28 @@ struct F_IPint_bits uchar temps[12]; Keyring_IPint* i; }; +void Keyring_blowfishcbc(void*); +typedef struct F_Keyring_blowfishcbc F_Keyring_blowfishcbc; +struct F_Keyring_blowfishcbc +{ + WORD regs[NREG-1]; + WORD noret; + uchar temps[12]; + Keyring_BFstate* state; + Array* buf; + WORD n; + WORD direction; +}; +void Keyring_blowfishsetup(void*); +typedef struct F_Keyring_blowfishsetup F_Keyring_blowfishsetup; +struct F_Keyring_blowfishsetup +{ + WORD regs[NREG-1]; + Keyring_BFstate** ret; + uchar temps[12]; + Array* key; + Array* ivec; +}; void IPint_bytestoip(void*); typedef struct F_IPint_bytestoip F_IPint_bytestoip; struct F_IPint_bytestoip @@ -3190,6 +3298,16 @@ struct F_DigestState_copy uchar temps[12]; Keyring_DigestState* d; }; +void RSAsk_decrypt(void*); +typedef struct F_RSAsk_decrypt F_RSAsk_decrypt; +struct F_RSAsk_decrypt +{ + WORD regs[NREG-1]; + Keyring_IPint** ret; + uchar temps[12]; + Keyring_RSAsk* k; + Keyring_IPint* m; +}; void Keyring_descbc(void*); typedef struct F_Keyring_descbc F_Keyring_descbc; struct F_Keyring_descbc @@ -3243,6 +3361,16 @@ struct F_IPint_div Keyring_IPint* i1; Keyring_IPint* i2; }; +void RSApk_encrypt(void*); +typedef struct F_RSApk_encrypt F_RSApk_encrypt; +struct F_RSApk_encrypt +{ + WORD regs[NREG-1]; + Keyring_IPint** ret; + uchar temps[12]; + Keyring_RSApk* k; + Keyring_IPint* m; +}; void IPint_eq(void*); typedef struct F_IPint_eq F_IPint_eq; struct F_IPint_eq @@ -3264,6 +3392,49 @@ struct F_IPint_expmod Keyring_IPint* exp; Keyring_IPint* mod; }; +void RSAsk_fill(void*); +typedef struct F_RSAsk_fill F_RSAsk_fill; +struct F_RSAsk_fill +{ + WORD regs[NREG-1]; + Keyring_RSAsk** ret; + uchar temps[12]; + Keyring_IPint* n; + Keyring_IPint* e; + Keyring_IPint* d; + Keyring_IPint* p; + Keyring_IPint* q; +}; +void RSAsk_gen(void*); +typedef struct F_RSAsk_gen F_RSAsk_gen; +struct F_RSAsk_gen +{ + WORD regs[NREG-1]; + Keyring_RSAsk** ret; + uchar temps[12]; + WORD nlen; + WORD elen; + WORD nrep; +}; +void DSAsk_gen(void*); +typedef struct F_DSAsk_gen F_DSAsk_gen; +struct F_DSAsk_gen +{ + WORD regs[NREG-1]; + Keyring_DSAsk** ret; + uchar temps[12]; + Keyring_DSApk* oldpk; +}; +void EGsk_gen(void*); +typedef struct F_EGsk_gen F_EGsk_gen; +struct F_EGsk_gen +{ + WORD regs[NREG-1]; + Keyring_EGsk** ret; + uchar temps[12]; + WORD nlen; + WORD nrep; +}; void Keyring_genSK(void*); typedef struct F_Keyring_genSK F_Keyring_genSK; struct F_Keyring_genSK @@ -3400,6 +3571,15 @@ struct F_IPint_iptob64 uchar temps[12]; Keyring_IPint* i; }; +void IPint_iptob64z(void*); +typedef struct F_IPint_iptob64z F_IPint_iptob64z; +struct F_IPint_iptob64z +{ + WORD regs[NREG-1]; + String** ret; + uchar temps[12]; + Keyring_IPint* i; +}; void IPint_iptobebytes(void*); typedef struct F_IPint_iptobebytes F_IPint_iptobebytes; struct F_IPint_iptobebytes @@ -3461,6 +3641,16 @@ struct F_Keyring_md5 Array* digest; Keyring_DigestState* state; }; +void IPint_mod(void*); +typedef struct F_IPint_mod F_IPint_mod; +struct F_IPint_mod +{ + WORD regs[NREG-1]; + Keyring_IPint** ret; + uchar temps[12]; + Keyring_IPint* i1; + Keyring_IPint* i2; +}; void IPint_mul(void*); typedef struct F_IPint_mul F_IPint_mul; struct F_IPint_mul @@ -3672,6 +3862,36 @@ struct F_Keyring_sign Keyring_DigestState* state; String* ha; }; +void RSAsk_sign(void*); +typedef struct F_RSAsk_sign F_RSAsk_sign; +struct F_RSAsk_sign +{ + WORD regs[NREG-1]; + Keyring_RSAsig** ret; + uchar temps[12]; + Keyring_RSAsk* k; + Keyring_IPint* m; +}; +void DSAsk_sign(void*); +typedef struct F_DSAsk_sign F_DSAsk_sign; +struct F_DSAsk_sign +{ + WORD regs[NREG-1]; + Keyring_DSAsig** ret; + uchar temps[12]; + Keyring_DSAsk* k; + Keyring_IPint* m; +}; +void EGsk_sign(void*); +typedef struct F_EGsk_sign F_EGsk_sign; +struct F_EGsk_sign +{ + WORD regs[NREG-1]; + Keyring_EGsig** ret; + uchar temps[12]; + Keyring_EGsk* k; + Keyring_IPint* m; +}; void Keyring_signm(void*); typedef struct F_Keyring_signm F_Keyring_signm; struct F_Keyring_signm @@ -3768,6 +3988,39 @@ struct F_Keyring_verify Keyring_Certificate* cert; Keyring_DigestState* state; }; +void RSApk_verify(void*); +typedef struct F_RSApk_verify F_RSApk_verify; +struct F_RSApk_verify +{ + WORD regs[NREG-1]; + WORD* ret; + uchar temps[12]; + Keyring_RSApk* k; + Keyring_RSAsig* sig; + Keyring_IPint* m; +}; +void DSApk_verify(void*); +typedef struct F_DSApk_verify F_DSApk_verify; +struct F_DSApk_verify +{ + WORD regs[NREG-1]; + WORD* ret; + uchar temps[12]; + Keyring_DSApk* k; + Keyring_DSAsig* sig; + Keyring_IPint* m; +}; +void EGpk_verify(void*); +typedef struct F_EGpk_verify F_EGpk_verify; +struct F_EGpk_verify +{ + WORD regs[NREG-1]; + WORD* ret; + uchar temps[12]; + Keyring_EGpk* k; + Keyring_EGsig* sig; + Keyring_IPint* m; +}; void Keyring_verifym(void*); typedef struct F_Keyring_verifym F_Keyring_verifym; struct F_Keyring_verifym @@ -3800,21 +4053,15 @@ struct F_IPint_xor Keyring_IPint* i2; }; #define Keyring_PATH "$Keyring" +#define Keyring_SHA1dlen 20 +#define Keyring_MD5dlen 16 +#define Keyring_MD4dlen 16 #define Keyring_Encrypt 0 #define Keyring_Decrypt 1 #define Keyring_AESbsize 16 #define Keyring_DESbsize 8 #define Keyring_IDEAbsize 8 -#define Keyring_DEScbc 0 -#define Keyring_DESecb 1 -#define Keyring_SHA1 2 -#define Keyring_MD5 3 -#define Keyring_MD4 4 -#define Keyring_IDEAcbc 5 -#define Keyring_IDEAecb 6 -#define Keyring_SHA1dlen 20 -#define Keyring_MD5dlen 16 -#define Keyring_MD4dlen 16 +#define Keyring_BFbsize 8 void Loader_compile(void*); typedef struct F_Loader_compile F_Loader_compile; struct F_Loader_compile diff --git a/libinterp/sysmod.h b/libinterp/sysmod.h index 5c352ae6..f18e9352 100644 --- a/libinterp/sysmod.h +++ b/libinterp/sysmod.h @@ -30,6 +30,7 @@ Runtab Sysmodtab[]={ "print",0xac849033,Sys_print,0,0,{0}, "pwrite",0x9d8aac6,Sys_pwrite,56,2,{0x0,0xc0,}, "read",0x7cfef557,Sys_read,48,2,{0x0,0xc0,}, + "readn",0x7cfef557,Sys_readn,48,2,{0x0,0xc0,}, "remove",0xc6935858,Sys_remove,40,2,{0x0,0x80,}, "seek",0xaeccaddb,Sys_seek,56,2,{0x0,0x80,}, "sleep",0xe67bf126,Sys_sleep,40,0,{0}, @@ -44,4 +45,4 @@ Runtab Sysmodtab[]={ "wstat",0x56b02096,Sys_wstat,104,2,{0x0,0xbc,}, 0 }; -#define Sysmodlen 42 +#define Sysmodlen 43 diff --git a/module/factotum.m b/module/factotum.m index 6dd98d93..85165ebd 100644 --- a/module/factotum.m +++ b/module/factotum.m @@ -33,4 +33,23 @@ Factotum: module dump: fn(a: array of byte): string; setdebug: fn(i: int); + + Aattr, Aval, Aquery: con iota; + + Attr: adt { + tag: int; + name: string; + val: string; + + text: fn(a: self ref Attr): string; + }; + + parseattrs: fn(s: string): list of ref Attr; + copyattrs: fn(l: list of ref Attr): list of ref Attr; + delattr: fn(l: list of ref Attr, n: string): list of ref Attr; + takeattrs: fn(l: list of ref Attr, names: list of string): list of ref Attr; + findattr: fn(l: list of ref Attr, n: string): ref Attr; + findattrval: fn(l: list of ref Attr, n: string): string; + publicattrs: fn(l: list of ref Attr): list of ref Attr; + attrtext: fn(l: list of ref Attr): string; }; diff --git a/module/keyring.m b/module/keyring.m index 08a3ef94..7bba0f1c 100644 --- a/module/keyring.m +++ b/module/keyring.m @@ -12,6 +12,7 @@ Keyring: module # conversions iptob64: fn(i: self ref IPint): string; + iptob64z: fn(i: self ref IPint): string; b64toip: fn(str: string): ref IPint; iptobytes: fn(i: self ref IPint): array of byte; iptobebytes: fn(i: self ref IPint): array of byte; @@ -34,6 +35,7 @@ Keyring: module neg: fn(i: self ref IPint): ref IPint; mul: fn(i1: self ref IPint, i2: ref IPint): ref IPint; div: fn(i1: self ref IPint, i2: ref IPint): (ref IPint, ref IPint); + mod: fn(i1: self ref IPint, i2: ref IPint): ref IPint; eq: fn(i1: self ref IPint, i2: ref IPint): int; cmp: fn(i1: self ref IPint, i2: ref IPint): int; copy: fn(i: self ref IPint): ref IPint; @@ -119,6 +121,13 @@ Keyring: module # all the state is hidden }; + # expanded Blowfish key + state for chaining + BFstate: adt + { + x: int; # dummy for C compiler for runt.h + # all the state is hidden + }; + # authentication info Authinfo: adt { @@ -178,6 +187,10 @@ Keyring: module hmac_md5: fn(data: array of byte, n: int, key: array of byte, digest: array of byte, state: ref DigestState): ref DigestState; + SHA1dlen: con 20; + MD5dlen: con 16; + MD4dlen: con 16; + # encryption interfaces Encrypt: con 0; Decrypt: con 1; @@ -199,6 +212,12 @@ Keyring: module ideaecb: fn(state: ref IDEAstate, buf: array of byte, n: int, direction: int); ideacbc: fn(state: ref IDEAstate, buf: array of byte, n: int, direction: int); + BFbsize: con 8; + + blowfishsetup: fn(key: array of byte, ivec: array of byte): ref BFstate; +# blowfishecb: fn(state: ref BFstate, buf: array of byte, n: int, direction: int); + blowfishcbc: fn(state: ref BFstate, buf: array of byte, n: int, direction: int); + rc4setup: fn(seed: array of byte): ref RC4state; rc4: fn(state: ref RC4state, buf: array of byte, n: int); rc4skip: fn(state: ref RC4state, n: int); @@ -229,16 +248,76 @@ Keyring: module sendmsg: fn(fd: ref Sys->FD, buf: array of byte, n: int): int; senderrmsg: fn(fd: ref Sys->FD, s: string): int; - # algorithms - DEScbc: con 0; - DESecb: con 1; - SHA1: con 2; - MD5: con 3; - MD4: con 4; - IDEAcbc: con 5; - IDEAecb: con 6; + RSApk: adt { + n: ref IPint; # modulus + ek: ref IPint; # exp (encryption key) + + encrypt: fn(k: self ref RSApk, m: ref IPint): ref IPint; + verify: fn(k: self ref RSApk, sig: ref RSAsig, m: ref IPint): int; + }; + + RSAsk: adt { + pk: ref RSApk; + dk: ref IPint; # exp (decryption key) + p: ref IPint; # q in pkcs + q: ref IPint; # p in pkcs + + # precomputed crt values + kp: ref IPint; # k mod p-1 + kq: ref IPint; # k mod q-1 + c2: ref IPint; # for converting residues to number + + gen: fn(nlen: int, elen: int, nrep: int): ref RSAsk; + fill: fn(n: ref IPint, e: ref IPint, d: ref IPint, p: ref IPint, q: ref IPint): ref RSAsk; + decrypt: fn(k: self ref RSAsk, m: ref IPint): ref IPint; + sign: fn(k: self ref RSAsk, m: ref IPint): ref RSAsig; + }; + + RSAsig: adt { + n: ref IPint; + }; + + DSApk: adt { + p: ref IPint; # modulus + q: ref IPint; # group order, q divides p-1 + alpha: ref IPint; # group generator + key: ref IPint; # encryption key (alpha**secret mod p) + + verify: fn(k: self ref DSApk, sig: ref DSAsig, m: ref IPint): int; + }; + + DSAsk: adt { + pk: ref DSApk; + secret: ref IPint; # decryption key + + gen: fn(oldpk: ref DSApk): ref DSAsk; + sign: fn(k: self ref DSAsk, m: ref IPint): ref DSAsig; + }; + + DSAsig: adt { + r: ref IPint; + s: ref IPint; + }; + + EGpk: adt { + p: ref IPint; # modulus + alpha: ref IPint; # generator + key: ref IPint; # encryption key (alpha**secret mod p) + + verify: fn(k: self ref EGpk, sig: ref EGsig, m: ref IPint): int; + }; + + EGsk: adt { + pk: ref EGpk; + secret: ref IPint; # decryption key + + gen: fn(nlen: int, nrep: int): ref EGsk; + sign: fn(k: self ref EGsk, m: ref IPint): ref EGsig; + }; + + EGsig: adt { + r: ref IPint; + s: ref IPint; + }; - SHA1dlen: con 20; - MD5dlen: con 16; - MD4dlen: con 16; }; |
