Unified · Split
| @@ -1,3 +1,6 @@ | |||
| 1 | 20081021 | ||
| 2 | /appl/cmd/auth/ai2key.b new command to convert authinfo files to factotum keys | ||
| 3 | /appl/cmd/auth/factotum/proto/infauth.b allow new key format | ||
| 1 | 20081019 | 4 | 20081019 |
| 2 | /appl/cmd/man2html.b implement "\ " => " " | 5 | /appl/cmd/man2html.b implement "\ " => " " |
| 3 | /man/3/prog change way a literal " was formatted | 6 | /man/3/prog change way a literal " was formatted |
| @@ -0,0 +1,144 @@ | |||
| 1 | implement Ai2fact; | ||
| 2 | |||
| 3 | # authinfo to factotum key set | ||
| 4 | # intermediate version, for use until revised Inferno authentication is ready | ||
| 5 | |||
| 6 | |||
| 7 | # converts an old authinfo entry in keyring directory to a key for factotum | ||
| 8 | # | ||
| 9 | # keys are in proto=infauth, and include the data for the signed certificate, and the diffie-helman parameters | ||
| 10 | |||
| 11 | include "sys.m"; | ||
| 12 | sys: Sys; | ||
| 13 | |||
| 14 | include "draw.m"; | ||
| 15 | |||
| 16 | include "keyring.m"; | ||
| 17 | keyring: Keyring; | ||
| 18 | Certificate, IPint, PK, SK: import keyring; | ||
| 19 | |||
| 20 | include "daytime.m"; | ||
| 21 | daytime: Daytime; | ||
| 22 | |||
| 23 | include "arg.m"; | ||
| 24 | |||
| 25 | Ai2fact: module | ||
| 26 | { | ||
| 27 | init: fn(nil: ref Draw->Context, nil: list of string); | ||
| 28 | }; | ||
| 29 | |||
| 30 | init(nil: ref Draw->Context, args: list of string) | ||
| 31 | { | ||
| 32 | sys = load Sys Sys->PATH; | ||
| 33 | keyring = load Keyring Keyring->PATH; | ||
| 34 | daytime = load Daytime Daytime->PATH; | ||
| 35 | |||
| 36 | arg := load Arg Arg->PATH; | ||
| 37 | arg->init(args); | ||
| 38 | arg->setusage("ai2key [-t 'attr=value attr=value ...'] keyfile ..."); | ||
| 39 | tag: string; | ||
| 40 | while((o := arg->opt()) != 0) | ||
| 41 | case o { | ||
| 42 | 't' => | ||
| 43 | tag = arg->earg(); | ||
| 44 | * => | ||
| 45 | arg->usage(); | ||
| 46 | } | ||
| 47 | args = arg->argv(); | ||
| 48 | if(args == nil) | ||
| 49 | arg->usage(); | ||
| 50 | arg = nil; | ||
| 51 | |||
| 52 | now := daytime->now(); | ||
| 53 | for(; args != nil; args = tl args){ | ||
| 54 | keyfile := hd args; | ||
| 55 | ai := keyring->readauthinfo(keyfile); | ||
| 56 | if(ai == nil) | ||
| 57 | error(sys->sprint("cannot read %s: %r", keyfile)); | ||
| 58 | if(ai.cert.exp != 0 && ai.cert.exp <= now){ | ||
| 59 | sys->fprint(sys->fildes(2), "ai2key: %s: certificate expired -- key ignored\n", keyfile); | ||
| 60 | continue; | ||
| 61 | } | ||
| 62 | |||
| 63 | if(ai.cert.exp != 0) | ||
| 64 | expires := sys->sprint(" expires=%ud", ai.cert.exp); | ||
| 65 | ha := ai.cert.ha; | ||
| 66 | if(ha == "sha") | ||
| 67 | ha = "sha1"; | ||
| 68 | |||
| 69 | if(tag != nil) | ||
| 70 | tag = " "+tag; | ||
| 71 | |||
| 72 | sys->print("key proto=infauth%s %s sigalg=%s-%s user=%q signer=%q pk=%s !sk=%s spk=%s cert=%s dh-alpha=%s dh-p=%s%s\n", | ||
| 73 | tag, locations(filename(keyfile)), ai.cert.sa.name, ha, ai.mypk.owner, ai.spk.owner, pktostr(ai.mypk), sktostr(ai.mysk), | ||
| 74 | pktostr(ai.spk), certtostr(ai.cert), ai.alpha.iptostr(16), ai.p.iptostr(16), expires); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | error(e: string) | ||
| 79 | { | ||
| 80 | sys->fprint(sys->fildes(2), "ai2key: %s\n", e); | ||
| 81 | raise "fail:error"; | ||
| 82 | } | ||
| 83 | |||
| 84 | filename(s: string): string | ||
| 85 | { | ||
| 86 | (nil, fld) := sys->tokenize(s, "/"); | ||
| 87 | for(; fld != nil && tl fld != nil; fld = tl fld){ | ||
| 88 | # skip | ||
| 89 | } | ||
| 90 | return hd fld; | ||
| 91 | } | ||
| 92 | |||
| 93 | # guess plausible domain, server and service attributes from the file name | ||
| 94 | locations(file: string): string | ||
| 95 | { | ||
| 96 | if(file == "default") | ||
| 97 | return "dom=* server=*"; | ||
| 98 | (nf, flds) := sys->tokenize(file, "!"); | ||
| 99 | case nf { | ||
| 100 | * => | ||
| 101 | return sys->sprint("%s", server(file)); | ||
| 102 | 2 => | ||
| 103 | return sys->sprint("%s", server(hd tl flds)); | ||
| 104 | 3 => | ||
| 105 | # ignore network component | ||
| 106 | return sys->sprint("%s service=%q", server(hd tl flds), hd tl tl flds); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | server(name: string): string | ||
| 111 | { | ||
| 112 | # if the name contains dot(s), we'll treat it as a domain name | ||
| 113 | if(sys->tokenize(name, ".").t0 > 1) | ||
| 114 | return sys->sprint("dom=%q server=%q", name, name); | ||
| 115 | return sys->sprint("server=%q", name); | ||
| 116 | } | ||
| 117 | |||
| 118 | certtostr(c: ref Certificate): string | ||
| 119 | { | ||
| 120 | return dnl(keyring->certtostr(c)); | ||
| 121 | } | ||
| 122 | |||
| 123 | pktostr(pk: ref PK): string | ||
| 124 | { | ||
| 125 | return dnl(keyring->pktostr(pk)); | ||
| 126 | } | ||
| 127 | |||
| 128 | sktostr(sk: ref SK): string | ||
| 129 | { | ||
| 130 | return dnl(keyring->sktostr(sk)); | ||
| 131 | } | ||
| 132 | |||
| 133 | dnl(s: string): string | ||
| 134 | { | ||
| 135 | for(i := 0; i < len s; i++) | ||
| 136 | if(s[i] == '\n') | ||
| 137 | s[i] = '^'; | ||
| 138 | while(--i > 0 && s[i] == '^'){ | ||
| 139 | # skip | ||
| 140 | } | ||
| 141 | if(i != len s) | ||
| 142 | return s[0: i+1]; | ||
| 143 | return s; | ||
| 144 | } | ||
| @@ -139,9 +139,8 @@ interaction(attrs: list of ref Attr, io: ref IO): string · 138 unmodified lines | |||
| 139 | senderr(io, e); | 139 | senderr(io, e); |
| 140 | break; | 140 | break; |
| 141 | Error1 => | 141 | Error1 => |
| 142 | senderr(io, "missing your authentication data"); | 142 | senderr(io, "failed"); # acknowledge error |
| 143 | x: string = e; | 143 | return remote(e); |
| 144 | return "remote: "+x; | ||
| 145 | } | 144 | } |
| 146 | 145 | ||
| 147 | { | 146 | { |
| @@ -151,8 +150,7 @@ interaction(attrs: list of ref Attr, io: ref IO): string · 3 unmodified lines | |||
| 151 | Error0 => | 150 | Error0 => |
| 152 | return e; | 151 | return e; |
| 153 | Error1 => | 152 | Error1 => |
| 154 | x: string = e; | 153 | return remote(e); |
| 155 | return "remote: "+x; | ||
| 156 | } | 154 | } |
| 157 | if(err != nil) | 155 | if(err != nil) |
| 158 | return err; | 156 | return err; |
| @@ -160,13 +158,26 @@ interaction(attrs: list of ref Attr, io: ref IO): string · 1 unmodified line | |||
| 160 | return negotiatecrypto(io, key, ai, rattrs); | 158 | return negotiatecrypto(io, key, ai, rattrs); |
| 161 | } | 159 | } |
| 162 | 160 | ||
| 161 | remote(s: string): string | ||
| 162 | { | ||
| 163 | # account for strange earlier interface | ||
| 164 | if(len s < 6 || s[0: 6] != "remote") | ||
| 165 | return "remote: "+s; | ||
| 166 | return s; | ||
| 167 | } | ||
| 168 | |||
| 169 | # TO DO: exchange attr/value pairs, covered by hmac (use part of secret up to hmac block size of 64 bytes) | ||
| 170 | # the old scheme can be distinguished either by a prefix "attrs " or simply because the string contains "=", | ||
| 171 | # and the server side can then reply. the hmac is to prevent tampering. | ||
| 163 | negotiatecrypto(io: ref IO, key: ref Key, ai: ref Authinfo, attrs: list of ref Sexp): string | 172 | negotiatecrypto(io: ref IO, key: ref Key, ai: ref Authinfo, attrs: list of ref Sexp): string |
| 164 | { | 173 | { |
| 165 | role := authio->lookattrval(key.attrs, "role"); | 174 | role := authio->lookattrval(key.attrs, "role"); |
| 166 | alg: string; | 175 | alg: string; |
| 167 | { | 176 | { |
| 168 | if(role == "client"){ | 177 | if(role == "client"){ |
| 169 | alg = authio->lookattrval(key.attrs, "alg"); | 178 | alg = authio->lookattrval(key.attrs, ":alg"); |
| 179 | if(alg == nil) | ||
| 180 | alg = authio->lookattrval(key.attrs, "alg"); # old way | ||
| 170 | if(alg == nil) | 181 | if(alg == nil) |
| 171 | alg = "md5/rc4_256"; | 182 | alg = "md5/rc4_256"; |
| 172 | sendmsg(io, array of byte alg); | 183 | sendmsg(io, array of byte alg); |
| @@ -297,7 +308,8 @@ getmsg(io: ref IO): array of byte raises (Error0, Error1) · 124 unmodified lines | |||
| 297 | if(len buf != m) | 308 | if(len buf != m) |
| 298 | raise Error0("io error: (impossible?) msg length " + string m); | 309 | raise Error0("io error: (impossible?) msg length " + string m); |
| 299 | if(h[0] == '!'){ | 310 | if(h[0] == '!'){ |
| 300 | sys->print("got remote error: %s, len %d\n", string buf, len string buf); | 311 | if(0) |
| 312 | sys->print("got remote error: %q, len %d\n", string buf, len string buf); | ||
| 301 | raise Error1(string buf); | 313 | raise Error1(string buf); |
| 302 | } | 314 | } |
| 303 | return buf; | 315 | return buf; |
| @@ -318,16 +330,46 @@ senderr(io: ref IO, e: string) · 14 unmodified lines | |||
| 318 | io.write(buf, len buf); | 330 | io.write(buf, len buf); |
| 319 | } | 331 | } |
| 320 | 332 | ||
| 333 | # both the s-expression and k=v form are interim, until all | ||
| 334 | # the factotum implementations can manage public keys | ||
| 335 | # the s-expression form was the original one used by Inferno factotum | ||
| 336 | # the form in which Authinfo components are separate attributes is the | ||
| 337 | # one now used by Plan 9 and Plan 9 Ports factotum implementations | ||
| 321 | keytoauthinfo(key:ref Key): (ref Keyring->Authinfo, string) | 338 | keytoauthinfo(key:ref Key): (ref Keyring->Authinfo, string) |
| 322 | { | 339 | { |
| 323 | if((s := authio->lookattrval(key.secrets, "!authinfo")) == nil){ | 340 | if((s := authio->lookattrval(key.secrets, "!authinfo")) != nil) |
| 324 | # XXX could look up authinfo by hash at this point | 341 | return strtoauthinfo(s); |
| 325 | return (nil, "no authinfo attribute"); | 342 | # TO DO: could look up authinfo by hash |
| 326 | } | 343 | ai := ref Keyring->Authinfo; |
| 344 | if((s = kv(key.secrets, "!sk")) == nil || (ai.mysk = keyring->strtosk(s)) == nil) | ||
| 345 | return (nil, "bad secret key"); | ||
| 346 | if((s = kv(key.attrs, "pk")) == nil || (ai.mypk = keyring->strtopk(s)) == nil) | ||
| 347 | return (nil, "bad public key"); | ||
| 348 | if((s = kv(key.attrs, "cert")) == nil || (ai.cert = keyring->strtocert(s)) == nil) | ||
| 349 | return (nil, "bad certificate"); | ||
| 350 | if((s = kv(key.attrs, "spk")) == nil || (ai.spk = keyring->strtopk(s)) == nil) | ||
| 351 | return (nil, "bad signer public key"); | ||
| 352 | if((s = kv(key.attrs, "dh-alpha")) == nil || (ai.alpha = IPint.strtoip(s, 16)) == nil) | ||
| 353 | return (nil, "bad value for alpha"); | ||
| 354 | if((s = kv(key.attrs, "dh-p")) == nil || (ai.p = IPint.strtoip(s, 16)) == nil) | ||
| 355 | return (nil, "bad value for p"); | ||
| 356 | return (ai, nil); | ||
| 357 | } | ||
| 327 | 358 | ||
| 328 | return strtoauthinfo(s); | 359 | kv(a: list of ref Attr, name: string): string |
| 360 | { | ||
| 361 | return rnl(authio->lookattrval(a, name)); | ||
| 362 | } | ||
| 363 | |||
| 364 | rnl(s: string): string | ||
| 365 | { | ||
| 366 | for(i := 0; i < len s; i++) | ||
| 367 | if(s[i] == '^') | ||
| 368 | s[i] = '\n'; | ||
| 369 | return s; | ||
| 329 | } | 370 | } |
| 330 | 371 | ||
| 372 | # s-expression form | ||
| 331 | strtoauthinfo(s: string): (ref Keyring->Authinfo, string) | 373 | strtoauthinfo(s: string): (ref Keyring->Authinfo, string) |
| 332 | { | 374 | { |
| 333 | (se, err, nil) := Sexp.parse(s); | 375 | (se, err, nil) := Sexp.parse(s); |
| @@ -5,6 +5,7 @@ DIRS=\ · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | TARG=\ | 6 | TARG=\ |
| 7 | aescbc.dis\ | 7 | aescbc.dis\ |
| 8 | ai2key.dis\ | ||
| 8 | changelogin.dis\ | 9 | changelogin.dis\ |
| 9 | countersigner.dis\ | 10 | countersigner.dis\ |
| 10 | convpasswd.dis\ | 11 | convpasswd.dis\ |
Binary file not shown.
Binary file not shown.
| @@ -1696,7 +1696,7 @@ if(0)print("Y"); · 1695 unmodified lines | |||
| 1696 | buf[n] = 0; | 1696 | buf[n] = 0; |
| 1697 | hiscert = strtocert(buf); | 1697 | hiscert = strtocert(buf); |
| 1698 | if(hiscert == H){ | 1698 | if(hiscert == H){ |
| 1699 | err = "bad certificate"; | 1699 | err = "bad certificate syntax"; |
| 1700 | goto out; | 1700 | goto out; |
| 1701 | } | 1701 | } |
| 1702 | certimmutable(hiscert); /* hide from the garbage collector */ | 1702 | certimmutable(hiscert); /* hide from the garbage collector */ |
| @@ -1,4 +1,5 @@ | |||
| 1 | intro 0intro | 1 | intro 0intro |
| 2 | ai2key ai2key | ||
| 2 | applylog applylog | 3 | applylog applylog |
| 3 | updatelog applylog | 4 | updatelog applylog |
| 4 | bootpd bootpd | 5 | bootpd bootpd |
| @@ -15,6 +16,7 @@ csquery cs · 10 unmodified lines | |||
| 15 | dhcp dhcp | 16 | dhcp dhcp |
| 16 | dns dns | 17 | dns dns |
| 17 | dnsquery dns | 18 | dnsquery dns |
| 19 | dsagen ai2key | ||
| 18 | fpgaload fpgaload | 20 | fpgaload fpgaload |
| 19 | ftl ftl | 21 | ftl ftl |
| 20 | getauthinfo getauthinfo | 22 | getauthinfo getauthinfo |
| @@ -39,6 +41,7 @@ prep prep · 18 unmodified lines | |||
| 39 | rdbgsrv rdbgsrv | 41 | rdbgsrv rdbgsrv |
| 40 | register register | 42 | register register |
| 41 | rip rip | 43 | rip rip |
| 44 | rsagen ai2key | ||
| 42 | rstyxd rstyxd | 45 | rstyxd rstyxd |
| 43 | styxd rstyxd | 46 | styxd rstyxd |
| 44 | shutdown shutdown | 47 | shutdown shutdown |
| @@ -0,0 +1,262 @@ | |||
| 1 | .TH AI2KEY 8 | ||
| 2 | .SH NAME | ||
| 3 | ai2key, dsagen, rsagen \- generate and reformat public keys | ||
| 4 | .SH SYNOPSIS | ||
| 5 | .B ai2key | ||
| 6 | [ | ||
| 7 | .BI -t " tag" | ||
| 8 | ] | ||
| 9 | .I keyfile | ||
| 10 | ... | ||
| 11 | .P | ||
| 12 | .B dsagen | ||
| 13 | [ | ||
| 14 | .BI -t " tag" | ||
| 15 | ] | ||
| 16 | .PP | ||
| 17 | .B rsagen | ||
| 18 | [ | ||
| 19 | .BI -b " nbits" | ||
| 20 | ] [ | ||
| 21 | .BI -t " tag" | ||
| 22 | ] | ||
| 23 | .SH DESCRIPTION | ||
| 24 | .IR Factotum (4) | ||
| 25 | represents public keys as lists of attribute-value pairs, each key on a single line prefixed with the string | ||
| 26 | .BR key . | ||
| 27 | .PP | ||
| 28 | .I Ai2key | ||
| 29 | converts the original Inferno representation of authentication data, | ||
| 30 | in the format defined for | ||
| 31 | .B authinfo | ||
| 32 | by | ||
| 33 | .IR keytext (6), | ||
| 34 | to an attribute-value format accepted by | ||
| 35 | .IR factotum (4) | ||
| 36 | for the | ||
| 37 | .B infauth | ||
| 38 | authentication protocol. | ||
| 39 | For each | ||
| 40 | .I keyfile | ||
| 41 | it writes a single line on standard output, containing | ||
| 42 | the following fields: | ||
| 43 | .IP | ||
| 44 | .EX | ||
| 45 | .fi | ||
| 46 | .ti -3n | ||
| 47 | key proto=infauth | ||
| 48 | [ | ||
| 49 | .I tag | ||
| 50 | ] | ||
| 51 | .BI "sigalg=" pkalg - hashalg | ||
| 52 | [ | ||
| 53 | .BI dom= host | ||
| 54 | ] | ||
| 55 | .BI server= host | ||
| 56 | [ | ||
| 57 | .BI service= svc | ||
| 58 | ] | ||
| 59 | .BI "user=" name | ||
| 60 | .BI "signer=" name | ||
| 61 | .BI "pk=" pk | ||
| 62 | .BI "!sk=" sk | ||
| 63 | .BI spk= pk | ||
| 64 | .BI cert= cert | ||
| 65 | .BI dh-alpha= hex | ||
| 66 | .BI dh-p= hex | ||
| 67 | .EE | ||
| 68 | .PP | ||
| 69 | where | ||
| 70 | .RS | ||
| 71 | .TP 15n | ||
| 72 | .I pkalg | ||
| 73 | is | ||
| 74 | .BR dsa , | ||
| 75 | .B elgamal | ||
| 76 | or | ||
| 77 | .BR rsa | ||
| 78 | .PD 0 | ||
| 79 | .ns | ||
| 80 | .TP | ||
| 81 | .I hashalg | ||
| 82 | is | ||
| 83 | .B md5 | ||
| 84 | or | ||
| 85 | .BR sha1 | ||
| 86 | .br | ||
| 87 | .ns | ||
| 88 | .TP | ||
| 89 | .B user | ||
| 90 | is the user name associated with the key, as vouched for by the supporting | ||
| 91 | certificate | ||
| 92 | .BR cert | ||
| 93 | .br | ||
| 94 | .ns | ||
| 95 | .TP | ||
| 96 | .B signer | ||
| 97 | is the user name associated with the key that signed the certificate | ||
| 98 | .br | ||
| 99 | .ns | ||
| 100 | .TP | ||
| 101 | .B pk | ||
| 102 | is the user's public key | ||
| 103 | .br | ||
| 104 | .ns | ||
| 105 | .TP | ||
| 106 | .B !sk | ||
| 107 | is the user's private (secret) key | ||
| 108 | .br | ||
| 109 | .ns | ||
| 110 | .TP | ||
| 111 | .B spk | ||
| 112 | is the signer's public key | ||
| 113 | .br | ||
| 114 | .ns | ||
| 115 | .TP | ||
| 116 | .B cert | ||
| 117 | is the | ||
| 118 | .I certificate | ||
| 119 | .br | ||
| 120 | .ns | ||
| 121 | .TP | ||
| 122 | .BR dh-alpha ,\ dh-p | ||
| 123 | are the Diffie-Hellman parameters shared by the user and file servers. | ||
| 124 | .RE | ||
| 125 | .PD | ||
| 126 | .PP | ||
| 127 | The key is tagged by one or more of | ||
| 128 | .BR dom , | ||
| 129 | .B server | ||
| 130 | and | ||
| 131 | .BR service , | ||
| 132 | derived from the file name | ||
| 133 | .IR keyfile . | ||
| 134 | The server is | ||
| 135 | .RB ` * ' | ||
| 136 | if | ||
| 137 | .I keyfile | ||
| 138 | is | ||
| 139 | .BR default . | ||
| 140 | Otherwise | ||
| 141 | .I keyfile | ||
| 142 | has the form | ||
| 143 | .IP | ||
| 144 | [ | ||
| 145 | .IB net ! | ||
| 146 | ] | ||
| 147 | .I host | ||
| 148 | [ | ||
| 149 | .BI ! srv | ||
| 150 | ] | ||
| 151 | .PP | ||
| 152 | and | ||
| 153 | .B server | ||
| 154 | and | ||
| 155 | .B service | ||
| 156 | are set accordingly; | ||
| 157 | .B dom | ||
| 158 | is set if | ||
| 159 | .I host | ||
| 160 | looks like a domain name. | ||
| 161 | Key and certificate values have the form defined in | ||
| 162 | .IR keytext (6); | ||
| 163 | .I hex | ||
| 164 | is a large number in hexadecimal. | ||
| 165 | .PP | ||
| 166 | .I Dsagen | ||
| 167 | prints a randomly-generated DSA private key using the NIST-recommended algorithm. | ||
| 168 | If | ||
| 169 | .I tag | ||
| 170 | text is specified, it is printed after the | ||
| 171 | .B proto | ||
| 172 | attribute-value pair. | ||
| 173 | Typically, | ||
| 174 | .I tag | ||
| 175 | is a sequence of attribute-value comments describing the key. | ||
| 176 | A DSA key has the following attributes | ||
| 177 | .RS | ||
| 178 | .TP 8n | ||
| 179 | .B p | ||
| 180 | prime public modulus | ||
| 181 | .PD 0 | ||
| 182 | .TP | ||
| 183 | .B q | ||
| 184 | prime group order; divides | ||
| 185 | .BR p -1 | ||
| 186 | .TP | ||
| 187 | .B alpha | ||
| 188 | group generator | ||
| 189 | .TP | ||
| 190 | .B key | ||
| 191 | .BR alpha ^ !secret | ||
| 192 | mod | ||
| 193 | .B p | ||
| 194 | .TP | ||
| 195 | .B !secret | ||
| 196 | the secret exponent | ||
| 197 | .RE | ||
| 198 | .PD | ||
| 199 | .PP | ||
| 200 | .I Rsagen | ||
| 201 | prints a randomly generated RSA private key | ||
| 202 | whose | ||
| 203 | .B n | ||
| 204 | has exactly | ||
| 205 | .I nbits | ||
| 206 | (default 1024) | ||
| 207 | significant bits. | ||
| 208 | The key has the following attributes: | ||
| 209 | .RS | ||
| 210 | .TP | ||
| 211 | .B size | ||
| 212 | the number of significant bits in | ||
| 213 | .B n | ||
| 214 | .PD 0 | ||
| 215 | .TP | ||
| 216 | .B ek | ||
| 217 | the encryption exponent | ||
| 218 | .TP | ||
| 219 | .B n | ||
| 220 | the product of | ||
| 221 | .B !p | ||
| 222 | and | ||
| 223 | .B !q | ||
| 224 | .TP | ||
| 225 | .B !dk | ||
| 226 | the decryption exponent | ||
| 227 | .TP | ||
| 228 | .B !p | ||
| 229 | a large prime | ||
| 230 | .TP | ||
| 231 | .B !q | ||
| 232 | another large prime | ||
| 233 | .TP | ||
| 234 | .B "!kp\fR, \fL!kq\fR, \fL!c2 | ||
| 235 | parameters derived from the other attributes, cached to speed decryption | ||
| 236 | .RE | ||
| 237 | .PD | ||
| 238 | .PP | ||
| 239 | All the numbers in | ||
| 240 | .I dsagen | ||
| 241 | and | ||
| 242 | .I rsagen | ||
| 243 | output are in hexadecimal except RSA's | ||
| 244 | .BR size , | ||
| 245 | which is decimal. | ||
| 246 | A public key omits the attributes beginning with | ||
| 247 | .L ! . | ||
| 248 | A key may have other attributes as well, for example a | ||
| 249 | .B service | ||
| 250 | attribute identifying how this key is typically used, | ||
| 251 | but to these utilities such attributes are merely comments. | ||
| 252 | They can be provided in a | ||
| 253 | .I tag | ||
| 254 | argument. | ||
| 255 | .SH SOURCE | ||
| 256 | .B /appl/cmd/auth/ai2key.b | ||
| 257 | .br | ||
| 258 | .B /appl/cmd/auth/dsagen.b | ||
| 259 | .br | ||
| 260 | .B /appl/cmd/auth/rsagen.b | ||
| 261 | .SH "SEE ALSO" | ||
| 262 | .IR factotum (4) | ||