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