Unified · Split
| @@ -77,6 +77,8 @@ TARG=\ · 76 unmodified lines | |||
| 77 | nametree.dis\ | 77 | nametree.dis\ |
| 78 | names.dis\ | 78 | names.dis\ |
| 79 | newns.dis\ | 79 | newns.dis\ |
| 80 | ninep.dis\ | ||
| 81 | oldauth.dis\ | ||
| 80 | palm.dis\ | 82 | palm.dis\ |
| 81 | palmdb.dis\ | 83 | palmdb.dis\ |
| 82 | palmfile.dis\ | 84 | palmfile.dis\ |
| @@ -0,0 +1,344 @@ | |||
| 1 | implement Oldauth; | ||
| 2 | |||
| 3 | # | ||
| 4 | # TO DO | ||
| 5 | # - more error checking? | ||
| 6 | # - details of auth error handling | ||
| 7 | # | ||
| 8 | |||
| 9 | include "sys.m"; | ||
| 10 | sys: Sys; | ||
| 11 | |||
| 12 | include "ipints.m"; | ||
| 13 | ipints: IPints; | ||
| 14 | IPint: import ipints; | ||
| 15 | |||
| 16 | include "crypt.m"; | ||
| 17 | crypt: Crypt; | ||
| 18 | PK, SK, PKsig: import crypt; | ||
| 19 | |||
| 20 | include "msgio.m"; | ||
| 21 | msgio: Msgio; | ||
| 22 | |||
| 23 | include "oldauth.m"; | ||
| 24 | |||
| 25 | init() | ||
| 26 | { | ||
| 27 | sys = load Sys Sys->PATH; | ||
| 28 | ipints = load IPints IPints->PATH; | ||
| 29 | crypt = load Crypt Crypt->PATH; | ||
| 30 | msgio = load Msgio Msgio->PATH; | ||
| 31 | msgio->init(); | ||
| 32 | } | ||
| 33 | |||
| 34 | efmt() | ||
| 35 | { | ||
| 36 | sys->werrstr("input or format error"); | ||
| 37 | } | ||
| 38 | |||
| 39 | readauthinfo(filename: string): ref Authinfo | ||
| 40 | { | ||
| 41 | fd := sys->open(filename, Sys->OREAD); | ||
| 42 | if(fd == nil) | ||
| 43 | return nil; | ||
| 44 | a := array[5] of string; | ||
| 45 | for(i := 0; i < len a; i++){ | ||
| 46 | (s, err) := getstr(fd); | ||
| 47 | if(err != nil){ | ||
| 48 | sys->werrstr(sys->sprint("%q: input or format error", filename)); | ||
| 49 | return nil; | ||
| 50 | } | ||
| 51 | a[i] = s; | ||
| 52 | } | ||
| 53 | info := ref Authinfo; | ||
| 54 | (info.spk, nil) = strtopk(a[0]); | ||
| 55 | info.cert = strtocert(a[1]); | ||
| 56 | (info.mysk, info.owner) = strtosk(a[2]); | ||
| 57 | if(info.spk == nil || info.cert == nil || info.mysk == nil){ | ||
| 58 | efmt(); | ||
| 59 | return nil; | ||
| 60 | } | ||
| 61 | info.mypk = crypt->sktopk(info.mysk); | ||
| 62 | info.alpha = IPint.strtoip(a[3], 64); | ||
| 63 | info.p = IPint.strtoip(a[4], 64); | ||
| 64 | if(info.alpha == nil || info.p == nil){ | ||
| 65 | efmt(); | ||
| 66 | return nil; | ||
| 67 | } | ||
| 68 | return info; | ||
| 69 | } | ||
| 70 | |||
| 71 | writeauthinfo(filename: string, info: ref Authinfo): int | ||
| 72 | { | ||
| 73 | if(info.alpha == nil || info.p == nil || | ||
| 74 | info.spk == nil || info.mysk == nil || info.cert == nil){ | ||
| 75 | sys->werrstr("invalid authinfo"); | ||
| 76 | return -1; | ||
| 77 | } | ||
| 78 | a := array[5] of string; | ||
| 79 | a[0] = pktostr(info.spk, info.cert.signer); # signer's public key | ||
| 80 | a[1] = certtostr(info.cert); # certificate for my public key | ||
| 81 | a[2] = sktostr(info.mysk, info.owner); # my secret/public key | ||
| 82 | a[3] = b64(info.alpha); # diffie hellman base | ||
| 83 | a[4] = b64(info.p); # diffie hellman modulus | ||
| 84 | fd := sys->open(filename, Sys->OWRITE|Sys->OTRUNC); | ||
| 85 | if(fd == nil){ | ||
| 86 | fd = sys->create(filename, Sys->OWRITE, 8r600); | ||
| 87 | if(fd == nil){ | ||
| 88 | fd = sys->open(filename, Sys->OWRITE); | ||
| 89 | if(fd == nil) | ||
| 90 | return -1; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | for(i := 0; i < len a; i++) | ||
| 94 | if(sendstr(fd, a[i]) <= 0) | ||
| 95 | return -1; | ||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | sendstr(fd: ref Sys->FD, s: string): int | ||
| 100 | { | ||
| 101 | a := array of byte s; | ||
| 102 | return msgio->sendmsg(fd, a, len a); | ||
| 103 | } | ||
| 104 | |||
| 105 | getstr(fd: ref Sys->FD): (string, string) | ||
| 106 | { | ||
| 107 | b := msgio->getmsg(fd); | ||
| 108 | if(b == nil) | ||
| 109 | return (nil, sys->sprint("%r")); | ||
| 110 | return (string b, nil); | ||
| 111 | } | ||
| 112 | |||
| 113 | certtostr(c: ref Certificate): string | ||
| 114 | { | ||
| 115 | s := sys->sprint("%s\n%s\n%s\n%ud\n", c.sa, c.ha, c.signer, c.exp); | ||
| 116 | pick r := c.sig { | ||
| 117 | RSA => | ||
| 118 | s += b64(r.n)+"\n"; | ||
| 119 | Elgamal => | ||
| 120 | s += b64(r.r)+"\n"+b64(r.s)+"\n"; | ||
| 121 | DSA => | ||
| 122 | s += b64(r.r)+"\n"+b64(r.s)+"\n"; | ||
| 123 | * => | ||
| 124 | raise "unknown key type"; | ||
| 125 | } | ||
| 126 | return s; | ||
| 127 | } | ||
| 128 | |||
| 129 | pktostr(pk: ref PK, owner: string): string | ||
| 130 | { | ||
| 131 | pick k := pk { | ||
| 132 | RSA => | ||
| 133 | s := sys->sprint("rsa\n%s\n", owner); | ||
| 134 | s += b64(k.n)+"\n"+b64(k.ek)+"\n"; | ||
| 135 | return s; | ||
| 136 | Elgamal => | ||
| 137 | s := sys->sprint("elgamal\n%s\n", owner); | ||
| 138 | s += b64(k.p)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n"; | ||
| 139 | return s; | ||
| 140 | DSA => | ||
| 141 | s := sys->sprint("dsa\n%s\n", owner); | ||
| 142 | s += b64(k.p)+"\n"+b64(k.q)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n"; | ||
| 143 | return s; | ||
| 144 | * => | ||
| 145 | raise "unknown key type"; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | sktostr(sk: ref SK, owner: string): string | ||
| 150 | { | ||
| 151 | pick k := sk { | ||
| 152 | RSA => | ||
| 153 | s := sys->sprint("rsa\n%s\n", owner); | ||
| 154 | s += b64(k.pk.n)+"\n"+b64(k.pk.ek)+"\n"+b64(k.dk)+"\n"+ | ||
| 155 | b64(k.p)+"\n"+b64(k.q)+"\n"+ | ||
| 156 | b64(k.kp)+"\n"+b64(k.kq)+"\n"+ | ||
| 157 | k.c2.iptob64()+"\n"; | ||
| 158 | return s; | ||
| 159 | Elgamal => | ||
| 160 | pk := k.pk; | ||
| 161 | s := sys->sprint("elgamal\n%s\n", owner); | ||
| 162 | s += b64(pk.p)+"\n"+b64(pk.alpha)+"\n"+b64(pk.key)+"\n"+b64(k.secret)+"\n"; | ||
| 163 | return s; | ||
| 164 | DSA => | ||
| 165 | pk := k.pk; | ||
| 166 | s := sys->sprint("dsa\n%s\n", owner); | ||
| 167 | s += b64(pk.p)+"\n"+b64(pk.q)+"\n"+b64(pk.alpha)+"\n"+b64(k.secret)+"\n"; | ||
| 168 | return s; | ||
| 169 | * => | ||
| 170 | raise "unknown key type"; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | fields(s: string): array of string | ||
| 175 | { | ||
| 176 | (nf, flds) := sys->tokenize(s, "\n^"); | ||
| 177 | a := array[nf] of string; | ||
| 178 | for(i := 0; i < len a; i++){ | ||
| 179 | a[i] = hd flds; | ||
| 180 | flds = tl flds; | ||
| 181 | } | ||
| 182 | return a; | ||
| 183 | } | ||
| 184 | |||
| 185 | bigs(a: array of string): array of ref IPint | ||
| 186 | { | ||
| 187 | b := array[len a] of ref IPint; | ||
| 188 | for(i := 0; i < len b; i++){ | ||
| 189 | b[i] = IPint.strtoip(a[i], 64); | ||
| 190 | if(b[i] == nil) | ||
| 191 | return nil; | ||
| 192 | } | ||
| 193 | return b; | ||
| 194 | } | ||
| 195 | |||
| 196 | need[T](a: array of T, min: int): int | ||
| 197 | { | ||
| 198 | if(len a < min){ | ||
| 199 | efmt(); | ||
| 200 | return 1; | ||
| 201 | } | ||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | |||
| 205 | strtocert(s: string): ref Certificate | ||
| 206 | { | ||
| 207 | f := fields(s); | ||
| 208 | if(need(f, 4)) | ||
| 209 | return nil; | ||
| 210 | sa := f[0]; | ||
| 211 | ha := f[1]; | ||
| 212 | signer := f[2]; | ||
| 213 | exp := int big f[3]; # unsigned | ||
| 214 | b := bigs(f[4:]); | ||
| 215 | case f[0] { | ||
| 216 | "rsa" => | ||
| 217 | if(need(b, 1)) | ||
| 218 | return nil; | ||
| 219 | return ref Certificate(sa, ha, signer, exp, ref PKsig.RSA(b[0])); | ||
| 220 | "elgamal" => | ||
| 221 | if(need(b, 2)) | ||
| 222 | return nil; | ||
| 223 | return ref Certificate(sa, ha, signer, exp, ref PKsig.Elgamal(b[0], b[1])); | ||
| 224 | "dsa" => | ||
| 225 | if(need(b, 2)) | ||
| 226 | return nil; | ||
| 227 | return ref Certificate(sa, ha, signer, exp, ref PKsig.DSA(b[0], b[1])); | ||
| 228 | * => | ||
| 229 | sys->werrstr("unknown algorithm: "+f[0]); | ||
| 230 | return nil; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | strtopk(s: string): (ref PK, string) | ||
| 235 | { | ||
| 236 | f := fields(s); | ||
| 237 | if(need(f, 3)) | ||
| 238 | return (nil, "format error"); | ||
| 239 | sa := f[0]; | ||
| 240 | owner := f[1]; | ||
| 241 | b := bigs(f[2:]); | ||
| 242 | case sa { | ||
| 243 | "rsa" => | ||
| 244 | if(need(b, 2)) | ||
| 245 | return (nil, "format error"); | ||
| 246 | return (ref PK.RSA(b[0], b[1]), owner); | ||
| 247 | "elgamal" => | ||
| 248 | if(need(b, 3)) | ||
| 249 | return (nil, "format error"); | ||
| 250 | return (ref PK.Elgamal(b[0], b[1], b[2]), owner); | ||
| 251 | "dsa" => | ||
| 252 | if(need(b, 4)) | ||
| 253 | return (nil, "format error"); | ||
| 254 | return (ref PK.DSA(b[0], b[1], b[2], b[3]), owner); | ||
| 255 | * => | ||
| 256 | return (nil, "unknown algorithm: "+f[0]); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | strtosk(s: string): (ref SK, string) | ||
| 261 | { | ||
| 262 | f := fields(s); | ||
| 263 | if(need(f, 3)) | ||
| 264 | return (nil, "format error"); | ||
| 265 | sa := f[0]; | ||
| 266 | owner := f[1]; | ||
| 267 | b := bigs(f[2:]); | ||
| 268 | case sa { | ||
| 269 | "rsa" => | ||
| 270 | if(need(b, 8)) | ||
| 271 | return (nil, "format error"); | ||
| 272 | return (ref SK.RSA(ref PK.RSA(b[0], b[1]), b[2], b[3], b[4], b[5], b[6], b[7]), owner); | ||
| 273 | "elgamal" => | ||
| 274 | if(need(b, 4)) | ||
| 275 | return (nil, "format error"); | ||
| 276 | return (ref SK.Elgamal(ref PK.Elgamal(b[0], b[1], b[2]), b[3]), owner); | ||
| 277 | "dsa" => | ||
| 278 | if(need(b, 5)) | ||
| 279 | return (nil, "format error"); | ||
| 280 | return (ref SK.DSA(ref PK.DSA(b[0], b[1], b[2], b[3]), b[4]), owner); | ||
| 281 | * => | ||
| 282 | return (nil, "unknown algorithm: "+f[0]); | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | skalg(sk: ref SK): string | ||
| 287 | { | ||
| 288 | if(sk == nil) | ||
| 289 | return "nil"; | ||
| 290 | case tagof sk { | ||
| 291 | tagof SK.RSA => return "rsa"; | ||
| 292 | tagof SK.Elgamal => return "elgamal"; | ||
| 293 | tagof SK.DSA => return "dsa"; | ||
| 294 | * => return "gok"; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | sign(sk: ref SK, signer: string, exp: int, state: ref Crypt->DigestState, ha: string): ref Certificate | ||
| 299 | { | ||
| 300 | # add signer name and expiration time to hash | ||
| 301 | if(state == nil) | ||
| 302 | return nil; | ||
| 303 | a := sys->aprint("%s %d", signer, exp); | ||
| 304 | digest := hash(ha, a, state); | ||
| 305 | if(digest == nil) | ||
| 306 | return nil; | ||
| 307 | b := IPint.bebytestoip(digest); | ||
| 308 | return ref Certificate(skalg(sk), ha, signer, exp, crypt->sign(sk, b)); | ||
| 309 | } | ||
| 310 | |||
| 311 | verify(pk: ref PK, cert: ref Certificate, state: ref Crypt->DigestState): int | ||
| 312 | { | ||
| 313 | if(state == nil) | ||
| 314 | return 0; | ||
| 315 | a := sys->aprint("%s %d", cert.signer, cert.exp); | ||
| 316 | digest := hash(cert.ha, a, state); | ||
| 317 | if(digest == nil) | ||
| 318 | return 0; | ||
| 319 | b := IPint.bebytestoip(digest); | ||
| 320 | return crypt->verify(pk, cert.sig, b); | ||
| 321 | } | ||
| 322 | |||
| 323 | hash(ha: string, a: array of byte, state: ref Crypt->DigestState): array of byte | ||
| 324 | { | ||
| 325 | digest: array of byte; | ||
| 326 | case ha { | ||
| 327 | "sha" or "sha1" => | ||
| 328 | digest = array[Crypt->SHA1dlen] of byte; | ||
| 329 | crypt->sha1(a, len a, digest, state); | ||
| 330 | "md5" => | ||
| 331 | digest = array[Crypt->MD5dlen] of byte; | ||
| 332 | crypt->md5(a, len a, digest, state); | ||
| 333 | * => | ||
| 334 | # don't bother with md4 | ||
| 335 | sys->werrstr("unimplemented algorithm: "+ha); | ||
| 336 | return nil; | ||
| 337 | } | ||
| 338 | return digest; | ||
| 339 | } | ||
| 340 | |||
| 341 | b64(ip: ref IPint): string | ||
| 342 | { | ||
| 343 | return ip.iptob64z(); | ||
| 344 | } | ||
Binary file not shown.
| @@ -0,0 +1,246 @@ | |||
| 1 | .TH SECURITY-OLDAUTH 2 | ||
| 2 | .SH NAME | ||
| 3 | oldauth: certtostr, pktostr, sktostr, strtocert, strtopk, strtosk, sign, verify, readauthinfo, writeauthinfo \- encoding for original Inferno authentication protocol | ||
| 4 | .SH SYNOPSIS | ||
| 5 | .EX | ||
| 6 | include "ipints.m"; | ||
| 7 | include "crypt.m"; | ||
| 8 | include "oldauth.m"; | ||
| 9 | oldauth := load Oldauth Oldauth->PATH; | ||
| 10 | |||
| 11 | Certificate: adt | ||
| 12 | { | ||
| 13 | sa: string; | ||
| 14 | ha: string; | ||
| 15 | signer: string; | ||
| 16 | exp: int; | ||
| 17 | sig: ref Crypt->PKsig; | ||
| 18 | }; | ||
| 19 | |||
| 20 | Authinfo: adt | ||
| 21 | { | ||
| 22 | mysk: ref Crypt->SK; | ||
| 23 | mypk: ref Crypt->PK; | ||
| 24 | owner: string; | ||
| 25 | cert: ref Certificate; | ||
| 26 | spk: ref Crypt->PK; | ||
| 27 | alpha: ref IPints->IPint; | ||
| 28 | p: ref IPints->IPint; | ||
| 29 | }; | ||
| 30 | |||
| 31 | sign: fn (sk: ref Crypt->SK, signer: string, exp: int, | ||
| 32 | state: ref Crypt->DigestState, ha: string): ref Certificate; | ||
| 33 | verify: fn (pk: ref Crypt->PK, cert: ref Certificate, | ||
| 34 | state: ref Crypt->DigestState): int; | ||
| 35 | |||
| 36 | strtocert: fn(s: string): ref Certificate; | ||
| 37 | certtostr: fn(c: ref Certificate): string; | ||
| 38 | strtopk: fn(s: string): (ref Crypt->PK, string); | ||
| 39 | pktostr: fn(pk: ref Crypt->PK, owner: string): string; | ||
| 40 | strtosk: fn(s: string): (ref Crypt->SK, string); | ||
| 41 | sktostr: fn(sk: ref Crypt->SK, owner: string): string; | ||
| 42 | |||
| 43 | readauthinfo: fn(filename: string): ref Authinfo; | ||
| 44 | writeauthinfo: fn(filename: string, info: ref Authinfo): int; | ||
| 45 | .EE | ||
| 46 | .SH DESCRIPTION | ||
| 47 | Certificates, public keys, and private keys are passed over networks and between applications using a Unicode representation. | ||
| 48 | This collection of functions provide a means to convert adts supplied by the system to and from their portable textual representation. These routines are used by | ||
| 49 | .IR login (2) | ||
| 50 | and | ||
| 51 | .IR factotum (4) | ||
| 52 | to implement the Inferno authentication protocol. | ||
| 53 | .PP | ||
| 54 | Public and private keys are represented by | ||
| 55 | .B Crypt->PK | ||
| 56 | and | ||
| 57 | .B Crypt->SK | ||
| 58 | (see | ||
| 59 | .IR keyring-intro (2)). | ||
| 60 | An authentication domain is represented by | ||
| 61 | the public key of the domain's | ||
| 62 | .IR signer , | ||
| 63 | typically in control of a | ||
| 64 | .IR keyfs (4) | ||
| 65 | and running a | ||
| 66 | .IR logind (8). | ||
| 67 | Two adts associate a public/private key pair with a user name within a specific authentication domain: | ||
| 68 | .TP | ||
| 69 | .B Authinfo | ||
| 70 | The | ||
| 71 | .B Authinfo | ||
| 72 | adt contains an individual user's private and public key, a human-readable name for the key (eg, a user name), | ||
| 73 | the signer's certificate | ||
| 74 | and the signer's public key, and the Diffie-Hellman parameters. | ||
| 75 | The signer's certificate binds the user's public key to the given key name in the signer's domain. | ||
| 76 | .TP | ||
| 77 | .B Certificate | ||
| 78 | The | ||
| 79 | .B Certificate | ||
| 80 | adt contains a digital signature with the certification of the trusted authority (CA). | ||
| 81 | The signature covers not only the user's public key, but the key's name, the signer's name and | ||
| 82 | the expiration time of the certificate. | ||
| 83 | Both the key's name and the signer's name are local to the signer's domain. | ||
| 84 | .PP | ||
| 85 | .B Init | ||
| 86 | must be called before using any other operation in the module. | ||
| 87 | .PP | ||
| 88 | .B Sign | ||
| 89 | returns a Certificate containing the digital signature using secret key | ||
| 90 | .I sk | ||
| 91 | of a digest's | ||
| 92 | .IR state , | ||
| 93 | which is the output of the hash algorithm named | ||
| 94 | .IR ha , | ||
| 95 | combined with the hash of the signer's name, and the certificate's expiration time (in seconds from the Epoch). | ||
| 96 | Valid hash algorithms are | ||
| 97 | .B sha1 | ||
| 98 | and | ||
| 99 | .BR md5 . | ||
| 100 | The expiry time should be zero if the certificate does not expire. | ||
| 101 | Typically the | ||
| 102 | .I state | ||
| 103 | is the result of hashing | ||
| 104 | .IP | ||
| 105 | .EX | ||
| 106 | array of byte pktostr(pk, username) | ||
| 107 | .EE | ||
| 108 | .PP | ||
| 109 | for a given public key | ||
| 110 | .I pk | ||
| 111 | that is associated with the given | ||
| 112 | .I username | ||
| 113 | by the signer. | ||
| 114 | .PP | ||
| 115 | .B Verify | ||
| 116 | checks that the given Certificate is the result of signing the given | ||
| 117 | .I state | ||
| 118 | using the secret (private) key corresponding to public key | ||
| 119 | .IR pk . | ||
| 120 | It returns true (non-zero) if the certificate is valid, including the signer's name, and the expiration time; | ||
| 121 | the caller must enforce the expiration time if desired. | ||
| 122 | It returns false (zero) if the certificate is invalid. | ||
| 123 | . ####### | ||
| 124 | .PP | ||
| 125 | .B Sign | ||
| 126 | creates a digital signature of a digest from the concatenation of: a message, the name of the signer, and an expiration time. | ||
| 127 | .I State | ||
| 128 | is the digest state after running | ||
| 129 | .BR sha1 , | ||
| 130 | .B md4 | ||
| 131 | or | ||
| 132 | .B md5 | ||
| 133 | over the message. | ||
| 134 | .I Ha | ||
| 135 | is a string specifying the hash algorithm to use: | ||
| 136 | .B | ||
| 137 | "sha"\fR, | ||
| 138 | .B | ||
| 139 | "sha1"\fR, | ||
| 140 | .B | ||
| 141 | "md4"\fR | ||
| 142 | or | ||
| 143 | .B | ||
| 144 | "md5"\fR. | ||
| 145 | .B Sign | ||
| 146 | extends the digest to cover the signer's name | ||
| 147 | (taken from the private key, | ||
| 148 | .IR sk ) | ||
| 149 | and the expiration time. | ||
| 150 | It returns a certificate containing the digital signature of the digest, signer name, hash algorithm and signature algorithm. | ||
| 151 | If any parameter is invalid, | ||
| 152 | .B sign | ||
| 153 | returns nil. | ||
| 154 | The signature algorithm is implied by the type of the private key. | ||
| 155 | .PP | ||
| 156 | .B Verify | ||
| 157 | uses public key | ||
| 158 | .I pk | ||
| 159 | to verify a certificate. | ||
| 160 | It returns non-zero (true) if the certificate is valid; zero (false) otherwise. | ||
| 161 | .I State | ||
| 162 | is the digest state after running the chosen digest algorithm | ||
| 163 | over the message. | ||
| 164 | . ####### | ||
| 165 | .PP | ||
| 166 | The remaining operations fetch and store those values and convert to and from text representations for use in protocols and for storage. | ||
| 167 | .PP | ||
| 168 | .B Strtocert | ||
| 169 | takes a string argument containing a varying number of newline-separated fields: | ||
| 170 | a signature algorithm, a hash algorithm, a signer's name, an expiration time, and values representing a digital signature. | ||
| 171 | It returns the corresponding | ||
| 172 | .BR Certificate . | ||
| 173 | If the string is of improper format, the result is | ||
| 174 | .IR nil . | ||
| 175 | .PP | ||
| 176 | .B Certtostr | ||
| 177 | performs the inverse operation: takes the | ||
| 178 | .B Certificate | ||
| 179 | .I c | ||
| 180 | and produces a text string suitable for communication over a network. | ||
| 181 | Note that the string will contain newline characters. | ||
| 182 | .PP | ||
| 183 | .B Strtopk | ||
| 184 | and | ||
| 185 | .B strtosk | ||
| 186 | take as their arguments a string | ||
| 187 | .I s | ||
| 188 | representing the public and private keys respectively. | ||
| 189 | .I S | ||
| 190 | contains an algorithm name, a user name and values representing the key. | ||
| 191 | Each returns a tuple | ||
| 192 | .BI ( k,\ s ), | ||
| 193 | where | ||
| 194 | .I k | ||
| 195 | is the resulting key value (ie, | ||
| 196 | .B Crypt->PK | ||
| 197 | or | ||
| 198 | .BR Crypt->SK ) | ||
| 199 | and | ||
| 200 | .I s | ||
| 201 | is a string giving the name associated with the key, typically a user name. | ||
| 202 | If the format of | ||
| 203 | .I s | ||
| 204 | is invalid, | ||
| 205 | .I k | ||
| 206 | is | ||
| 207 | .IR nil , | ||
| 208 | and | ||
| 209 | .I s | ||
| 210 | contains a diagnostic. | ||
| 211 | .PP | ||
| 212 | .B Pktostr | ||
| 213 | and | ||
| 214 | .B sktostr | ||
| 215 | perform the inverse operations: | ||
| 216 | they take a public key (secret key) | ||
| 217 | .I pk | ||
| 218 | or | ||
| 219 | .IR sk , | ||
| 220 | the | ||
| 221 | .I owner | ||
| 222 | name to be associated with that key, and produce a printable representation as a string. | ||
| 223 | The | ||
| 224 | .I owner | ||
| 225 | names the user that owns the key; in the case of a public key, | ||
| 226 | the user is expected to possess the corresponding private key. | ||
| 227 | .PP | ||
| 228 | .B Readauthinfo | ||
| 229 | reads a representation of an | ||
| 230 | .B Authinfo | ||
| 231 | from a file. | ||
| 232 | It returns nil if there is a read error or a conversion error; | ||
| 233 | it returns a reference to the | ||
| 234 | .B Authinfo | ||
| 235 | otherwise. | ||
| 236 | .PP | ||
| 237 | .B Writeauthinfo | ||
| 238 | writes a representation of | ||
| 239 | .I info | ||
| 240 | to a file. It returns -1 if the write operation fails, 0 otherwise. | ||
| 241 | .SH SOURCE | ||
| 242 | .B /appl/lib/oldauth.b | ||
| 243 | .SH SEE ALSO | ||
| 244 | .IR crypt-intro (2), | ||
| 245 | .IR ipints (2), | ||
| 246 | .IR security-intro (2) | ||
| @@ -0,0 +1,48 @@ | |||
| 1 | Oldauth: module | ||
| 2 | { | ||
| 3 | PATH: con "/dis/lib/oldauth.dis"; | ||
| 4 | |||
| 5 | init: fn(); | ||
| 6 | |||
| 7 | # Inferno certificate | ||
| 8 | Certificate: adt | ||
| 9 | { | ||
| 10 | sa: string; # signature algorithm | ||
| 11 | ha: string; # hash algorithm | ||
| 12 | signer: string; # name of signer | ||
| 13 | exp: int; # expiration date | ||
| 14 | sig: ref Crypt->PKsig; | ||
| 15 | }; | ||
| 16 | |||
| 17 | # authentication info | ||
| 18 | Authinfo: adt | ||
| 19 | { | ||
| 20 | mysk: ref Crypt->SK; # my private key | ||
| 21 | mypk: ref Crypt->PK; # my public key | ||
| 22 | owner: string; # owner of mypk for certificate | ||
| 23 | cert: ref Certificate; # signature of my public key | ||
| 24 | spk: ref Crypt->PK; # signers public key | ||
| 25 | alpha: ref IPints->IPint; # diffie helman parameters | ||
| 26 | p: ref IPints->IPint; | ||
| 27 | }; | ||
| 28 | |||
| 29 | # auth io | ||
| 30 | readauthinfo: fn(filename: string): ref Authinfo; | ||
| 31 | writeauthinfo: fn(filename: string, info: ref Authinfo): int; | ||
| 32 | |||
| 33 | # convert types to text in a canonical form | ||
| 34 | certtostr: fn (c: ref Certificate): string; | ||
| 35 | pktostr: fn (pk: ref Crypt->PK, owner: string): string; | ||
| 36 | sktostr: fn (sk: ref Crypt->SK, owner: string): string; | ||
| 37 | |||
| 38 | # parse text into types | ||
| 39 | strtocert: fn (s: string): ref Certificate; | ||
| 40 | strtopk: fn (s: string): (ref Crypt->PK, string); | ||
| 41 | strtosk: fn (s: string): (ref Crypt->SK, string); | ||
| 42 | |||
| 43 | # create and verify Certificates | ||
| 44 | sign: fn (sk: ref Crypt->SK, signer: string, exp: int, state: ref Crypt->DigestState, ha: string): | ||
| 45 | ref Certificate; | ||
| 46 | verify: fn (pk: ref Crypt->PK, cert: ref Certificate, state: ref Crypt->DigestState): | ||
| 47 | int; | ||
| 48 | }; | ||