diff options
Diffstat (limited to 'appl/cmd/auth/factotum/proto/keyreps.b')
| -rw-r--r-- | appl/cmd/auth/factotum/proto/keyreps.b | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/appl/cmd/auth/factotum/proto/keyreps.b b/appl/cmd/auth/factotum/proto/keyreps.b new file mode 100644 index 00000000..5fdac2c0 --- /dev/null +++ b/appl/cmd/auth/factotum/proto/keyreps.b @@ -0,0 +1,173 @@ +implement Keyreps; +include "sys.m"; + sys: Sys; +include "keyring.m"; + kr: Keyring; + IPint: import kr; +include "sexprs.m"; +include "spki.m"; +include "encoding.m"; + base64: Encoding; +include "keyreps.m"; + +init() +{ + sys = load Sys Sys->PATH; + kr = load Keyring Keyring->PATH; + base64 = load Encoding Encoding->BASE64PATH; +} + +keyextract(flds: list of string, names: list of (string, int)): list of (string, ref IPint) +{ + a := array[len flds] of ref IPint; + for(i := 0; i < len a; i++){ + a[i] = IPint.b64toip(hd flds); + flds = tl flds; + } + rl: list of (string, ref IPint); + for(; names != nil; names = tl names){ + (n, p) := hd names; + if(p < len a) + rl = (n, a[p]) :: rl; + } + return revt(rl); +} + +Keyrep.pk(pk: ref Keyring->PK): ref Keyrep.PK +{ + s := kr->pktostr(pk); + (nf, flds) := sys->tokenize(s, "\n"); + if((nf -= 2) < 0) + return nil; + case hd flds { + "rsa" => + return ref Keyrep.PK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("e",1), ("n",0)})); + "elgamal" or "dsa" => + return ref Keyrep.PK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",1), ("key",2)})); + * => + return nil; + } +} + +Keyrep.sk(pk: ref Keyring->SK): ref Keyrep.SK +{ + s := kr->pktostr(pk); + (nf, flds) := sys->tokenize(s, "\n"); + if((nf -= 2) < 0) + return nil; + case hd flds { + "rsa" => + return ref Keyrep.SK(hd flds, hd tl flds, + keyextract(tl tl flds,list of {("e",1), ("n",0), ("!dk",2), ("!p",3), ("!q",4), ("!kp",5), ("!kq",6), ("!c2",7)})); + "elgamal" or "dsa" => + return ref Keyrep.SK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",1), ("key",2), ("!secret",3)})); + * => + return nil; + } +} + +Keyrep.get(k: self ref Keyrep, n: string): ref IPint +{ + for(el := k.els; el != nil; el = tl el) + if((hd el).t0 == n) + return (hd el).t1; + return nil; +} + +Keyrep.getb(k: self ref Keyrep, n: string): array of byte +{ + v := k.get(n); + if(v == nil) + return nil; + return pre0(v.iptobebytes()); +} + +pre0(a: array of byte): array of byte +{ + for(i:=0; i<len a-1; i++) + if(a[i] != a[i+1] && (a[i] != byte 0 || (int a[i+1] & 16r80) != 0)) + break; + if(i > 0) + a = a[i:]; + if(len a < 1 || (int a[0] & 16r80) == 0) + return a; + b := array[len a + 1] of byte; + b[0] = byte 0; + b[1:] = a; + return b; +} + +Keyrep.mkpk(k: self ref Keyrep): (ref Keyring->PK, int) +{ + case k.alg { + "rsa" => + e := k.get("e"); + n := k.get("n"); + return (kr->strtopk(sys->sprint("rsa\n%s\n%s\n%s\n", k.owner, n.iptob64(), e.iptob64())), n.bits()); + * => + raise "Keyrep: unknown algorithm" + k.alg; + } +} + +Keyrep.mksk(k: self ref Keyrep): ref Keyring->SK +{ + case k.alg { + "rsa" => + e := k.get("e"); + n := k.get("n"); + dk := k.get("!dk"); + p := k.get("!p"); + q := k.get("!q"); + kp := k.get("!kp"); + kq := k.get("!kq"); + c12 := k.get("!c2"); + return kr->strtosk(sys->sprint("rsa\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", + k.owner, n.iptob64(), e.iptob64(), dk.iptob64(), p.iptob64(), q.iptob64(), + kp.iptob64(), kq.iptob64(), c12.iptob64())); + * => + raise "Keyrep: unknown algorithm"; + } +} + +Keyrep.eq(k1: self ref Keyrep, k2: ref Keyrep): int +{ + # n but n is small + for(l1 := k1.els; l1 != nil; l1 = tl l1){ + (n, v1) := hd l1; + v2 := k2.get(n); + if(v2 == nil || !v1.eq(v2)) + return 0; + } + for(l2 := k2.els; l2 != nil; l2 = tl l2) + if(k1.get((hd l2).t0) == nil) + return 0; + return 1; +} + +Keyrep.mkkey(kr: self ref Keyrep): ref SPKI->Key +{ + k := ref SPKI->Key; + (k.pk, k.nbits) = kr.mkpk(); + k.sk = kr.mksk(); + return k; +} + +sig2icert(sig: ref SPKI->Signature, signer: string, exp: int): ref Keyring->Certificate +{ + if(sig.sig == nil) + return nil; + s := sys->sprint("%s\n%s\n%s\n%d\n%s\n", "rsa", sig.hash.alg, signer, exp, base64->enc((hd sig.sig).t1)); +#sys->print("alg %s *** %s\n", sig.sa, base64->enc((hd sig.sig).t1)); + return kr->strtocert(s); +} + +revt[S,T](l: list of (S,T)): list of (S,T) +{ + rl: list of (S,T); + for(; l != nil; l = tl l) + rl = hd l :: rl; + return rl; +} |
