xref: /plan9/sys/src/cmd/auth/rsa2any.c (revision 2d8b52e80aea4fb9116c3dab5690599d2d0cf529)
1fb7f0c93SDavid du Colombier #include <u.h>
2fb7f0c93SDavid du Colombier #include <libc.h>
3fb7f0c93SDavid du Colombier #include <bio.h>
4fb7f0c93SDavid du Colombier #include <auth.h>
5fb7f0c93SDavid du Colombier #include <mp.h>
6fb7f0c93SDavid du Colombier #include <libsec.h>
7fb7f0c93SDavid du Colombier #include "rsa2any.h"
8fb7f0c93SDavid du Colombier 
9fb7f0c93SDavid du Colombier RSApriv*
getkey(int argc,char ** argv,int needprivate,Attr ** pa)10fb7f0c93SDavid du Colombier getkey(int argc, char **argv, int needprivate, Attr **pa)
11fb7f0c93SDavid du Colombier {
12fb7f0c93SDavid du Colombier 	char *file, *s, *p;
13fb7f0c93SDavid du Colombier 	int sz;
14fb7f0c93SDavid du Colombier 	RSApriv *key;
15fb7f0c93SDavid du Colombier 	Biobuf *b;
16fb7f0c93SDavid du Colombier 	int regen;
17fb7f0c93SDavid du Colombier 	Attr *a;
18fb7f0c93SDavid du Colombier 
19fb7f0c93SDavid du Colombier 	if(argc == 0)
20fb7f0c93SDavid du Colombier 		file = "#d/0";
21fb7f0c93SDavid du Colombier 	else
22fb7f0c93SDavid du Colombier 		file = argv[0];
23fb7f0c93SDavid du Colombier 
24fb7f0c93SDavid du Colombier 	key = mallocz(sizeof(RSApriv), 1);
25fb7f0c93SDavid du Colombier 	if(key == nil)
26fb7f0c93SDavid du Colombier 		return nil;
27fb7f0c93SDavid du Colombier 
28fb7f0c93SDavid du Colombier 	if((b = Bopen(file, OREAD)) == nil){
29fb7f0c93SDavid du Colombier 		werrstr("open %s: %r", file);
30fb7f0c93SDavid du Colombier 		return nil;
31fb7f0c93SDavid du Colombier 	}
32fb7f0c93SDavid du Colombier 	s = Brdstr(b, '\n', 1);
33fb7f0c93SDavid du Colombier 	if(s == nil){
34fb7f0c93SDavid du Colombier 		werrstr("read %s: %r", file);
35fb7f0c93SDavid du Colombier 		return nil;
36fb7f0c93SDavid du Colombier 	}
37fb7f0c93SDavid du Colombier 	if(strncmp(s, "key ", 4) != 0){
38fb7f0c93SDavid du Colombier 		werrstr("bad key format");
39fb7f0c93SDavid du Colombier 		return nil;
40fb7f0c93SDavid du Colombier 	}
41fb7f0c93SDavid du Colombier 
42fb7f0c93SDavid du Colombier 	regen = 0;
43fb7f0c93SDavid du Colombier 	a = _parseattr(s+4);
44fb7f0c93SDavid du Colombier 	if(a == nil){
45fb7f0c93SDavid du Colombier 		werrstr("empty key");
46fb7f0c93SDavid du Colombier 		return nil;
47fb7f0c93SDavid du Colombier 	}
48fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "proto")) == nil){
49fb7f0c93SDavid du Colombier 		werrstr("no proto");
50fb7f0c93SDavid du Colombier 		return nil;
51fb7f0c93SDavid du Colombier 	}
52fb7f0c93SDavid du Colombier 	if(strcmp(p, "rsa") != 0){
53fb7f0c93SDavid du Colombier 		werrstr("proto not rsa");
54fb7f0c93SDavid du Colombier 		return nil;
55fb7f0c93SDavid du Colombier 	}
56fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "ek")) == nil){
57fb7f0c93SDavid du Colombier 		werrstr("no ek");
58fb7f0c93SDavid du Colombier 		return nil;
59fb7f0c93SDavid du Colombier 	}
60fb7f0c93SDavid du Colombier 	if((key->pub.ek = strtomp(p, &p, 16, nil)) == nil || *p != 0){
61fb7f0c93SDavid du Colombier 		werrstr("bad ek");
62fb7f0c93SDavid du Colombier 		return nil;
63fb7f0c93SDavid du Colombier 	}
64fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "n")) == nil){
65fb7f0c93SDavid du Colombier 		werrstr("no n");
66fb7f0c93SDavid du Colombier 		return nil;
67fb7f0c93SDavid du Colombier 	}
68fb7f0c93SDavid du Colombier 	if((key->pub.n = strtomp(p, &p, 16, nil)) == nil || *p != 0){
69fb7f0c93SDavid du Colombier 		werrstr("bad n");
70fb7f0c93SDavid du Colombier 		return nil;
71fb7f0c93SDavid du Colombier 	}
72fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "size")) == nil)
73*2d8b52e8SDavid du Colombier 		fprint(2, "warning: missing size; will add\n");
74fb7f0c93SDavid du Colombier 	else if((sz = strtol(p, &p, 10)) == 0 || *p != 0)
75*2d8b52e8SDavid du Colombier 		fprint(2, "warning: bad size; will correct\n");
76fb7f0c93SDavid du Colombier 	else if(sz != mpsignif(key->pub.n))
77*2d8b52e8SDavid du Colombier 		fprint(2, "warning: wrong size (got %d, expected %d); will correct\n",
78fb7f0c93SDavid du Colombier 			sz, mpsignif(key->pub.n));
79fb7f0c93SDavid du Colombier 	if(!needprivate)
80fb7f0c93SDavid du Colombier 		goto call;
81fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "!dk")) == nil){
82fb7f0c93SDavid du Colombier 		werrstr("no !dk");
83fb7f0c93SDavid du Colombier 		return nil;
84fb7f0c93SDavid du Colombier 	}
85fb7f0c93SDavid du Colombier 	if((key->dk = strtomp(p, &p, 16, nil)) == nil || *p != 0){
86fb7f0c93SDavid du Colombier 		werrstr("bad !dk");
87fb7f0c93SDavid du Colombier 		return nil;
88fb7f0c93SDavid du Colombier 	}
89fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "!p")) == nil){
90fb7f0c93SDavid du Colombier 		werrstr("no !p");
91fb7f0c93SDavid du Colombier 		return nil;
92fb7f0c93SDavid du Colombier 	}
93fb7f0c93SDavid du Colombier 	if((key->p = strtomp(p, &p, 16, nil)) == nil || *p != 0){
94fb7f0c93SDavid du Colombier 		werrstr("bad !p");
95fb7f0c93SDavid du Colombier 		return nil;
96fb7f0c93SDavid du Colombier 	}
97fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "!q")) == nil){
98fb7f0c93SDavid du Colombier 		werrstr("no !q");
99fb7f0c93SDavid du Colombier 		return nil;
100fb7f0c93SDavid du Colombier 	}
101fb7f0c93SDavid du Colombier 	if((key->q = strtomp(p, &p, 16, nil)) == nil || *p != 0){
102fb7f0c93SDavid du Colombier 		werrstr("bad !q");
103fb7f0c93SDavid du Colombier 		return nil;
104fb7f0c93SDavid du Colombier 	}
105fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "!kp")) == nil){
106*2d8b52e8SDavid du Colombier 		fprint(2, "warning: no !kp\n");
107fb7f0c93SDavid du Colombier 		regen = 1;
108fb7f0c93SDavid du Colombier 		goto regen;
109fb7f0c93SDavid du Colombier 	}
110fb7f0c93SDavid du Colombier 	if((key->kp = strtomp(p, &p, 16, nil)) == nil || *p != 0){
111*2d8b52e8SDavid du Colombier 		fprint(2, "warning: bad !kp\n");
112fb7f0c93SDavid du Colombier 		regen = 1;
113fb7f0c93SDavid du Colombier 		goto regen;
114fb7f0c93SDavid du Colombier 	}
115fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "!kq")) == nil){
116*2d8b52e8SDavid du Colombier 		fprint(2, "warning: no !kq\n");
117fb7f0c93SDavid du Colombier 		regen = 1;
118fb7f0c93SDavid du Colombier 		goto regen;
119fb7f0c93SDavid du Colombier 	}
120fb7f0c93SDavid du Colombier 	if((key->kq = strtomp(p, &p, 16, nil)) == nil || *p != 0){
121*2d8b52e8SDavid du Colombier 		fprint(2, "warning: bad !kq\n");
122fb7f0c93SDavid du Colombier 		regen = 1;
123fb7f0c93SDavid du Colombier 		goto regen;
124fb7f0c93SDavid du Colombier 	}
125fb7f0c93SDavid du Colombier 	if((p = _strfindattr(a, "!c2")) == nil){
126*2d8b52e8SDavid du Colombier 		fprint(2, "warning: no !c2\n");
127fb7f0c93SDavid du Colombier 		regen = 1;
128fb7f0c93SDavid du Colombier 		goto regen;
129fb7f0c93SDavid du Colombier 	}
130fb7f0c93SDavid du Colombier 	if((key->c2 = strtomp(p, &p, 16, nil)) == nil || *p != 0){
131*2d8b52e8SDavid du Colombier 		fprint(2, "warning: bad !c2\n");
132fb7f0c93SDavid du Colombier 		regen = 1;
133fb7f0c93SDavid du Colombier 		goto regen;
134fb7f0c93SDavid du Colombier 	}
135fb7f0c93SDavid du Colombier regen:
136fb7f0c93SDavid du Colombier 	if(regen){
137fb7f0c93SDavid du Colombier 		RSApriv *k2;
138fb7f0c93SDavid du Colombier 
139fb7f0c93SDavid du Colombier 		k2 = rsafill(key->pub.n, key->pub.ek, key->dk, key->p, key->q);
140fb7f0c93SDavid du Colombier 		if(k2 == nil){
141fb7f0c93SDavid du Colombier 			werrstr("regenerating chinese-remainder parts failed: %r");
142fb7f0c93SDavid du Colombier 			return nil;
143fb7f0c93SDavid du Colombier 		}
144fb7f0c93SDavid du Colombier 		key = k2;
145fb7f0c93SDavid du Colombier 	}
146fb7f0c93SDavid du Colombier call:
147fb7f0c93SDavid du Colombier 	a = _delattr(a, "ek");
148fb7f0c93SDavid du Colombier 	a = _delattr(a, "n");
149fb7f0c93SDavid du Colombier 	a = _delattr(a, "size");
150fb7f0c93SDavid du Colombier 	a = _delattr(a, "!dk");
151fb7f0c93SDavid du Colombier 	a = _delattr(a, "!p");
152fb7f0c93SDavid du Colombier 	a = _delattr(a, "!q");
153fb7f0c93SDavid du Colombier 	a = _delattr(a, "!c2");
154fb7f0c93SDavid du Colombier 	a = _delattr(a, "!kp");
155fb7f0c93SDavid du Colombier 	a = _delattr(a, "!kq");
156fb7f0c93SDavid du Colombier 	if(pa)
157fb7f0c93SDavid du Colombier 		*pa = a;
158fb7f0c93SDavid du Colombier 	return key;
159fb7f0c93SDavid du Colombier }
160fb7f0c93SDavid du Colombier 
161*2d8b52e8SDavid du Colombier DSApriv*
getdsakey(int argc,char ** argv,int needprivate,Attr ** pa)162*2d8b52e8SDavid du Colombier getdsakey(int argc, char **argv, int needprivate, Attr **pa)
163*2d8b52e8SDavid du Colombier {
164*2d8b52e8SDavid du Colombier 	char *file, *s, *p;
165*2d8b52e8SDavid du Colombier 	DSApriv *key;
166*2d8b52e8SDavid du Colombier 	Biobuf *b;
167*2d8b52e8SDavid du Colombier 	Attr *a;
168*2d8b52e8SDavid du Colombier 
169*2d8b52e8SDavid du Colombier 	if(argc == 0)
170*2d8b52e8SDavid du Colombier 		file = "#d/0";
171*2d8b52e8SDavid du Colombier 	else
172*2d8b52e8SDavid du Colombier 		file = argv[0];
173*2d8b52e8SDavid du Colombier 
174*2d8b52e8SDavid du Colombier 	key = mallocz(sizeof(RSApriv), 1);
175*2d8b52e8SDavid du Colombier 	if(key == nil)
176*2d8b52e8SDavid du Colombier 		return nil;
177*2d8b52e8SDavid du Colombier 
178*2d8b52e8SDavid du Colombier 	if((b = Bopen(file, OREAD)) == nil){
179*2d8b52e8SDavid du Colombier 		werrstr("open %s: %r", file);
180*2d8b52e8SDavid du Colombier 		return nil;
181*2d8b52e8SDavid du Colombier 	}
182*2d8b52e8SDavid du Colombier 	s = Brdstr(b, '\n', 1);
183*2d8b52e8SDavid du Colombier 	if(s == nil){
184*2d8b52e8SDavid du Colombier 		werrstr("read %s: %r", file);
185*2d8b52e8SDavid du Colombier 		return nil;
186*2d8b52e8SDavid du Colombier 	}
187*2d8b52e8SDavid du Colombier 	if(strncmp(s, "key ", 4) != 0){
188*2d8b52e8SDavid du Colombier 		werrstr("bad key format");
189*2d8b52e8SDavid du Colombier 		return nil;
190*2d8b52e8SDavid du Colombier 	}
191*2d8b52e8SDavid du Colombier 
192*2d8b52e8SDavid du Colombier 	a = _parseattr(s+4);
193*2d8b52e8SDavid du Colombier 	if(a == nil){
194*2d8b52e8SDavid du Colombier 		werrstr("empty key");
195*2d8b52e8SDavid du Colombier 		return nil;
196*2d8b52e8SDavid du Colombier 	}
197*2d8b52e8SDavid du Colombier 	if((p = _strfindattr(a, "proto")) == nil){
198*2d8b52e8SDavid du Colombier 		werrstr("no proto");
199*2d8b52e8SDavid du Colombier 		return nil;
200*2d8b52e8SDavid du Colombier 	}
201*2d8b52e8SDavid du Colombier 	if(strcmp(p, "dsa") != 0){
202*2d8b52e8SDavid du Colombier 		werrstr("proto not dsa");
203*2d8b52e8SDavid du Colombier 		return nil;
204*2d8b52e8SDavid du Colombier 	}
205*2d8b52e8SDavid du Colombier 	if((p = _strfindattr(a, "p")) == nil){
206*2d8b52e8SDavid du Colombier 		werrstr("no p");
207*2d8b52e8SDavid du Colombier 		return nil;
208*2d8b52e8SDavid du Colombier 	}
209*2d8b52e8SDavid du Colombier 	if((key->pub.p = strtomp(p, &p, 16, nil)) == nil || *p != 0){
210*2d8b52e8SDavid du Colombier 		werrstr("bad p");
211*2d8b52e8SDavid du Colombier 		return nil;
212*2d8b52e8SDavid du Colombier 	}
213*2d8b52e8SDavid du Colombier 	if((p = _strfindattr(a, "q")) == nil){
214*2d8b52e8SDavid du Colombier 		werrstr("no q");
215*2d8b52e8SDavid du Colombier 		return nil;
216*2d8b52e8SDavid du Colombier 	}
217*2d8b52e8SDavid du Colombier 	if((key->pub.q = strtomp(p, &p, 16, nil)) == nil || *p != 0){
218*2d8b52e8SDavid du Colombier 		werrstr("bad q");
219*2d8b52e8SDavid du Colombier 		return nil;
220*2d8b52e8SDavid du Colombier 	}
221*2d8b52e8SDavid du Colombier 	if((p = _strfindattr(a, "alpha")) == nil){
222*2d8b52e8SDavid du Colombier 		werrstr("no alpha");
223*2d8b52e8SDavid du Colombier 		return nil;
224*2d8b52e8SDavid du Colombier 	}
225*2d8b52e8SDavid du Colombier 	if((key->pub.alpha = strtomp(p, &p, 16, nil)) == nil || *p != 0){
226*2d8b52e8SDavid du Colombier 		werrstr("bad alpha");
227*2d8b52e8SDavid du Colombier 		return nil;
228*2d8b52e8SDavid du Colombier 	}
229*2d8b52e8SDavid du Colombier 	if((p = _strfindattr(a, "key")) == nil){
230*2d8b52e8SDavid du Colombier 		werrstr("no key=");
231*2d8b52e8SDavid du Colombier 		return nil;
232*2d8b52e8SDavid du Colombier 	}
233*2d8b52e8SDavid du Colombier 	if((key->pub.key = strtomp(p, &p, 16, nil)) == nil || *p != 0){
234*2d8b52e8SDavid du Colombier 		werrstr("bad key=");
235*2d8b52e8SDavid du Colombier 		return nil;
236*2d8b52e8SDavid du Colombier 	}
237*2d8b52e8SDavid du Colombier 	if(!needprivate)
238*2d8b52e8SDavid du Colombier 		goto call;
239*2d8b52e8SDavid du Colombier 	if((p = _strfindattr(a, "!secret")) == nil){
240*2d8b52e8SDavid du Colombier 		werrstr("no !secret");
241*2d8b52e8SDavid du Colombier 		return nil;
242*2d8b52e8SDavid du Colombier 	}
243*2d8b52e8SDavid du Colombier 	if((key->secret = strtomp(p, &p, 16, nil)) == nil || *p != 0){
244*2d8b52e8SDavid du Colombier 		werrstr("bad !secret");
245*2d8b52e8SDavid du Colombier 		return nil;
246*2d8b52e8SDavid du Colombier 	}
247*2d8b52e8SDavid du Colombier call:
248*2d8b52e8SDavid du Colombier 	a = _delattr(a, "p");
249*2d8b52e8SDavid du Colombier 	a = _delattr(a, "q");
250*2d8b52e8SDavid du Colombier 	a = _delattr(a, "alpha");
251*2d8b52e8SDavid du Colombier 	a = _delattr(a, "key");
252*2d8b52e8SDavid du Colombier 	a = _delattr(a, "!secret");
253*2d8b52e8SDavid du Colombier 	if(pa)
254*2d8b52e8SDavid du Colombier 		*pa = a;
255*2d8b52e8SDavid du Colombier 	return key;
256*2d8b52e8SDavid du Colombier }
257*2d8b52e8SDavid du Colombier 
258*2d8b52e8SDavid du Colombier uchar*
put4(uchar * p,uint n)259*2d8b52e8SDavid du Colombier put4(uchar *p, uint n)
260*2d8b52e8SDavid du Colombier {
261*2d8b52e8SDavid du Colombier 	p[0] = (n>>24)&0xFF;
262*2d8b52e8SDavid du Colombier 	p[1] = (n>>16)&0xFF;
263*2d8b52e8SDavid du Colombier 	p[2] = (n>>8)&0xFF;
264*2d8b52e8SDavid du Colombier 	p[3] = n&0xFF;
265*2d8b52e8SDavid du Colombier 	return p+4;
266*2d8b52e8SDavid du Colombier }
267*2d8b52e8SDavid du Colombier 
268*2d8b52e8SDavid du Colombier uchar*
putn(uchar * p,void * v,uint n)269*2d8b52e8SDavid du Colombier putn(uchar *p, void *v, uint n)
270*2d8b52e8SDavid du Colombier {
271*2d8b52e8SDavid du Colombier 	memmove(p, v, n);
272*2d8b52e8SDavid du Colombier 	p += n;
273*2d8b52e8SDavid du Colombier 	return p;
274*2d8b52e8SDavid du Colombier }
275*2d8b52e8SDavid du Colombier 
276*2d8b52e8SDavid du Colombier uchar*
putstr(uchar * p,char * s)277*2d8b52e8SDavid du Colombier putstr(uchar *p, char *s)
278*2d8b52e8SDavid du Colombier {
279*2d8b52e8SDavid du Colombier 	p = put4(p, strlen(s));
280*2d8b52e8SDavid du Colombier 	p = putn(p, s, strlen(s));
281*2d8b52e8SDavid du Colombier 	return p;
282*2d8b52e8SDavid du Colombier }
283*2d8b52e8SDavid du Colombier 
284*2d8b52e8SDavid du Colombier uchar*
putmp2(uchar * p,mpint * b)285*2d8b52e8SDavid du Colombier putmp2(uchar *p, mpint *b)
286*2d8b52e8SDavid du Colombier {
287*2d8b52e8SDavid du Colombier 	int bits, n;
288*2d8b52e8SDavid du Colombier 
289*2d8b52e8SDavid du Colombier 	if(mpcmp(b, mpzero) == 0)
290*2d8b52e8SDavid du Colombier 		return put4(p, 0);
291*2d8b52e8SDavid du Colombier 	bits = mpsignif(b);
292*2d8b52e8SDavid du Colombier 	n = (bits+7)/8;
293*2d8b52e8SDavid du Colombier 	if(bits%8 == 0){
294*2d8b52e8SDavid du Colombier 		p = put4(p, n+1);
295*2d8b52e8SDavid du Colombier 		*p++ = 0;
296*2d8b52e8SDavid du Colombier 	}else
297*2d8b52e8SDavid du Colombier 		p = put4(p, n);
298*2d8b52e8SDavid du Colombier 	mptobe(b, p, n, nil);
299*2d8b52e8SDavid du Colombier 	p += n;
300*2d8b52e8SDavid du Colombier 	return p;
301*2d8b52e8SDavid du Colombier }
302