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