diff options
Diffstat (limited to 'appl')
| -rw-r--r-- | appl/cmd/auth/factotum/authio.m | 5 | ||||
| -rw-r--r-- | appl/cmd/auth/factotum/factotum.b | 128 | ||||
| -rw-r--r-- | appl/cmd/auth/factotum/proto/infauth.b | 5 | ||||
| -rw-r--r-- | appl/cmd/auth/factotum/proto/p9any.b | 5 | ||||
| -rw-r--r-- | appl/cmd/auth/factotum/proto/pass.b | 5 | ||||
| -rw-r--r-- | appl/cmd/auth/factotum/proto/rsa.b | 126 | ||||
| -rw-r--r-- | appl/cmd/auth/factotum/rpc.b | 2 | ||||
| -rw-r--r-- | appl/cmd/diff.b | 10 | ||||
| -rw-r--r-- | appl/lib/factotum.b | 120 | ||||
| -rw-r--r-- | appl/lib/spki/spki.b | 50 |
10 files changed, 411 insertions, 45 deletions
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 |
