summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--appl/cmd/auth/factotum/authio.m5
-rw-r--r--appl/cmd/auth/factotum/factotum.b128
-rw-r--r--appl/cmd/auth/factotum/proto/infauth.b5
-rw-r--r--appl/cmd/auth/factotum/proto/p9any.b5
-rw-r--r--appl/cmd/auth/factotum/proto/pass.b5
-rw-r--r--appl/cmd/auth/factotum/proto/rsa.b126
-rw-r--r--appl/cmd/auth/factotum/rpc.b2
-rw-r--r--appl/cmd/diff.b10
-rw-r--r--appl/lib/factotum.b120
-rw-r--r--appl/lib/spki/spki.b50
-rw-r--r--dis/auth/factotum.disbin13393 -> 14780 bytes
-rw-r--r--dis/auth/proto/p9any.disbin3648 -> 3672 bytes
-rw-r--r--dis/auth/proto/pass.disbin383 -> 405 bytes
-rw-r--r--dis/auth/proto/rsa.disbin0 -> 1740 bytes
-rw-r--r--dis/auth/rpc.disbin903 -> 903 bytes
-rw-r--r--dis/diff.disbin10350 -> 10345 bytes
-rw-r--r--dis/lib/factotum.disbin4952 -> 6097 bytes
-rw-r--r--dis/lib/spki/spki.disbin32975 -> 33509 bytes
-rw-r--r--emu/Nt/devfs.c6
-rw-r--r--include/version.h2
-rw-r--r--libinterp/ipint.c91
-rw-r--r--libinterp/keyring.c544
-rw-r--r--libinterp/keyring.h18
-rw-r--r--libinterp/runt.h267
-rw-r--r--libinterp/sysmod.h3
-rw-r--r--module/factotum.m19
-rw-r--r--module/keyring.m101
28 files changed, 1414 insertions, 99 deletions
diff --git a/CHANGES b/CHANGES
index 53eb57a9..d5bcd21c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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
index 47cedcca..fb04eca7 100644
--- a/dis/auth/factotum.dis
+++ b/dis/auth/factotum.dis
Binary files differ
diff --git a/dis/auth/proto/p9any.dis b/dis/auth/proto/p9any.dis
index 4a3057c8..4371874a 100644
--- a/dis/auth/proto/p9any.dis
+++ b/dis/auth/proto/p9any.dis
Binary files differ
diff --git a/dis/auth/proto/pass.dis b/dis/auth/proto/pass.dis
index 6bd14645..7ee7d36c 100644
--- a/dis/auth/proto/pass.dis
+++ b/dis/auth/proto/pass.dis
Binary files differ
diff --git a/dis/auth/proto/rsa.dis b/dis/auth/proto/rsa.dis
new file mode 100644
index 00000000..bfddb804
--- /dev/null
+++ b/dis/auth/proto/rsa.dis
Binary files differ
diff --git a/dis/auth/rpc.dis b/dis/auth/rpc.dis
index b929d5f8..31dd709e 100644
--- a/dis/auth/rpc.dis
+++ b/dis/auth/rpc.dis
Binary files differ
diff --git a/dis/diff.dis b/dis/diff.dis
index 311f7e4e..5f8f5c3a 100644
--- a/dis/diff.dis
+++ b/dis/diff.dis
Binary files differ
diff --git a/dis/lib/factotum.dis b/dis/lib/factotum.dis
index 0fb35884..27722fc8 100644
--- a/dis/lib/factotum.dis
+++ b/dis/lib/factotum.dis
Binary files differ
diff --git a/dis/lib/spki/spki.dis b/dis/lib/spki/spki.dis
index 07f9f4a8..d6b89a34 100644
--- a/dis/lib/spki/spki.dis
+++ b/dis/lib/spki/spki.dis
Binary files differ
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;
};