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