summaryrefslogtreecommitdiff
path: root/appl/lib/spki
diff options
context:
space:
mode:
Diffstat (limited to 'appl/lib/spki')
-rw-r--r--appl/lib/spki/spki.b536
-rw-r--r--appl/lib/spki/verifier.b6
2 files changed, 236 insertions, 306 deletions
diff --git a/appl/lib/spki/spki.b b/appl/lib/spki/spki.b
index 615aa48e..7a4854df 100644
--- a/appl/lib/spki/spki.b
+++ b/appl/lib/spki/spki.b
@@ -1,7 +1,7 @@
implement SPKI;
#
-# Copyright © 2004 Vita Nuova Holdings Limited
+# Copyright © 2004,2008 Vita Nuova Holdings Limited
#
# To do:
# - diagnostics
@@ -14,11 +14,13 @@ include "sys.m";
include "daytime.m";
daytime: Daytime;
-include "keyring.m";
- kr: Keyring;
- IPint, Certificate, PK, SK: import kr;
+include "ipints.m";
+ ipints: IPints;
+ IPint: import ipints;
-include "security.m";
+include "crypt.m";
+ crypt: Crypt;
+ PK, PKsig, SK: import crypt;
include "bufio.m";
@@ -37,7 +39,7 @@ debug: con 0;
init()
{
sys = load Sys Sys->PATH;
- kr = load Keyring Keyring->PATH;
+ crypt = load Crypt Crypt->PATH;
daytime = load Daytime Daytime->PATH;
sexprs = load Sexprs Sexprs->PATH;
base16 = load Encoding Encoding->BASE16PATH;
@@ -263,23 +265,24 @@ parsesig(e: ref Sexp): ref Signature
sigalg: string;
if(k != nil)
sigalg = k.sigalg();
- return ref Signature(hash, k, sigalg, (nil, val.asdata()) :: nil);
+ return ref Signature(hash, k, sigalg, array[] of {("", val.asdata())});
}
sigalg := val.op();
if(sigalg == nil)
return nil;
- rl: list of (string, array of byte);
+ vals := array[len val.args()] of (string, array of byte);
+ i := 0;
for(els := val.args(); els != nil; els = tl els){
g := hd els;
if(g.islist()){
arg := onlyarg(g);
if(arg == nil)
return nil;
- rl = (g.op(), arg.asdata()) :: rl;
+ vals[i++] = (g.op(), arg.asdata());
}else
- rl = (nil, g.asdata()) :: rl;
+ vals[i++] = ("", g.asdata());
}
- return ref Signature(hash, k, sigalg, revt(rl));
+ return ref Signature(hash, k, sigalg, vals);
}
parsecompound(e: ref Sexp): ref Name
@@ -359,31 +362,30 @@ parsekey(e: ref Sexp): ref Key
kl := (hd l).args();
if(kl == nil)
return nil;
- els: list of (string, ref IPint);
+ els := array[len kl] of (string, array of byte);
+ i := 0;
for(; kl != nil; kl = tl kl){
t := (hd kl).op();
a := onlyarg(hd kl).asdata();
if(a == nil)
return nil;
- 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;
+ els[i++] = (t, a);
}
- sk: ref Keyring->SK;
+ pk: ref Crypt->PK;
+ sk: ref Crypt->SK;
+ nbits := 0;
if(issk){
- krp = ref Keyrep.SK(alg, "sdsi", els);
- sk = krp.mksk();
+ (sk, pk, nbits) = mksk(alg, els);
if(sk == nil){
- sys->print("can't convert private-key\n");
+ sys->werrstr("can't convert private-key");
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);
@@ -550,12 +552,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.sig == nil)
+ if(sig.params == nil)
return "missing signature value";
pk := sig.key.pk;
if(pk == nil)
- 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);
+ 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);
#sys->print("nbits= %d\n", sig.key.nbits);
(alg, enc, hashalg) := sig.algs();
if(alg == nil)
@@ -574,10 +576,12 @@ checksig(c: ref Cert, sig: ref Signature): string
#dump("check/hashed", hash);
#dump("check/h", h);
ip := IPint.bebytestoip(h);
- isig := sig2icert(sig, "sdsi", 0);
+ isig := sig2isig(sig);
if(isig == nil)
- return "couldn't convert SPKI signature to Keyring form";
- if(!kr->verifym(pk, isig, ip))
+ 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 "signature does not match";
return nil;
}
@@ -598,7 +602,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 Keyring->SK for signature");
+ return (nil, "missing private key 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)
@@ -620,18 +624,16 @@ 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);
- 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);
+ 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
+ }
return (sig, nil);
}
@@ -645,11 +647,11 @@ hashbytes(a: array of byte, alg: string): array of byte
hash: array of byte;
case alg {
"md5" =>
- hash = array[Keyring->MD5dlen] of byte;
- kr->md5(a, len a, hash, nil);
+ hash = array[Crypt->MD5dlen] of byte;
+ crypt->md5(a, len a, hash, nil);
"sha" or "sha1" =>
- hash = array[Keyring->SHA1dlen] of byte;
- kr->sha1(a, len a, hash, nil);
+ hash = array[Crypt->SHA1dlen] of byte;
+ crypt->sha1(a, len a, hash, nil);
* =>
raise "Spki->hashbytes: unknown algorithm: "+alg;
}
@@ -701,10 +703,10 @@ sigalgs(alg: string): (string, string, string)
Signature.sexp(sg: self ref Signature): ref Sexp
{
sv: ref Sexp;
- if(len sg.sig != 1){
+ if(len sg.params != 1){
l: list of ref Sexp;
- for(els := sg.sig; els != nil; els = tl els){
- (op, val) := hd els;
+ for(i := 0; i < len sg.params; i++){
+ (op, val) := sg.params[i];
if(op != nil)
l = ref Sexp.List(ref Sexp.String(op,nil) :: ref Sexp.Binary(val,nil) :: nil) :: l;
else
@@ -712,7 +714,7 @@ Signature.sexp(sg: self ref Signature): ref Sexp
}
sv = ref Sexp.List(rev(l));
}else
- sv = ref Sexp.Binary((hd sg.sig).t1, nil); # no list if signature has one component
+ sv = ref Sexp.Binary(sg.params[0].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() ::
@@ -1005,11 +1007,16 @@ Name.eq(a: self ref Name, b: ref Name): int
Key.public(key: self ref Key): ref Key
{
if(key.sk != nil){
- pk := ref *key;
- if(pk.pk == nil)
- pk.pk = kr->sktopk(pk.sk);
- pk.sk = nil;
- return pk;
+ 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;
}
if(key.pk == nil)
return nil;
@@ -1049,9 +1056,9 @@ Key.hashexp(key: self ref Key, alg: string): ref Hash
Key.sigalg(k: self ref Key): string
{
if(k.pk != nil)
- alg := k.pk.sa.name;
+ alg := pkalg(k.pk);
else if(k.sk != nil)
- alg = k.sk.sa.name;
+ alg = skalg(k.sk);
else
return nil;
if(k.halg != nil){
@@ -1062,6 +1069,30 @@ 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();
@@ -1078,24 +1109,19 @@ Key.sexp(k: self ref Key): ref Sexp
return nil;
}
sort := "public-key";
- els: list of (string, ref IPint);
+ els: array of (string, ref IPint);
if(k.sk != nil){
- krp := Keyrep.sk(k.sk);
- if(krp == nil)
- return nil;
- els = krp.els;
+ els = repsk(k.sk);
sort = "private-key";
- }else{
- krp := Keyrep.pk(k.pk);
- if(krp == nil)
- return nil;
- els = krp.els;
- }
+ }else
+ els = reppk(k.pk);
+ if(els == nil)
+ return nil;
rl: list of ref Sexp;
- for(; els != nil; els = tl els){
- (n, v) := hd els;
+ for(i := 0; i < len els; i++){
+ (n, v) := els[i];
a := pre0(v.iptobebytes());
- rl = ref Sexp.List(ref Sexp.String(f2s("rsa", n),nil) :: ref Sexp.Binary(a,nil) :: nil) :: rl;
+ rl = ref Sexp.List(ref Sexp.String(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);
@@ -1115,8 +1141,27 @@ Key.eq(k1: self ref Key, k2: ref Key): int
return 1;
}
}
- if(k1.pk != nil && k2.pk != nil)
- return kr->pktostr(k1.pk) == kr->pktostr(k2.pk); # TO DO
+ 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);
+ }
+ }
+ }
return 0;
}
@@ -2032,250 +2077,133 @@ 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;
-}
-
#
-# the following should probably be in a separate Limbo library module,
-# or provided in some way directly by Keyring
+# these are in the order given in draft-ietf-spki-cert-structure-06.txt
#
-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)
+mkpk(alg: string, els: array of (string, array of byte)): (ref Crypt->PK, int)
{
- 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 {
+ case alg {
"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)}));
+ a := getparams(els, "e" :: "n" :: nil);
+ if(a == nil)
+ break;
+ return (ref PK.RSA(a[1], a[0]), a[1].bits());
"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;
+ 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());
}
+ return (nil, 0);
}
-Keyrep.sk(pk: ref Keyring->SK): ref Keyrep.SK
+reppk(pk: ref Crypt->PK): array of (string, ref IPint)
{
- 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" =>
- 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" =>
- 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)}));
+ 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)};
* =>
return nil;
}
}
-Keyrep.get(k: self ref Keyrep, n: string): ref IPint
-{
- 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)
+mksk(alg: string, els: array of (string, array of byte)): (ref Crypt->SK, ref Crypt->PK, int)
{
- case k.alg {
+ case 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";
+ 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());
+ "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 (nil, nil, 0);
}
-Keyrep.mksk(k: self ref Keyrep): ref Keyring->SK
+repsk(sk: ref Crypt->SK): array of (string, ref IPint)
{
- case k.alg {
- "rsa" =>
- 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 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()));
+ 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)};
* =>
- 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;
+ return nil;
}
}
-f2s(alg: string, s: string): string
+sig2isig(sig: ref Signature): ref Crypt->PKsig
{
- case alg {
+ if(sig.params == nil)
+ return nil;
+ case sig.algs().t0 {
"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";
- }
+ ip := getp(sig.params, "");
+ if(ip == nil)
+ return nil;
+ return ref PKsig.RSA(ip);
"dsa" =>
- case s {
- "p" or "q" => return s;
- "alpha" => return "g";
- "key" => return "y";
- }
+ 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]);
* =>
- ;
+ return nil;
}
- if(s != nil && s[0] == '!')
- return s[1:];
- return s;
}
-Keyrep.eq(k1: self ref Keyrep, k2: ref Keyrep): int
+getparams(v: array of (string, array of byte), names: list of string): array of ref IPint
{
- # 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;
+ 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++;
}
- for(l2 := k2.els; l2 != nil; l2 = tl l2)
- if(k1.get((hd l2).t0) == nil)
- return 0;
- return 1;
+ return r;
}
-sig2icert(sig: ref Signature, signer: string, exp: int): ref Keyring->Certificate
+getp(v: array of (string, array of byte), name: string): ref IPint
{
- 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));
+ for(i := 0; i < len v; i++)
+ if(v[i].t0 == name)
+ return IPint.bebytestoip(v[i].t1);
+ return nil;
}
#
@@ -2343,23 +2271,27 @@ pkcs1_encode(ha: string, hash: array of byte, mlen: int): array of byte
#
rsacomp(block: array of byte, akey: ref Key): array of byte
{
- 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;
+ 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;
+ }
}
diff --git a/appl/lib/spki/verifier.b b/appl/lib/spki/verifier.b
index ffcdfcad..b2304a10 100644
--- a/appl/lib/spki/verifier.b
+++ b/appl/lib/spki/verifier.b
@@ -7,9 +7,8 @@ implement Verifier;
include "sys.m";
sys: Sys;
-include "keyring.m";
- kr: Keyring;
- IPint: import kr;
+include "ipints.m";
+include "crypt.m";
include "bufio.m";
bufio: Bufio;
@@ -32,7 +31,6 @@ 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;