History

20081021-2253

Charles.Forsyth committed 18 years ago

Commit 85210ff1 parent aaafc859 files · +466 −11Browse files

Unified · Split

9 files
  1. CHANGES +3 −0
  2. appl/cmd/auth/ai2key.b +144 −0
  3. appl/cmd/auth/factotum/proto/infauth.b +54 −12
  4. appl/cmd/auth/mkfile +1 −0
  5. dis/auth/ai2key.dis +0 −0
  6. dis/auth/proto/infauth.dis +0 −0
  7. libinterp/keyring.c +1 −1
  8. man/8/INDEX +3 −0
  9. man/8/ai2key +262 −0
CHANGES+3−0
@@ -1,3 +1,6 @@
120081021
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
120081019420081019
2 /appl/cmd/man2html.b implement "\ " => " "5 /appl/cmd/man2html.b implement "\ " => " "
3 /man/3/prog change way a literal " was formatted6 /man/3/prog change way a literal " was formatted
appl/cmd/auth/ai2key.b+144−0
@@ -0,0 +1,144 @@
1implement 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
11include "sys.m";
12 sys: Sys;
13
14include "draw.m";
15
16include "keyring.m";
17 keyring: Keyring;
18 Certificate, IPint, PK, SK: import keyring;
19
20include "daytime.m";
21 daytime: Daytime;
22
23include "arg.m";
24
25Ai2fact: module
26{
27 init: fn(nil: ref Draw->Context, nil: list of string);
28};
29
30init(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
78error(e: string)
79{
80 sys->fprint(sys->fildes(2), "ai2key: %s\n", e);
81 raise "fail:error";
82}
83
84filename(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
94locations(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
110server(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
118certtostr(c: ref Certificate): string
119{
120 return dnl(keyring->certtostr(c));
121}
122
123pktostr(pk: ref PK): string
124{
125 return dnl(keyring->pktostr(pk));
126}
127
128sktostr(sk: ref SK): string
129{
130 return dnl(keyring->sktostr(sk));
131}
132
133dnl(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}
appl/cmd/auth/factotum/proto/infauth.b+54−12
@@ -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
161remote(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.
163negotiatecrypto(io: ref IO, key: ref Key, ai: ref Authinfo, attrs: list of ref Sexp): string172negotiatecrypto(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] == '!'){
300sys->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
321keytoauthinfo(key:ref Key): (ref Keyring->Authinfo, string)338keytoauthinfo(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 point341 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);359kv(a: list of ref Attr, name: string): string
360{
361 return rnl(authio->lookattrval(a, name));
362}
363
364rnl(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
331strtoauthinfo(s: string): (ref Keyring->Authinfo, string)373strtoauthinfo(s: string): (ref Keyring->Authinfo, string)
332{374{
333 (se, err, nil) := Sexp.parse(s);375 (se, err, nil) := Sexp.parse(s);
appl/cmd/auth/mkfile+1−0
@@ -5,6 +5,7 @@ DIRS=\ · 4 unmodified lines
5 5
6TARG=\6TARG=\
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\
dis/auth/ai2key.dis+0−0

Binary file not shown.

dis/auth/proto/infauth.dis+0−0

Binary file not shown.

libinterp/keyring.c+1−1
@@ -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 */
man/8/INDEX+3−0
@@ -1,4 +1,5 @@
1intro 0intro1intro 0intro
2ai2key ai2key
2applylog applylog3applylog applylog
3updatelog applylog4updatelog applylog
4bootpd bootpd5bootpd bootpd
@@ -15,6 +16,7 @@ csquery cs · 10 unmodified lines
15dhcp dhcp16dhcp dhcp
16dns dns17dns dns
17dnsquery dns18dnsquery dns
19dsagen ai2key
18fpgaload fpgaload20fpgaload fpgaload
19ftl ftl21ftl ftl
20getauthinfo getauthinfo22getauthinfo getauthinfo
@@ -39,6 +41,7 @@ prep prep · 18 unmodified lines
39rdbgsrv rdbgsrv41rdbgsrv rdbgsrv
40register register42register register
41rip rip43rip rip
44rsagen ai2key
42rstyxd rstyxd45rstyxd rstyxd
43styxd rstyxd46styxd rstyxd
44shutdown shutdown47shutdown shutdown
man/8/ai2key+262−0
@@ -0,0 +1,262 @@
1.TH AI2KEY 8
2.SH NAME
3ai2key, 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)
25represents 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
29converts the original Inferno representation of authentication data,
30in the format defined for
31.B authinfo
32by
33.IR keytext (6),
34to an attribute-value format accepted by
35.IR factotum (4)
36for the
37.B infauth
38authentication protocol.
39For each
40.I keyfile
41it writes a single line on standard output, containing
42the following fields:
43.IP
44.EX
45.fi
46.ti -3n
47key 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
69where
70.RS
71.TP 15n
72.I pkalg
73is
74.BR dsa ,
75.B elgamal
76or
77.BR rsa
78.PD 0
79.ns
80.TP
81.I hashalg
82is
83.B md5
84or
85.BR sha1
86.br
87.ns
88.TP
89.B user
90is the user name associated with the key, as vouched for by the supporting
91certificate
92.BR cert
93.br
94.ns
95.TP
96.B signer
97is the user name associated with the key that signed the certificate
98.br
99.ns
100.TP
101.B pk
102is the user's public key
103.br
104.ns
105.TP
106.B !sk
107is the user's private (secret) key
108.br
109.ns
110.TP
111.B spk
112is the signer's public key
113.br
114.ns
115.TP
116.B cert
117is the
118.I certificate
119.br
120.ns
121.TP
122.BR dh-alpha ,\ dh-p
123are the Diffie-Hellman parameters shared by the user and file servers.
124.RE
125.PD
126.PP
127The key is tagged by one or more of
128.BR dom ,
129.B server
130and
131.BR service ,
132derived from the file name
133.IR keyfile .
134The server is
135.RB ` * '
136if
137.I keyfile
138is
139.BR default .
140Otherwise
141.I keyfile
142has the form
143.IP
144[
145.IB net !
146]
147.I host
148[
149.BI ! srv
150]
151.PP
152and
153.B server
154and
155.B service
156are set accordingly;
157.B dom
158is set if
159.I host
160looks like a domain name.
161Key and certificate values have the form defined in
162.IR keytext (6);
163.I hex
164is a large number in hexadecimal.
165.PP
166.I Dsagen
167prints a randomly-generated DSA private key using the NIST-recommended algorithm.
168If
169.I tag
170text is specified, it is printed after the
171.B proto
172attribute-value pair.
173Typically,
174.I tag
175is a sequence of attribute-value comments describing the key.
176A DSA key has the following attributes
177.RS
178.TP 8n
179.B p
180prime public modulus
181.PD 0
182.TP
183.B q
184prime group order; divides
185.BR p -1
186.TP
187.B alpha
188group generator
189.TP
190.B key
191.BR alpha ^ !secret
192mod
193.B p
194.TP
195.B !secret
196the secret exponent
197.RE
198.PD
199.PP
200.I Rsagen
201prints a randomly generated RSA private key
202whose
203.B n
204has exactly
205.I nbits
206(default 1024)
207significant bits.
208The key has the following attributes:
209.RS
210.TP
211.B size
212the number of significant bits in
213.B n
214.PD 0
215.TP
216.B ek
217the encryption exponent
218.TP
219.B n
220the product of
221.B !p
222and
223.B !q
224.TP
225.B !dk
226the decryption exponent
227.TP
228.B !p
229a large prime
230.TP
231.B !q
232another large prime
233.TP
234.B "!kp\fR, \fL!kq\fR, \fL!c2
235parameters derived from the other attributes, cached to speed decryption
236.RE
237.PD
238.PP
239All the numbers in
240.I dsagen
241and
242.I rsagen
243output are in hexadecimal except RSA's
244.BR size ,
245which is decimal.
246A public key omits the attributes beginning with
247.L ! .
248A key may have other attributes as well, for example a
249.B service
250attribute identifying how this key is typically used,
251but to these utilities such attributes are merely comments.
252They can be provided in a
253.I tag
254argument.
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)