1 #include "lib9.h" 2 #include "kernel.h" 3 #include <isa.h> 4 #include "interp.h" 5 #include "runt.h" 6 #include "keyring.h" 7 #include <mp.h> 8 #include <libsec.h> 9 #include "pool.h" 10 #include "raise.h" 11 #include "../libkeyring/keys.h" 12 13 14 Type *TSigAlg; 15 Type *TCertificate; 16 Type *TSK; 17 Type *TPK; 18 Type *TDigestState; 19 Type *TAuthinfo; 20 Type *TAESstate; 21 Type *TDESstate; 22 Type *TIDEAstate; 23 Type *TBFstate; 24 Type *TRC4state; 25 Type *TIPint; 26 Type *TDSAsk; 27 Type *TDSApk; 28 Type *TDSAsig; 29 Type *TEGsk; 30 Type *TEGpk; 31 Type *TEGsig; 32 Type *TRSAsk; 33 Type *TRSApk; 34 Type *TRSAsig; 35 36 enum { 37 Maxmsg= 4096 38 }; 39 40 uchar IPintmap[] = Keyring_IPint_map; 41 uchar SigAlgmap[] = Keyring_SigAlg_map; 42 uchar SKmap[] = Keyring_SK_map; 43 uchar PKmap[] = Keyring_PK_map; 44 uchar Certificatemap[] = Keyring_Certificate_map; 45 uchar DigestStatemap[] = Keyring_DigestState_map; 46 uchar Authinfomap[] = Keyring_Authinfo_map; 47 uchar AESstatemap[] = Keyring_AESstate_map; 48 uchar DESstatemap[] = Keyring_DESstate_map; 49 uchar IDEAstatemap[] = Keyring_IDEAstate_map; 50 uchar BFstatemap[] = Keyring_BFstate_map; 51 uchar RC4statemap[] = Keyring_RC4state_map; 52 uchar DSAskmap[] = Keyring_DSAsk_map; 53 uchar DSApkmap[] = Keyring_DSApk_map; 54 uchar DSAsigmap[] = Keyring_DSAsig_map; 55 uchar EGskmap[] = Keyring_EGsk_map; 56 uchar EGpkmap[] = Keyring_EGpk_map; 57 uchar EGsigmap[] = Keyring_EGsig_map; 58 uchar RSAskmap[] = Keyring_RSAsk_map; 59 uchar RSApkmap[] = Keyring_RSApk_map; 60 uchar RSAsigmap[] = Keyring_RSAsig_map; 61 62 PK* checkPK(Keyring_PK *k); 63 64 extern void setid(char*, int); 65 extern vlong osusectime(void); 66 extern Keyring_IPint* newIPint(mpint*); 67 extern mpint* checkIPint(Keyring_IPint*); 68 extern void freeIPint(Heap*, int); 69 70 static char exBadSA[] = "bad signature algorithm"; 71 static char exBadSK[] = "bad secret key"; 72 static char exBadPK[] = "bad public key"; 73 static char exBadCert[] = "bad certificate"; 74 static char exBadBsize[] = "data not multiple of block size"; 75 static char exBadKey[] = "bad encryption key"; 76 static char exBadDigest[] = "bad digest value"; 77 static char exBadIvec[] = "bad ivec"; 78 static char exBadState[] = "bad encryption state"; 79 80 typedef struct XBFstate XBFstate; 81 82 /* BF state */ 83 struct XBFstate 84 { 85 Keyring_BFstate x; 86 BFstate state; 87 }; 88 89 /* 90 * Infinite (actually kind of big) precision integers 91 */ 92 93 /* convert a Big to base64 ascii */ 94 int 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 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* 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* 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* 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* 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 212 freeSigAlg(Heap *h, int swept) 213 { 214 if(!swept) 215 freeheap(h, 0); 216 } 217 218 SigAlgVec* 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* 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* 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* 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* 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 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* 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 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 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* 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 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 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 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* 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 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* 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 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 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 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 PK* 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 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 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 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 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* 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 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 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 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* 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 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* 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 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 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 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* 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 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* 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 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 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 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 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 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 static void* 1174 checktype(void *v, Type *t, char *name, int newref) 1175 { 1176 Heap *h; 1177 1178 if(v == H || v == nil) 1179 error(exNilref); 1180 h = D2H(v); 1181 if(h->t != t) 1182 errorf("%s: %s", exType, name); 1183 if(newref){ 1184 h->ref++; 1185 Setmark(h); 1186 } 1187 return v; 1188 } 1189 1190 /* 1191 * digests 1192 */ 1193 void 1194 DigestState_copy(void *fp) 1195 { 1196 F_DigestState_copy *f; 1197 Heap *h; 1198 XDigestState *ds, *ods; 1199 void *r; 1200 1201 f = fp; 1202 r = *f->ret; 1203 *f->ret = H; 1204 destroy(r); 1205 1206 if(f->d != H){ 1207 ods = checktype(f->d, TDigestState, "DigestState", 0); 1208 h = heap(TDigestState); 1209 ds = H2D(XDigestState*, h); 1210 memmove(&ds->state, &ods->state, sizeof(ds->state)); 1211 *f->ret = (Keyring_DigestState*)ds; 1212 } 1213 } 1214 1215 static Keyring_DigestState* 1216 keyring_digest_x(Array *buf, int n, Array *digest, int dlen, Keyring_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, DigestState*)) 1217 { 1218 Heap *h; 1219 XDigestState *ds; 1220 uchar *cbuf, *cdigest; 1221 1222 if(buf != H){ 1223 if(n > buf->len) 1224 n = buf->len; 1225 cbuf = buf->data; 1226 }else{ 1227 if(n != 0) 1228 error(exInval); 1229 cbuf = nil; 1230 } 1231 1232 if(digest != H){ 1233 if(digest->len < dlen) 1234 error(exBadDigest); 1235 cdigest = digest->data; 1236 } else 1237 cdigest = nil; 1238 1239 if(state == H){ 1240 h = heap(TDigestState); 1241 ds = H2D(XDigestState*, h); 1242 memset(&ds->state, 0, sizeof(ds->state)); 1243 } else 1244 ds = checktype(state, TDigestState, "DigestState", 1); 1245 1246 (*fn)(cbuf, n, cdigest, &ds->state); 1247 1248 return (Keyring_DigestState*)ds; 1249 } 1250 1251 void 1252 Keyring_sha1(void *fp) 1253 { 1254 F_Keyring_sha1 *f; 1255 void *r; 1256 1257 f = fp; 1258 r = *f->ret; 1259 *f->ret = H; 1260 destroy(r); 1261 1262 *f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA1dlen, f->state, sha1); 1263 } 1264 1265 void 1266 Keyring_md5(void *fp) 1267 { 1268 F_Keyring_md5 *f; 1269 void *r; 1270 1271 f = fp; 1272 r = *f->ret; 1273 *f->ret = H; 1274 destroy(r); 1275 1276 *f->ret = keyring_digest_x(f->buf, f->n, f->digest, MD5dlen, f->state, md5); 1277 } 1278 1279 void 1280 Keyring_md4(void *fp) 1281 { 1282 F_Keyring_md4 *f; 1283 void *r; 1284 1285 f = fp; 1286 r = *f->ret; 1287 *f->ret = H; 1288 destroy(r); 1289 1290 *f->ret = keyring_digest_x(f->buf, f->n, f->digest, MD4dlen, f->state, md4); 1291 } 1292 1293 static Keyring_DigestState* 1294 keyring_hmac_x(Array *data, int n, Array *key, Array *digest, int dlen, Keyring_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*)) 1295 { 1296 Heap *h; 1297 XDigestState *ds; 1298 uchar *cdata, *cdigest; 1299 1300 if(data != H){ 1301 if(n > data->len) 1302 n = data->len; 1303 cdata = data->data; 1304 }else{ 1305 if(n != 0) 1306 error(exInval); 1307 cdata = nil; 1308 } 1309 1310 if(key == H || key->len > 64) 1311 error(exBadKey); 1312 1313 if(digest != H){ 1314 if(digest->len < dlen) 1315 error(exBadDigest); 1316 cdigest = digest->data; 1317 } else 1318 cdigest = nil; 1319 1320 if(state == H){ 1321 h = heap(TDigestState); 1322 ds = H2D(XDigestState*, h); 1323 memset(&ds->state, 0, sizeof(ds->state)); 1324 } else 1325 ds = checktype(state, TDigestState, "DigestState", 1); 1326 1327 (*fn)(cdata, n, key->data, key->len, cdigest, &ds->state); 1328 1329 return (Keyring_DigestState*)ds; 1330 } 1331 1332 void 1333 Keyring_hmac_sha1(void *fp) 1334 { 1335 F_Keyring_hmac_sha1 *f; 1336 void *r; 1337 1338 f = fp; 1339 r = *f->ret; 1340 *f->ret = H; 1341 destroy(r); 1342 *f->ret = keyring_hmac_x(f->data, f->n, f->key, f->digest, SHA1dlen, f->state, hmac_sha1); 1343 } 1344 1345 void 1346 Keyring_hmac_md5(void *fp) 1347 { 1348 F_Keyring_hmac_md5 *f; 1349 void *r; 1350 1351 f = fp; 1352 r = *f->ret; 1353 *f->ret = H; 1354 destroy(r); 1355 *f->ret = keyring_hmac_x(f->data, f->n, f->key, f->digest, MD5dlen, f->state, hmac_md5); 1356 } 1357 1358 void 1359 Keyring_dhparams(void *fp) 1360 { 1361 F_Keyring_dhparams *f; 1362 mpint *p, *alpha; 1363 void *v; 1364 1365 f = fp; 1366 v = f->ret->t0; 1367 f->ret->t0 = H; 1368 destroy(v); 1369 v = f->ret->t1; 1370 f->ret->t1 = H; 1371 destroy(v); 1372 1373 p = mpnew(0); 1374 alpha = mpnew(0); 1375 release(); 1376 if(f->nbits == 1024) 1377 DSAprimes(alpha, p, nil); 1378 else 1379 gensafeprime(p, alpha, f->nbits, 0); 1380 acquire(); 1381 f->ret->t0 = newIPint(alpha); 1382 f->ret->t1 = newIPint(p); 1383 } 1384 1385 static int 1386 sendmsg(int fd, void *buf, int n) 1387 { 1388 char num[10]; 1389 1390 release(); 1391 snprint(num, sizeof(num), "%4.4d\n", n); 1392 if(kwrite(fd, num, 5) != 5){ 1393 acquire(); 1394 return -1; 1395 } 1396 n = kwrite(fd, buf, n); 1397 acquire(); 1398 return n; 1399 } 1400 1401 void 1402 Keyring_sendmsg(void *fp) 1403 { 1404 F_Keyring_sendmsg *f; 1405 int n; 1406 1407 f = fp; 1408 *f->ret = -1; 1409 if(f->fd == H || f->buf == H || f->n < 0) 1410 return; 1411 n = f->n; 1412 if(n < 0 || n > f->buf->len) 1413 error(exBounds); 1414 *f->ret = sendmsg(f->fd->fd, f->buf->data, n); 1415 } 1416 1417 static int 1418 senderr(int fd, char *err, int addrmt) 1419 { 1420 char num[10]; 1421 int n, m; 1422 1423 release(); 1424 n = strlen(err); 1425 m = 0; 1426 if(addrmt) 1427 m = strlen("remote: "); 1428 snprint(num, sizeof(num), "!%3.3d\n", n+m); 1429 if(kwrite(fd, num, 5) != 5){ 1430 acquire(); 1431 return -1; 1432 } 1433 if(addrmt) 1434 kwrite(fd, "remote: ", m); 1435 n = kwrite(fd, err, n); 1436 acquire(); 1437 return n; 1438 } 1439 1440 void 1441 Keyring_senderrmsg(void *fp) 1442 { 1443 F_Keyring_senderrmsg *f; 1444 char *s; 1445 1446 f = fp; 1447 *f->ret = -1; 1448 if(f->fd == H) 1449 return; 1450 s = string2c(f->s); 1451 if(senderr(f->fd->fd, s, 0) > 0) 1452 *f->ret = 0; 1453 } 1454 1455 static int 1456 nreadn(int fd, void *av, int n) 1457 { 1458 1459 char *a; 1460 long m, t; 1461 1462 a = av; 1463 t = 0; 1464 while(t < n){ 1465 m = kread(fd, a+t, n-t); 1466 if(m <= 0){ 1467 if(t == 0) 1468 return m; 1469 break; 1470 } 1471 t += m; 1472 } 1473 return t; 1474 } 1475 1476 #define MSG "input or format error" 1477 1478 static void 1479 getmsgerr(char *buf, int n, int r) 1480 { 1481 char *e; 1482 int l; 1483 1484 e = r>0? MSG: "hungup"; 1485 l = strlen(e)+1; 1486 if(n > l) 1487 n = l; 1488 memmove(buf, e, n-1); 1489 buf[n-1] = 0; 1490 } 1491 1492 static int 1493 getmsg(int fd, char *buf, int n) 1494 { 1495 char num[6]; 1496 int len, r; 1497 1498 release(); 1499 if((r = nreadn(fd, num, 5)) != 5){ 1500 getmsgerr(buf, n, r); 1501 acquire(); 1502 return -1; 1503 } 1504 num[5] = 0; 1505 1506 if(num[0] == '!') 1507 len = strtoul(num+1, 0, 10); 1508 else 1509 len = strtoul(num, 0, 10); 1510 1511 r = -1; 1512 if(len < 0 || len >= n || (r = nreadn(fd, buf, len)) != len){ 1513 getmsgerr(buf, n, r); 1514 acquire(); 1515 return -1; 1516 } 1517 1518 buf[len] = 0; 1519 acquire(); 1520 if(num[0] == '!') 1521 return -len; 1522 1523 return len; 1524 } 1525 1526 void 1527 Keyring_getmsg(void *fp) 1528 { 1529 F_Keyring_getmsg *f; 1530 char *buf; 1531 int n; 1532 void *r; 1533 1534 f = fp; 1535 r = *f->ret; 1536 *f->ret = H; 1537 destroy(r); 1538 if(f->fd == H){ 1539 kwerrstr("nil fd"); 1540 return; 1541 } 1542 1543 buf = malloc(Maxmsg); 1544 if(buf == nil){ 1545 kwerrstr(exNomem); 1546 return; 1547 } 1548 1549 n = getmsg(f->fd->fd, buf, Maxmsg); 1550 if(n < 0){ 1551 kwerrstr("%s", buf); 1552 free(buf); 1553 return; 1554 } 1555 1556 *f->ret = mem2array(buf, n); 1557 free(buf); 1558 } 1559 1560 void 1561 Keyring_auth(void *fp) 1562 { 1563 F_Keyring_auth *f; 1564 mpint *r0, *r1, *p, *alpha, *alphar0, *alphar1, *alphar0r1; 1565 SK *mysk; 1566 PK *mypk, *spk, *hispk; 1567 Certificate *cert, *hiscert, *alphacert; 1568 char *buf, *err; 1569 uchar *cvb; 1570 int n, fd, version; 1571 long now; 1572 1573 hispk = H; 1574 hiscert = H; 1575 alphacert = H; 1576 err = nil; 1577 1578 /* null out the return values */ 1579 f = fp; 1580 destroy(f->ret->t0); 1581 f->ret->t0 = H; 1582 destroy(f->ret->t1); 1583 f->ret->t1 = H; 1584 r0 = r1 = alphar0 = alphar1 = alphar0r1 = nil; 1585 1586 /* check args */ 1587 if(f->fd == H || f->fd->fd < 0){ 1588 retstr("bad fd", &f->ret->t0); 1589 return; 1590 } 1591 fd = f->fd->fd; 1592 1593 buf = malloc(Maxbuf); 1594 if(buf == nil){ 1595 retstr(exNomem, &f->ret->t0); 1596 return; 1597 } 1598 1599 /* send auth protocol version number */ 1600 if(sendmsg(fd, "1", 1) <= 0){ 1601 err = MSG; 1602 goto out; 1603 } 1604 1605 /* get auth protocol version number */ 1606 n = getmsg(fd, buf, Maxbuf-1); 1607 if(n < 0){ 1608 err = buf; 1609 goto out; 1610 } 1611 buf[n] = 0; 1612 version = atoi(buf); 1613 if(version != 1 || n > 4){ 1614 err = "incompatible authentication protocol"; 1615 goto out; 1616 } 1617 1618 if(f->info == H){ 1619 err = "no authentication information"; 1620 goto out; 1621 } 1622 if(f->info->p == H){ 1623 err = "missing diffie hellman mod"; 1624 goto out; 1625 } 1626 if(f->info->alpha == H){ 1627 err = "missing diffie hellman base"; 1628 goto out; 1629 } 1630 mysk = checkSK(f->info->mysk); 1631 if(mysk == H){ 1632 err = "bad sk arg"; 1633 goto out; 1634 } 1635 mypk = checkPK(f->info->mypk); 1636 if(mypk == H){ 1637 err = "bad pk arg"; 1638 goto out; 1639 } 1640 cert = checkCertificate(f->info->cert); 1641 if(cert == H){ 1642 err = "bad certificate arg"; 1643 goto out; 1644 } 1645 spk = checkPK(f->info->spk); 1646 if(spk == H){ 1647 err = "bad signer key arg"; 1648 goto out; 1649 } 1650 1651 /* get alpha and p */ 1652 p = checkIPint(f->info->p); 1653 alpha = checkIPint(f->info->alpha); 1654 1655 if(p->sign == -1) { 1656 err = "-ve modulus"; 1657 goto out; 1658 } 1659 1660 r0 = mpnew(0); 1661 r1 = mpnew(0); 1662 alphar0 = mpnew(0); 1663 alphar0r1 = mpnew(0); 1664 1665 /* generate alpha**r0 */ 1666 if(0)print("X"); 1667 release(); 1668 mprand(mpsignif(p), genrandom, r0); 1669 mpexp(alpha, r0, p, alphar0); 1670 acquire(); 1671 if(0)print("Y"); 1672 1673 /* send alpha**r0 mod p, mycert, and mypk */ 1674 n = bigtobase64(alphar0, buf, Maxbuf); 1675 if(sendmsg(fd, buf, n) <= 0){ 1676 err = MSG; 1677 goto out; 1678 } 1679 1680 n = certtostr(cert, buf, Maxbuf); 1681 if(sendmsg(fd, buf, n) <= 0){ 1682 err = MSG; 1683 goto out; 1684 } 1685 1686 n = pktostr(mypk, buf, Maxbuf); 1687 if(sendmsg(fd, buf, n) <= 0){ 1688 err = MSG; 1689 goto out; 1690 } 1691 1692 /* get alpha**r1 mod p, hiscert, hispk */ 1693 n = getmsg(fd, buf, Maxbuf-1); 1694 if(n < 0){ 1695 err = buf; 1696 goto out; 1697 } 1698 buf[n] = 0; 1699 alphar1 = strtomp(buf, nil, 64, nil); 1700 1701 /* trying a fast one */ 1702 if(mpcmp(p, alphar1) <= 0){ 1703 err = "implausible parameter value"; 1704 goto out; 1705 } 1706 1707 /* if alpha**r1 == alpha**r0, someone may be trying a replay */ 1708 if(mpcmp(alphar0, alphar1) == 0){ 1709 err = "possible replay attack"; 1710 goto out; 1711 } 1712 1713 n = getmsg(fd, buf, Maxbuf-1); 1714 if(n < 0){ 1715 err = buf; 1716 goto out; 1717 } 1718 buf[n] = 0; 1719 hiscert = strtocert(buf); 1720 if(hiscert == H){ 1721 err = "bad certificate syntax"; 1722 goto out; 1723 } 1724 certimmutable(hiscert); /* hide from the garbage collector */ 1725 1726 n = getmsg(fd, buf, Maxbuf-1); 1727 if(n < 0){ 1728 err = buf; 1729 goto out; 1730 } 1731 buf[n] = 0; 1732 hispk = strtopk(buf); 1733 if(hispk == H){ 1734 err = "bad public key"; 1735 goto out; 1736 } 1737 pkimmutable(hispk); /* hide from the garbage collector */ 1738 1739 /* verify his public key */ 1740 if(verify(spk, hiscert, buf, n) == 0){ 1741 err = "pk doesn't match certificate"; 1742 goto out; 1743 } 1744 1745 /* check expiration date - in seconds of epoch */ 1746 1747 now = osusectime()/1000000; 1748 if(hiscert->x.exp != 0 && hiscert->x.exp <= now){ 1749 err = "certificate expired"; 1750 goto out; 1751 } 1752 1753 /* sign alpha**r0 and alpha**r1 and send */ 1754 n = bigtobase64(alphar0, buf, Maxbuf); 1755 n += bigtobase64(alphar1, buf+n, Maxbuf-n); 1756 alphacert = sign(mysk, "sha1", 0, (uchar*)buf, n); 1757 n = certtostr(alphacert, buf, Maxbuf); 1758 if(sendmsg(fd, buf, n) <= 0){ 1759 err = MSG; 1760 goto out; 1761 } 1762 certmutable(alphacert); 1763 destroy(alphacert); 1764 alphacert = H; 1765 1766 /* get signature of alpha**r1 and alpha**r0 and verify */ 1767 n = getmsg(fd, buf, Maxbuf-1); 1768 if(n < 0){ 1769 err = buf; 1770 goto out; 1771 } 1772 buf[n] = 0; 1773 alphacert = strtocert(buf); 1774 if(alphacert == H){ 1775 err = "alpha**r1 doesn't match certificate"; 1776 goto out; 1777 } 1778 certimmutable(alphacert); /* hide from the garbage collector */ 1779 n = bigtobase64(alphar1, buf, Maxbuf); 1780 n += bigtobase64(alphar0, buf+n, Maxbuf-n); 1781 if(verify(hispk, alphacert, buf, n) == 0){ 1782 err = "bad certificate"; 1783 goto out; 1784 } 1785 1786 /* we are now authenticated and have a common secret, alpha**(r0*r1) */ 1787 f->ret->t0 = stringdup(hispk->x.owner); 1788 mpexp(alphar1, r0, p, alphar0r1); 1789 n = mptobe(alphar0r1, nil, Maxbuf, &cvb); 1790 if(n < 0){ 1791 err = "bad conversion"; 1792 goto out; 1793 } 1794 f->ret->t1 = mem2array(cvb, n); 1795 free(cvb); 1796 1797 out: 1798 /* return status */ 1799 if(f->ret->t0 == H){ 1800 if(err == buf) 1801 senderr(fd, "missing your authentication data", 1); 1802 else 1803 senderr(fd, err, 1); 1804 }else 1805 sendmsg(fd, "OK", 2); 1806 1807 /* read responses */ 1808 if(err != buf){ 1809 for(;;){ 1810 n = getmsg(fd, buf, Maxbuf-1); 1811 if(n < 0){ 1812 destroy(f->ret->t0); 1813 f->ret->t0 = H; 1814 destroy(f->ret->t1); 1815 f->ret->t1 = H; 1816 if(err == nil){ 1817 if(n < -1) 1818 err = buf; 1819 else 1820 err = MSG; 1821 } 1822 break; 1823 } 1824 if(n == 2 && buf[0] == 'O' && buf[1] == 'K') 1825 break; 1826 } 1827 } 1828 1829 /* set error and id to nobody */ 1830 if(f->ret->t0 == H){ 1831 if(err == nil) 1832 err = MSG; 1833 retstr(err, &f->ret->t0); 1834 if(f->setid) 1835 setid("nobody", 1); 1836 } else { 1837 /* change user id */ 1838 if(f->setid) 1839 setid(string2c(f->ret->t0), 1); 1840 } 1841 1842 /* free resources */ 1843 if(hispk != H){ 1844 pkmutable(hispk); 1845 destroy(hispk); 1846 } 1847 if(hiscert != H){ 1848 certmutable(hiscert); 1849 destroy(hiscert); 1850 } 1851 if(alphacert != H){ 1852 certmutable(alphacert); 1853 destroy(alphacert); 1854 } 1855 free(buf); 1856 if(r0 != nil){ 1857 mpfree(r0); 1858 mpfree(r1); 1859 mpfree(alphar0); 1860 mpfree(alphar1); 1861 mpfree(alphar0r1); 1862 } 1863 } 1864 1865 static Keyring_Authinfo* 1866 newAuthinfo(void) 1867 { 1868 return H2D(Keyring_Authinfo*, heap(TAuthinfo)); 1869 } 1870 1871 void 1872 Keyring_writeauthinfo(void *fp) 1873 { 1874 F_Keyring_writeauthinfo *f; 1875 int n, fd; 1876 char *buf; 1877 PK *spk; 1878 SK *mysk; 1879 Certificate *c; 1880 1881 f = fp; 1882 *f->ret = -1; 1883 1884 if(f->filename == H) 1885 return; 1886 if(f->info == H) 1887 return; 1888 if(f->info->alpha == H || f->info->p == H) 1889 return; 1890 if(((IPint*)f->info->alpha)->b == 0 || ((IPint*)f->info->p)->b == H) 1891 return; 1892 spk = checkPK(f->info->spk); 1893 mysk = checkSK(f->info->mysk); 1894 c = checkCertificate(f->info->cert); 1895 1896 buf = malloc(Maxbuf); 1897 if(buf == nil) 1898 return; 1899 1900 /* 1901 * The file may already exist or be a file2chan file so first 1902 * try opening with truncation since create will change the 1903 * permissions of the file and create doesn't work with a 1904 * file2chan. 1905 */ 1906 release(); 1907 fd = kopen(string2c(f->filename), OTRUNC|OWRITE); 1908 if(fd < 0) 1909 fd = kcreate(string2c(f->filename), OWRITE, 0600); 1910 if(fd < 0) 1911 fd = kopen(string2c(f->filename), OWRITE); 1912 acquire(); 1913 if(fd < 0) 1914 goto out; 1915 1916 /* signer's public key */ 1917 n = pktostr(spk, buf, Maxmsg); 1918 if(sendmsg(fd, buf, n) <= 0) 1919 goto out; 1920 1921 /* certificate for my public key */ 1922 n = certtostr(c, buf, Maxmsg); 1923 if(sendmsg(fd, buf, n) <= 0) 1924 goto out; 1925 1926 /* my secret/public key */ 1927 n = sktostr(mysk, buf, Maxmsg); 1928 if(sendmsg(fd, buf, n) <= 0) 1929 goto out; 1930 1931 /* diffie hellman base */ 1932 n = bigtobase64(((IPint*)f->info->alpha)->b, buf, Maxbuf); 1933 if(sendmsg(fd, buf, n) <= 0) 1934 goto out; 1935 1936 /* diffie hellman modulus */ 1937 n = bigtobase64(((IPint*)f->info->p)->b, buf, Maxbuf); 1938 if(sendmsg(fd, buf, n) <= 0) 1939 goto out; 1940 1941 *f->ret = 0; 1942 out: 1943 free(buf); 1944 if(fd >= 0){ 1945 release(); 1946 kclose(fd); 1947 acquire(); 1948 } 1949 } 1950 1951 void 1952 Keyring_readauthinfo(void *fp) 1953 { 1954 F_Keyring_readauthinfo *f; 1955 int fd; 1956 char *buf; 1957 int n, ok; 1958 PK *mypk; 1959 SK *mysk; 1960 SigAlg *sa; 1961 Keyring_Authinfo *ai; 1962 mpint *b; 1963 void *r; 1964 1965 f = fp; 1966 r = *f->ret; 1967 *f->ret = H; 1968 destroy(r); 1969 1970 ok = 0; 1971 1972 if(f->filename == H) 1973 return; 1974 1975 buf = malloc(Maxbuf); 1976 if(buf == nil) 1977 return; 1978 1979 ai = newAuthinfo(); 1980 *f->ret = ai; 1981 1982 release(); 1983 fd = kopen(string2c(f->filename), OREAD); 1984 acquire(); 1985 if(fd < 0) 1986 goto out; 1987 1988 /* signer's public key */ 1989 n = getmsg(fd, buf, Maxmsg); 1990 if(n < 0) 1991 goto out; 1992 1993 ai->spk = (Keyring_PK*)strtopk(buf); 1994 if(ai->spk == H) 1995 goto out; 1996 1997 /* certificate for my public key */ 1998 n = getmsg(fd, buf, Maxmsg); 1999 if(n < 0) 2000 goto out; 2001 ai->cert = (Keyring_Certificate*)strtocert(buf); 2002 if(ai->cert == H) 2003 goto out; 2004 2005 /* my secret/public key */ 2006 n = getmsg(fd, buf, Maxmsg); 2007 if(n < 0) 2008 goto out; 2009 mysk = strtosk(buf); 2010 ai->mysk = (Keyring_SK*)mysk; 2011 if(mysk == H) 2012 goto out; 2013 sa = checkSigAlg(mysk->x.sa); 2014 mypk = newPK(sa, stringdup(mysk->x.owner), 1); 2015 mypk->key = (*sa->vec->sk2pk)(mysk->key); 2016 ai->mypk = (Keyring_PK*)mypk; 2017 2018 /* diffie hellman base */ 2019 n = getmsg(fd, buf, Maxmsg); 2020 if(n < 0) 2021 goto out; 2022 b = strtomp(buf, nil, 64, nil); 2023 ai->alpha = newIPint(b); 2024 2025 /* diffie hellman modulus */ 2026 n = getmsg(fd, buf, Maxmsg); 2027 if(n < 0) 2028 goto out; 2029 b = strtomp(buf, nil, 64, nil); 2030 ai->p = newIPint(b); 2031 ok = 1; 2032 out: 2033 if(!ok){ 2034 r = *f->ret; 2035 *f->ret = H; 2036 destroy(r); 2037 } 2038 free(buf); 2039 if(fd >= 0){ 2040 release(); 2041 kclose(fd); 2042 acquire(); 2043 kwerrstr("%q: %s", string2c(f->filename), MSG); 2044 } 2045 } 2046 2047 void 2048 keyringmodinit(void) 2049 { 2050 SigAlgVec *sav; 2051 extern SigAlgVec* elgamalinit(void); 2052 extern SigAlgVec* rsainit(void); 2053 extern SigAlgVec* dsainit(void); 2054 2055 TIPint = dtype(freeIPint, sizeof(IPint), IPintmap, sizeof(IPintmap)); 2056 TSigAlg = dtype(freeSigAlg, sizeof(SigAlg), SigAlgmap, sizeof(SigAlgmap)); 2057 TSK = dtype(freeSK, sizeof(SK), SKmap, sizeof(SKmap)); 2058 TPK = dtype(freePK, sizeof(PK), PKmap, sizeof(PKmap)); 2059 TCertificate = dtype(freeCertificate, sizeof(Certificate), Certificatemap, 2060 sizeof(Certificatemap)); 2061 TDigestState = dtype(freeheap, sizeof(XDigestState), DigestStatemap, 2062 sizeof(DigestStatemap)); 2063 TAESstate = dtype(freeheap, sizeof(XAESstate), AESstatemap, 2064 sizeof(AESstatemap)); 2065 TDESstate = dtype(freeheap, sizeof(XDESstate), DESstatemap, 2066 sizeof(DESstatemap)); 2067 TIDEAstate = dtype(freeheap, sizeof(XIDEAstate), IDEAstatemap, 2068 sizeof(IDEAstatemap)); 2069 TBFstate = dtype(freeheap, sizeof(XBFstate), BFstatemap, 2070 sizeof(BFstatemap)); 2071 TRC4state = dtype(freeheap, sizeof(XRC4state), RC4statemap, 2072 sizeof(RC4statemap)); 2073 TAuthinfo = dtype(freeheap, sizeof(Keyring_Authinfo), Authinfomap, sizeof(Authinfomap)); 2074 TDSAsk = dtype(freeheap, sizeof(Keyring_DSAsk), DSAskmap, sizeof(DSAskmap)); 2075 TDSApk = dtype(freeheap, sizeof(Keyring_DSApk), DSApkmap, sizeof(DSApkmap)); 2076 TDSAsig = dtype(freeheap, sizeof(Keyring_DSAsig), DSAsigmap, sizeof(DSAsigmap)); 2077 TEGsk = dtype(freeheap, sizeof(Keyring_EGsk), EGskmap, sizeof(EGskmap)); 2078 TEGpk = dtype(freeheap, sizeof(Keyring_EGpk), EGpkmap, sizeof(EGpkmap)); 2079 TEGsig = dtype(freeheap, sizeof(Keyring_EGsig), EGsigmap, sizeof(EGsigmap)); 2080 TRSAsk = dtype(freeheap, sizeof(Keyring_RSAsk), RSAskmap, sizeof(RSAskmap)); 2081 TRSApk = dtype(freeheap, sizeof(Keyring_RSApk), RSApkmap, sizeof(RSApkmap)); 2082 TRSAsig = dtype(freeheap, sizeof(Keyring_RSAsig), RSAsigmap, sizeof(RSAsigmap)); 2083 2084 if((sav = elgamalinit()) != nil) 2085 algs[nalg++] = sav; 2086 if((sav = rsainit()) != nil) 2087 algs[nalg++] = sav; 2088 if((sav = dsainit()) != nil) 2089 algs[nalg++] = sav; 2090 2091 fmtinstall('U', big64conv); 2092 builtinmod("$Keyring", Keyringmodtab, Keyringmodlen); 2093 } 2094 2095 /* 2096 * IO on a delimited channel. A message starting with 0x00 is a normal 2097 * message. One starting with 0xff is an error string. 2098 * 2099 * return negative number for error messages (including hangup) 2100 */ 2101 static int 2102 getbuf(int fd, uchar *buf, int n, char *err, int nerr) 2103 { 2104 int len; 2105 2106 release(); 2107 len = kread(fd, buf, n); 2108 acquire(); 2109 if(len <= 0){ 2110 strncpy(err, "hungup", nerr); 2111 buf[nerr-1] = 0; 2112 return -1; 2113 } 2114 if(buf[0] == 0) 2115 return len-1; 2116 if(buf[0] != 0xff){ 2117 /* 2118 * this happens when the client's password is wrong: both sides use a digest of the 2119 * password as a crypt key for devssl. When they don't match decryption garbles 2120 * messages 2121 */ 2122 strncpy(err, "failure", nerr); 2123 err[nerr-1] = 0; 2124 return -1; 2125 } 2126 2127 /* error string */ 2128 len--; 2129 if(len < 1){ 2130 strncpy(err, "unknown", nerr); 2131 err[nerr-1] = 0; 2132 } else { 2133 if(len >= nerr) 2134 len = nerr-1; 2135 memmove(err, buf+1, len); 2136 err[len] = 0; 2137 } 2138 return -1; 2139 } 2140 2141 void 2142 Keyring_getstring(void *fp) 2143 { 2144 F_Keyring_getstring *f; 2145 uchar *buf; 2146 char err[64]; 2147 int n; 2148 2149 f = fp; 2150 destroy(f->ret->t0); 2151 f->ret->t0 = H; 2152 destroy(f->ret->t1); 2153 f->ret->t1 = H; 2154 2155 if(f->fd == H) 2156 return; 2157 2158 buf = malloc(Maxmsg); 2159 if(buf == nil) 2160 return; 2161 2162 n = getbuf(f->fd->fd, buf, Maxmsg, err, sizeof(err)); 2163 if(n < 0) 2164 retnstr(err, strlen(err), &f->ret->t1); 2165 else 2166 retnstr(((char*)buf)+1, n, &f->ret->t0); 2167 2168 free(buf); 2169 } 2170 2171 void 2172 Keyring_getbytearray(void *fp) 2173 { 2174 F_Keyring_getbytearray *f; 2175 uchar *buf; 2176 char err[64]; 2177 int n; 2178 2179 f = fp; 2180 destroy(f->ret->t0); 2181 f->ret->t0 = H; 2182 destroy(f->ret->t1); 2183 f->ret->t1 = H; 2184 2185 if(f->fd == H) 2186 return; 2187 2188 buf = malloc(Maxmsg); 2189 if(buf == nil) 2190 return; 2191 2192 n = getbuf(f->fd->fd, buf, Maxmsg, err, sizeof(err)); 2193 if(n < 0) 2194 retnstr(err, strlen(err), &f->ret->t1); 2195 else 2196 f->ret->t0 = mem2array(buf+1, n); 2197 2198 free(buf); 2199 } 2200 2201 static int 2202 putbuf(int fd, void *p, int n) 2203 { 2204 char *buf; 2205 2206 buf = malloc(Maxmsg); 2207 if(buf == nil) 2208 return -1; 2209 2210 release(); 2211 buf[0] = 0; 2212 if(n < 0){ 2213 buf[0] = 0xff; 2214 n = -n; 2215 } 2216 if(n >= Maxmsg) 2217 n = Maxmsg - 1; 2218 memmove(buf+1, p, n); 2219 n = kwrite(fd, buf, n+1); 2220 acquire(); 2221 2222 free(buf); 2223 return n; 2224 } 2225 2226 void 2227 Keyring_putstring(void *fp) 2228 { 2229 F_Keyring_putstring *f; 2230 2231 f = fp; 2232 *f->ret = -1; 2233 if(f->fd == H || f->s == H) 2234 return; 2235 *f->ret = putbuf(f->fd->fd, string2c(f->s), strlen(string2c(f->s))); 2236 } 2237 2238 void 2239 Keyring_puterror(void *fp) 2240 { 2241 F_Keyring_puterror *f; 2242 2243 f = fp; 2244 *f->ret = -1; 2245 if(f->fd == H || f->s == H) 2246 return; 2247 *f->ret = putbuf(f->fd->fd, string2c(f->s), -strlen(string2c(f->s))); 2248 } 2249 2250 void 2251 Keyring_putbytearray(void *fp) 2252 { 2253 F_Keyring_putbytearray *f; 2254 int n; 2255 2256 f = fp; 2257 *f->ret = -1; 2258 if(f->fd == H || f->a == H) 2259 return; 2260 n = f->n; 2261 if(n < 0 || n > f->a->len) 2262 error(exBounds); 2263 *f->ret = putbuf(f->fd->fd, f->a->data, n); 2264 } 2265 2266 void 2267 Keyring_dessetup(void *fp) 2268 { 2269 F_Keyring_dessetup *f; 2270 Heap *h; 2271 XDESstate *ds; 2272 uchar *ivec; 2273 void *r; 2274 2275 f = fp; 2276 r = *f->ret; 2277 *f->ret = H; 2278 destroy(r); 2279 2280 if(f->key == H || f->key->len < 8) 2281 error(exBadKey); 2282 if(f->ivec != H){ 2283 if(f->ivec->len < 8) 2284 error(exBadIvec); 2285 ivec = f->ivec->data; 2286 }else 2287 ivec = nil; 2288 2289 h = heap(TDESstate); 2290 ds = H2D(XDESstate*, h); 2291 setupDESstate(&ds->state, f->key->data, ivec); 2292 2293 *f->ret = (Keyring_DESstate*)ds; 2294 } 2295 2296 void 2297 Keyring_desecb(void *fp) 2298 { 2299 F_Keyring_desecb *f; 2300 XDESstate *ds; 2301 int i; 2302 uchar *p; 2303 2304 f = fp; 2305 2306 if(f->buf == H) 2307 return; 2308 if(f->n < 0 || f->n > f->buf->len) 2309 error(exBounds); 2310 if(f->n & 7) 2311 error(exBadBsize); 2312 2313 ds = checktype(f->state, TDESstate, exBadState, 0); 2314 p = f->buf->data; 2315 2316 for(i = 8; i <= f->n; i += 8, p += 8) 2317 block_cipher(ds->state.expanded, p, f->direction); 2318 } 2319 2320 void 2321 Keyring_descbc(void *fp) 2322 { 2323 F_Keyring_descbc *f; 2324 XDESstate *ds; 2325 uchar *p, *ep, *ip, *p2, *eip; 2326 uchar tmp[8]; 2327 2328 f = fp; 2329 2330 if(f->buf == H) 2331 return; 2332 if(f->n < 0 || f->n > f->buf->len) 2333 error(exBounds); 2334 if(f->n & 7) 2335 error(exBadBsize); 2336 2337 ds = checktype(f->state, TDESstate, exBadState, 0); 2338 p = f->buf->data; 2339 2340 if(f->direction == 0){ 2341 for(ep = p + f->n; p < ep; p += 8){ 2342 p2 = p; 2343 ip = ds->state.ivec; 2344 for(eip = ip+8; ip < eip; ) 2345 *p2++ ^= *ip++; 2346 block_cipher(ds->state.expanded, p, 0); 2347 memmove(ds->state.ivec, p, 8); 2348 } 2349 } else { 2350 for(ep = p + f->n; p < ep; ){ 2351 memmove(tmp, p, 8); 2352 block_cipher(ds->state.expanded, p, 1); 2353 p2 = tmp; 2354 ip = ds->state.ivec; 2355 for(eip = ip+8; ip < eip; ){ 2356 *p++ ^= *ip; 2357 *ip++ = *p2++; 2358 } 2359 } 2360 } 2361 } 2362 2363 void 2364 Keyring_ideasetup(void *fp) 2365 { 2366 F_Keyring_ideasetup *f; 2367 Heap *h; 2368 XIDEAstate *is; 2369 uchar *ivec; 2370 void *r; 2371 2372 f = fp; 2373 r = *f->ret; 2374 *f->ret = H; 2375 destroy(r); 2376 2377 if(f->key == H || f->key->len < 16) 2378 error(exBadKey); 2379 if(f->ivec != H){ 2380 if(f->ivec->len < 8) 2381 error(exBadIvec); 2382 ivec = f->ivec->data; 2383 }else 2384 ivec = nil; 2385 2386 h = heap(TIDEAstate); 2387 is = H2D(XIDEAstate*, h); 2388 2389 setupIDEAstate(&is->state, f->key->data, ivec); 2390 2391 *f->ret = (Keyring_IDEAstate*)is; 2392 } 2393 2394 void 2395 Keyring_ideaecb(void *fp) 2396 { 2397 F_Keyring_ideaecb *f; 2398 XIDEAstate *is; 2399 int i; 2400 uchar *p; 2401 2402 f = fp; 2403 2404 if(f->buf == H) 2405 return; 2406 if(f->n < 0 || f->n > f->buf->len) 2407 error(exBounds); 2408 if(f->n & 7) 2409 error(exBadBsize); 2410 2411 is = checktype(f->state, TIDEAstate, exBadState, 0); 2412 p = f->buf->data; 2413 2414 for(i = 8; i <= f->n; i += 8, p += 8) 2415 idea_cipher(is->state.edkey, p, f->direction); 2416 } 2417 2418 void 2419 Keyring_ideacbc(void *fp) 2420 { 2421 F_Keyring_ideacbc *f; 2422 XIDEAstate *is; 2423 uchar *p, *ep, *ip, *p2, *eip; 2424 uchar tmp[8]; 2425 2426 f = fp; 2427 2428 if(f->buf == H) 2429 return; 2430 if(f->n < 0 || f->n > f->buf->len) 2431 error(exBounds); 2432 if(f->n & 7) 2433 error(exBadBsize); 2434 2435 is = checktype(f->state, TIDEAstate, exBadState, 0); 2436 p = f->buf->data; 2437 2438 if(f->direction == 0){ 2439 for(ep = p + f->n; p < ep; p += 8){ 2440 p2 = p; 2441 ip = is->state.ivec; 2442 for(eip = ip+8; ip < eip; ) 2443 *p2++ ^= *ip++; 2444 idea_cipher(is->state.edkey, p, 0); 2445 memmove(is->state.ivec, p, 8); 2446 } 2447 } else { 2448 for(ep = p + f->n; p < ep; ){ 2449 memmove(tmp, p, 8); 2450 idea_cipher(is->state.edkey, p, 1); 2451 p2 = tmp; 2452 ip = is->state.ivec; 2453 for(eip = ip+8; ip < eip; ){ 2454 *p++ ^= *ip; 2455 *ip++ = *p2++; 2456 } 2457 } 2458 } 2459 } 2460 2461 void 2462 Keyring_aessetup(void *fp) 2463 { 2464 F_Keyring_aessetup *f; 2465 Heap *h; 2466 XAESstate *is; 2467 uchar *ivec; 2468 void *r; 2469 2470 f = fp; 2471 r = *f->ret; 2472 *f->ret = H; 2473 destroy(r); 2474 2475 if(f->key == H || 2476 f->key->len != 16 && f->key->len != 24 && f->key->len != 32) 2477 error(exBadKey); 2478 if(f->ivec != H){ 2479 if(f->ivec->len < AESbsize) 2480 error(exBadIvec); 2481 ivec = f->ivec->data; 2482 }else 2483 ivec = nil; 2484 2485 h = heap(TAESstate); 2486 is = H2D(XAESstate*, h); 2487 2488 setupAESstate(&is->state, f->key->data, f->key->len, ivec); 2489 2490 *f->ret = (Keyring_AESstate*)is; 2491 } 2492 2493 void 2494 Keyring_aescbc(void *fp) 2495 { 2496 F_Keyring_aescbc *f; 2497 XAESstate *is; 2498 uchar *p; 2499 2500 f = fp; 2501 2502 if(f->buf == H) 2503 return; 2504 if(f->n < 0 || f->n > f->buf->len) 2505 error(exBounds); 2506 2507 is = checktype(f->state, TAESstate, exBadState, 0); 2508 p = f->buf->data; 2509 2510 if(f->direction == 0) 2511 aesCBCencrypt(p, f->n, &is->state); 2512 else 2513 aesCBCdecrypt(p, f->n, &is->state); 2514 } 2515 2516 void 2517 Keyring_blowfishsetup(void *fp) 2518 { 2519 F_Keyring_blowfishsetup *f; 2520 Heap *h; 2521 XBFstate *is; 2522 uchar *ivec; 2523 void *r; 2524 2525 f = fp; 2526 r = *f->ret; 2527 *f->ret = H; 2528 destroy(r); 2529 2530 if(f->key == H || f->key->len <= 0) 2531 error(exBadKey); 2532 if(f->ivec != H){ 2533 if(f->ivec->len != BFbsize) 2534 error(exBadIvec); 2535 ivec = f->ivec->data; 2536 }else 2537 ivec = nil; 2538 2539 h = heap(TBFstate); 2540 is = H2D(XBFstate*, h); 2541 2542 setupBFstate(&is->state, f->key->data, f->key->len, ivec); 2543 2544 *f->ret = (Keyring_BFstate*)is; 2545 } 2546 2547 void 2548 Keyring_blowfishcbc(void *fp) 2549 { 2550 F_Keyring_blowfishcbc *f; 2551 XBFstate *is; 2552 uchar *p; 2553 2554 f = fp; 2555 2556 if(f->buf == H) 2557 return; 2558 if(f->n < 0 || f->n > f->buf->len) 2559 error(exBounds); 2560 if(f->n & 7) 2561 error(exBadBsize); 2562 2563 is = checktype(f->state, TBFstate, exBadState, 0); 2564 p = f->buf->data; 2565 2566 if(f->direction == 0) 2567 bfCBCencrypt(p, f->n, &is->state); 2568 else 2569 bfCBCdecrypt(p, f->n, &is->state); 2570 } 2571 2572 void 2573 Keyring_rc4setup(void *fp) 2574 { 2575 F_Keyring_rc4setup *f; 2576 Heap *h; 2577 XRC4state *is; 2578 void *r; 2579 2580 f = fp; 2581 r = *f->ret; 2582 *f->ret = H; 2583 destroy(r); 2584 2585 if(f->seed == H) 2586 return; 2587 2588 h = heap(TRC4state); 2589 is = H2D(XRC4state*, h); 2590 2591 setupRC4state(&is->state, f->seed->data, f->seed->len); 2592 2593 *f->ret = (Keyring_RC4state*)is; 2594 } 2595 2596 void 2597 Keyring_rc4(void *fp) 2598 { 2599 F_Keyring_rc4 *f; 2600 XRC4state *is; 2601 uchar *p; 2602 2603 f = fp; 2604 if(f->buf == H) 2605 return; 2606 if(f->n < 0 || f->n > f->buf->len) 2607 error(exBounds); 2608 is = checktype(f->state, TRC4state, exBadState, 0); 2609 p = f->buf->data; 2610 rc4(&is->state, p, f->n); 2611 } 2612 2613 void 2614 Keyring_rc4skip(void *fp) 2615 { 2616 F_Keyring_rc4skip *f; 2617 XRC4state *is; 2618 2619 f = fp; 2620 is = checktype(f->state, TRC4state, exBadState, 0); 2621 rc4skip(&is->state, f->n); 2622 } 2623 2624 void 2625 Keyring_rc4back(void *fp) 2626 { 2627 F_Keyring_rc4back *f; 2628 XRC4state *is; 2629 2630 f = fp; 2631 is = checktype(f->state, TRC4state, exBadState, 0); 2632 rc4back(&is->state, f->n); 2633 } 2634 2635 /* 2636 * public/secret keys, signing and verifying 2637 */ 2638 2639 static void 2640 dsapk2pub(DSApub* p, Keyring_DSApk* pk) 2641 { 2642 if(pk == H) 2643 error(exNilref); 2644 p->p = checkIPint(pk->p); 2645 p->q = checkIPint(pk->q); 2646 p->alpha = checkIPint(pk->alpha); 2647 p->key = checkIPint(pk->key); 2648 } 2649 2650 static void 2651 dsask2priv(DSApriv* p, Keyring_DSAsk* sk) 2652 { 2653 if(sk == H || sk->pk == H) 2654 error(exNilref); 2655 dsapk2pub(&p->pub, sk->pk); 2656 p->secret = checkIPint(sk->secret); 2657 } 2658 2659 static void 2660 dsapriv2sk(Keyring_DSAsk* sk, DSApriv* p) 2661 { 2662 Keyring_DSApk* pk; 2663 2664 pk = sk->pk; 2665 pk->p = ipcopymp(p->pub.p); 2666 pk->q = ipcopymp(p->pub.q); 2667 pk->alpha = ipcopymp(p->pub.alpha); 2668 pk->key = ipcopymp(p->pub.key); 2669 sk->secret = ipcopymp(p->secret); 2670 } 2671 2672 void 2673 DSAsk_gen(void *fp) 2674 { 2675 F_DSAsk_gen *f; 2676 Keyring_DSAsk *sk; 2677 DSApriv *p; 2678 DSApub pub, *oldpk; 2679 void *v; 2680 2681 f = fp; 2682 v = *f->ret; 2683 sk = newthing(TDSAsk, 0); 2684 sk->pk = newthing(TDSApk, 0); 2685 *f->ret = sk; 2686 destroy(v); 2687 oldpk = nil; 2688 if(f->oldpk != H){ 2689 dsapk2pub(&pub, f->oldpk); 2690 oldpk = &pub; 2691 } 2692 release(); 2693 p = dsagen(oldpk); 2694 acquire(); 2695 dsapriv2sk(sk, p); 2696 dsaprivfree(p); 2697 } 2698 2699 void 2700 DSAsk_sign(void *fp) 2701 { 2702 F_DSAsk_sign *f; 2703 Keyring_DSAsig *sig; 2704 DSApriv p; 2705 mpint *m; 2706 DSAsig *s; 2707 void *v; 2708 2709 f = fp; 2710 v = *f->ret; 2711 sig = newthing(TDSAsig, 0); 2712 *f->ret = sig; 2713 destroy(v); 2714 2715 dsask2priv(&p, f->k); 2716 m = checkIPint(f->m); 2717 release(); 2718 s = dsasign(&p, m); 2719 acquire(); 2720 sig->r = ipcopymp(s->r); 2721 sig->s = ipcopymp(s->s); 2722 dsasigfree(s); 2723 } 2724 2725 void 2726 DSApk_verify(void *fp) 2727 { 2728 F_DSApk_verify *f; 2729 DSApub p; 2730 DSAsig sig; 2731 mpint *m; 2732 2733 f = fp; 2734 *f->ret = 0; 2735 if(f->m == H || f->sig == H) 2736 return; 2737 dsapk2pub(&p, f->k); 2738 sig.r = checkIPint(f->sig->r); 2739 sig.s = checkIPint(f->sig->s); 2740 m = checkIPint(f->m); 2741 release(); 2742 *f->ret = dsaverify(&p, &sig, m) == 0; 2743 acquire(); 2744 } 2745 2746 static void 2747 egpk2pub(EGpub* p, Keyring_EGpk* pk) 2748 { 2749 if(pk == H) 2750 error(exNilref); 2751 p->p = checkIPint(pk->p); 2752 p->alpha = checkIPint(pk->alpha); 2753 p->key = checkIPint(pk->key); 2754 } 2755 2756 static void 2757 egsk2priv(EGpriv* p, Keyring_EGsk* sk) 2758 { 2759 if(sk == H || sk->pk == H) 2760 error(exNilref); 2761 egpk2pub(&p->pub, sk->pk); 2762 p->secret = checkIPint(sk->secret); 2763 } 2764 2765 static void 2766 egpriv2sk(Keyring_EGsk* sk, EGpriv* p) 2767 { 2768 Keyring_EGpk* pk; 2769 2770 pk = sk->pk; 2771 pk->p = ipcopymp(p->pub.p); 2772 pk->alpha = ipcopymp(p->pub.alpha); 2773 pk->key = ipcopymp(p->pub.key); 2774 sk->secret = ipcopymp(p->secret); 2775 } 2776 2777 void 2778 EGsk_gen(void *fp) 2779 { 2780 F_EGsk_gen *f; 2781 Keyring_EGsk *sk; 2782 EGpriv *p; 2783 void *v; 2784 2785 f = fp; 2786 v = *f->ret; 2787 sk = newthing(TEGsk, 0); 2788 sk->pk = newthing(TEGpk, 0); 2789 *f->ret = sk; 2790 destroy(v); 2791 release(); 2792 for(;;){ 2793 p = eggen(f->nlen, f->nrep); 2794 if(mpsignif(p->pub.p) == f->nlen) 2795 break; 2796 egprivfree(p); 2797 } 2798 acquire(); 2799 egpriv2sk(sk, p); 2800 egprivfree(p); 2801 } 2802 2803 void 2804 EGsk_sign(void *fp) 2805 { 2806 F_EGsk_sign *f; 2807 Keyring_EGsig *sig; 2808 EGpriv p; 2809 mpint *m; 2810 EGsig *s; 2811 void *v; 2812 2813 f = fp; 2814 v = *f->ret; 2815 sig = newthing(TEGsig, 0); 2816 *f->ret = sig; 2817 destroy(v); 2818 2819 egsk2priv(&p, f->k); 2820 m = checkIPint(f->m); 2821 release(); 2822 s = egsign(&p, m); 2823 acquire(); 2824 sig->r = ipcopymp(s->r); 2825 sig->s = ipcopymp(s->s); 2826 egsigfree(s); 2827 } 2828 2829 void 2830 EGpk_verify(void *fp) 2831 { 2832 F_EGpk_verify *f; 2833 EGpub p; 2834 EGsig sig; 2835 mpint *m; 2836 2837 f = fp; 2838 *f->ret = 0; 2839 if(f->m == H || f->sig == H) 2840 return; 2841 egpk2pub(&p, f->k); 2842 sig.r = checkIPint(f->sig->r); 2843 sig.s = checkIPint(f->sig->s); 2844 m = checkIPint(f->m); 2845 release(); 2846 *f->ret = egverify(&p, &sig, m) == 0; 2847 acquire(); 2848 } 2849 2850 static void 2851 rsapk2pub(RSApub* p, Keyring_RSApk* pk) 2852 { 2853 if(pk == H) 2854 error(exNilref); 2855 memset(p, 0, sizeof(*p)); 2856 p->n = checkIPint(pk->n); 2857 p->ek = checkIPint(pk->ek); 2858 } 2859 2860 static void 2861 rsask2priv(RSApriv* p, Keyring_RSAsk* sk) 2862 { 2863 if(sk == H || sk->pk == H) 2864 error(exNilref); 2865 rsapk2pub(&p->pub, sk->pk); 2866 p->dk = checkIPint(sk->dk); 2867 p->p = checkIPint(sk->p); 2868 p->q = checkIPint(sk->q); 2869 p->kp = checkIPint(sk->kp); 2870 p->kq = checkIPint(sk->kq); 2871 p->c2 = checkIPint(sk->c2); 2872 } 2873 2874 static void 2875 rsapriv2sk(Keyring_RSAsk* sk, RSApriv* p) 2876 { 2877 Keyring_RSApk* pk; 2878 2879 pk = sk->pk; 2880 pk->n = ipcopymp(p->pub.n); 2881 pk->ek = ipcopymp(p->pub.ek); 2882 sk->dk = ipcopymp(p->dk); 2883 sk->p = ipcopymp(p->p); 2884 sk->q = ipcopymp(p->q); 2885 sk->kp = ipcopymp(p->kp); 2886 sk->kq = ipcopymp(p->kq); 2887 sk->c2 = ipcopymp(p->c2); 2888 } 2889 2890 void 2891 RSApk_encrypt(void *fp) 2892 { 2893 F_RSApk_encrypt *f; 2894 RSApub p; 2895 mpint *m, *o; 2896 void *v; 2897 2898 f = fp; 2899 v = *f->ret; 2900 *f->ret = H; 2901 destroy(v); 2902 2903 rsapk2pub(&p, f->k); 2904 m = checkIPint(f->m); 2905 release(); 2906 o = rsaencrypt(&p, m, nil); 2907 acquire(); 2908 *f->ret = newIPint(o); 2909 } 2910 2911 void 2912 RSAsk_gen(void *fp) 2913 { 2914 F_RSAsk_gen *f; 2915 Keyring_RSAsk *sk; 2916 RSApriv *p; 2917 void *v; 2918 2919 f = fp; 2920 v = *f->ret; 2921 sk = newthing(TRSAsk, 0); 2922 sk->pk = newthing(TRSApk, 0); 2923 *f->ret = sk; 2924 destroy(v); 2925 release(); 2926 for(;;){ 2927 p = rsagen(f->nlen, f->elen, f->nrep); 2928 if(mpsignif(p->pub.n) == f->nlen) 2929 break; 2930 rsaprivfree(p); 2931 } 2932 acquire(); 2933 rsapriv2sk(sk, p); 2934 rsaprivfree(p); 2935 } 2936 2937 void 2938 RSAsk_fill(void *fp) 2939 { 2940 F_RSAsk_fill *f; 2941 Keyring_RSAsk *sk; 2942 RSApriv *p; 2943 void *v; 2944 2945 f = fp; 2946 v = *f->ret; 2947 sk = newthing(TRSAsk, 0); 2948 sk->pk = newthing(TRSApk, 0); 2949 *f->ret = sk; 2950 destroy(v); 2951 release(); 2952 p = rsafill(checkIPint(f->n), checkIPint(f->e), checkIPint(f->d), 2953 checkIPint(f->p), checkIPint(f->q)); 2954 acquire(); 2955 if(p == nil) { 2956 *f->ret = H; 2957 destroy(sk); 2958 }else{ 2959 rsapriv2sk(sk, p); 2960 rsaprivfree(p); 2961 } 2962 } 2963 2964 void 2965 RSAsk_decrypt(void *fp) 2966 { 2967 F_RSAsk_decrypt *f; 2968 RSApriv p; 2969 mpint *m, *o; 2970 void *v; 2971 2972 f = fp; 2973 v = *f->ret; 2974 *f->ret = H; 2975 destroy(v); 2976 2977 rsask2priv(&p, f->k); 2978 m = checkIPint(f->m); 2979 release(); 2980 o = rsadecrypt(&p, m, nil); 2981 acquire(); 2982 *f->ret = newIPint(o); 2983 } 2984 2985 void 2986 RSAsk_sign(void *fp) 2987 { 2988 F_RSAsk_sign *f; 2989 Keyring_RSAsig *sig; 2990 RSApriv p; 2991 mpint *m, *s; 2992 void *v; 2993 2994 f = fp; 2995 v = *f->ret; 2996 sig = newthing(TRSAsig, 0); 2997 *f->ret = sig; 2998 destroy(v); 2999 3000 rsask2priv(&p, f->k); 3001 m = checkIPint(f->m); 3002 release(); 3003 s = rsadecrypt(&p, m, nil); 3004 acquire(); 3005 sig->n = newIPint(s); 3006 } 3007 3008 void 3009 RSApk_verify(void *fp) 3010 { 3011 F_RSApk_verify *f; 3012 RSApub p; 3013 mpint *sig, *m, *t; 3014 3015 f = fp; 3016 *f->ret = 0; 3017 if(f->m == H || f->sig == H) 3018 return; 3019 rsapk2pub(&p, f->k); 3020 sig = checkIPint(f->sig->n); 3021 m = checkIPint(f->m); 3022 release(); 3023 t = rsaencrypt(&p, sig, nil); 3024 *f->ret = mpcmp(t, m) == 0; 3025 mpfree(t); 3026 acquire(); 3027 } 3028