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