diff options
| author | forsyth <forsyth@vitanuova.com> | 2011-01-17 11:10:35 +0000 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2011-01-17 11:10:35 +0000 |
| commit | d6b4eae8eb0a5ca3119414005e483fedd63a62d6 (patch) | |
| tree | 4959b04b1ae02ce5ccb4b3c0a8c459ff46587eb7 /appl/lib | |
| parent | 9e6910dc0c747c8f30b87f6482f4eadb48ad6654 (diff) | |
20110117-1110
Diffstat (limited to 'appl/lib')
| -rw-r--r-- | appl/lib/factotum.b | 31 | ||||
| -rw-r--r-- | appl/lib/spki/spki.b | 536 | ||||
| -rw-r--r-- | appl/lib/spki/verifier.b | 6 |
3 files changed, 308 insertions, 265 deletions
diff --git a/appl/lib/factotum.b b/appl/lib/factotum.b index bcf65e6c..97138fe1 100644 --- a/appl/lib/factotum.b +++ b/appl/lib/factotum.b @@ -11,8 +11,6 @@ include "sys.m"; include "string.m"; -include "encoding.m"; - include "factotum.m"; debug := 0; @@ -185,37 +183,12 @@ rpc(afd: ref Sys->FD, verb: string, a: array of byte): (string, array of byte) Authinfo.read(fd: ref Sys->FD): ref Authinfo { - (o, a) := rpc(fd, "authinfo", nil); # deprecated in p9p factotum - e := sys->sprint("%r"); - attrs := rpcattrs(fd); - cuid := findattrval(attrs, "cuid"); - suid := findattrval(attrs, "suid"); - secret16 := findattrval(attrs, "secret"); - secret: array of byte; - if(secret16 != nil){ - enc16 := load Encoding Encoding->BASE16PATH; - if(enc16 != nil) - secret = enc16->dec(secret16); - } - cap := findattrval(attrs, "cap"); - if(o != "ok"){ - if(cuid != nil || suid != nil || secret != nil || cap != nil || attrs != nil) - return ref Authinfo(cuid, suid, cap, secret, attrs); - sys->werrstr(e); + (o, a) := rpc(fd, "authinfo", nil); + if(o != "ok") return nil; - } (n, ai) := Authinfo.unpack(a); if(n <= 0) sys->werrstr("bad auth info from factotum"); - ai.attrs = attrs; - if(ai.cuid == nil) - ai.cuid = cuid; - if(ai.suid == nil) - ai.suid = suid; - if(ai.cap == nil) - ai.cap = cap; - if(ai.secret == nil) - ai.secret = secret; return ai; } diff --git a/appl/lib/spki/spki.b b/appl/lib/spki/spki.b index 7a4854df..615aa48e 100644 --- a/appl/lib/spki/spki.b +++ b/appl/lib/spki/spki.b @@ -1,7 +1,7 @@ implement SPKI; # -# Copyright © 2004,2008 Vita Nuova Holdings Limited +# Copyright © 2004 Vita Nuova Holdings Limited # # To do: # - diagnostics @@ -14,13 +14,11 @@ include "sys.m"; include "daytime.m"; daytime: Daytime; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; +include "keyring.m"; + kr: Keyring; + IPint, Certificate, PK, SK: import kr; -include "crypt.m"; - crypt: Crypt; - PK, PKsig, SK: import crypt; +include "security.m"; include "bufio.m"; @@ -39,7 +37,7 @@ debug: con 0; init() { sys = load Sys Sys->PATH; - crypt = load Crypt Crypt->PATH; + kr = load Keyring Keyring->PATH; daytime = load Daytime Daytime->PATH; sexprs = load Sexprs Sexprs->PATH; base16 = load Encoding Encoding->BASE16PATH; @@ -265,24 +263,23 @@ parsesig(e: ref Sexp): ref Signature sigalg: string; if(k != nil) sigalg = k.sigalg(); - return ref Signature(hash, k, sigalg, array[] of {("", val.asdata())}); + return ref Signature(hash, k, sigalg, (nil, val.asdata()) :: nil); } sigalg := val.op(); if(sigalg == nil) return nil; - vals := array[len val.args()] of (string, array of byte); - i := 0; + rl: list of (string, array of byte); for(els := val.args(); els != nil; els = tl els){ g := hd els; if(g.islist()){ arg := onlyarg(g); if(arg == nil) return nil; - vals[i++] = (g.op(), arg.asdata()); + rl = (g.op(), arg.asdata()) :: rl; }else - vals[i++] = ("", g.asdata()); + rl = (nil, g.asdata()) :: rl; } - return ref Signature(hash, k, sigalg, vals); + return ref Signature(hash, k, sigalg, revt(rl)); } parsecompound(e: ref Sexp): ref Name @@ -362,30 +359,31 @@ parsekey(e: ref Sexp): ref Key kl := (hd l).args(); if(kl == nil) return nil; - els := array[len kl] of (string, array of byte); - i := 0; + els: list of (string, ref IPint); for(; kl != nil; kl = tl kl){ t := (hd kl).op(); a := onlyarg(hd kl).asdata(); if(a == nil) return nil; - els[i++] = (t, a); + ip := IPint.bebytestoip(a); + if(ip == nil) + return nil; + els = (t, ip) :: els; + } + krp := ref Keyrep.PK(alg, "sdsi", els); + (pk, nbits) := krp.mkpk(); + if(pk == nil){ + sys->print("can't convert public-key\n"); + return nil; } - pk: ref Crypt->PK; - sk: ref Crypt->SK; - nbits := 0; + sk: ref Keyring->SK; if(issk){ - (sk, pk, nbits) = mksk(alg, els); + krp = ref Keyrep.SK(alg, "sdsi", els); + sk = krp.mksk(); if(sk == nil){ - sys->werrstr("can't convert private-key"); + sys->print("can't convert private-key\n"); return nil; } - }else{ - (pk, nbits) = mkpk(alg, els); - if(pk == nil){ - sys->werrstr("can't convert public-key"); - return nil; - } } #(ref Key(pk,nil,"md5",nil,nil)).hashed("md5"); # TEST return ref Key(pk, sk, nbits, mha, enc, nil); @@ -552,12 +550,12 @@ checksig(c: ref Cert, sig: ref Signature): string return "missing key for signature"; if(sig.hash == nil) return "missing hash for signature"; - if(sig.params == nil) + if(sig.sig == nil) return "missing signature value"; pk := sig.key.pk; if(pk == nil) - return "missing Crypt->PK for signature"; # TO DO (need a way to tell that key was just a hash) -#rsacomp((hd sig.params).t1, sig.key); + return "missing Keyring->PK for signature"; # TO DO (need a way to tell that key was just a hash) +#rsacomp((hd sig.sig).t1, sig.key); #sys->print("nbits= %d\n", sig.key.nbits); (alg, enc, hashalg) := sig.algs(); if(alg == nil) @@ -576,12 +574,10 @@ checksig(c: ref Cert, sig: ref Signature): string #dump("check/hashed", hash); #dump("check/h", h); ip := IPint.bebytestoip(h); - isig := sig2isig(sig); + isig := sig2icert(sig, "sdsi", 0); if(isig == nil) - return "couldn't convert SPKI signature to Crypt form"; - if(tagof pk != tagof isig) - return "signature and public key are incompatible"; - if(!crypt->verify(pk, isig, ip)) + return "couldn't convert SPKI signature to Keyring form"; + if(!kr->verifym(pk, isig, ip)) return "signature does not match"; return nil; } @@ -602,7 +598,7 @@ signcert(c: ref Cert, sigalg: string, key: ref Key): (ref Signature, string) signbytes(data: array of byte, sigalg: string, key: ref Key): (ref Signature, string) { if(key.sk == nil) - return (nil, "missing private key for signature"); + return (nil, "missing Keyring->SK for signature"); pubkey := ref *key; pubkey.sk = nil; sig := ref Signature(nil, pubkey, sigalg, nil); # ref Hash, key, alg, sig: list of (string, array of byte) @@ -624,16 +620,18 @@ signbytes(data: array of byte, sigalg: string, key: ref Key): (ref Signature, st #dump("sign/h", h); sig.hash = ref Hash(hashalg, hash); ip := IPint.bebytestoip(h); - pick isig := crypt->sign(key.sk, ip) { - RSA => - sig.params = array[] of {("", isig.n.iptobebytes())}; - DSA => - sig.params = array[] of {("r", isig.r.iptobebytes()), ("s", isig.s.iptobebytes())}; - Elgamal => - sig.params = array[] of {("r", isig.r.iptobebytes()), ("s", isig.s.iptobebytes())}; - * => - return (nil, "unsupported signature type"); # don't know the elements - } + icert := kr->signm(key.sk, ip, hashalg); + if(icert == nil) + return (nil, "signature failed"); # can't happen? + (nil, nil, nil, vals) := icert2els(icert); + if(vals == nil) + return (nil, "couldn't extract values from Keyring Certificate"); + l: list of (string, array of byte); + for(; vals != nil; vals = tl vals){ + (n, v) := hd vals; + l = (f2s("rsa", n), v) :: l; + } + sig.sig = revt(l); return (sig, nil); } @@ -647,11 +645,11 @@ hashbytes(a: array of byte, alg: string): array of byte hash: array of byte; case alg { "md5" => - hash = array[Crypt->MD5dlen] of byte; - crypt->md5(a, len a, hash, nil); + hash = array[Keyring->MD5dlen] of byte; + kr->md5(a, len a, hash, nil); "sha" or "sha1" => - hash = array[Crypt->SHA1dlen] of byte; - crypt->sha1(a, len a, hash, nil); + hash = array[Keyring->SHA1dlen] of byte; + kr->sha1(a, len a, hash, nil); * => raise "Spki->hashbytes: unknown algorithm: "+alg; } @@ -703,10 +701,10 @@ sigalgs(alg: string): (string, string, string) Signature.sexp(sg: self ref Signature): ref Sexp { sv: ref Sexp; - if(len sg.params != 1){ + if(len sg.sig != 1){ l: list of ref Sexp; - for(i := 0; i < len sg.params; i++){ - (op, val) := sg.params[i]; + for(els := sg.sig; els != nil; els = tl els){ + (op, val) := hd els; if(op != nil) l = ref Sexp.List(ref Sexp.String(op,nil) :: ref Sexp.Binary(val,nil) :: nil) :: l; else @@ -714,7 +712,7 @@ Signature.sexp(sg: self ref Signature): ref Sexp } sv = ref Sexp.List(rev(l)); }else - sv = ref Sexp.Binary(sg.params[0].t1, nil); # no list if signature has one component + sv = ref Sexp.Binary((hd sg.sig).t1, nil); # no list if signature has one component if(sg.sa != nil) sv = ref Sexp.List(ref Sexp.String(sg.sa,nil) :: sv :: nil); return ref Sexp.List(ref Sexp.String("signature",nil) :: sg.hash.sexp() :: sg.key.sexp() :: @@ -1007,16 +1005,11 @@ Name.eq(a: self ref Name, b: ref Name): int Key.public(key: self ref Key): ref Key { if(key.sk != nil){ - pk := key.pk; - if(pk == nil){ - pk = crypt->sktopk(key.sk); - if(pk == nil) - return nil; - } - key = ref *key; - key.pk = pk; - key.sk = nil; - return key; + pk := ref *key; + if(pk.pk == nil) + pk.pk = kr->sktopk(pk.sk); + pk.sk = nil; + return pk; } if(key.pk == nil) return nil; @@ -1056,9 +1049,9 @@ Key.hashexp(key: self ref Key, alg: string): ref Hash Key.sigalg(k: self ref Key): string { if(k.pk != nil) - alg := pkalg(k.pk); + alg := k.pk.sa.name; else if(k.sk != nil) - alg = skalg(k.sk); + alg = k.sk.sa.name; else return nil; if(k.halg != nil){ @@ -1069,30 +1062,6 @@ Key.sigalg(k: self ref Key): string return alg; } -skalg(sk: ref SK): string -{ - if(sk == nil) - return "nil"; - case tagof sk { - tagof SK.RSA => return "rsa"; - tagof SK.Elgamal => return "elgamal"; - tagof SK.DSA => return "dsa"; - * => return "gok"; - } -} - -pkalg(pk: ref PK): string -{ - if(pk == nil) - return "nil"; - case tagof pk { - tagof PK.RSA => return "rsa"; - tagof PK.Elgamal => return "elgamal"; - tagof PK.DSA => return "dsa"; - * => return "gok"; - } -} - Key.text(k: self ref Key): string { e := k.sexp(); @@ -1109,19 +1078,24 @@ Key.sexp(k: self ref Key): ref Sexp return nil; } sort := "public-key"; - els: array of (string, ref IPint); + els: list of (string, ref IPint); if(k.sk != nil){ - els = repsk(k.sk); + krp := Keyrep.sk(k.sk); + if(krp == nil) + return nil; + els = krp.els; sort = "private-key"; - }else - els = reppk(k.pk); - if(els == nil) - return nil; + }else{ + krp := Keyrep.pk(k.pk); + if(krp == nil) + return nil; + els = krp.els; + } rl: list of ref Sexp; - for(i := 0; i < len els; i++){ - (n, v) := els[i]; + for(; els != nil; els = tl els){ + (n, v) := hd els; a := pre0(v.iptobebytes()); - rl = ref Sexp.List(ref Sexp.String(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); @@ -1141,27 +1115,8 @@ Key.eq(k1: self ref Key, k2: ref Key): int return 1; } } - if(k1.pk != nil && k2.pk != nil){ - pick rk1 := k1.pk { - RSA => - pick rk2 := k2.pk { - RSA => - return rk1.n.eq(rk2.n) && rk1.ek.eq(rk2.n); - } - DSA => - pick rk2 := k2.pk { - DSA => - return rk1.p.eq(rk2.p) && rk1.q.eq(rk2.q) && - rk1.alpha.eq(rk2.alpha) && rk1.key.eq(rk2.key); - } - Elgamal => - pick rk2 := k2.pk { - Elgamal => - return rk1.p.eq(rk2.p) && rk1.alpha.eq(rk2.alpha) && - rk1.key.eq(rk2.key); - } - } - } + if(k1.pk != nil && k2.pk != nil) + return kr->pktostr(k1.pk) == kr->pktostr(k2.pk); # TO DO return 0; } @@ -2077,133 +2032,250 @@ rev[T](l: list of T): list of T return rl; } +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; +} + # -# these are in the order given in draft-ietf-spki-cert-structure-06.txt +# the following should probably be in a separate Limbo library module, +# or provided in some way directly by Keyring # -mkpk(alg: string, els: array of (string, array of byte)): (ref Crypt->PK, int) +Keyrep: adt { + alg: string; + owner: string; + els: list of (string, ref IPint); + pick{ # keeps a type distance between public and private keys + PK => + SK => + } + + pk: fn(pk: ref Keyring->PK): ref Keyrep.PK; + sk: fn(sk: ref Keyring->SK): ref Keyrep.SK; + mkpk: fn(k: self ref Keyrep): (ref Keyring->PK, int); + mksk: fn(k: self ref Keyrep): ref Keyring->SK; + get: fn(k: self ref Keyrep, n: string): ref IPint; + getb: fn(k: self ref Keyrep, n: string): array of byte; + eq: fn(k1: self ref Keyrep, k2: ref Keyrep): int; +}; + +# +# convert an Inferno key into a (name, IPint) representation, +# where `names' maps between Inferno key component offsets and factotum names +# +keyextract(flds: list of string, names: list of (string, int)): list of (string, ref IPint) { - case alg { - "rsa" => - a := getparams(els, "e" :: "n" :: nil); - if(a == nil) - break; - return (ref PK.RSA(a[1], a[0]), a[1].bits()); - "dsa" => - a := getparams(els, "p" :: "g" :: "q" :: "y" :: nil); - if(a == nil) - break; - return (ref PK.DSA(a[0], a[2], a[1], a[3]), a[0].bits()); - "elgamal" => - a := getparams(els, "p" :: "g" :: "y" :: nil); - if(a == nil) - break; - return (ref PK.Elgamal(a[0], a[1], a[2]), a[0].bits()); + a := array[len flds] of ref IPint; + for(i := 0; i < len a; i++){ + a[i] = IPint.b64toip(hd flds); + flds = tl flds; } - return (nil, 0); + 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); } -reppk(pk: ref Crypt->PK): array of (string, ref IPint) +Keyrep.pk(pk: ref Keyring->PK): ref Keyrep.PK { - pick k := pk { - RSA => - return array[] of {("e", k.ek), ("n", k.n)}; - DSA => - return array[] of {("p", k.p), ("g", k.alpha), ("q", k.q), ("y", k.key)}; - Elgamal => - return array[] of {("p", k.p), ("g", k.alpha), ("y", k.key)}; + 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 {("ek",1), ("n",0)})); + "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; } } -mksk(alg: string, els: array of (string, array of byte)): (ref Crypt->SK, ref Crypt->PK, int) +Keyrep.sk(pk: ref Keyring->SK): ref Keyrep.SK { - case alg { + s := kr->sktostr(pk); + (nf, flds) := sys->tokenize(s, "\n"); + if((nf -= 2) < 0) + return nil; + # the ordering of components below should match the one defined in the spki spec + case hd flds { "rsa" => - a := getparams(els, "e" :: "n" :: "d" :: "p" :: "q" :: "a" :: "b" :: "c" :: nil); - if(a == nil) - break; - # NB: p and q (and a and b) roles are reversed between libsec and pkcs - pk := ref PK.RSA(a[1], a[0]); - sk := ref SK.RSA(pk, a[2], a[4], a[3], a[6], a[5], a[7]); - return (sk, pk, a[1].bits()); - "dsa" => - a := getparams(els, "p" :: "g" :: "q" :: "y" :: "x" :: nil); - if(a == nil) - break; - pk := ref PK.DSA(a[0], a[2], a[1], a[3]); - sk := ref SK.DSA(pk, a[4]); - return (sk, pk, a[0].bits()); + 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" => - a := getparams(els, "p" :: "g" :: "y" :: "x" :: nil); - if(a == nil) - break; - pk := ref PK.Elgamal(a[0], a[1], a[2]); - sk := ref SK.Elgamal(pk, a[3]); - return (sk, pk, a[0].bits()); + 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; } - return (nil, nil, 0); } -repsk(sk: ref Crypt->SK): array of (string, ref IPint) +Keyrep.get(k: self ref Keyrep, n: string): ref IPint { - pick k := sk { - RSA => - return array[] of - {("e", k.pk.ek), ("n", k.pk.n), ("d", k.dk), ("p", k.q), ("q", k.p), ("a", k.kq), ("b", k.kp), ("c", k.c2)}; - DSA => - return array[] of {("p", k.pk.p), ("g", k.pk.alpha), ("q", k.pk.q), ("y", k.pk.key), ("x", k.secret)}; - Elgamal => - return array[] of {("p", k.pk.p), ("g", k.pk.alpha), ("y", k.pk.key), ("x", k.secret)}; - * => + 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; + 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()); +} + +Keyrep.mkpk(k: self ref Keyrep): (ref Keyring->PK, int) +{ + case k.alg { + "rsa" => + e := k.get("ek"); + n := k.get("n"); + if(e == nil || n == nil) + return (nil, 0); + 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"; } } -sig2isig(sig: ref Signature): ref Crypt->PKsig +Keyrep.mksk(k: self ref Keyrep): ref Keyring->SK { - if(sig.params == nil) - return nil; - case sig.algs().t0 { + case k.alg { "rsa" => - ip := getp(sig.params, ""); - if(ip == nil) + e := k.get("ek"); + 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"); + if(e == nil || n == nil || dk == nil || p == nil || q == nil || kp == nil || kq == nil || c12 == nil) return nil; - return ref PKsig.RSA(ip); + 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"; + } +} + +# +# account for naming differences between keyring and factotum, and spki. +# this might not be the best place for this. +# +s2f(s: string): string +{ + case s { + "e" => return "ek"; + "d" => return "!dk"; + "p" => return "!q"; # NB: p and q (kp and kq) roles are reversed between libsec and pkcs + "q" => return "!p"; + "a" => return "!kq"; + "b" => return "!kp"; + "c" => return "!c2"; + * => return s; + } +} + +f2s(alg: string, s: string): string +{ + 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" => - a := getparams(sig.params, "r" :: "s" :: nil); - if(a == nil) - return nil; - return ref PKsig.DSA(a[0], a[1]); - "elgamal" => - a := getparams(sig.params, "r" :: "s" :: nil); - if(a == nil) - return nil; - return ref PKsig.Elgamal(a[0], a[1]); + case s { + "p" or "q" => return s; + "alpha" => return "g"; + "key" => return "y"; + } * => - return nil; + ; } + if(s != nil && s[0] == '!') + return s[1:]; + return s; } -getparams(v: array of (string, array of byte), names: list of string): array of ref IPint +Keyrep.eq(k1: self ref Keyrep, k2: ref Keyrep): int { - r := array[len names] of ref IPint; - for(i := 0; names != nil; names = tl names){ - r[i] = getp(v, hd names); - if(r[i] == nil) - return nil; - i++; + # 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; } - return r; + for(l2 := k2.els; l2 != nil; l2 = tl l2) + if(k1.get((hd l2).t0) == nil) + return 0; + return 1; } -getp(v: array of (string, array of byte), name: string): ref IPint +sig2icert(sig: ref Signature, signer: string, exp: int): ref Keyring->Certificate { - for(i := 0; i < len v; i++) - if(v[i].t0 == name) - return IPint.bebytestoip(v[i].t1); - return nil; + 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); +} + +icert2els(cert: ref Keyring->Certificate): (string, string, string, list of (string, array of byte)) +{ + s := kr->certtoattr(cert); + if(s == nil) + return (nil, nil, nil, nil); + (nil, l) := sys->tokenize(s, " "); # really need parseattr, and a better interface + vals: list of (string, array of byte); + alg, hashalg, signer: string; + for(; l != nil; l = tl l){ + (nf, fld) := sys->tokenize(hd l, "="); + if(nf != 2) + continue; + case hd fld { + "sigalg" => + (nf, fld) = sys->tokenize(hd tl fld, "-"); + if(nf != 2) + continue; + alg = hd fld; + hashalg = hd tl fld; + "signer" => + signer = hd tl fld; + "expires" => + ; # don't care + * => + vals = (hd fld, base16->dec(hd tl fld)) :: vals; + } + } + return (alg, hashalg, signer, revt(vals)); } # @@ -2271,27 +2343,23 @@ pkcs1_encode(ha: string, hash: array of byte, mlen: int): array of byte # rsacomp(block: array of byte, akey: ref Key): array of byte { - pick pk := akey.pk { - RSA => - x := IPint.bebytestoip(block); - y := x.expmod(pk.ek, pk.n); - ybytes := y.iptobebytes(); - #dump("rsacomp", ybytes); - k := 1024; # key.modlen; - ylen := len ybytes; - if(ylen < k) { - a := array[k] of { * => byte 0}; - a[k-ylen:] = ybytes[0:]; - ybytes = a; - } - else if(ylen > k) { - # assume it has leading zeros (mod should make it so) - a := array[k] of byte; - a[0:] = ybytes[ylen-k:]; - ybytes = a; - } - return ybytes; - * => - return nil; - } + key := Keyrep.pk(akey.pk); + x := kr->IPint.bebytestoip(block); + y := x.expmod(key.get("e"), key.get("n")); + ybytes := y.iptobebytes(); +#dump("rsacomp", ybytes); + k := 1024; # key.modlen; + ylen := len ybytes; + if(ylen < k) { + a := array[k] of { * => byte 0}; + a[k-ylen:] = ybytes[0:]; + ybytes = a; + } + else if(ylen > k) { + # assume it has leading zeros (mod should make it so) + a := array[k] of byte; + a[0:] = ybytes[ylen-k:]; + ybytes = a; + } + return ybytes; } diff --git a/appl/lib/spki/verifier.b b/appl/lib/spki/verifier.b index b2304a10..ffcdfcad 100644 --- a/appl/lib/spki/verifier.b +++ b/appl/lib/spki/verifier.b @@ -7,8 +7,9 @@ implement Verifier; include "sys.m"; sys: Sys; -include "ipints.m"; -include "crypt.m"; +include "keyring.m"; + kr: Keyring; + IPint: import kr; include "bufio.m"; bufio: Bufio; @@ -31,6 +32,7 @@ debug := 0; init() { sys = load Sys Sys->PATH; + kr = load Keyring Keyring->PATH; bufio = load Bufio Bufio->PATH; sexprs = load Sexprs Sexprs->PATH; spki = load SPKI SPKI->PATH; |
