1Rawsexprs: module 2{ 3 PATH: con "rawsexprs.dis"; 4 5 Sexp: adt { 6 pick { 7 String => 8 s: string; 9 hint: string; 10 Binary => 11 data: array of byte; 12 hint: string; 13 List => 14 l: cyclic list of ref Sexp; 15 } 16 17 unpack: fn(a: array of byte): (ref Sexp, array of byte, string); 18 text: fn(e: self ref Sexp): string; 19 packedsize: fn(e: self ref Sexp): int; 20 pack: fn(e: self ref Sexp): array of byte; 21 }; 22 23 init: fn(); 24}; 25 26SPKI: module 27{ 28 PATH: con "/dis/lib/spki/spki.dis"; 29 30 Hash: adt { 31 alg: string; 32 hash: array of byte; 33 34 sexp: fn(h: self ref Hash): ref Sexprs->Sexp; 35 text: fn(h: self ref Hash): string; 36 eq: fn(h1: self ref Hash, h2: ref Hash): int; 37 }; 38 39 Key: adt { 40 pk: ref Keyring->PK; # either pk/sk or hash might be nil 41 sk: ref Keyring->SK; 42 nbits: int; 43 halg: string; # basic signature hash algorithm 44 henc: string; # pre-signature encoding 45 hash: list of ref Hash; 46 47 hashed: fn(k: self ref Key, alg: string): array of byte; 48 hashexp: fn(k: self ref Key, alg: string): ref Hash; 49 ishash: fn(k: self ref Key): int; 50 public: fn(k: self ref Key): ref Key; 51 sigalg: fn(k: self ref Key): string; 52 text: fn(k: self ref Key): string; 53 sexp: fn(k: self ref Key): ref Sexprs->Sexp; 54 eq: fn(k1: self ref Key, k2: ref Key): int; 55 }; 56 57 Name: adt { 58 principal: ref Key; 59 names: list of string; 60 61 isprincipal: fn(n: self ref Name): int; 62 local: fn(n: self ref Name): ref Name; 63 islocal: fn(n: self ref Name): int; 64 isprefix: fn(n1: self ref Name, n2: ref Name): int; 65 text: fn(n: self ref Name): string; 66 sexp: fn(n: self ref Name): ref Sexprs->Sexp; 67 eq: fn(n1: self ref Name, n2: ref Name): int; 68 }; 69 70 Cert: adt { 71 e: ref Sexprs->Sexp; # S-expression, if originally parsed 72 issuer: ref Name; 73 subject: ref Subject; 74 valid: ref Valid; 75 pick { 76 A or KH or O => # auth, keyholder or object 77 delegate: int; 78 tag: ref Sexprs->Sexp; 79 N => # name 80 } 81 82 text: fn(c: self ref Cert): string; 83 sexp: fn(c: self ref Cert): ref Sexprs->Sexp; 84 }; 85 86 # the pick might move to a more general `Principal' structure, 87 # allowing compound and quoting principals 88 Subject: adt { 89 pick{ 90 P => 91 key: ref Key; 92 N => 93 name: ref Name; 94 O => 95 hash: ref Hash; 96 KH => 97 holder: ref Name; 98 T => 99 k, n: int; 100 subs: cyclic list of ref Subject; 101 } 102 103 eq: fn(s1: self ref Subject, s2: ref Subject): int; 104 principal: fn(s: self ref Subject): ref Key; 105 text: fn(s: self ref Subject): string; 106 sexp: fn(s: self ref Subject): ref Sexprs->Sexp; 107 }; 108 109 Principal: adt[T] { 110 pick{ 111 N => 112 name: ref Name; 113 Q => 114 quoter: T; 115 quotes: cyclic ref Principal; 116 } 117 }; 118 119 Signature: adt { 120 hash: ref Hash; 121 key: ref Key; # find by hash if necessary 122 sa: string; # alg[-[encoding-]hash] 123 sig: list of (string, array of byte); 124 125 algs: fn(s: self ref Signature): (string, string, string); 126 sexp: fn(s: self ref Signature): ref Sexprs->Sexp; 127 text: fn(s: self ref Signature): string; 128 }; 129 130 Seqel: adt { 131 pick{ 132 C => 133 c: ref Cert; 134 K => 135 k: ref Key; 136 O => 137 op: string; 138 args: list of ref Sexprs->Sexp; 139 S => 140 sig: ref Signature; 141 RV => # <reval> 142 ok: list of (string, string); 143 onetime: array of byte; 144 valid: ref Valid; 145 CRL => 146 bad: list of (string, string); 147 valid: ref Valid; 148 Delta => 149 hash: string; 150 bad: list of (string, string); 151 valid: ref Valid; 152 E => 153 exp: ref Sexprs->Sexp; 154 } 155 156 sexp: fn(se: self ref Seqel): ref Sexprs->Sexp; 157 text: fn(se: self ref Seqel): string; 158 }; 159 160 Valid: adt { 161 notbefore: string; 162 notafter: string; 163 164 intersect: fn(a: self Valid, b: Valid): (int, Valid); 165 text: fn(a: self Valid): string; 166 sexp: fn(a: self Valid): ref Sexprs->Sexp; 167 }; 168 169 Toplev: adt { 170 pick { 171 C => 172 v: ref Cert; 173 Sig => 174 v: ref Signature; 175 K => 176 v: ref Key; 177 Seq => 178 v: list of ref Seqel; 179 } 180 181 sexp: fn(t: self ref Toplev): ref Sexprs->Sexp; 182 text: fn(t: self ref Toplev): string; 183 }; 184 185 init: fn(); 186 187 # parse structures 188 parse: fn(s: ref Sexprs->Sexp): (ref Toplev, string); 189 parseseq: fn(s: ref Sexprs->Sexp): list of ref Seqel; 190 parsecert: fn(s: ref Sexprs->Sexp): ref Cert; 191 parsesig: fn(s: ref Sexprs->Sexp): ref Signature; 192 parsename: fn(s: ref Sexprs->Sexp): ref Name; 193 parsekey: fn(s: ref Sexprs->Sexp): ref Key; 194 parsehash: fn(s: ref Sexprs->Sexp): ref Hash; 195 parsecompound: fn(s: ref Sexprs->Sexp): ref Name; 196 parsevalid: fn(s: ref Sexprs->Sexp): ref Valid; 197 198 # signature checking 199 checksig: fn(c: ref Cert, sig: ref Signature): string; 200 sig2icert: fn(sig: ref Signature, signer: string, exp: int): ref Keyring->Certificate; 201 202 # signature making 203 signcert: fn(c: ref Cert, sigalg: string, key: ref Key): (ref Signature, string); 204 signbytes: fn(a: array of byte, sigalg: string, key: ref Key): (ref Signature, string); 205 206 # tags 207 maketag: fn(e: ref Sexprs->Sexp): ref Sexprs->Sexp; 208 tagintersect: fn(t1: ref Sexprs->Sexp, t2: ref Sexprs->Sexp): ref Sexprs->Sexp; 209 tagimplies: fn(t1: ref Sexprs->Sexp, t2: ref Sexprs->Sexp): int; 210 211 # hash canonical s-expression 212 hashbytes: fn(a: array of byte, alg: string): array of byte; 213 hashexp: fn(e: ref Sexprs->Sexp, alg: string): array of byte; 214 215 # convert between date and time strings and Inferno form 216 date2epoch: fn(s: string): int; # YYYY-MM-DD_HH:MM:SS 217 epoch2date: fn(t: int): string; 218 time2secs: fn(s: string): int; # HH:MM:SS 219 secs2time: fn(t: int): string; 220 221 # misc 222 sigalgs: fn(algs: string): (string, string, string); 223 224 # debugging 225 dump: fn(s: string, a: array of byte); 226}; 227 228Proofs: module 229{ 230 Proof: adt { 231 n: int; 232 233 parse: fn(s: string): ref Proof; 234 sexp: fn(p: self ref Proof): ref Sexprs->Sexp; 235 text: fn(p: self ref Proof): string; 236 }; 237 238 init: fn(): string; 239}; 240 241Verifier: module 242{ 243 PATH: con "/dis/lib/spki/verifier.dis"; 244 245 Speaksfor: adt { 246 subject: ref SPKI->Subject; 247 name: ref SPKI->Name; 248 regarding: ref Sexprs->Sexp; 249 valid: ref SPKI->Valid; 250 }; 251 252 init: fn(); 253 verify: fn(seq: list of ref SPKI->Seqel): (ref Speaksfor, list of ref SPKI->Seqel, string); 254}; 255