xref: /inferno-os/appl/lib/oldauth.b (revision 25b96b1d6a760df53b31e14ed1ae5f3c36e87bf5)
1*25b96b1dSforsythimplement Oldauth;
2*25b96b1dSforsyth
3*25b96b1dSforsyth#
4*25b96b1dSforsyth# TO DO
5*25b96b1dSforsyth#	- more error checking?
6*25b96b1dSforsyth#	- details of auth error handling
7*25b96b1dSforsyth#
8*25b96b1dSforsyth
9*25b96b1dSforsythinclude "sys.m";
10*25b96b1dSforsyth	sys: Sys;
11*25b96b1dSforsyth
12*25b96b1dSforsythinclude "ipints.m";
13*25b96b1dSforsyth	ipints: IPints;
14*25b96b1dSforsyth	IPint: import ipints;
15*25b96b1dSforsyth
16*25b96b1dSforsythinclude "crypt.m";
17*25b96b1dSforsyth	crypt: Crypt;
18*25b96b1dSforsyth	PK, SK, PKsig: import crypt;
19*25b96b1dSforsyth
20*25b96b1dSforsythinclude "msgio.m";
21*25b96b1dSforsyth	msgio: Msgio;
22*25b96b1dSforsyth
23*25b96b1dSforsythinclude "oldauth.m";
24*25b96b1dSforsyth
25*25b96b1dSforsythinit()
26*25b96b1dSforsyth{
27*25b96b1dSforsyth	sys = load Sys Sys->PATH;
28*25b96b1dSforsyth	ipints = load IPints IPints->PATH;
29*25b96b1dSforsyth	crypt = load Crypt Crypt->PATH;
30*25b96b1dSforsyth	msgio = load Msgio Msgio->PATH;
31*25b96b1dSforsyth	msgio->init();
32*25b96b1dSforsyth}
33*25b96b1dSforsyth
34*25b96b1dSforsythefmt()
35*25b96b1dSforsyth{
36*25b96b1dSforsyth	sys->werrstr("input or format error");
37*25b96b1dSforsyth}
38*25b96b1dSforsyth
39*25b96b1dSforsythreadauthinfo(filename: string): ref Authinfo
40*25b96b1dSforsyth{
41*25b96b1dSforsyth	fd := sys->open(filename, Sys->OREAD);
42*25b96b1dSforsyth	if(fd == nil)
43*25b96b1dSforsyth		return nil;
44*25b96b1dSforsyth	a := array[5] of string;
45*25b96b1dSforsyth	for(i := 0; i < len a; i++){
46*25b96b1dSforsyth		(s, err) := getstr(fd);
47*25b96b1dSforsyth		if(err != nil){
48*25b96b1dSforsyth			sys->werrstr(sys->sprint("%q: input or format error", filename));
49*25b96b1dSforsyth			return nil;
50*25b96b1dSforsyth		}
51*25b96b1dSforsyth		a[i] = s;
52*25b96b1dSforsyth	}
53*25b96b1dSforsyth	info := ref Authinfo;
54*25b96b1dSforsyth	(info.spk, nil) = strtopk(a[0]);
55*25b96b1dSforsyth	info.cert = strtocert(a[1]);
56*25b96b1dSforsyth	(info.mysk, info.owner) = strtosk(a[2]);
57*25b96b1dSforsyth	if(info.spk == nil || info.cert == nil || info.mysk == nil){
58*25b96b1dSforsyth		efmt();
59*25b96b1dSforsyth		return nil;
60*25b96b1dSforsyth	}
61*25b96b1dSforsyth	info.mypk = crypt->sktopk(info.mysk);
62*25b96b1dSforsyth	info.alpha = IPint.strtoip(a[3], 64);
63*25b96b1dSforsyth	info.p = IPint.strtoip(a[4], 64);
64*25b96b1dSforsyth	if(info.alpha == nil || info.p == nil){
65*25b96b1dSforsyth		efmt();
66*25b96b1dSforsyth		return nil;
67*25b96b1dSforsyth	}
68*25b96b1dSforsyth	return info;
69*25b96b1dSforsyth}
70*25b96b1dSforsyth
71*25b96b1dSforsythwriteauthinfo(filename: string, info: ref Authinfo): int
72*25b96b1dSforsyth{
73*25b96b1dSforsyth	if(info.alpha == nil || info.p == nil ||
74*25b96b1dSforsyth	   info.spk == nil || info.mysk == nil || info.cert == nil){
75*25b96b1dSforsyth		sys->werrstr("invalid authinfo");
76*25b96b1dSforsyth		return -1;
77*25b96b1dSforsyth	}
78*25b96b1dSforsyth	a := array[5] of string;
79*25b96b1dSforsyth	a[0] = pktostr(info.spk, info.cert.signer);	# signer's public key
80*25b96b1dSforsyth	a[1] = certtostr(info.cert);	# certificate for my public key
81*25b96b1dSforsyth	a[2] = sktostr(info.mysk, info.owner);	# my secret/public key
82*25b96b1dSforsyth	a[3] = b64(info.alpha);	# diffie hellman base
83*25b96b1dSforsyth	a[4] = b64(info.p);	# diffie hellman modulus
84*25b96b1dSforsyth	fd := sys->open(filename, Sys->OWRITE|Sys->OTRUNC);
85*25b96b1dSforsyth	if(fd == nil){
86*25b96b1dSforsyth		fd = sys->create(filename, Sys->OWRITE, 8r600);
87*25b96b1dSforsyth		if(fd == nil){
88*25b96b1dSforsyth			fd = sys->open(filename, Sys->OWRITE);
89*25b96b1dSforsyth			if(fd == nil)
90*25b96b1dSforsyth				return -1;
91*25b96b1dSforsyth		}
92*25b96b1dSforsyth	}
93*25b96b1dSforsyth	for(i := 0; i < len a; i++)
94*25b96b1dSforsyth		if(sendstr(fd, a[i]) <= 0)
95*25b96b1dSforsyth			return -1;
96*25b96b1dSforsyth	return 0;
97*25b96b1dSforsyth}
98*25b96b1dSforsyth
99*25b96b1dSforsythsendstr(fd: ref Sys->FD, s: string): int
100*25b96b1dSforsyth{
101*25b96b1dSforsyth	a := array of byte s;
102*25b96b1dSforsyth	return msgio->sendmsg(fd, a, len a);
103*25b96b1dSforsyth}
104*25b96b1dSforsyth
105*25b96b1dSforsythgetstr(fd: ref Sys->FD): (string, string)
106*25b96b1dSforsyth{
107*25b96b1dSforsyth	b := msgio->getmsg(fd);
108*25b96b1dSforsyth	if(b == nil)
109*25b96b1dSforsyth		return (nil, sys->sprint("%r"));
110*25b96b1dSforsyth	return (string b, nil);
111*25b96b1dSforsyth}
112*25b96b1dSforsyth
113*25b96b1dSforsythcerttostr(c: ref Certificate): string
114*25b96b1dSforsyth{
115*25b96b1dSforsyth	s := sys->sprint("%s\n%s\n%s\n%ud\n", c.sa, c.ha, c.signer, c.exp);
116*25b96b1dSforsyth	pick r := c.sig {
117*25b96b1dSforsyth	RSA =>
118*25b96b1dSforsyth		s += b64(r.n)+"\n";
119*25b96b1dSforsyth	Elgamal =>
120*25b96b1dSforsyth		s += b64(r.r)+"\n"+b64(r.s)+"\n";
121*25b96b1dSforsyth	DSA =>
122*25b96b1dSforsyth		s += b64(r.r)+"\n"+b64(r.s)+"\n";
123*25b96b1dSforsyth	* =>
124*25b96b1dSforsyth		raise "unknown key type";
125*25b96b1dSforsyth	}
126*25b96b1dSforsyth	return s;
127*25b96b1dSforsyth}
128*25b96b1dSforsyth
129*25b96b1dSforsythpktostr(pk: ref PK, owner: string): string
130*25b96b1dSforsyth{
131*25b96b1dSforsyth	pick k := pk {
132*25b96b1dSforsyth	RSA =>
133*25b96b1dSforsyth		s := sys->sprint("rsa\n%s\n", owner);
134*25b96b1dSforsyth		s += b64(k.n)+"\n"+b64(k.ek)+"\n";
135*25b96b1dSforsyth		return s;
136*25b96b1dSforsyth	Elgamal =>
137*25b96b1dSforsyth		s := sys->sprint("elgamal\n%s\n", owner);
138*25b96b1dSforsyth		s += b64(k.p)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n";
139*25b96b1dSforsyth		return s;
140*25b96b1dSforsyth	DSA =>
141*25b96b1dSforsyth		s := sys->sprint("dsa\n%s\n", owner);
142*25b96b1dSforsyth		s += b64(k.p)+"\n"+b64(k.q)+"\n"+b64(k.alpha)+"\n"+b64(k.key)+"\n";
143*25b96b1dSforsyth		return s;
144*25b96b1dSforsyth	* =>
145*25b96b1dSforsyth		raise "unknown key type";
146*25b96b1dSforsyth	}
147*25b96b1dSforsyth}
148*25b96b1dSforsyth
149*25b96b1dSforsythsktostr(sk: ref SK, owner: string): string
150*25b96b1dSforsyth{
151*25b96b1dSforsyth	pick k := sk {
152*25b96b1dSforsyth	RSA =>
153*25b96b1dSforsyth		s := sys->sprint("rsa\n%s\n", owner);
154*25b96b1dSforsyth		s += b64(k.pk.n)+"\n"+b64(k.pk.ek)+"\n"+b64(k.dk)+"\n"+
155*25b96b1dSforsyth			b64(k.p)+"\n"+b64(k.q)+"\n"+
156*25b96b1dSforsyth			b64(k.kp)+"\n"+b64(k.kq)+"\n"+
157*25b96b1dSforsyth			k.c2.iptob64()+"\n";
158*25b96b1dSforsyth		return s;
159*25b96b1dSforsyth	Elgamal =>
160*25b96b1dSforsyth		pk := k.pk;
161*25b96b1dSforsyth		s := sys->sprint("elgamal\n%s\n", owner);
162*25b96b1dSforsyth		s += b64(pk.p)+"\n"+b64(pk.alpha)+"\n"+b64(pk.key)+"\n"+b64(k.secret)+"\n";
163*25b96b1dSforsyth		return s;
164*25b96b1dSforsyth	DSA =>
165*25b96b1dSforsyth		pk := k.pk;
166*25b96b1dSforsyth		s := sys->sprint("dsa\n%s\n", owner);
167*25b96b1dSforsyth		s += b64(pk.p)+"\n"+b64(pk.q)+"\n"+b64(pk.alpha)+"\n"+b64(k.secret)+"\n";
168*25b96b1dSforsyth		return s;
169*25b96b1dSforsyth	* =>
170*25b96b1dSforsyth		raise "unknown key type";
171*25b96b1dSforsyth	}
172*25b96b1dSforsyth}
173*25b96b1dSforsyth
174*25b96b1dSforsythfields(s: string): array of string
175*25b96b1dSforsyth{
176*25b96b1dSforsyth	(nf, flds) := sys->tokenize(s, "\n^");
177*25b96b1dSforsyth	a := array[nf] of string;
178*25b96b1dSforsyth	for(i := 0; i < len a; i++){
179*25b96b1dSforsyth		a[i] = hd flds;
180*25b96b1dSforsyth		flds = tl flds;
181*25b96b1dSforsyth	}
182*25b96b1dSforsyth	return a;
183*25b96b1dSforsyth}
184*25b96b1dSforsyth
185*25b96b1dSforsythbigs(a: array of string): array of ref IPint
186*25b96b1dSforsyth{
187*25b96b1dSforsyth	b := array[len a] of ref IPint;
188*25b96b1dSforsyth	for(i := 0; i < len b; i++){
189*25b96b1dSforsyth		b[i] = IPint.strtoip(a[i], 64);
190*25b96b1dSforsyth		if(b[i] == nil)
191*25b96b1dSforsyth			return nil;
192*25b96b1dSforsyth	}
193*25b96b1dSforsyth	return b;
194*25b96b1dSforsyth}
195*25b96b1dSforsyth
196*25b96b1dSforsythneed[T](a: array of T, min: int): int
197*25b96b1dSforsyth{
198*25b96b1dSforsyth	if(len a < min){
199*25b96b1dSforsyth		efmt();
200*25b96b1dSforsyth		return 1;
201*25b96b1dSforsyth	}
202*25b96b1dSforsyth	return 0;
203*25b96b1dSforsyth}
204*25b96b1dSforsyth
205*25b96b1dSforsythstrtocert(s: string): ref Certificate
206*25b96b1dSforsyth{
207*25b96b1dSforsyth	f := fields(s);
208*25b96b1dSforsyth	if(need(f, 4))
209*25b96b1dSforsyth		return nil;
210*25b96b1dSforsyth	sa := f[0];
211*25b96b1dSforsyth	ha := f[1];
212*25b96b1dSforsyth	signer := f[2];
213*25b96b1dSforsyth	exp := int big f[3];	# unsigned
214*25b96b1dSforsyth	b := bigs(f[4:]);
215*25b96b1dSforsyth	case f[0] {
216*25b96b1dSforsyth	"rsa" =>
217*25b96b1dSforsyth		if(need(b, 1))
218*25b96b1dSforsyth			return nil;
219*25b96b1dSforsyth		return ref Certificate(sa, ha, signer, exp, ref PKsig.RSA(b[0]));
220*25b96b1dSforsyth	"elgamal" =>
221*25b96b1dSforsyth		if(need(b, 2))
222*25b96b1dSforsyth			return nil;
223*25b96b1dSforsyth		return ref Certificate(sa, ha, signer, exp, ref PKsig.Elgamal(b[0], b[1]));
224*25b96b1dSforsyth	"dsa" =>
225*25b96b1dSforsyth		if(need(b, 2))
226*25b96b1dSforsyth			return nil;
227*25b96b1dSforsyth		return ref Certificate(sa, ha, signer, exp, ref PKsig.DSA(b[0], b[1]));
228*25b96b1dSforsyth	* =>
229*25b96b1dSforsyth		sys->werrstr("unknown algorithm: "+f[0]);
230*25b96b1dSforsyth		return nil;
231*25b96b1dSforsyth	}
232*25b96b1dSforsyth}
233*25b96b1dSforsyth
234*25b96b1dSforsythstrtopk(s: string): (ref PK, string)
235*25b96b1dSforsyth{
236*25b96b1dSforsyth	f := fields(s);
237*25b96b1dSforsyth	if(need(f, 3))
238*25b96b1dSforsyth		return (nil, "format error");
239*25b96b1dSforsyth	sa := f[0];
240*25b96b1dSforsyth	owner := f[1];
241*25b96b1dSforsyth	b := bigs(f[2:]);
242*25b96b1dSforsyth	case sa {
243*25b96b1dSforsyth	"rsa" =>
244*25b96b1dSforsyth		if(need(b, 2))
245*25b96b1dSforsyth			return (nil, "format error");
246*25b96b1dSforsyth		return (ref PK.RSA(b[0], b[1]), owner);
247*25b96b1dSforsyth	"elgamal" =>
248*25b96b1dSforsyth		if(need(b, 3))
249*25b96b1dSforsyth			return (nil, "format error");
250*25b96b1dSforsyth		return (ref PK.Elgamal(b[0], b[1], b[2]), owner);
251*25b96b1dSforsyth	"dsa" =>
252*25b96b1dSforsyth		if(need(b, 4))
253*25b96b1dSforsyth			return (nil, "format error");
254*25b96b1dSforsyth		return (ref PK.DSA(b[0], b[1], b[2], b[3]), owner);
255*25b96b1dSforsyth	* =>
256*25b96b1dSforsyth		return (nil, "unknown algorithm: "+f[0]);
257*25b96b1dSforsyth	}
258*25b96b1dSforsyth}
259*25b96b1dSforsyth
260*25b96b1dSforsythstrtosk(s: string): (ref SK, string)
261*25b96b1dSforsyth{
262*25b96b1dSforsyth	f := fields(s);
263*25b96b1dSforsyth	if(need(f, 3))
264*25b96b1dSforsyth		return (nil, "format error");
265*25b96b1dSforsyth	sa := f[0];
266*25b96b1dSforsyth	owner := f[1];
267*25b96b1dSforsyth	b := bigs(f[2:]);
268*25b96b1dSforsyth	case sa {
269*25b96b1dSforsyth	"rsa" =>
270*25b96b1dSforsyth		if(need(b, 8))
271*25b96b1dSforsyth			return (nil, "format error");
272*25b96b1dSforsyth		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*25b96b1dSforsyth	"elgamal" =>
274*25b96b1dSforsyth		if(need(b, 4))
275*25b96b1dSforsyth			return (nil, "format error");
276*25b96b1dSforsyth		return (ref SK.Elgamal(ref PK.Elgamal(b[0], b[1], b[2]), b[3]), owner);
277*25b96b1dSforsyth	"dsa" =>
278*25b96b1dSforsyth		if(need(b, 5))
279*25b96b1dSforsyth			return (nil, "format error");
280*25b96b1dSforsyth		return (ref SK.DSA(ref PK.DSA(b[0], b[1], b[2], b[3]), b[4]), owner);
281*25b96b1dSforsyth	* =>
282*25b96b1dSforsyth		return (nil, "unknown algorithm: "+f[0]);
283*25b96b1dSforsyth	}
284*25b96b1dSforsyth}
285*25b96b1dSforsyth
286*25b96b1dSforsythskalg(sk: ref SK): string
287*25b96b1dSforsyth{
288*25b96b1dSforsyth	if(sk == nil)
289*25b96b1dSforsyth		return "nil";
290*25b96b1dSforsyth	case tagof sk {
291*25b96b1dSforsyth	tagof SK.RSA =>	return "rsa";
292*25b96b1dSforsyth	tagof SK.Elgamal =>	return "elgamal";
293*25b96b1dSforsyth	tagof SK.DSA =>	return "dsa";
294*25b96b1dSforsyth	* =>	return "gok";
295*25b96b1dSforsyth	}
296*25b96b1dSforsyth}
297*25b96b1dSforsyth
298*25b96b1dSforsythsign(sk: ref SK, signer: string, exp: int, state: ref Crypt->DigestState, ha: string): ref Certificate
299*25b96b1dSforsyth{
300*25b96b1dSforsyth	# add signer name and expiration time to hash
301*25b96b1dSforsyth	if(state == nil)
302*25b96b1dSforsyth		return nil;
303*25b96b1dSforsyth	a := sys->aprint("%s %d", signer, exp);
304*25b96b1dSforsyth	digest := hash(ha, a, state);
305*25b96b1dSforsyth	if(digest == nil)
306*25b96b1dSforsyth		return nil;
307*25b96b1dSforsyth	b := IPint.bebytestoip(digest);
308*25b96b1dSforsyth	return ref Certificate(skalg(sk), ha, signer, exp, crypt->sign(sk, b));
309*25b96b1dSforsyth}
310*25b96b1dSforsyth
311*25b96b1dSforsythverify(pk: ref PK, cert: ref Certificate, state: ref Crypt->DigestState): int
312*25b96b1dSforsyth{
313*25b96b1dSforsyth	if(state == nil)
314*25b96b1dSforsyth		return 0;
315*25b96b1dSforsyth	a := sys->aprint("%s %d", cert.signer, cert.exp);
316*25b96b1dSforsyth	digest := hash(cert.ha, a, state);
317*25b96b1dSforsyth	if(digest == nil)
318*25b96b1dSforsyth		return 0;
319*25b96b1dSforsyth	b := IPint.bebytestoip(digest);
320*25b96b1dSforsyth	return crypt->verify(pk, cert.sig, b);
321*25b96b1dSforsyth}
322*25b96b1dSforsyth
323*25b96b1dSforsythhash(ha: string, a: array of byte, state: ref Crypt->DigestState): array of byte
324*25b96b1dSforsyth{
325*25b96b1dSforsyth	digest: array of byte;
326*25b96b1dSforsyth	case ha {
327*25b96b1dSforsyth	"sha" or "sha1" =>
328*25b96b1dSforsyth		digest = array[Crypt->SHA1dlen] of byte;
329*25b96b1dSforsyth		crypt->sha1(a, len a, digest, state);
330*25b96b1dSforsyth	"md5" =>
331*25b96b1dSforsyth		digest = array[Crypt->MD5dlen] of byte;
332*25b96b1dSforsyth		crypt->md5(a, len a, digest, state);
333*25b96b1dSforsyth	* =>
334*25b96b1dSforsyth		# don't bother with md4
335*25b96b1dSforsyth		sys->werrstr("unimplemented algorithm: "+ha);
336*25b96b1dSforsyth		return nil;
337*25b96b1dSforsyth	}
338*25b96b1dSforsyth	return digest;
339*25b96b1dSforsyth}
340*25b96b1dSforsyth
341*25b96b1dSforsythb64(ip: ref IPint): string
342*25b96b1dSforsyth{
343*25b96b1dSforsyth	return ip.iptob64z();
344*25b96b1dSforsyth}
345