xref: /inferno-os/libinterp/keyring.c (revision 7de2b42d50e3c05cc143e7b51284009b5e185581)
1 #include "lib9.h"
2 #include "kernel.h"
3 #include <isa.h>
4 #include "interp.h"
5 #include <mp.h>
6 #include <libsec.h>
7 #include "pool.h"
8 #include "raise.h"
9 
10 /* arguably limbo -t should qualify type name */
11 #define	DigestState_copy Keyring_DigestState_copy
12 #define	IPint_random Keyring_IPint_random
13 #include "keyringif.h"
14 #include "keyring.h"
15 
16 #include "ipint.h"
17 #include "../libkeyring/keys.h"
18 
19 static Type*	TDigestState;
20 static Type*	TAESstate;
21 static Type*	TDESstate;
22 static Type*	TIDEAstate;
23 static Type*	TBFstate;
24 static Type*	TRC4state;
25 
26 static Type*	TSigAlg;
27 static Type*	TCertificate;
28 static Type*	TSK;
29 static Type*	TPK;
30 static Type*	TAuthinfo;
31 
32 static Type*	TDSAsk;
33 static Type*	TDSApk;
34 static Type*	TDSAsig;
35 static Type*	TEGsk;
36 static Type*	TEGpk;
37 static Type*	TEGsig;
38 static Type*	TRSAsk;
39 static Type*	TRSApk;
40 static Type*	TRSAsig;
41 
42 enum {
43 	Maxmsg=	4096
44 };
45 
46 static uchar DigestStatemap[] = Keyring_DigestState_map;
47 static uchar AESstatemap[] = Keyring_AESstate_map;
48 static uchar DESstatemap[] = Keyring_DESstate_map;
49 static uchar IDEAstatemap[] = Keyring_IDEAstate_map;
50 static uchar BFstatemap[] = Keyring_BFstate_map;
51 static uchar RC4statemap[] = Keyring_RC4state_map;
52 
53 static uchar SigAlgmap[] = Keyring_SigAlg_map;
54 static uchar SKmap[] = Keyring_SK_map;
55 static uchar PKmap[] = Keyring_PK_map;
56 static uchar Certificatemap[] = Keyring_Certificate_map;
57 static uchar Authinfomap[] = Keyring_Authinfo_map;
58 static uchar DSAskmap[] = Keyring_DSAsk_map;
59 static uchar DSApkmap[] = Keyring_DSApk_map;
60 static uchar DSAsigmap[] = Keyring_DSAsig_map;
61 static uchar EGskmap[] = Keyring_EGsk_map;
62 static uchar EGpkmap[] = Keyring_EGpk_map;
63 static uchar EGsigmap[] = Keyring_EGsig_map;
64 static uchar RSAskmap[] = Keyring_RSAsk_map;
65 static uchar RSApkmap[] = Keyring_RSApk_map;
66 static uchar RSAsigmap[] = Keyring_RSAsig_map;
67 
68 static	PK*	checkPK(Keyring_PK *k);
69 
70 extern void		setid(char*, int);
71 extern vlong		osusectime(void);
72 extern void		freeIPint(Heap*, int);
73 
74 static char exBadSA[]	= "bad signature algorithm";
75 static char exBadSK[]	= "bad secret key";
76 static char exBadPK[]	= "bad public key";
77 static char exBadCert[]	= "bad certificate";
78 static char exBadBsize[]	= "data not multiple of block size";
79 static char exBadKey[]	= "bad encryption key";
80 static char exBadDigest[]	= "bad digest value";
81 static char exBadIvec[]	= "bad ivec";
82 static char exBadState[] = "bad encryption state";
83 
84 typedef struct XBFstate XBFstate;
85 
86 /* BF state */
87 struct XBFstate
88 {
89 	Keyring_BFstate	x;
90 	BFstate	state;
91 };
92 
93 /* convert a Big to base64 ascii */
94 int
bigtobase64(mpint * b,char * buf,int len)95 bigtobase64(mpint* b, char *buf, int len)
96 {
97 	uchar *p;
98 	int n, rv, o;
99 
100 	n = (b->top+1)*Dbytes;
101 	p = malloc(n+1);
102 	if(p == nil)
103 		goto Err;
104 	n = mptobe(b, p+1, n, nil);
105 	if(n < 0)
106 		goto Err;
107 	p[0] = 0;
108 	if(n != 0 && (p[1]&0x80)){
109 		/* force leading 0 byte for compatibility with older representation */
110 		/* TO DO: if b->sign < 0, complement bits and add one */
111 		o = 0;
112 		n++;
113 	}else
114 		o = 1;
115 	rv = enc64(buf, len, p+o, n);
116 	free(p);
117 	return rv;
118 
119 Err:
120 	free(p);
121 	if(len > 0){
122 		*buf = '*';
123 		return 1;
124 	}
125 	return 0;
126 }
127 
128 /* convert a Big to base64 ascii for %U */
129 int
big64conv(Fmt * f)130 big64conv(Fmt *f)
131 {
132 	mpint *b;
133 	char *buf;
134 	int n;
135 
136 	b = va_arg(f->args, mpint*);
137 	n = (b->top+1)*Dbytes + 1;
138 	n = ((n+3)/3)*4 + 1;
139 	buf = malloc(n);
140 	bigtobase64(b, buf, n);
141 	n = fmtstrcpy(f, buf);
142 	free(buf);
143 	return  n;
144 }
145 
146 static void*
newthing(Type * t,int add)147 newthing(Type *t, int add)
148 {
149 	Heap *h;
150 
151 	h = heap(t);
152 	if(add)
153 		ptradd(h);
154 	return H2D(void*, h);
155 }
156 
157 static Keyring_IPint*
ipcopymp(mpint * b)158 ipcopymp(mpint* b)
159 {
160 	if(b == nil)
161 		return H;
162 	return newIPint(mpcopy(b));
163 }
164 
165 /* convert a base64 string to a big */
166 mpint*
base64tobig(char * str,char ** strp)167 base64tobig(char *str, char **strp)
168 {
169 	int n;
170 	char *p;
171 	mpint *b;
172 	uchar hex[(MaxBigBytes*6 + 7)/8];
173 
174 	for(p = str; *p && *p != '\n'; p++)
175 		;
176 	if(p == str)
177 		return nil;
178 	n = dec64(hex, sizeof(hex), str, p - str);
179 	b = betomp(hex, n, nil);
180 	if(strp){
181 		if(*p)
182 			p++;
183 		*strp = p;
184 	}
185 	return b;
186 }
187 
188 /*
189  *  signature algorithms
190  */
191 enum
192 {
193 	Maxalg = 8
194 };
195 static SigAlgVec	*algs[Maxalg];
196 static int		nalg;
197 
198 static SigAlg*
newSigAlg(SigAlgVec * vec)199 newSigAlg(SigAlgVec *vec)
200 {
201 	Heap *h;
202 	SigAlg *sa;
203 
204 	h = heap(TSigAlg);
205 	sa = H2D(SigAlg*, h);
206 	retstr(vec->name, &sa->x.name);
207 	sa->vec = vec;
208 	return sa;
209 }
210 
211 static void
freeSigAlg(Heap * h,int swept)212 freeSigAlg(Heap *h, int swept)
213 {
214 	if(!swept)
215 		freeheap(h, 0);
216 }
217 
218 SigAlgVec*
findsigalg(char * name)219 findsigalg(char *name)
220 {
221 	SigAlgVec **sap;
222 
223 	for(sap = algs; sap < &algs[nalg]; sap++)
224 		if(strcmp(name, (*sap)->name) == 0)
225 			return *sap;
226 	return nil;
227 }
228 
229 SigAlg*
strtoalg(char * str,char ** strp)230 strtoalg(char *str, char **strp)
231 {
232 	int n;
233 	char *p, name[20];
234 	SigAlgVec *sa;
235 
236 
237 	p = strchr(str, '\n');
238 	if(p == 0){
239 		p = str + strlen(str);
240 		if(strp)
241 			*strp = p;
242 	} else {
243 		if(strp)
244 			*strp = p+1;
245 	}
246 
247 	n = p - str;
248 	if(n < sizeof(name)){
249 		strncpy(name, str, n);
250 		name[n] = 0;
251 		sa = findsigalg(name);
252 		if(sa != nil)
253 			return newSigAlg(sa);
254 	}
255 	return nil;
256 }
257 
258 static SigAlg*
checkSigAlg(Keyring_SigAlg * ksa)259 checkSigAlg(Keyring_SigAlg *ksa)
260 {
261 	SigAlgVec **sap;
262 	SigAlg *sa;
263 
264 	sa = (SigAlg*)ksa;
265 
266 	for(sap = algs; sap < &algs[Maxalg]; sap++)
267 		if(sa->vec == *sap)
268 			return sa;
269 	errorf("%s: %s", exType, exBadSA);
270 	return nil;
271 }
272 
273 /*
274  *  parse next new line terminated string into a String
275  */
276 String*
strtostring(char * str,char ** strp)277 strtostring(char *str, char **strp)
278 {
279 	char *p;
280 	String *s;
281 
282 	p = strchr(str, '\n');
283 	if(p == 0)
284 		p = str + strlen(str);
285 	s = H;
286 	retnstr(str, p - str, &s);
287 
288 	if(strp){
289 		if(*p)
290 			p++;
291 		*strp = p;
292 	}
293 
294 	return s;
295 }
296 
297 /*
298  *  private part of a key
299  */
300 static SK*
newSK(SigAlg * sa,String * owner,int increfsa)301 newSK(SigAlg *sa, String *owner, int increfsa)
302 {
303 	Heap *h;
304 	SK *k;
305 
306 	h = heap(TSK);
307 	k = H2D(SK*, h);
308 	k->x.sa = (Keyring_SigAlg*)sa;
309 	if(increfsa) {
310 		h = D2H(sa);
311 		h->ref++;
312 		Setmark(h);
313 	}
314 	k->x.owner = owner;
315 	k->key = 0;
316 	return k;
317 }
318 
319 static void
freeSK(Heap * h,int swept)320 freeSK(Heap *h, int swept)
321 {
322 	SK *k;
323 	SigAlg *sa;
324 
325 	k = H2D(SK*, h);
326 	sa = checkSigAlg(k->x.sa);
327 	if(k->key)
328 		(*sa->vec->skfree)(k->key);
329 	freeheap(h, swept);
330 }
331 
332 static SK*
checkSK(Keyring_SK * k)333 checkSK(Keyring_SK *k)
334 {
335 	SK *sk;
336 
337 	sk = (SK*)k;
338 	if(sk == H || sk == nil || sk->key == 0 || D2H(sk)->t != TSK){
339 		errorf("%s: %s", exType, exBadSK);
340 		return nil;
341 	}
342 	return sk;
343 }
344 
345 void
Keyring_genSK(void * fp)346 Keyring_genSK(void *fp)
347 {
348 	F_Keyring_genSK *f;
349 	SK *sk;
350 	SigAlg *sa;
351 	void *v;
352 
353 	f = fp;
354 	v = *f->ret;
355 	*f->ret = H;
356 	destroy(v);
357 
358 	sa = strtoalg(string2c(f->algname), 0);
359 	if(sa == nil)
360 		return;
361 
362 	sk = newSK(sa, stringdup(f->owner), 0);
363 	*f->ret = (Keyring_SK*)sk;
364 	release();
365 	sk->key = (*sa->vec->gensk)(f->length);
366 	acquire();
367 }
368 
369 void
Keyring_genSKfromPK(void * fp)370 Keyring_genSKfromPK(void *fp)
371 {
372 	F_Keyring_genSKfromPK *f;
373 	SigAlg *sa;
374 	PK *pk;
375 	SK *sk;
376 	void *v;
377 
378 	f = fp;
379 	v = *f->ret;
380 	*f->ret = H;
381 	destroy(v);
382 
383 	pk = checkPK(f->pk);
384 	sa = checkSigAlg(pk->x.sa);
385 	sk = newSK(sa, stringdup(f->owner), 1);
386 	*f->ret = (Keyring_SK*)sk;
387 	release();
388 	sk->key = (*sa->vec->genskfrompk)(pk->key);
389 	acquire();
390 }
391 
392 /* converts a sequence of newline-separated base64-encoded mpints to attr=hexval ... in f */
393 static char*
bigs2attr(Fmt * f,char * bigs,char ** names)394 bigs2attr(Fmt *f, char *bigs, char **names)
395 {
396 	int i, n, nd;
397 	char *b16, *vals[20];
398 	uchar data[(MaxBigBytes*6 + 7)/8];
399 
400 	b16 = malloc(2*MaxBigBytes+1);
401 	if(b16 == nil)
402 		return nil;
403 	n = getfields(bigs, vals, nelem(vals), 0, "\n");
404 	for(i = 0; i < n-1; i++){
405 		if(names == nil || names[i] == nil)
406 			break;	/* shouldn't happen */
407 		nd = dec64(data, sizeof(data), vals[i], strlen(vals[i]));
408 		if(nd < 0)
409 			break;
410 		enc16(b16, 2*MaxBigBytes+1, data, nd);
411 		fmtprint(f, " %s=%s", names[i], b16);
412 	}
413 	free(b16);
414 	return fmtstrflush(f);
415 }
416 
417 void
Keyring_sktoattr(void * fp)418 Keyring_sktoattr(void *fp)
419 {
420 	F_Keyring_sktoattr *f;
421 	char *val, *buf, *owner;
422 	SigAlg *sa;
423 	Fmt o;
424 	SK *sk;
425 
426 	f = fp;
427 	sk = checkSK(f->sk);
428 	sa = checkSigAlg(sk->x.sa);
429 	buf = malloc(Maxbuf);
430 	if(buf == nil){
431 		retstr(nil, f->ret);
432 		return;
433 	}
434 	(*sa->vec->sk2str)(sk->key, buf, Maxbuf);
435 	fmtstrinit(&o);
436 	fmtprint(&o, "alg=%q", string2c(sa->x.name));
437 	owner = string2c(sk->x.owner);
438 	if(*owner)
439 		fmtprint(&o, " owner=%q", owner);
440 	val = bigs2attr(&o, buf, sa->vec->skattr);
441 	free(buf);
442 	retstr(val, f->ret);
443 	free(val);
444 }
445 
446 static int
sktostr(SK * sk,char * buf,int len)447 sktostr(SK *sk, char *buf, int len)
448 {
449 	int n;
450 	SigAlg *sa;
451 
452 	sa = checkSigAlg(sk->x.sa);
453 	n = snprint(buf, len, "%s\n%s\n", string2c(sa->x.name),
454 			string2c(sk->x.owner));
455 	return n + (*sa->vec->sk2str)(sk->key, buf+n, len - n);
456 }
457 
458 void
Keyring_sktostr(void * fp)459 Keyring_sktostr(void *fp)
460 {
461 	F_Keyring_sktostr *f;
462 	char *buf;
463 
464 	f = fp;
465 	buf = malloc(Maxbuf);
466 
467 	if(buf)
468 		sktostr(checkSK(f->sk), buf, Maxbuf);
469 	retstr(buf, f->ret);
470 
471 	free(buf);
472 }
473 
474 static SK*
strtosk(char * buf)475 strtosk(char *buf)
476 {
477 	SK *sk;
478 	char *p;
479 	SigAlg *sa;
480 	String *owner;
481 	void *key;
482 
483 	sa = strtoalg(buf, &p);
484 	if(sa == nil)
485 		return H;
486 	owner = strtostring(p, &p);
487 	if(owner == H){
488 		destroy(sa);
489 		return H;
490 	}
491 
492 	key = (*sa->vec->str2sk)(p, &p);
493 	if(key == nil){
494 		destroy(sa);
495 		destroy(owner);
496 		return H;
497 	}
498 	sk = newSK(sa, owner, 0);
499 	sk->key = key;
500 
501 	return sk;
502 }
503 
504 void
Keyring_strtosk(void * fp)505 Keyring_strtosk(void *fp)
506 {
507 	F_Keyring_strtosk *f;
508 	void *v;
509 
510 	f = fp;
511 	v = *f->ret;
512 	*f->ret = H;
513 	destroy(v);
514 	*f->ret = (Keyring_SK*)strtosk(string2c(f->s));
515 }
516 
517 /*
518  *  public part of a key
519  */
520 PK*
newPK(SigAlg * sa,String * owner,int increfsa)521 newPK(SigAlg *sa, String *owner, int increfsa)
522 {
523 	Heap *h;
524 	PK *k;
525 
526 	h = heap(TPK);
527 	k = H2D(PK*, h);
528 	k->x.sa = (Keyring_SigAlg*)sa;
529 	if(increfsa) {
530 		h = D2H(sa);
531 		h->ref++;
532 		Setmark(h);
533 	}
534 	k->x.owner = owner;
535 	k->key = 0;
536 	return k;
537 }
538 
539 void
pkimmutable(PK * k)540 pkimmutable(PK *k)
541 {
542 	poolimmutable(D2H(k));
543 	poolimmutable(D2H(k->x.sa));
544 	poolimmutable(D2H(k->x.sa->name));
545 	poolimmutable(D2H(k->x.owner));
546 }
547 
548 void
pkmutable(PK * k)549 pkmutable(PK *k)
550 {
551 	poolmutable(D2H(k));
552 	poolmutable(D2H(k->x.sa));
553 	poolmutable(D2H(k->x.sa->name));
554 	poolmutable(D2H(k->x.owner));
555 }
556 
557 void
freePK(Heap * h,int swept)558 freePK(Heap *h, int swept)
559 {
560 	PK *k;
561 	SigAlg *sa;
562 
563 	k = H2D(PK*, h);
564 	sa = checkSigAlg(k->x.sa);
565 	if(k->key)
566 		(*sa->vec->pkfree)(k->key);
567 	freeheap(h, swept);
568 }
569 
570 static PK*
checkPK(Keyring_PK * k)571 checkPK(Keyring_PK *k)
572 {
573 	PK *pk;
574 
575 	pk = (PK*)k;
576 	if(pk == H || pk == nil || pk->key == 0 || D2H(pk)->t != TPK){
577 		errorf("%s: %s", exType, exBadPK);
578 		return nil;
579 	}
580 	return pk;
581 }
582 
583 void
Keyring_sktopk(void * fp)584 Keyring_sktopk(void *fp)
585 {
586 	F_Keyring_sktopk *f;
587 	PK *pk;
588 	SigAlg *sa;
589 	SK *sk;
590 	void *r;
591 
592 	f = fp;
593 	r = *f->ret;
594 	*f->ret = H;
595 	destroy(r);
596 
597 	sk = checkSK(f->sk);
598 	sa = checkSigAlg(sk->x.sa);
599 	pk = newPK(sa, stringdup(sk->x.owner), 1);
600 	pk->key = (*sa->vec->sk2pk)(sk->key);
601 	*f->ret = (Keyring_PK*)pk;
602 }
603 
604 static int
pktostr(PK * pk,char * buf,int len)605 pktostr(PK *pk, char *buf, int len)
606 {
607 	int n;
608 	SigAlg *sa;
609 
610 	sa = checkSigAlg(pk->x.sa);
611 	n = snprint(buf, len, "%s\n%s\n", string2c(sa->x.name), string2c(pk->x.owner));
612 	return n + (*sa->vec->pk2str)(pk->key, buf+n, len - n);
613 }
614 
615 void
Keyring_pktostr(void * fp)616 Keyring_pktostr(void *fp)
617 {
618 	F_Keyring_pktostr *f;
619 	char *buf;
620 
621 	f = fp;
622 	buf = malloc(Maxbuf);
623 
624 	if(buf)
625 		pktostr(checkPK(f->pk), buf, Maxbuf);
626 	retstr(buf, f->ret);
627 
628 	free(buf);
629 }
630 
631 void
Keyring_pktoattr(void * fp)632 Keyring_pktoattr(void *fp)
633 {
634 	F_Keyring_pktoattr *f;
635 	char *val, *buf, *owner;
636 	SigAlg *sa;
637 	Fmt o;
638 	PK *pk;
639 
640 	f = fp;
641 	pk = checkPK(f->pk);
642 	sa = checkSigAlg(pk->x.sa);
643 	buf = malloc(Maxbuf);
644 	if(buf == nil){
645 		retstr(nil, f->ret);
646 		return;
647 	}
648 	(*sa->vec->pk2str)(pk->key, buf, Maxbuf);
649 	fmtstrinit(&o);
650 	fmtprint(&o, "alg=%q", string2c(sa->x.name));
651 	owner = string2c(pk->x.owner);
652 	if(*owner)
653 		fmtprint(&o, " owner=%q", owner);
654 	val = bigs2attr(&o, buf, sa->vec->pkattr);
655 	free(buf);
656 	retstr(val, f->ret);
657 	free(val);
658 }
659 
660 static PK*
strtopk(char * buf)661 strtopk(char *buf)
662 {
663 	PK *pk;
664 	char *p;
665 	SigAlg *sa;
666 	String *owner;
667 	void *key;
668 
669 	sa = strtoalg(buf, &p);
670 	if(sa == nil)
671 		return H;
672 	owner = strtostring(p, &p);
673 	if(owner == H){
674 		destroy(sa);
675 		return H;
676 	}
677 
678 	key = (*sa->vec->str2pk)(p, &p);
679 	if(key == nil){
680 		destroy(sa);
681 		destroy(owner);
682 		return H;
683 	}
684 	pk = newPK(sa, owner, 0);
685 	pk->key = key;
686 
687 	return pk;
688 }
689 
690 void
Keyring_strtopk(void * fp)691 Keyring_strtopk(void *fp)
692 {
693 	F_Keyring_strtopk *f;
694 	void *v;
695 
696 	f = fp;
697 	v = *f->ret;
698 	*f->ret = H;
699 	destroy(v);
700 	*f->ret = (Keyring_PK*)strtopk(string2c(f->s));
701 }
702 
703 /*
704  *  Certificates/signatures
705  */
706 
707 void
certimmutable(Certificate * c)708 certimmutable(Certificate *c)
709 {
710 	poolimmutable(D2H(c));
711 	poolimmutable(D2H(c->x.signer));
712 	poolimmutable(D2H(c->x.ha));
713 	poolimmutable(D2H(c->x.sa));
714 	poolimmutable(D2H(c->x.sa->name));
715 }
716 
717 void
certmutable(Certificate * c)718 certmutable(Certificate *c)
719 {
720 	poolmutable(D2H(c));
721 	poolmutable(D2H(c->x.signer));
722 	poolmutable(D2H(c->x.ha));
723 	Setmark(D2H(c->x.sa));
724 	poolmutable(D2H(c->x.sa));
725 	Setmark(D2H(c->x.sa->name));
726 	poolmutable(D2H(c->x.sa->name));
727 }
728 
729 Certificate*
newCertificate(SigAlg * sa,String * ha,String * signer,long exp,int increfsa)730 newCertificate(SigAlg *sa, String *ha, String *signer, long exp, int increfsa)
731 {
732 	Heap *h;
733 	Certificate *c;
734 
735 	h = heap(TCertificate);
736 	c = H2D(Certificate*, h);
737 	c->x.sa = (Keyring_SigAlg*)sa;
738 	if(increfsa) {
739 		h = D2H(sa);
740 		h->ref++;
741 		Setmark(h);
742 	}
743 	c->x.signer = signer;
744 	c->x.ha = ha;
745 	c->x.exp = exp;
746 	c->signa = 0;
747 
748 	return c;
749 }
750 
751 void
freeCertificate(Heap * h,int swept)752 freeCertificate(Heap *h, int swept)
753 {
754 	Certificate *c;
755 	SigAlg *sa;
756 
757 	c = H2D(Certificate*, h);
758 	sa = checkSigAlg(c->x.sa);
759 	if(c->signa)
760 		(*sa->vec->sigfree)(c->signa);
761 	freeheap(h, swept);
762 }
763 
764 Certificate*
checkCertificate(Keyring_Certificate * c)765 checkCertificate(Keyring_Certificate *c)
766 {
767 	Certificate *cert;
768 
769 	cert = (Certificate*)c;
770 	if(cert == H || cert == nil || cert->signa == 0 || D2H(cert)->t != TCertificate){
771 		errorf("%s: %s", exType, exBadCert);
772 		return nil;
773 	}
774 	return cert;
775 }
776 
777 static int
certtostr(Certificate * c,char * buf,int len)778 certtostr(Certificate *c, char *buf, int len)
779 {
780 	SigAlg *sa;
781 	int n;
782 
783 	sa = checkSigAlg(c->x.sa);
784 	n = snprint(buf, len, "%s\n%s\n%s\n%d\n", string2c(sa->x.name),
785 		string2c(c->x.ha), string2c(c->x.signer), c->x.exp);
786 	return n + (*sa->vec->sig2str)(c->signa, buf+n, len - n);
787 }
788 
789 void
Keyring_certtostr(void * fp)790 Keyring_certtostr(void *fp)
791 {
792 	F_Keyring_certtostr *f;
793 	char *buf;
794 
795 	f = fp;
796 	buf = malloc(Maxbuf);
797 
798 	if(buf)
799 		certtostr(checkCertificate(f->c), buf, Maxbuf);
800 	retstr(buf, f->ret);
801 
802 	free(buf);
803 }
804 
805 void
Keyring_certtoattr(void * fp)806 Keyring_certtoattr(void *fp)
807 {
808 	F_Keyring_certtoattr *f;
809 	char *val, *buf, *ha;
810 	SigAlg *sa;
811 	Fmt o;
812 	Certificate *c;
813 
814 	f = fp;
815 	c = checkCertificate(f->c);
816 	sa = checkSigAlg(c->x.sa);
817 	buf = malloc(Maxbuf);
818 	if(buf == nil){
819 		retstr(nil, f->ret);
820 		return;
821 	}
822 	(*sa->vec->sig2str)(c->signa, buf, Maxbuf);
823 	ha = string2c(c->x.ha);
824 	if(strcmp(ha, "sha") == 0)
825 		ha = "sha1";	/* normalise */
826 	fmtstrinit(&o);
827 	fmtprint(&o, "sigalg=%q-%q signer=%q expires=%ud", string2c(sa->x.name), ha,
828 		string2c(c->x.signer), c->x.exp);
829 	val = bigs2attr(&o, buf, sa->vec->sigattr);
830 	free(buf);
831 	retstr(val, f->ret);
832 	free(val);
833 }
834 
835 static Certificate*
strtocert(char * buf)836 strtocert(char *buf)
837 {
838 	Certificate *c;
839 	char *p;
840 	SigAlg *sa;
841 	String *signer, *ha;
842 	long exp;
843 	void *signa;
844 
845 	sa = strtoalg(buf, &p);
846 	if(sa == 0)
847 		return H;
848 
849 	ha = strtostring(p, &p);
850 	if(ha == H){
851 		destroy(sa);
852 		return H;
853 	}
854 
855 	signer = strtostring(p, &p);
856 	if(signer == H){
857 		destroy(sa);
858 		destroy(ha);
859 		return H;
860 	}
861 
862 	exp = strtoul(p, &p, 10);
863 	if(*p)
864 		p++;
865 	signa = (*sa->vec->str2sig)(p, &p);
866 	if(signa == nil){
867 		destroy(sa);
868 		destroy(ha);
869 		destroy(signer);
870 		return H;
871 	}
872 
873 	c = newCertificate(sa, ha, signer, exp, 0);
874 	c->signa = signa;
875 
876 	return c;
877 }
878 
879 void
Keyring_strtocert(void * fp)880 Keyring_strtocert(void *fp)
881 {
882 	F_Keyring_strtocert *f;
883 	void *r;
884 
885 	f = fp;
886 	r = *f->ret;
887 	*f->ret = H;
888 	destroy(r);
889 	*f->ret = (Keyring_Certificate*)strtocert(string2c(f->s));
890 }
891 
892 static Certificate*
sign(SK * sk,char * ha,ulong exp,uchar * a,int len)893 sign(SK *sk, char *ha, ulong exp, uchar *a, int len)
894 {
895 	Certificate *c;
896 	mpint *b;
897 	int n;
898 	SigAlg *sa;
899 	DigestState *ds;
900 	uchar digest[SHA1dlen];
901 	char *buf;
902 	String *hastr;
903 
904 	hastr = H;
905 	sa = checkSigAlg(sk->x.sa);
906 	buf = malloc(Maxbuf);
907 	if(buf == nil)
908 		return nil;
909 
910 	/* add signer name and expiration time to hash */
911 	n = snprint(buf, Maxbuf, "%s %lud", string2c(sk->x.owner), exp);
912 	if(strcmp(ha, "sha") == 0 || strcmp(ha, "sha1") == 0){
913 		ds = sha1(a, len, 0, 0);
914 		sha1((uchar*)buf, n, digest, ds);
915 		n = Keyring_SHA1dlen;
916 	} else if(strcmp(ha, "md5") == 0){
917 		ds = md5(a, len, 0, 0);
918 		md5((uchar*)buf, n, digest, ds);
919 		n = Keyring_MD5dlen;
920 	} else if(strcmp(ha, "md4") == 0){
921 		ds = md4(a, len, 0, 0);
922 		md4((uchar*)buf, n, digest, ds);
923 		n = Keyring_MD5dlen;
924 	} else {
925 		free(buf);
926 		return nil;
927 	}
928 	free(buf);
929 
930 	/* turn message into a big integer */
931 	b = betomp(digest, n, nil);
932 	if(b == nil)
933 		return nil;
934 
935 	/* sign */
936 	retstr(ha, &hastr);
937 	c = newCertificate(sa, hastr, stringdup(sk->x.owner), exp, 1);
938 	certimmutable(c);		/* hide from the garbage collector */
939 	release();
940 	c->signa = (*sa->vec->sign)(b, sk->key);
941 	acquire();
942 	mpfree(b);
943 
944 	return c;
945 }
946 
947 void
Keyring_sign(void * fp)948 Keyring_sign(void *fp)
949 {
950 	F_Keyring_sign *f;
951 	Certificate *c;
952 	mpint *b;
953 	int n;
954 	SigAlg *sa;
955 	SK *sk;
956 	XDigestState *ds;
957 	uchar digest[SHA1dlen];
958 	char *buf;
959 	void *v;
960 
961 	f = fp;
962 	v = *f->ret;
963 	*f->ret = H;
964 	destroy(v);
965 
966 	sk = checkSK(f->sk);
967 	sa = checkSigAlg(sk->x.sa);
968 
969 	/* add signer name and expiration time to hash */
970 	if(f->state == H)
971 		return;
972 	buf = malloc(Maxbuf);
973 	if(buf == nil)
974 		return;
975 	ds = (XDigestState*)f->state;
976 	n = snprint(buf, Maxbuf, "%s %d", string2c(sk->x.owner), f->exp);
977 	if(strcmp(string2c(f->ha), "sha") == 0 || strcmp(string2c(f->ha), "sha1") == 0){
978 		sha1((uchar*)buf, n, digest, &ds->state);
979 		n = Keyring_SHA1dlen;
980 	} else if(strcmp(string2c(f->ha), "md5") == 0){
981 		md5((uchar*)buf, n, digest, &ds->state);
982 		n = Keyring_MD5dlen;
983 	} else if(strcmp(string2c(f->ha), "md4") == 0){
984 		md4((uchar*)buf, n, digest, &ds->state);
985 		n = Keyring_MD5dlen;
986 	} else {
987 		free(buf);
988 		return;
989 	}
990 	free(buf);
991 
992 	/* turn message into a big integer */
993 	b = betomp(digest, n, nil);
994 	if(b == nil)
995 		return;
996 
997 	/* sign */
998 	c = newCertificate(sa, stringdup(f->ha), stringdup(sk->x.owner), f->exp, 1);
999 	*f->ret = (Keyring_Certificate*)c;
1000 	release();
1001 	c->signa = (*sa->vec->sign)(b, sk->key);
1002 	acquire();
1003 	mpfree(b);
1004 }
1005 
1006 void
Keyring_signm(void * fp)1007 Keyring_signm(void *fp)
1008 {
1009 	F_Keyring_signm *f;
1010 	Certificate *c;
1011 	mpint *b;
1012 	SigAlg *sa;
1013 	SK *sk;
1014 	void *v;
1015 
1016 	f = fp;
1017 	v = *f->ret;
1018 	*f->ret = H;
1019 	destroy(v);
1020 
1021 	sk = checkSK(f->sk);
1022 	sa = checkSigAlg(sk->x.sa);
1023 
1024 	if(f->m == H)
1025 		return;
1026 	b = checkIPint(f->m);
1027 
1028 	/* sign */
1029 	c = newCertificate(sa, stringdup(f->ha), stringdup(sk->x.owner), 0, 1);
1030 	*f->ret = (Keyring_Certificate*)c;
1031 	release();
1032 	c->signa = (*sa->vec->sign)(b, sk->key);
1033 	acquire();
1034 }
1035 
1036 static int
verify(PK * pk,Certificate * c,char * a,int len)1037 verify(PK *pk, Certificate *c, char *a, int len)
1038 {
1039 	mpint *b;
1040 	int n;
1041 	SigAlg *sa, *pksa;
1042 	DigestState *ds;
1043 	uchar digest[SHA1dlen];
1044 	char *buf;
1045 
1046 	sa = checkSigAlg(c->x.sa);
1047 	pksa = checkSigAlg(pk->x.sa);
1048 	if(sa->vec != pksa->vec)
1049 		return 0;
1050 
1051 	/* add signer name and expiration time to hash */
1052 	buf = malloc(Maxbuf);
1053 	if(buf == nil)
1054 		return 0;
1055 	n = snprint(buf, Maxbuf, "%s %d", string2c(c->x.signer), c->x.exp);
1056 	if(strcmp(string2c(c->x.ha), "sha") == 0 || strcmp(string2c(c->x.ha), "sha1") == 0){
1057 		ds = sha1((uchar*)a, len, 0, 0);
1058 		sha1((uchar*)buf, n, digest, ds);
1059 		n = Keyring_SHA1dlen;
1060 	} else if(strcmp(string2c(c->x.ha), "md5") == 0){
1061 		ds = md5((uchar*)a, len, 0, 0);
1062 		md5((uchar*)buf, n, digest, ds);
1063 		n = Keyring_MD5dlen;
1064 	} else if(strcmp(string2c(c->x.ha), "md4") == 0){
1065 		ds = md4((uchar*)a, len, 0, 0);
1066 		md4((uchar*)buf, n, digest, ds);
1067 		n = Keyring_MD5dlen;
1068 	} else {
1069 		free(buf);
1070 		return 0;
1071 	}
1072 	free(buf);
1073 
1074 	/* turn message into a big integer */
1075 	b = betomp(digest, n, nil);
1076 	if(b == nil)
1077 		return 0;
1078 	/* verify */
1079 	release();
1080 	n = (*sa->vec->verify)(b, c->signa, pk->key);
1081 	acquire();
1082 
1083 	mpfree(b);
1084 	return n;
1085 }
1086 
1087 void
Keyring_verify(void * fp)1088 Keyring_verify(void *fp)
1089 {
1090 	F_Keyring_verify *f;
1091 	Certificate *c;
1092 	mpint *b;
1093 	int n;
1094 	SigAlg *sa, *pksa;
1095 	PK *pk;
1096 	XDigestState *ds;
1097 	uchar digest[SHA1dlen];
1098 	char *buf;
1099 
1100 	f = fp;
1101 	*f->ret = 0;
1102 
1103 	c = checkCertificate(f->cert);
1104 	sa = checkSigAlg(c->x.sa);
1105 	pk = checkPK(f->pk);
1106 	pksa = checkSigAlg(pk->x.sa);
1107 	if(sa->vec != pksa->vec)
1108 		return;
1109 
1110 	/* add signer name and expiration time to hash */
1111 	if(f->state == H)
1112 		return;
1113 	buf = malloc(Maxbuf);
1114 	if(buf == nil)
1115 		return;
1116 	n = snprint(buf, Maxbuf, "%s %d", string2c(c->x.signer), c->x.exp);
1117 	ds = (XDigestState*)f->state;
1118 
1119 	if(strcmp(string2c(c->x.ha), "sha") == 0 || strcmp(string2c(c->x.ha), "sha1") == 0){
1120 		sha1((uchar*)buf, n, digest, &ds->state);
1121 		n = Keyring_SHA1dlen;
1122 	} else if(strcmp(string2c(c->x.ha), "md5") == 0){
1123 		md5((uchar*)buf, n, digest, &ds->state);
1124 		n = Keyring_MD5dlen;
1125 	} else if(strcmp(string2c(c->x.ha), "md4") == 0){
1126 		md4((uchar*)buf, n, digest, &ds->state);
1127 		n = Keyring_MD5dlen;
1128 	} else {
1129 		free(buf);
1130 		return;
1131 	}
1132 	free(buf);
1133 
1134 	/* turn message into a big integer */
1135 	b = betomp(digest, n, nil);
1136 	if(b == nil)
1137 		return;
1138 
1139 	/* verify */
1140 	release();
1141 	*f->ret = (*sa->vec->verify)(b, c->signa, pk->key);
1142 	acquire();
1143 
1144 	mpfree(b);
1145 }
1146 
1147 void
Keyring_verifym(void * fp)1148 Keyring_verifym(void *fp)
1149 {
1150 	F_Keyring_verifym *f;
1151 	Certificate *c;
1152 	SigAlg *sa, *pksa;
1153 	PK *pk;
1154 
1155 	f = fp;
1156 	*f->ret = 0;
1157 
1158 	c = checkCertificate(f->cert);
1159 	sa = checkSigAlg(c->x.sa);
1160 	pk = checkPK(f->pk);
1161 	pksa = checkSigAlg(pk->x.sa);
1162 	if(sa->vec != pksa->vec)
1163 		return;
1164 
1165 	if(f->m == H)
1166 		return;
1167 
1168 	release();
1169 	*f->ret = (*sa->vec->verify)(checkIPint(f->m), c->signa, pk->key);
1170 	acquire();
1171 }
1172 
1173 /*
1174  *  digests
1175  */
1176 void
Keyring_DigestState_copy(void * fp)1177 Keyring_DigestState_copy(void *fp)
1178 {
1179 	F_DigestState_copy *f;
1180 	Heap *h;
1181 	XDigestState *ds, *ods;
1182 	void *r;
1183 
1184 	f = fp;
1185 	r = *f->ret;
1186 	*f->ret = H;
1187 	destroy(r);
1188 
1189 	if(f->d != H){
1190 		ods = checktype(f->d, TDigestState, "DigestState", 0);
1191 		h = heap(TDigestState);
1192 		ds = H2D(XDigestState*, h);
1193 		memmove(&ds->state, &ods->state, sizeof(ds->state));
1194 		*f->ret = (Keyring_DigestState*)ds;
1195 	}
1196 }
1197 
1198 static Keyring_DigestState*
keyring_digest_x(Array * buf,int n,Array * digest,int dlen,Keyring_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,DigestState *))1199 keyring_digest_x(Array *buf, int n, Array *digest, int dlen, Keyring_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, DigestState*))
1200 {
1201 	Heap *h;
1202 	XDigestState *ds;
1203 	uchar *cbuf, *cdigest;
1204 
1205 	if(buf != H){
1206 		if(n > buf->len)
1207 			n = buf->len;
1208 		cbuf = buf->data;
1209 	}else{
1210 		if(n != 0)
1211 			error(exInval);
1212 		cbuf = nil;
1213 	}
1214 
1215 	if(digest != H){
1216 		if(digest->len < dlen)
1217 			error(exBadDigest);
1218 		cdigest = digest->data;
1219 	} else
1220 		cdigest = nil;
1221 
1222 	if(state == H){
1223 		h = heap(TDigestState);
1224 		ds = H2D(XDigestState*, h);
1225 		memset(&ds->state, 0, sizeof(ds->state));
1226 	} else
1227 		ds = checktype(state, TDigestState, "DigestState", 1);
1228 
1229 	(*fn)(cbuf, n, cdigest, &ds->state);
1230 
1231 	return (Keyring_DigestState*)ds;
1232 }
1233 
1234 void
Keyring_sha1(void * fp)1235 Keyring_sha1(void *fp)
1236 {
1237 	F_Keyring_sha1 *f;
1238 	void *r;
1239 
1240 	f = fp;
1241 	r = *f->ret;
1242 	*f->ret = H;
1243 	destroy(r);
1244 
1245 	*f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA1dlen, f->state, sha1);
1246 }
1247 
1248 void
Keyring_sha224(void * fp)1249 Keyring_sha224(void *fp)
1250 {
1251 	F_Keyring_sha224 *f;
1252 	void *r;
1253 
1254 	f = fp;
1255 	r = *f->ret;
1256 	*f->ret = H;
1257 	destroy(r);
1258 
1259 	*f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA224dlen, f->state, sha224);
1260 }
1261 
1262 void
Keyring_sha256(void * fp)1263 Keyring_sha256(void *fp)
1264 {
1265 	F_Keyring_sha256 *f;
1266 	void *r;
1267 
1268 	f = fp;
1269 	r = *f->ret;
1270 	*f->ret = H;
1271 	destroy(r);
1272 
1273 	*f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA256dlen, f->state, sha256);
1274 }
1275 
1276 void
Keyring_sha384(void * fp)1277 Keyring_sha384(void *fp)
1278 {
1279 	F_Keyring_sha384 *f;
1280 	void *r;
1281 
1282 	f = fp;
1283 	r = *f->ret;
1284 	*f->ret = H;
1285 	destroy(r);
1286 
1287 	*f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA384dlen, f->state, sha384);
1288 }
1289 
1290 void
Keyring_sha512(void * fp)1291 Keyring_sha512(void *fp)
1292 {
1293 	F_Keyring_sha512 *f;
1294 	void *r;
1295 
1296 	f = fp;
1297 	r = *f->ret;
1298 	*f->ret = H;
1299 	destroy(r);
1300 
1301 	*f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA512dlen, f->state, sha512);
1302 }
1303 
1304 void
Keyring_md5(void * fp)1305 Keyring_md5(void *fp)
1306 {
1307 	F_Keyring_md5 *f;
1308 	void *r;
1309 
1310 	f = fp;
1311 	r = *f->ret;
1312 	*f->ret = H;
1313 	destroy(r);
1314 
1315 	*f->ret = keyring_digest_x(f->buf, f->n, f->digest, MD5dlen, f->state, md5);
1316 }
1317 
1318 void
Keyring_md4(void * fp)1319 Keyring_md4(void *fp)
1320 {
1321 	F_Keyring_md4 *f;
1322 	void *r;
1323 
1324 	f = fp;
1325 	r = *f->ret;
1326 	*f->ret = H;
1327 	destroy(r);
1328 
1329 	*f->ret = keyring_digest_x(f->buf, f->n, f->digest, MD4dlen, f->state, md4);
1330 }
1331 
1332 static Keyring_DigestState*
keyring_hmac_x(Array * data,int n,Array * key,Array * digest,int dlen,Keyring_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,ulong,uchar *,DigestState *))1333 keyring_hmac_x(Array *data, int n, Array *key, Array *digest, int dlen, Keyring_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*))
1334 {
1335 	Heap *h;
1336 	XDigestState *ds;
1337 	uchar *cdata, *cdigest;
1338 
1339 	if(data != H){
1340 		if(n > data->len)
1341 			n = data->len;
1342 		cdata = data->data;
1343 	}else{
1344 		if(n != 0)
1345 			error(exInval);
1346 		cdata = nil;
1347 	}
1348 
1349 	if(key == H || key->len > 64)
1350 		error(exBadKey);
1351 
1352 	if(digest != H){
1353 		if(digest->len < dlen)
1354 			error(exBadDigest);
1355 		cdigest = digest->data;
1356 	} else
1357 		cdigest = nil;
1358 
1359 	if(state == H){
1360 		h = heap(TDigestState);
1361 		ds = H2D(XDigestState*, h);
1362 		memset(&ds->state, 0, sizeof(ds->state));
1363 	} else
1364 		ds = checktype(state, TDigestState, "DigestState", 1);
1365 
1366 	(*fn)(cdata, n, key->data, key->len, cdigest, &ds->state);
1367 
1368 	return (Keyring_DigestState*)ds;
1369 }
1370 
1371 void
Keyring_hmac_sha1(void * fp)1372 Keyring_hmac_sha1(void *fp)
1373 {
1374 	F_Keyring_hmac_sha1 *f;
1375 	void *r;
1376 
1377 	f = fp;
1378 	r = *f->ret;
1379 	*f->ret = H;
1380 	destroy(r);
1381 	*f->ret = keyring_hmac_x(f->data, f->n, f->key, f->digest, SHA1dlen, f->state, hmac_sha1);
1382 }
1383 
1384 void
Keyring_hmac_md5(void * fp)1385 Keyring_hmac_md5(void *fp)
1386 {
1387 	F_Keyring_hmac_md5 *f;
1388 	void *r;
1389 
1390 	f = fp;
1391 	r = *f->ret;
1392 	*f->ret = H;
1393 	destroy(r);
1394 	*f->ret = keyring_hmac_x(f->data, f->n, f->key, f->digest, MD5dlen, f->state, hmac_md5);
1395 }
1396 
1397 void
Keyring_dhparams(void * fp)1398 Keyring_dhparams(void *fp)
1399 {
1400 	F_Keyring_dhparams *f;
1401 	mpint *p, *alpha;
1402 	void *v;
1403 
1404 	f = fp;
1405 	v = f->ret->t0;
1406 	f->ret->t0 = H;
1407 	destroy(v);
1408 	v = f->ret->t1;
1409 	f->ret->t1 = H;
1410 	destroy(v);
1411 
1412 	p = mpnew(0);
1413 	alpha = mpnew(0);
1414 	release();
1415 	if(f->nbits == 1024)
1416 		DSAprimes(alpha, p, nil);
1417 	else
1418 		gensafeprime(p, alpha, f->nbits, 0);
1419 	acquire();
1420 	f->ret->t0 = newIPint(alpha);
1421 	f->ret->t1 = newIPint(p);
1422 }
1423 
1424 static int
sendmsg(int fd,void * buf,int n)1425 sendmsg(int fd, void *buf, int n)
1426 {
1427 	char num[10];
1428 
1429 	release();
1430 	snprint(num, sizeof(num), "%4.4d\n", n);
1431 	if(kwrite(fd, num, 5) != 5){
1432 		acquire();
1433 		return -1;
1434 	}
1435 	n = kwrite(fd, buf, n);
1436 	acquire();
1437 	return n;
1438 }
1439 
1440 void
Keyring_sendmsg(void * fp)1441 Keyring_sendmsg(void *fp)
1442 {
1443 	F_Keyring_sendmsg *f;
1444 	int n;
1445 
1446 	f = fp;
1447 	*f->ret = -1;
1448 	if(f->fd == H || f->buf == H || f->n < 0)
1449 		return;
1450 	n = f->n;
1451 	if(n < 0 || n > f->buf->len)
1452 		error(exBounds);
1453 	*f->ret = sendmsg(f->fd->fd, f->buf->data, n);
1454 }
1455 
1456 static int
senderr(int fd,char * err,int addrmt)1457 senderr(int fd, char *err, int addrmt)
1458 {
1459 	char num[10];
1460 	int n, m;
1461 
1462 	release();
1463 	n = strlen(err);
1464 	m = 0;
1465 	if(addrmt)
1466 		m = strlen("remote: ");
1467 	snprint(num, sizeof(num), "!%3.3d\n", n+m);
1468 	if(kwrite(fd, num, 5) != 5){
1469 		acquire();
1470 		return -1;
1471 	}
1472 	if(addrmt)
1473 		kwrite(fd, "remote: ", m);
1474 	n = kwrite(fd, err, n);
1475 	acquire();
1476 	return n;
1477 }
1478 
1479 void
Keyring_senderrmsg(void * fp)1480 Keyring_senderrmsg(void *fp)
1481 {
1482 	F_Keyring_senderrmsg *f;
1483 	char *s;
1484 
1485 	f = fp;
1486 	*f->ret = -1;
1487 	if(f->fd == H)
1488 		return;
1489 	s = string2c(f->s);
1490 	if(senderr(f->fd->fd, s, 0) > 0)
1491 		*f->ret = 0;
1492 }
1493 
1494 static int
nreadn(int fd,void * av,int n)1495 nreadn(int fd, void *av, int n)
1496 {
1497 
1498 	char *a;
1499 	long m, t;
1500 
1501 	a = av;
1502 	t = 0;
1503 	while(t < n){
1504 		m = kread(fd, a+t, n-t);
1505 		if(m <= 0){
1506 			if(t == 0)
1507 				return m;
1508 			break;
1509 		}
1510 		t += m;
1511 	}
1512 	return t;
1513 }
1514 
1515 #define MSG "input or format error"
1516 
1517 static void
getmsgerr(char * buf,int n,int r)1518 getmsgerr(char *buf, int n, int r)
1519 {
1520 	char *e;
1521 	int l;
1522 
1523 	e = r>0? MSG: "hungup";
1524 	l = strlen(e)+1;
1525 	if(n > l)
1526 		n = l;
1527 	memmove(buf, e, n-1);
1528 	buf[n-1] = 0;
1529 }
1530 
1531 static int
getmsg(int fd,char * buf,int n)1532 getmsg(int fd, char *buf, int n)
1533 {
1534 	char num[6];
1535 	int len, r;
1536 
1537 	release();
1538 	if((r = nreadn(fd, num, 5)) != 5){
1539 		getmsgerr(buf, n, r);
1540 		acquire();
1541 		return -1;
1542 	}
1543 	num[5] = 0;
1544 
1545 	if(num[0] == '!')
1546 		len = strtoul(num+1, 0, 10);
1547 	else
1548 		len = strtoul(num, 0, 10);
1549 
1550 	r = -1;
1551 	if(len < 0 || len >= n || (r = nreadn(fd, buf, len)) != len){
1552 		getmsgerr(buf, n, r);
1553 		acquire();
1554 		return -1;
1555 	}
1556 
1557 	buf[len] = 0;
1558 	acquire();
1559 	if(num[0] == '!')
1560 		return -len;
1561 
1562 	return len;
1563 }
1564 
1565 void
Keyring_getmsg(void * fp)1566 Keyring_getmsg(void *fp)
1567 {
1568 	F_Keyring_getmsg *f;
1569 	char *buf;
1570 	int n;
1571 	void *r;
1572 
1573 	f = fp;
1574 	r = *f->ret;
1575 	*f->ret = H;
1576 	destroy(r);
1577 	if(f->fd == H){
1578 		kwerrstr("nil fd");
1579 		return;
1580 	}
1581 
1582 	buf = malloc(Maxmsg);
1583 	if(buf == nil){
1584 		kwerrstr(exNomem);
1585 		return;
1586 	}
1587 
1588 	n = getmsg(f->fd->fd, buf, Maxmsg);
1589 	if(n < 0){
1590 		kwerrstr("%s", buf);
1591 		free(buf);
1592 		return;
1593 	}
1594 
1595 	*f->ret = mem2array(buf, n);
1596 	free(buf);
1597 }
1598 
1599 void
Keyring_auth(void * fp)1600 Keyring_auth(void *fp)
1601 {
1602 	F_Keyring_auth *f;
1603 	mpint *r0, *r1, *p, *alpha, *alphar0, *alphar1, *alphar0r1;
1604 	SK *mysk;
1605 	PK *mypk, *spk, *hispk;
1606 	Certificate *cert, *hiscert, *alphacert;
1607 	char *buf, *err;
1608 	uchar *cvb;
1609 	int n, fd, version;
1610 	long now;
1611 
1612 	hispk = H;
1613 	hiscert = H;
1614 	alphacert = H;
1615 	err = nil;
1616 
1617 	/* null out the return values */
1618 	f = fp;
1619 	destroy(f->ret->t0);
1620 	f->ret->t0 = H;
1621 	destroy(f->ret->t1);
1622 	f->ret->t1 = H;
1623 	r0 = r1 = alphar0 = alphar1 = alphar0r1 = nil;
1624 
1625 	/* check args */
1626 	if(f->fd == H || f->fd->fd < 0){
1627 		retstr("bad fd", &f->ret->t0);
1628 		return;
1629 	}
1630 	fd = f->fd->fd;
1631 
1632 	buf = malloc(Maxbuf);
1633 	if(buf == nil){
1634 		retstr(exNomem, &f->ret->t0);
1635 		return;
1636 	}
1637 
1638 	/* send auth protocol version number */
1639 	if(sendmsg(fd, "1", 1) <= 0){
1640 		err = MSG;
1641 		goto out;
1642 	}
1643 
1644 	/* get auth protocol version number */
1645 	n = getmsg(fd, buf, Maxbuf-1);
1646 	if(n < 0){
1647 		err = buf;
1648 		goto out;
1649 	}
1650 	buf[n] = 0;
1651 	version = atoi(buf);
1652 	if(version != 1 || n > 4){
1653 		err = "incompatible authentication protocol";
1654 		goto out;
1655 	}
1656 
1657 	if(f->info == H){
1658 		err = "no authentication information";
1659 		goto out;
1660 	}
1661 	if(f->info->p == H){
1662 		err = "missing diffie hellman mod";
1663 		goto out;
1664 	}
1665 	if(f->info->alpha == H){
1666 		err = "missing diffie hellman base";
1667 		goto out;
1668 	}
1669 	mysk = checkSK(f->info->mysk);
1670 	if(mysk == H){
1671 		err = "bad sk arg";
1672 		goto out;
1673 	}
1674 	mypk = checkPK(f->info->mypk);
1675 	if(mypk == H){
1676 		err = "bad pk arg";
1677 		goto out;
1678 	}
1679 	cert = checkCertificate(f->info->cert);
1680 	if(cert == H){
1681 		err = "bad certificate arg";
1682 		goto out;
1683 	}
1684 	spk = checkPK(f->info->spk);
1685 	if(spk == H){
1686 		err = "bad signer key arg";
1687 		goto out;
1688 	}
1689 
1690 	/* get alpha and p */
1691 	p = checkIPint(f->info->p);
1692 	alpha = checkIPint(f->info->alpha);
1693 
1694 	if(p->sign == -1) {
1695 		err = "-ve modulus";
1696 		goto out;
1697 	}
1698 
1699 	r0 = mpnew(0);
1700 	r1 = mpnew(0);
1701 	alphar0 = mpnew(0);
1702 	alphar0r1 = mpnew(0);
1703 
1704 	/* generate alpha**r0 */
1705 if(0)print("X");
1706 	release();
1707 	mprand(mpsignif(p), genrandom, r0);
1708 	mpexp(alpha, r0, p, alphar0);
1709 	acquire();
1710 if(0)print("Y");
1711 
1712 	/* send alpha**r0 mod p, mycert, and mypk */
1713 	n = bigtobase64(alphar0, buf, Maxbuf);
1714 	if(sendmsg(fd, buf, n) <= 0){
1715 		err = MSG;
1716 		goto out;
1717 	}
1718 
1719 	n = certtostr(cert, buf, Maxbuf);
1720 	if(sendmsg(fd, buf, n) <= 0){
1721 		err = MSG;
1722 		goto out;
1723 	}
1724 
1725 	n = pktostr(mypk, buf, Maxbuf);
1726 	if(sendmsg(fd, buf, n) <= 0){
1727 		err = MSG;
1728 		goto out;
1729 	}
1730 
1731 	/* get alpha**r1 mod p, hiscert, hispk */
1732 	n = getmsg(fd, buf, Maxbuf-1);
1733 	if(n < 0){
1734 		err = buf;
1735 		goto out;
1736 	}
1737 	buf[n] = 0;
1738 	alphar1 = strtomp(buf, nil, 64, nil);
1739 
1740 	/* trying a fast one */
1741 	if(mpcmp(p, alphar1) <= 0){
1742 		err = "implausible parameter value";
1743 		goto out;
1744 	}
1745 
1746 	/* if alpha**r1 == alpha**r0, someone may be trying a replay */
1747 	if(mpcmp(alphar0, alphar1) == 0){
1748 		err = "possible replay attack";
1749 		goto out;
1750 	}
1751 
1752 	n = getmsg(fd, buf, Maxbuf-1);
1753 	if(n < 0){
1754 		err = buf;
1755 		goto out;
1756 	}
1757 	buf[n] = 0;
1758 	hiscert = strtocert(buf);
1759 	if(hiscert == H){
1760 		err = "bad certificate syntax";
1761 		goto out;
1762 	}
1763 	certimmutable(hiscert);		/* hide from the garbage collector */
1764 
1765 	n = getmsg(fd, buf, Maxbuf-1);
1766 	if(n < 0){
1767 		err = buf;
1768 		goto out;
1769 	}
1770 	buf[n] = 0;
1771 	hispk = strtopk(buf);
1772 	if(hispk == H){
1773 		err = "bad public key";
1774 		goto out;
1775 	}
1776 	pkimmutable(hispk);		/* hide from the garbage collector */
1777 
1778 	/* verify his public key */
1779 	if(verify(spk, hiscert, buf, n) == 0){
1780 		err = "pk doesn't match certificate";
1781 		goto out;
1782 	}
1783 
1784 	/* check expiration date - in seconds of epoch */
1785 
1786 	now = osusectime()/1000000;
1787 	if(hiscert->x.exp != 0 && hiscert->x.exp <= now){
1788 		err = "certificate expired";
1789 		goto out;
1790 	}
1791 
1792 	/* sign alpha**r0 and alpha**r1 and send */
1793 	n = bigtobase64(alphar0, buf, Maxbuf);
1794 	n += bigtobase64(alphar1, buf+n, Maxbuf-n);
1795 	alphacert = sign(mysk, "sha1", 0, (uchar*)buf, n);
1796 	n = certtostr(alphacert, buf, Maxbuf);
1797 	if(sendmsg(fd, buf, n) <= 0){
1798 		err = MSG;
1799 		goto out;
1800 	}
1801 	certmutable(alphacert);
1802 	destroy(alphacert);
1803 	alphacert = H;
1804 
1805 	/* get signature of alpha**r1 and alpha**r0 and verify */
1806 	n = getmsg(fd, buf, Maxbuf-1);
1807 	if(n < 0){
1808 		err = buf;
1809 		goto out;
1810 	}
1811 	buf[n] = 0;
1812 	alphacert = strtocert(buf);
1813 	if(alphacert == H){
1814 		err = "alpha**r1 doesn't match certificate";
1815 		goto out;
1816 	}
1817 	certimmutable(alphacert);		/* hide from the garbage collector */
1818 	n = bigtobase64(alphar1, buf, Maxbuf);
1819 	n += bigtobase64(alphar0, buf+n, Maxbuf-n);
1820 	if(verify(hispk, alphacert, buf, n) == 0){
1821 		err = "bad certificate";
1822 		goto out;
1823 	}
1824 
1825 	/* we are now authenticated and have a common secret, alpha**(r0*r1) */
1826 	f->ret->t0 = stringdup(hispk->x.owner);
1827 	mpexp(alphar1, r0, p, alphar0r1);
1828 	n = mptobe(alphar0r1, nil, Maxbuf, &cvb);
1829 	if(n < 0){
1830 		err = "bad conversion";
1831 		goto out;
1832 	}
1833 	f->ret->t1 = mem2array(cvb, n);
1834 	free(cvb);
1835 
1836 out:
1837 	/* return status */
1838 	if(f->ret->t0 == H){
1839 		if(err == buf)
1840 			senderr(fd, "missing your authentication data", 1);
1841 		else
1842 			senderr(fd, err, 1);
1843 	}else
1844 		sendmsg(fd, "OK", 2);
1845 
1846 	/* read responses */
1847 	if(err != buf){
1848 		for(;;){
1849 			n = getmsg(fd, buf, Maxbuf-1);
1850 			if(n < 0){
1851 				destroy(f->ret->t0);
1852 				f->ret->t0 = H;
1853 				destroy(f->ret->t1);
1854 				f->ret->t1 = H;
1855 				if(err == nil){
1856 					if(n < -1)
1857 						err = buf;
1858 					else
1859 						err = MSG;
1860 				}
1861 				break;
1862 			}
1863 			if(n == 2 && buf[0] == 'O' && buf[1] == 'K')
1864 				break;
1865 		}
1866 	}
1867 
1868 	/* set error and id to nobody */
1869 	if(f->ret->t0 == H){
1870 		if(err == nil)
1871 			err = MSG;
1872 		retstr(err, &f->ret->t0);
1873 		if(f->setid)
1874 			setid("nobody", 1);
1875 	} else {
1876 		/* change user id */
1877 		if(f->setid)
1878 			setid(string2c(f->ret->t0), 1);
1879 	}
1880 
1881 	/* free resources */
1882 	if(hispk != H){
1883 		pkmutable(hispk);
1884 		destroy(hispk);
1885 	}
1886 	if(hiscert != H){
1887 		certmutable(hiscert);
1888 		destroy(hiscert);
1889 	}
1890 	if(alphacert != H){
1891 		certmutable(alphacert);
1892 		destroy(alphacert);
1893 	}
1894 	free(buf);
1895 	if(r0 != nil){
1896 		mpfree(r0);
1897 		mpfree(r1);
1898 		mpfree(alphar0);
1899 		mpfree(alphar1);
1900 		mpfree(alphar0r1);
1901 	}
1902 }
1903 
1904 static Keyring_Authinfo*
newAuthinfo(void)1905 newAuthinfo(void)
1906 {
1907 	return H2D(Keyring_Authinfo*, heap(TAuthinfo));
1908 }
1909 
1910 void
Keyring_writeauthinfo(void * fp)1911 Keyring_writeauthinfo(void *fp)
1912 {
1913 	F_Keyring_writeauthinfo *f;
1914 	int n, fd;
1915 	char *buf;
1916 	PK *spk;
1917 	SK *mysk;
1918 	Certificate *c;
1919 	mpint *p, *alpha;
1920 
1921 	f = fp;
1922 	*f->ret = -1;
1923 
1924 	if(f->filename == H)
1925 		error(exNilref);
1926 	if(f->info == H)
1927 		error(exNilref);
1928 	alpha = checkIPint(f->info->alpha);
1929 	p = checkIPint(f->info->p);
1930 	spk = checkPK(f->info->spk);
1931 	mysk = checkSK(f->info->mysk);
1932 	c = checkCertificate(f->info->cert);
1933 
1934 	buf = malloc(Maxbuf);
1935 	if(buf == nil)
1936 		return;
1937 
1938 	/*
1939 	 *  The file may already exist or be a file2chan file so first
1940 	 *  try opening with truncation since create will change the
1941 	 *  permissions of the file and create doesn't work with a
1942 	 *  file2chan.
1943 	 */
1944 	release();
1945 	fd = kopen(string2c(f->filename), OTRUNC|OWRITE);
1946 	if(fd < 0)
1947 		fd = kcreate(string2c(f->filename), OWRITE, 0600);
1948 	if(fd < 0)
1949 		fd = kopen(string2c(f->filename), OWRITE);
1950 	acquire();
1951 	if(fd < 0)
1952 		goto out;
1953 
1954 	/* signer's public key */
1955 	n = pktostr(spk, buf, Maxmsg);
1956 	if(sendmsg(fd, buf, n) <= 0)
1957 		goto out;
1958 
1959 	/* certificate for my public key */
1960 	n = certtostr(c, buf, Maxmsg);
1961 	if(sendmsg(fd, buf, n) <= 0)
1962 		goto out;
1963 
1964 	/* my secret/public key */
1965 	n = sktostr(mysk, buf, Maxmsg);
1966 	if(sendmsg(fd, buf, n) <= 0)
1967 		goto out;
1968 
1969 	/* diffie hellman base */
1970 	n = bigtobase64(alpha, buf, Maxbuf);
1971 	if(sendmsg(fd, buf, n) <= 0)
1972 		goto out;
1973 
1974 	/* diffie hellman modulus */
1975 	n = bigtobase64(p, buf, Maxbuf);
1976 	if(sendmsg(fd, buf, n) <= 0)
1977 		goto out;
1978 
1979 	*f->ret = 0;
1980 out:
1981 	free(buf);
1982 	if(fd >= 0){
1983 		release();
1984 		kclose(fd);
1985 		acquire();
1986 	}
1987 }
1988 
1989 void
Keyring_readauthinfo(void * fp)1990 Keyring_readauthinfo(void *fp)
1991 {
1992 	F_Keyring_readauthinfo *f;
1993 	int fd;
1994 	char *buf;
1995 	int n, ok;
1996 	PK *mypk;
1997 	SK *mysk;
1998 	SigAlg *sa;
1999 	Keyring_Authinfo *ai;
2000 	mpint *b;
2001 	void *r;
2002 
2003 	f = fp;
2004 	r = *f->ret;
2005 	*f->ret = H;
2006 	destroy(r);
2007 
2008 	ok = 0;
2009 
2010 	if(f->filename == H)
2011 		return;
2012 
2013 	buf = malloc(Maxbuf);
2014 	if(buf == nil)
2015 		return;
2016 
2017 	ai = newAuthinfo();
2018 	*f->ret = ai;
2019 
2020 	release();
2021 	fd = kopen(string2c(f->filename), OREAD);
2022 	acquire();
2023 	if(fd < 0)
2024 		goto out;
2025 
2026 	/* signer's public key */
2027 	n = getmsg(fd, buf, Maxmsg);
2028 	if(n < 0)
2029 		goto out;
2030 
2031 	ai->spk = (Keyring_PK*)strtopk(buf);
2032 	if(ai->spk == H)
2033 		goto out;
2034 
2035 	/* certificate for my public key */
2036 	n = getmsg(fd, buf, Maxmsg);
2037 	if(n < 0)
2038 		goto out;
2039 	ai->cert = (Keyring_Certificate*)strtocert(buf);
2040 	if(ai->cert == H)
2041 		goto out;
2042 
2043 	/* my secret/public key */
2044 	n = getmsg(fd, buf, Maxmsg);
2045 	if(n < 0)
2046 		goto out;
2047 	mysk = strtosk(buf);
2048 	ai->mysk = (Keyring_SK*)mysk;
2049 	if(mysk == H)
2050 		goto out;
2051 	sa = checkSigAlg(mysk->x.sa);
2052 	mypk = newPK(sa, stringdup(mysk->x.owner), 1);
2053 	mypk->key = (*sa->vec->sk2pk)(mysk->key);
2054 	ai->mypk = (Keyring_PK*)mypk;
2055 
2056 	/* diffie hellman base */
2057 	n = getmsg(fd, buf, Maxmsg);
2058 	if(n < 0)
2059 		goto out;
2060 	b = strtomp(buf, nil, 64, nil);
2061 	ai->alpha = newIPint(b);
2062 
2063 	/* diffie hellman modulus */
2064 	n = getmsg(fd, buf, Maxmsg);
2065 	if(n < 0)
2066 		goto out;
2067 	b = strtomp(buf, nil, 64, nil);
2068 	ai->p = newIPint(b);
2069 	ok = 1;
2070 out:
2071 	if(!ok){
2072 		r = *f->ret;
2073 		*f->ret = H;
2074 		destroy(r);
2075 	}
2076 	free(buf);
2077 	if(fd >= 0){
2078 		release();
2079 		kclose(fd);
2080 		acquire();
2081 		kwerrstr("%q: %s", string2c(f->filename), MSG);
2082 	}
2083 }
2084 
2085 void
keyringmodinit(void)2086 keyringmodinit(void)
2087 {
2088 	SigAlgVec *sav;
2089 	extern SigAlgVec* elgamalinit(void);
2090 	extern SigAlgVec* rsainit(void);
2091 	extern SigAlgVec* dsainit(void);
2092 
2093 	ipintsmodinit();	/* in case only Keyring is configured */
2094 	TSigAlg = dtype(freeSigAlg, sizeof(SigAlg), SigAlgmap, sizeof(SigAlgmap));
2095 	TSK = dtype(freeSK, sizeof(SK), SKmap, sizeof(SKmap));
2096 	TPK = dtype(freePK, sizeof(PK), PKmap, sizeof(PKmap));
2097 	TCertificate = dtype(freeCertificate, sizeof(Certificate), Certificatemap,
2098 		sizeof(Certificatemap));
2099 	TDigestState = dtype(freeheap, sizeof(XDigestState), DigestStatemap,
2100 		sizeof(DigestStatemap));
2101 	TAESstate = dtype(freeheap, sizeof(XAESstate), AESstatemap,
2102 		sizeof(AESstatemap));
2103 	TDESstate = dtype(freeheap, sizeof(XDESstate), DESstatemap,
2104 		sizeof(DESstatemap));
2105 	TIDEAstate = dtype(freeheap, sizeof(XIDEAstate), IDEAstatemap,
2106 		sizeof(IDEAstatemap));
2107 	TBFstate = dtype(freeheap, sizeof(XBFstate), BFstatemap,
2108 		sizeof(BFstatemap));
2109 	TRC4state = dtype(freeheap, sizeof(XRC4state), RC4statemap,
2110 		sizeof(RC4statemap));
2111 	TAuthinfo = dtype(freeheap, sizeof(Keyring_Authinfo), Authinfomap, sizeof(Authinfomap));
2112 	TDSAsk = dtype(freeheap, sizeof(Keyring_DSAsk), DSAskmap, sizeof(DSAskmap));
2113 	TDSApk = dtype(freeheap, sizeof(Keyring_DSApk), DSApkmap, sizeof(DSApkmap));
2114 	TDSAsig = dtype(freeheap, sizeof(Keyring_DSAsig), DSAsigmap, sizeof(DSAsigmap));
2115 	TEGsk = dtype(freeheap, sizeof(Keyring_EGsk), EGskmap, sizeof(EGskmap));
2116 	TEGpk = dtype(freeheap, sizeof(Keyring_EGpk), EGpkmap, sizeof(EGpkmap));
2117 	TEGsig = dtype(freeheap, sizeof(Keyring_EGsig), EGsigmap, sizeof(EGsigmap));
2118 	TRSAsk = dtype(freeheap, sizeof(Keyring_RSAsk), RSAskmap, sizeof(RSAskmap));
2119 	TRSApk = dtype(freeheap, sizeof(Keyring_RSApk), RSApkmap, sizeof(RSApkmap));
2120 	TRSAsig = dtype(freeheap, sizeof(Keyring_RSAsig), RSAsigmap, sizeof(RSAsigmap));
2121 
2122 	if((sav = elgamalinit()) != nil)
2123 		algs[nalg++] = sav;
2124 	if((sav = rsainit()) != nil)
2125 		algs[nalg++] = sav;
2126 	if((sav = dsainit()) != nil)
2127 		algs[nalg++] = sav;
2128 
2129 	fmtinstall('U', big64conv);
2130 	builtinmod("$Keyring", Keyringmodtab, Keyringmodlen);
2131 }
2132 
2133 /*
2134  *  IO on a delimited channel.  A message starting with 0x00 is a normal
2135  *  message.  One starting with 0xff is an error string.
2136  *
2137  *  return negative number for error messages (including hangup)
2138  */
2139 static int
getbuf(int fd,uchar * buf,int n,char * err,int nerr)2140 getbuf(int fd, uchar *buf, int n, char *err, int nerr)
2141 {
2142 	int len;
2143 
2144 	release();
2145 	len = kread(fd, buf, n);
2146 	acquire();
2147 	if(len <= 0){
2148 		strncpy(err, "hungup", nerr);
2149 		buf[nerr-1] = 0;
2150 		return -1;
2151 	}
2152 	if(buf[0] == 0)
2153 		return len-1;
2154 	if(buf[0] != 0xff){
2155 		/*
2156 		 * this happens when the client's password is wrong: both sides use a digest of the
2157 		 * password as a crypt key for devssl. When they don't match decryption garbles
2158 		 * messages
2159 		 */
2160 		strncpy(err, "failure", nerr);
2161 		err[nerr-1] = 0;
2162 		return -1;
2163 	}
2164 
2165 	/* error string */
2166 	len--;
2167 	if(len < 1){
2168 		strncpy(err, "unknown", nerr);
2169 		err[nerr-1] = 0;
2170 	} else {
2171 		if(len >= nerr)
2172 			len = nerr-1;
2173 		memmove(err, buf+1, len);
2174 		err[len] = 0;
2175 	}
2176 	return -1;
2177 }
2178 
2179 void
Keyring_getstring(void * fp)2180 Keyring_getstring(void *fp)
2181 {
2182 	F_Keyring_getstring *f;
2183 	uchar *buf;
2184 	char err[64];
2185 	int n;
2186 
2187 	f = fp;
2188 	destroy(f->ret->t0);
2189 	f->ret->t0 = H;
2190 	destroy(f->ret->t1);
2191 	f->ret->t1 = H;
2192 
2193 	if(f->fd == H)
2194 		return;
2195 
2196 	buf = malloc(Maxmsg);
2197 	if(buf == nil)
2198 		return;
2199 
2200 	n = getbuf(f->fd->fd, buf, Maxmsg, err, sizeof(err));
2201 	if(n < 0)
2202 		retnstr(err, strlen(err), &f->ret->t1);
2203 	else
2204 		retnstr(((char*)buf)+1, n, &f->ret->t0);
2205 
2206 	free(buf);
2207 }
2208 
2209 void
Keyring_getbytearray(void * fp)2210 Keyring_getbytearray(void *fp)
2211 {
2212 	F_Keyring_getbytearray *f;
2213 	uchar *buf;
2214 	char err[64];
2215 	int n;
2216 
2217 	f = fp;
2218 	destroy(f->ret->t0);
2219 	f->ret->t0 = H;
2220 	destroy(f->ret->t1);
2221 	f->ret->t1 = H;
2222 
2223 	if(f->fd == H)
2224 		return;
2225 
2226 	buf = malloc(Maxmsg);
2227 	if(buf == nil)
2228 		return;
2229 
2230 	n = getbuf(f->fd->fd, buf, Maxmsg, err, sizeof(err));
2231 	if(n < 0)
2232 		retnstr(err, strlen(err), &f->ret->t1);
2233 	else
2234 		f->ret->t0 = mem2array(buf+1, n);
2235 
2236 	free(buf);
2237 }
2238 
2239 static int
putbuf(int fd,void * p,int n)2240 putbuf(int fd, void *p, int n)
2241 {
2242 	char *buf;
2243 
2244 	buf = malloc(Maxmsg);
2245 	if(buf == nil)
2246 		return -1;
2247 
2248 	release();
2249 	buf[0] = 0;
2250 	if(n < 0){
2251 		buf[0] = 0xff;
2252 		n = -n;
2253 	}
2254 	if(n >= Maxmsg)
2255 		n = Maxmsg - 1;
2256 	memmove(buf+1, p, n);
2257 	n = kwrite(fd, buf, n+1);
2258 	acquire();
2259 
2260 	free(buf);
2261 	return n;
2262 }
2263 
2264 void
Keyring_putstring(void * fp)2265 Keyring_putstring(void *fp)
2266 {
2267 	F_Keyring_putstring *f;
2268 
2269 	f = fp;
2270 	*f->ret = -1;
2271 	if(f->fd == H || f->s == H)
2272 		return;
2273 	*f->ret = putbuf(f->fd->fd, string2c(f->s), strlen(string2c(f->s)));
2274 }
2275 
2276 void
Keyring_puterror(void * fp)2277 Keyring_puterror(void *fp)
2278 {
2279 	F_Keyring_puterror *f;
2280 
2281 	f = fp;
2282 	*f->ret = -1;
2283 	if(f->fd == H || f->s == H)
2284 		return;
2285 	*f->ret = putbuf(f->fd->fd, string2c(f->s), -strlen(string2c(f->s)));
2286 }
2287 
2288 void
Keyring_putbytearray(void * fp)2289 Keyring_putbytearray(void *fp)
2290 {
2291 	F_Keyring_putbytearray *f;
2292 	int n;
2293 
2294 	f = fp;
2295 	*f->ret = -1;
2296 	if(f->fd == H || f->a == H)
2297 		return;
2298 	n = f->n;
2299 	if(n < 0 || n > f->a->len)
2300 		error(exBounds);
2301 	*f->ret = putbuf(f->fd->fd, f->a->data, n);
2302 }
2303 
2304 void
Keyring_dessetup(void * fp)2305 Keyring_dessetup(void *fp)
2306 {
2307 	F_Keyring_dessetup *f;
2308 	Heap *h;
2309 	XDESstate *ds;
2310 	uchar *ivec;
2311 	void *r;
2312 
2313 	f = fp;
2314 	r = *f->ret;
2315 	*f->ret = H;
2316 	destroy(r);
2317 
2318 	if(f->key == H || f->key->len < 8)
2319 		error(exBadKey);
2320 	if(f->ivec != H){
2321 		if(f->ivec->len < 8)
2322 			error(exBadIvec);
2323 		ivec = f->ivec->data;
2324 	}else
2325 		ivec = nil;
2326 
2327 	h = heap(TDESstate);
2328 	ds = H2D(XDESstate*, h);
2329 	setupDESstate(&ds->state, f->key->data, ivec);
2330 
2331 	*f->ret = (Keyring_DESstate*)ds;
2332 }
2333 
2334 void
Keyring_desecb(void * fp)2335 Keyring_desecb(void *fp)
2336 {
2337 	F_Keyring_desecb *f;
2338 	XDESstate *ds;
2339 	int i;
2340 	uchar *p;
2341 
2342 	f = fp;
2343 
2344 	if(f->buf == H)
2345 		return;
2346 	if(f->n < 0 || f->n > f->buf->len)
2347 		error(exBounds);
2348 	if(f->n & 7)
2349 		error(exBadBsize);
2350 
2351 	ds = checktype(f->state, TDESstate, exBadState, 0);
2352 	p = f->buf->data;
2353 
2354 	for(i = 8; i <= f->n; i += 8, p += 8)
2355 		block_cipher(ds->state.expanded, p, f->direction);
2356 }
2357 
2358 void
Keyring_descbc(void * fp)2359 Keyring_descbc(void *fp)
2360 {
2361 	F_Keyring_descbc *f;
2362 	XDESstate *ds;
2363 	uchar *p, *ep, *ip, *p2, *eip;
2364 	uchar tmp[8];
2365 
2366 	f = fp;
2367 
2368 	if(f->buf == H)
2369 		return;
2370 	if(f->n < 0 || f->n > f->buf->len)
2371 		error(exBounds);
2372 	if(f->n & 7)
2373 		error(exBadBsize);
2374 
2375 	ds = checktype(f->state, TDESstate, exBadState, 0);
2376 	p = f->buf->data;
2377 
2378 	if(f->direction == 0){
2379 		for(ep = p + f->n; p < ep; p += 8){
2380 			p2 = p;
2381 			ip = ds->state.ivec;
2382 			for(eip = ip+8; ip < eip; )
2383 				*p2++ ^= *ip++;
2384 			block_cipher(ds->state.expanded, p, 0);
2385 			memmove(ds->state.ivec, p, 8);
2386 		}
2387 	} else {
2388 		for(ep = p + f->n; p < ep; ){
2389 			memmove(tmp, p, 8);
2390 			block_cipher(ds->state.expanded, p, 1);
2391 			p2 = tmp;
2392 			ip = ds->state.ivec;
2393 			for(eip = ip+8; ip < eip; ){
2394 				*p++ ^= *ip;
2395 				*ip++ = *p2++;
2396 			}
2397 		}
2398 	}
2399 }
2400 
2401 void
Keyring_ideasetup(void * fp)2402 Keyring_ideasetup(void *fp)
2403 {
2404 	F_Keyring_ideasetup *f;
2405 	Heap *h;
2406 	XIDEAstate *is;
2407 	uchar *ivec;
2408 	void *r;
2409 
2410 	f = fp;
2411 	r = *f->ret;
2412 	*f->ret = H;
2413 	destroy(r);
2414 
2415 	if(f->key == H || f->key->len < 16)
2416 		error(exBadKey);
2417 	if(f->ivec != H){
2418 		if(f->ivec->len < 8)
2419 			error(exBadIvec);
2420 		ivec = f->ivec->data;
2421 	}else
2422 		ivec = nil;
2423 
2424 	h = heap(TIDEAstate);
2425 	is = H2D(XIDEAstate*, h);
2426 
2427 	setupIDEAstate(&is->state, f->key->data, ivec);
2428 
2429 	*f->ret = (Keyring_IDEAstate*)is;
2430 }
2431 
2432 void
Keyring_ideaecb(void * fp)2433 Keyring_ideaecb(void *fp)
2434 {
2435 	F_Keyring_ideaecb *f;
2436 	XIDEAstate *is;
2437 	int i;
2438 	uchar *p;
2439 
2440 	f = fp;
2441 
2442 	if(f->buf == H)
2443 		return;
2444 	if(f->n < 0 || f->n > f->buf->len)
2445 		error(exBounds);
2446 	if(f->n & 7)
2447 		error(exBadBsize);
2448 
2449 	is = checktype(f->state, TIDEAstate, exBadState, 0);
2450 	p = f->buf->data;
2451 
2452 	for(i = 8; i <= f->n; i += 8, p += 8)
2453 		idea_cipher(is->state.edkey, p, f->direction);
2454 }
2455 
2456 void
Keyring_ideacbc(void * fp)2457 Keyring_ideacbc(void *fp)
2458 {
2459 	F_Keyring_ideacbc *f;
2460 	XIDEAstate *is;
2461 	uchar *p, *ep, *ip, *p2, *eip;
2462 	uchar tmp[8];
2463 
2464 	f = fp;
2465 
2466 	if(f->buf == H)
2467 		return;
2468 	if(f->n < 0 || f->n > f->buf->len)
2469 		error(exBounds);
2470 	if(f->n & 7)
2471 		error(exBadBsize);
2472 
2473 	is = checktype(f->state, TIDEAstate, exBadState, 0);
2474 	p = f->buf->data;
2475 
2476 	if(f->direction == 0){
2477 		for(ep = p + f->n; p < ep; p += 8){
2478 			p2 = p;
2479 			ip = is->state.ivec;
2480 			for(eip = ip+8; ip < eip; )
2481 				*p2++ ^= *ip++;
2482 			idea_cipher(is->state.edkey, p, 0);
2483 			memmove(is->state.ivec, p, 8);
2484 		}
2485 	} else {
2486 		for(ep = p + f->n; p < ep; ){
2487 			memmove(tmp, p, 8);
2488 			idea_cipher(is->state.edkey, p, 1);
2489 			p2 = tmp;
2490 			ip = is->state.ivec;
2491 			for(eip = ip+8; ip < eip; ){
2492 				*p++ ^= *ip;
2493 				*ip++ = *p2++;
2494 			}
2495 		}
2496 	}
2497 }
2498 
2499 void
Keyring_aessetup(void * fp)2500 Keyring_aessetup(void *fp)
2501 {
2502 	F_Keyring_aessetup *f;
2503 	Heap *h;
2504 	XAESstate *is;
2505 	uchar *ivec;
2506 	void *r;
2507 
2508 	f = fp;
2509 	r = *f->ret;
2510 	*f->ret = H;
2511 	destroy(r);
2512 
2513 	if(f->key == H ||
2514 	   f->key->len != 16 && f->key->len != 24 && f->key->len != 32)
2515 		error(exBadKey);
2516 	if(f->ivec != H){
2517 		if(f->ivec->len < AESbsize)
2518 			error(exBadIvec);
2519 		ivec = f->ivec->data;
2520 	}else
2521 		ivec = nil;
2522 
2523 	h = heap(TAESstate);
2524 	is = H2D(XAESstate*, h);
2525 
2526 	setupAESstate(&is->state, f->key->data, f->key->len, ivec);
2527 
2528 	*f->ret = (Keyring_AESstate*)is;
2529 }
2530 
2531 void
Keyring_aescbc(void * fp)2532 Keyring_aescbc(void *fp)
2533 {
2534 	F_Keyring_aescbc *f;
2535 	XAESstate *is;
2536 	uchar *p;
2537 
2538 	f = fp;
2539 
2540 	if(f->buf == H)
2541 		return;
2542 	if(f->n < 0 || f->n > f->buf->len)
2543 		error(exBounds);
2544 
2545 	is = checktype(f->state, TAESstate, exBadState, 0);
2546 	p = f->buf->data;
2547 
2548 	if(f->direction == 0)
2549 		aesCBCencrypt(p, f->n, &is->state);
2550 	else
2551 		aesCBCdecrypt(p, f->n, &is->state);
2552 }
2553 
2554 void
Keyring_blowfishsetup(void * fp)2555 Keyring_blowfishsetup(void *fp)
2556 {
2557 	F_Keyring_blowfishsetup *f;
2558 	Heap *h;
2559 	XBFstate *is;
2560 	uchar *ivec;
2561 	void *r;
2562 
2563 	f = fp;
2564 	r = *f->ret;
2565 	*f->ret = H;
2566 	destroy(r);
2567 
2568 	if(f->key == H || f->key->len <= 0)
2569 		error(exBadKey);
2570 	if(f->ivec != H){
2571 		if(f->ivec->len != BFbsize)
2572 			error(exBadIvec);
2573 		ivec = f->ivec->data;
2574 	}else
2575 		ivec = nil;
2576 
2577 	h = heap(TBFstate);
2578 	is = H2D(XBFstate*, h);
2579 
2580 	setupBFstate(&is->state, f->key->data, f->key->len, ivec);
2581 
2582 	*f->ret = (Keyring_BFstate*)is;
2583 }
2584 
2585 void
Keyring_blowfishcbc(void * fp)2586 Keyring_blowfishcbc(void *fp)
2587 {
2588 	F_Keyring_blowfishcbc *f;
2589 	XBFstate *is;
2590 	uchar *p;
2591 
2592 	f = fp;
2593 
2594 	if(f->buf == H)
2595 		return;
2596 	if(f->n < 0 || f->n > f->buf->len)
2597 		error(exBounds);
2598 	if(f->n & 7)
2599 		error(exBadBsize);
2600 
2601 	is = checktype(f->state, TBFstate, exBadState, 0);
2602 	p = f->buf->data;
2603 
2604 	if(f->direction == 0)
2605 		bfCBCencrypt(p, f->n, &is->state);
2606 	else
2607 		bfCBCdecrypt(p, f->n, &is->state);
2608 }
2609 
2610 void
Keyring_rc4setup(void * fp)2611 Keyring_rc4setup(void *fp)
2612 {
2613 	F_Keyring_rc4setup *f;
2614 	Heap *h;
2615 	XRC4state *is;
2616 	void *r;
2617 
2618 	f = fp;
2619 	r = *f->ret;
2620 	*f->ret = H;
2621 	destroy(r);
2622 
2623 	if(f->seed == H)
2624 		return;
2625 
2626 	h = heap(TRC4state);
2627 	is = H2D(XRC4state*, h);
2628 
2629 	setupRC4state(&is->state, f->seed->data, f->seed->len);
2630 
2631 	*f->ret = (Keyring_RC4state*)is;
2632 }
2633 
2634 void
Keyring_rc4(void * fp)2635 Keyring_rc4(void *fp)
2636 {
2637 	F_Keyring_rc4 *f;
2638 	XRC4state *is;
2639 	uchar *p;
2640 
2641 	f = fp;
2642 	if(f->buf == H)
2643 		return;
2644 	if(f->n < 0 || f->n > f->buf->len)
2645 		error(exBounds);
2646 	is = checktype(f->state, TRC4state, exBadState, 0);
2647 	p = f->buf->data;
2648 	rc4(&is->state, p, f->n);
2649 }
2650 
2651 void
Keyring_rc4skip(void * fp)2652 Keyring_rc4skip(void *fp)
2653 {
2654 	F_Keyring_rc4skip *f;
2655 	XRC4state *is;
2656 
2657 	f = fp;
2658 	is = checktype(f->state, TRC4state, exBadState, 0);
2659 	rc4skip(&is->state, f->n);
2660 }
2661 
2662 void
Keyring_rc4back(void * fp)2663 Keyring_rc4back(void *fp)
2664 {
2665 	F_Keyring_rc4back *f;
2666 	XRC4state *is;
2667 
2668 	f = fp;
2669 	is = checktype(f->state, TRC4state, exBadState, 0);
2670 	rc4back(&is->state, f->n);
2671 }
2672 
2673 /*
2674  *  public/secret keys, signing and verifying
2675  */
2676 
2677 static void
dsapk2pub(DSApub * p,Keyring_DSApk * pk)2678 dsapk2pub(DSApub* p, Keyring_DSApk* pk)
2679 {
2680 	if(pk == H)
2681 		error(exNilref);
2682 	p->p = checkIPint(pk->p);
2683 	p->q = checkIPint(pk->q);
2684 	p->alpha = checkIPint(pk->alpha);
2685 	p->key = checkIPint(pk->key);
2686 }
2687 
2688 static void
dsask2priv(DSApriv * p,Keyring_DSAsk * sk)2689 dsask2priv(DSApriv* p, Keyring_DSAsk* sk)
2690 {
2691 	if(sk == H || sk->pk == H)
2692 		error(exNilref);
2693 	dsapk2pub(&p->pub, sk->pk);
2694 	p->secret = checkIPint(sk->secret);
2695 }
2696 
2697 static void
dsapriv2sk(Keyring_DSAsk * sk,DSApriv * p)2698 dsapriv2sk(Keyring_DSAsk* sk, DSApriv* p)
2699 {
2700 	Keyring_DSApk* pk;
2701 
2702 	pk = sk->pk;
2703 	pk->p = ipcopymp(p->pub.p);
2704 	pk->q = ipcopymp(p->pub.q);
2705 	pk->alpha = ipcopymp(p->pub.alpha);
2706 	pk->key = ipcopymp(p->pub.key);
2707 	sk->secret = ipcopymp(p->secret);
2708 }
2709 
2710 void
DSAsk_gen(void * fp)2711 DSAsk_gen(void *fp)
2712 {
2713 	F_DSAsk_gen *f;
2714 	Keyring_DSAsk *sk;
2715 	DSApriv *p;
2716 	DSApub pub, *oldpk;
2717 	void *v;
2718 
2719 	f = fp;
2720 	v = *f->ret;
2721 	sk = newthing(TDSAsk, 0);
2722 	sk->pk = newthing(TDSApk, 0);
2723 	*f->ret = sk;
2724 	destroy(v);
2725 	oldpk = nil;
2726 	if(f->oldpk != H){
2727 		dsapk2pub(&pub, f->oldpk);
2728 		oldpk = &pub;
2729 	}
2730 	release();
2731 	p = dsagen(oldpk);
2732 	acquire();
2733 	dsapriv2sk(sk, p);
2734 	dsaprivfree(p);
2735 }
2736 
2737 void
DSAsk_sign(void * fp)2738 DSAsk_sign(void *fp)
2739 {
2740 	F_DSAsk_sign *f;
2741 	Keyring_DSAsig *sig;
2742 	DSApriv p;
2743 	mpint *m;
2744 	DSAsig *s;
2745 	void *v;
2746 
2747 	f = fp;
2748 	v = *f->ret;
2749 	sig = newthing(TDSAsig, 0);
2750 	*f->ret = sig;
2751 	destroy(v);
2752 
2753 	dsask2priv(&p, f->k);
2754 	m = checkIPint(f->m);
2755 	release();
2756 	s = dsasign(&p, m);
2757 	acquire();
2758 	sig->r = ipcopymp(s->r);
2759 	sig->s = ipcopymp(s->s);
2760 	dsasigfree(s);
2761 }
2762 
2763 void
DSApk_verify(void * fp)2764 DSApk_verify(void *fp)
2765 {
2766 	F_DSApk_verify *f;
2767 	DSApub p;
2768 	DSAsig sig;
2769 	mpint *m;
2770 
2771 	f = fp;
2772 	*f->ret = 0;
2773 	if(f->m == H || f->sig == H)
2774 		return;
2775 	dsapk2pub(&p, f->k);
2776 	sig.r = checkIPint(f->sig->r);
2777 	sig.s = checkIPint(f->sig->s);
2778 	m = checkIPint(f->m);
2779 	release();
2780 	*f->ret = dsaverify(&p, &sig, m) == 0;
2781 	acquire();
2782 }
2783 
2784 static void
egpk2pub(EGpub * p,Keyring_EGpk * pk)2785 egpk2pub(EGpub* p, Keyring_EGpk* pk)
2786 {
2787 	if(pk == H)
2788 		error(exNilref);
2789 	p->p = checkIPint(pk->p);
2790 	p->alpha = checkIPint(pk->alpha);
2791 	p->key = checkIPint(pk->key);
2792 }
2793 
2794 static void
egsk2priv(EGpriv * p,Keyring_EGsk * sk)2795 egsk2priv(EGpriv* p, Keyring_EGsk* sk)
2796 {
2797 	if(sk == H || sk->pk == H)
2798 		error(exNilref);
2799 	egpk2pub(&p->pub, sk->pk);
2800 	p->secret = checkIPint(sk->secret);
2801 }
2802 
2803 static void
egpriv2sk(Keyring_EGsk * sk,EGpriv * p)2804 egpriv2sk(Keyring_EGsk* sk, EGpriv* p)
2805 {
2806 	Keyring_EGpk* pk;
2807 
2808 	pk = sk->pk;
2809 	pk->p = ipcopymp(p->pub.p);
2810 	pk->alpha = ipcopymp(p->pub.alpha);
2811 	pk->key = ipcopymp(p->pub.key);
2812 	sk->secret = ipcopymp(p->secret);
2813 }
2814 
2815 void
EGsk_gen(void * fp)2816 EGsk_gen(void *fp)
2817 {
2818 	F_EGsk_gen *f;
2819 	Keyring_EGsk *sk;
2820 	EGpriv *p;
2821 	void *v;
2822 
2823 	f = fp;
2824 	v = *f->ret;
2825 	sk = newthing(TEGsk, 0);
2826 	sk->pk = newthing(TEGpk, 0);
2827 	*f->ret = sk;
2828 	destroy(v);
2829 	release();
2830 	for(;;){
2831 		p = eggen(f->nlen, f->nrep);
2832 		if(mpsignif(p->pub.p) == f->nlen)
2833 			break;
2834 		egprivfree(p);
2835 	}
2836 	acquire();
2837 	egpriv2sk(sk, p);
2838 	egprivfree(p);
2839 }
2840 
2841 void
EGsk_sign(void * fp)2842 EGsk_sign(void *fp)
2843 {
2844 	F_EGsk_sign *f;
2845 	Keyring_EGsig *sig;
2846 	EGpriv p;
2847 	mpint *m;
2848 	EGsig *s;
2849 	void *v;
2850 
2851 	f = fp;
2852 	v = *f->ret;
2853 	sig = newthing(TEGsig, 0);
2854 	*f->ret = sig;
2855 	destroy(v);
2856 
2857 	egsk2priv(&p, f->k);
2858 	m = checkIPint(f->m);
2859 	release();
2860 	s = egsign(&p, m);
2861 	acquire();
2862 	sig->r = ipcopymp(s->r);
2863 	sig->s = ipcopymp(s->s);
2864 	egsigfree(s);
2865 }
2866 
2867 void
EGpk_verify(void * fp)2868 EGpk_verify(void *fp)
2869 {
2870 	F_EGpk_verify *f;
2871 	EGpub p;
2872 	EGsig sig;
2873 	mpint *m;
2874 
2875 	f = fp;
2876 	*f->ret = 0;
2877 	if(f->m == H || f->sig == H)
2878 		return;
2879 	egpk2pub(&p, f->k);
2880 	sig.r = checkIPint(f->sig->r);
2881 	sig.s = checkIPint(f->sig->s);
2882 	m = checkIPint(f->m);
2883 	release();
2884 	*f->ret = egverify(&p, &sig, m) == 0;
2885 	acquire();
2886 }
2887 
2888 static void
rsapk2pub(RSApub * p,Keyring_RSApk * pk)2889 rsapk2pub(RSApub* p, Keyring_RSApk* pk)
2890 {
2891 	if(pk == H)
2892 		error(exNilref);
2893 	memset(p, 0, sizeof(*p));
2894 	p->n = checkIPint(pk->n);
2895 	p->ek = checkIPint(pk->ek);
2896 }
2897 
2898 static void
rsask2priv(RSApriv * p,Keyring_RSAsk * sk)2899 rsask2priv(RSApriv* p, Keyring_RSAsk* sk)
2900 {
2901 	if(sk == H || sk->pk == H)
2902 		error(exNilref);
2903 	rsapk2pub(&p->pub, sk->pk);
2904 	p->dk = checkIPint(sk->dk);
2905 	p->p = checkIPint(sk->p);
2906 	p->q = checkIPint(sk->q);
2907 	p->kp = checkIPint(sk->kp);
2908 	p->kq = checkIPint(sk->kq);
2909 	p->c2 = checkIPint(sk->c2);
2910 }
2911 
2912 static void
rsapriv2sk(Keyring_RSAsk * sk,RSApriv * p)2913 rsapriv2sk(Keyring_RSAsk* sk, RSApriv* p)
2914 {
2915 	Keyring_RSApk* pk;
2916 
2917 	pk = sk->pk;
2918 	pk->n = ipcopymp(p->pub.n);
2919 	pk->ek = ipcopymp(p->pub.ek);
2920 	sk->dk = ipcopymp(p->dk);
2921 	sk->p = ipcopymp(p->p);
2922 	sk->q = ipcopymp(p->q);
2923 	sk->kp = ipcopymp(p->kp);
2924 	sk->kq = ipcopymp(p->kq);
2925 	sk->c2 = ipcopymp(p->c2);
2926 }
2927 
2928 void
RSApk_encrypt(void * fp)2929 RSApk_encrypt(void *fp)
2930 {
2931 	F_RSApk_encrypt *f;
2932 	RSApub p;
2933 	mpint *m, *o;
2934 	void *v;
2935 
2936 	f = fp;
2937 	v = *f->ret;
2938 	*f->ret = H;
2939 	destroy(v);
2940 
2941 	rsapk2pub(&p, f->k);
2942 	m = checkIPint(f->m);
2943 	release();
2944 	o = rsaencrypt(&p, m, nil);
2945 	acquire();
2946 	*f->ret = newIPint(o);
2947 }
2948 
2949 void
RSAsk_gen(void * fp)2950 RSAsk_gen(void *fp)
2951 {
2952 	F_RSAsk_gen *f;
2953 	Keyring_RSAsk *sk;
2954 	RSApriv *p;
2955 	void *v;
2956 
2957 	f = fp;
2958 	v = *f->ret;
2959 	sk = newthing(TRSAsk, 0);
2960 	sk->pk = newthing(TRSApk, 0);
2961 	*f->ret = sk;
2962 	destroy(v);
2963 	release();
2964 	for(;;){
2965 		p = rsagen(f->nlen, f->elen, f->nrep);
2966 		if(mpsignif(p->pub.n) == f->nlen)
2967 			break;
2968 		rsaprivfree(p);
2969 	}
2970 	acquire();
2971 	rsapriv2sk(sk, p);
2972 	rsaprivfree(p);
2973 }
2974 
2975 void
RSAsk_fill(void * fp)2976 RSAsk_fill(void *fp)
2977 {
2978 	F_RSAsk_fill *f;
2979 	Keyring_RSAsk *sk;
2980 	RSApriv *p;
2981 	void *v;
2982 
2983 	f = fp;
2984 	v = *f->ret;
2985 	sk = newthing(TRSAsk, 0);
2986 	sk->pk = newthing(TRSApk, 0);
2987 	*f->ret = sk;
2988 	destroy(v);
2989 	release();
2990 	p = rsafill(checkIPint(f->n), checkIPint(f->e), checkIPint(f->d),
2991 			checkIPint(f->p), checkIPint(f->q));
2992 	acquire();
2993 	if(p == nil) {
2994 		*f->ret = H;
2995 		destroy(sk);
2996 	}else{
2997 		rsapriv2sk(sk, p);
2998 		rsaprivfree(p);
2999 	}
3000 }
3001 
3002 void
RSAsk_decrypt(void * fp)3003 RSAsk_decrypt(void *fp)
3004 {
3005 	F_RSAsk_decrypt *f;
3006 	RSApriv p;
3007 	mpint *m, *o;
3008 	void *v;
3009 
3010 	f = fp;
3011 	v = *f->ret;
3012 	*f->ret = H;
3013 	destroy(v);
3014 
3015 	rsask2priv(&p, f->k);
3016 	m = checkIPint(f->m);
3017 	release();
3018 	o = rsadecrypt(&p, m, nil);
3019 	acquire();
3020 	*f->ret = newIPint(o);
3021 }
3022 
3023 void
RSAsk_sign(void * fp)3024 RSAsk_sign(void *fp)
3025 {
3026 	F_RSAsk_sign *f;
3027 	Keyring_RSAsig *sig;
3028 	RSApriv p;
3029 	mpint *m, *s;
3030 	void *v;
3031 
3032 	f = fp;
3033 	v = *f->ret;
3034 	sig = newthing(TRSAsig, 0);
3035 	*f->ret = sig;
3036 	destroy(v);
3037 
3038 	rsask2priv(&p, f->k);
3039 	m = checkIPint(f->m);
3040 	release();
3041 	s = rsadecrypt(&p, m, nil);
3042 	acquire();
3043 	sig->n = newIPint(s);
3044 }
3045 
3046 void
RSApk_verify(void * fp)3047 RSApk_verify(void *fp)
3048 {
3049 	F_RSApk_verify *f;
3050 	RSApub p;
3051 	mpint *sig, *m, *t;
3052 
3053 	f = fp;
3054 	*f->ret = 0;
3055 	if(f->m == H || f->sig == H)
3056 		return;
3057 	rsapk2pub(&p, f->k);
3058 	sig = checkIPint(f->sig->n);
3059 	m = checkIPint(f->m);
3060 	release();
3061 	t = rsaencrypt(&p, sig, nil);
3062 	*f->ret = mpcmp(t, m) == 0;
3063 	mpfree(t);
3064 	acquire();
3065 }
3066 
3067 void
Keyring_IPint_random(void * fp)3068 Keyring_IPint_random(void *fp)
3069 {
3070 	F_IPint_random *f;
3071 	mpint *b;
3072 	void *v;
3073 
3074 	f = fp;
3075 	v = *f->ret;
3076 	*f->ret = H;
3077 	destroy(v);
3078 
3079 	release();
3080 	b = mprand(f->maxbits, genrandom, nil);
3081 	acquire();
3082 	*f->ret = newIPint(b);
3083 }
3084