1/* Copyright (c) 2001,2003-2006,2008 Apple Inc. 2 * 3 * keyStore.c - basic key pair store/lookup routines. 4 * 5 * create key pair, varying pub is permanent, priv is permanent; 6 * sign some data with priv; 7 * lookUpPub = lookup pub by label; 8 * vfy with lookUpPub; 9 * lookUpPriv = lookup priv by label; 10 * if(privIsPerm) { 11 * ensure lookUpPriv == priv; 12 * freeKey(lookUpPriv); 13 * obtainedPriv = obtainPubFromPriv(lookUpPub); 14 * ensure obtainedPriv == priv; 15 * freeKey(obtainedPriv); 16 * delete priv; // cspwrap does implicit freeKey here... 17 * } 18 * else { 19 * free priv; 20 * } 21 * lookUpPriv = lookup priv by label; verify fail; 22 * lookUpPriv = obtainPubFromPriv(pub); verify fail; 23 * freeKey(lookUpPub); 24 * if pub is permament { 25 * lookUpPub = lookup pub by label; verify OK; 26 * deleteKey(lookUpPub); 27 * lookUpPub = lookup pub by label; verify fail; 28 * } 29 * lookUpPub = lookup pub by label; verify fail; 30 */ 31 32#include <stdlib.h> 33#include <stdio.h> 34#include <time.h> 35#include <string.h> 36#include <unistd.h> 37#include <Security/cssm.h> 38#include "cspwrap.h" 39#include "common.h" 40#include "cspdlTesting.h" 41 42#define LOOPS_DEF 10 43#define MAX_DATA_SIZE 100 44#define DB_NAME "keyStore.db" 45 46/* can't lookup non-permanent keys! */ 47#define FORCE_PUB_PERMANENT 0 48 49static void usage(char **argv) 50{ 51 printf("usage: %s [options]\n", argv[0]); 52 printf(" Options:\n"); 53 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF); 54 printf(" r(RSA; default = FEE)\n"); 55 printf(" p(ermanent keys, implies l=1)\n"); 56 printf(" k=keyChainFile\n"); 57 printf(" n(o sign/verify)\n"); 58 printf(" N(o lookup of nonexistent keys)\n"); 59 printf(" x (privKey always extractable)\n"); 60 printf(" P(ause for MallocDebug)\n"); 61 printf(" v(erbose)\n"); 62 printf(" q(uiet)\n"); 63 printf(" h(elp)\n"); 64 exit(1); 65} 66 67#define FEE_PRIV_DATA_SIZE 20 68 69/* 70 * NULL wrap, error tolerant. 71 */ 72CSSM_RETURN cspNullWrapKey( 73 CSSM_CSP_HANDLE cspHand, 74 const CSSM_KEY *refKey, 75 CSSM_KEY_PTR rawKey) // RETURNED on success, caller must FreeKey 76{ 77 CSSM_CC_HANDLE ccHand; 78 CSSM_RETURN crtn; 79 CSSM_ACCESS_CREDENTIALS creds; 80 CSSM_DATA descData = {0, 0}; 81 82 memset(rawKey, 0, sizeof(CSSM_KEY)); 83 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); 84 crtn = CSSM_CSP_CreateSymmetricContext(cspHand, 85 CSSM_ALGID_NONE, 86 CSSM_ALGMODE_NONE, 87 &creds, // passPhrase, 88 NULL, // wrappingKey, 89 NULL, // initVector, 90 CSSM_PADDING_NONE, 91 0, // Params 92 &ccHand); 93 if(crtn) { 94 printError("cspNullWrapKey/CreateContext", crtn); 95 return crtn; 96 } 97 crtn = CSSM_WrapKey(ccHand, 98 &creds, 99 refKey, 100 &descData, // DescriptiveData 101 rawKey); 102 if(CSSM_DeleteContext(ccHand)) { 103 printf("CSSM_DeleteContext failure\n"); 104 } 105 return crtn; 106} 107 108 109/* 110 * Generate key pair, default size. This is like cspGenKeyPair in cspwrap.c, 111 * tweaked for this test To allow varying permanent attribute. 112 */ 113static CSSM_RETURN genKeyPair(CSSM_CSP_HANDLE cspHand, 114 CSSM_DL_HANDLE dlHand, 115 CSSM_DB_HANDLE dbHand, 116 const CSSM_DATA_PTR keyLabel, 117 CSSM_KEY_PTR pubKey, // mallocd by caller 118 uint32 pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc. 119 uint32 pubKeyAttr, 120 CSSM_KEY_PTR privKey, // mallocd by caller 121 uint32 privKeyUsage, // CSSM_KEYUSE_DECRYPT, etc. 122 uint32 privKeyAttr, 123 uint32 keyGenAlg) 124{ 125 CSSM_RETURN crtn; 126 CSSM_CC_HANDLE ccHand; 127 CSSM_RETURN ocrtn = CSSM_OK; 128 uint32 keySize; 129 130 if(keyGenAlg == CSSM_ALGID_FEE) { 131 keySize = CSP_FEE_KEY_SIZE_DEFAULT; 132 } 133 else { 134 keySize = CSP_RSA_KEY_SIZE_DEFAULT; 135 } 136 memset(pubKey, 0, sizeof(CSSM_KEY)); 137 memset(privKey, 0, sizeof(CSSM_KEY)); 138 139 crtn = CSSM_CSP_CreateKeyGenContext(cspHand, 140 keyGenAlg, 141 keySize, 142 NULL, // Seed 143 NULL, // Salt 144 NULL, // StartDate 145 NULL, // EndDate 146 NULL, // Params 147 &ccHand); 148 if(crtn) { 149 printError("CSSM_CSP_CreateKeyGenContext", crtn); 150 ocrtn = crtn; 151 goto abort; 152 } 153 154 /* add in DL/DB to context */ 155 crtn = cspAddDlDbToContext(ccHand, dlHand, dbHand); 156 if(crtn) { 157 ocrtn = crtn; 158 goto abort; 159 } 160 crtn = CSSM_GenerateKeyPair(ccHand, 161 pubKeyUsage, 162 pubKeyAttr, 163 keyLabel, 164 pubKey, 165 privKeyUsage, 166 privKeyAttr, 167 keyLabel, // same labels 168 NULL, // cred/acl 169 privKey); 170 if(crtn) { 171 printError("CSSM_GenerateKeyPair", crtn); 172 ocrtn = crtn; 173 goto abort; 174 } 175 176 /* basic checks...*/ 177 if(privKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) { 178 printf("privKey blob type: exp %u got %u\n", 179 CSSM_KEYBLOB_REFERENCE, (unsigned)privKey->KeyHeader.BlobType); 180 } 181 if(pubKeyAttr & CSSM_KEYATTR_RETURN_REF) { 182 if(pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) { 183 printf("pubKey blob type: exp %u got %u\n", 184 CSSM_KEYBLOB_REFERENCE, (unsigned)privKey->KeyHeader.BlobType); 185 ocrtn = -1; 186 goto abort; 187 } 188 } 189 else { 190 if(pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_RAW) { 191 printf("pubKey blob type: exp %u got %u\n", 192 CSSM_KEYBLOB_RAW, (unsigned)privKey->KeyHeader.BlobType); 193 ocrtn = -1; 194 goto abort; 195 } 196 } 197 198abort: 199 if(ccHand != 0) { 200 crtn = CSSM_DeleteContext(ccHand); 201 if(crtn) { 202 printError("CSSM_DeleteContext", crtn); 203 ocrtn = crtn; 204 } 205 } 206 return ocrtn; 207} 208 209#define KEY_LABEL "testKey" 210 211/* 212 * when true, keyref in key obtained from DL differs from 213 * keyref in key from CSP 214 */ 215#define DL_REF_KEYS_DIFFER 1 216 217/* 218 * ObtainPrivateKeyFromPublicKey doesn't work yet 219 */ 220#define DO_OBTAIN_FROM_PUB CSPDL_OBTAIN_PRIV_FROM_PUB 221 222/* we're assumed to be logged in for access to private objects */ 223static int doTest(CSSM_CSP_HANDLE cspHand, 224 CSSM_DL_HANDLE dlHand, 225 CSSM_DB_HANDLE dbHand, 226 CSSM_BOOL pubIsPerm, // pub is permanent 227 CSSM_BOOL privIsPerm, // priv is permanent 228 CSSM_BOOL privIsExtractable, 229 CSSM_BOOL permKeys, // leave them in the KC 230 CSSM_BOOL doSignVerify, 231 CSSM_BOOL doFailedLookup, 232 CSSM_DATA_PTR ptext, 233 CSSM_BOOL verbose, 234 CSSM_BOOL quiet, 235 uint32 keyGenAlg, 236 uint32 sigAlg) 237{ 238 CSSM_KEY pubKey; // from GenerateKeyPair 239 CSSM_KEY privKey; 240 CSSM_KEY_PTR lookUpPub; // from cspLookUpKeyByLabel, etc. 241 CSSM_KEY_PTR lookUpPriv; 242 CSSM_RETURN crtn; 243 CSSM_DATA sig; 244 CSSM_DATA labelData; 245 CSSM_KEY obtainedPriv; 246 uint32 pubAttr; 247 uint32 privAttr; 248 CSSM_KEY rawPrivKey; 249 labelData.Data = (uint8 *)KEY_LABEL; 250 labelData.Length = strlen(KEY_LABEL); 251 CSSM_BOOL doLookup; 252 253 /* create key pair */ 254 if(verbose) { 255 printf(" ...generating key pair (pubIsPerm %d privIsPerm %d privIsExtract" 256 " %d)\n", (int)pubIsPerm, (int)privIsPerm, (int)privIsExtractable); 257 } 258 pubAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF; 259 if(pubIsPerm) { 260 pubAttr |= CSSM_KEYATTR_PERMANENT; 261 } 262 263 /* 264 * To use a NULL wrap to test detection of !EXTRACTABLE, we're relying on 265 * being able to create !SENSITIVE private keys. We'll make 'em sensitive 266 * if we're not trying to null wrap them. 267 */ 268 privAttr = CSSM_KEYATTR_RETURN_REF; 269 if(privIsPerm) { 270 privAttr |= CSSM_KEYATTR_PERMANENT; 271 } 272 if(privIsExtractable) { 273 privAttr |= CSSM_KEYATTR_EXTRACTABLE; 274 } 275 else { 276 privAttr |= CSSM_KEYATTR_SENSITIVE; 277 } 278 #if CSPDL_KEYATTR_PRIVATE 279 privAttr |= CSSM_KEYATTR_PRIVATE; 280 #endif 281 crtn = genKeyPair(cspHand, 282 dlHand, 283 dbHand, 284 &labelData, 285 &pubKey, 286 CSSM_KEYUSE_VERIFY, // pubKeyUsage 287 pubAttr, 288 &privKey, 289 CSSM_KEYUSE_SIGN, 290 privAttr, 291 keyGenAlg); 292 if(crtn) { 293 return testError(quiet); 294 } 295 296 /* lookUpPub = lookup pub by label; */ 297 doLookup = CSSM_TRUE; 298 if(verbose) { 299 if(pubIsPerm) { 300 printf(" ...lookup pub by label\n"); 301 } 302 else { 303 if(doFailedLookup) { 304 printf(" ...lookup (nonexistent) pub by label\n"); 305 } 306 else { 307 doLookup = CSSM_FALSE; 308 lookUpPub = NULL; 309 } 310 } 311 } 312 if(doLookup) { 313 lookUpPub = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Public); 314 } 315 if(pubIsPerm) { 316 if(lookUpPub == NULL) { 317 printf("lookup pub by label failed\n"); 318 return testError(quiet); 319 } 320 321 /* sign some data with priv; */ 322 sig.Data = NULL; 323 sig.Length = 0; 324 if(doSignVerify) { 325 if(cspSign(cspHand, 326 sigAlg, 327 &privKey, 328 ptext, 329 &sig)) { 330 return testError(quiet); 331 } 332 } 333 /* verify header compare */ 334 if(memcmp(&lookUpPub->KeyHeader, &pubKey.KeyHeader, 335 sizeof(CSSM_KEYHEADER))) { 336 printf("**pubKey header miscompare\n"); 337 return testError(quiet); 338 } 339 340 /* vfy with lookUpPub; */ 341 if(doSignVerify) { 342 if(cspSigVerify(cspHand, 343 sigAlg, 344 lookUpPub, 345 ptext, 346 &sig, 347 CSSM_OK)) { 348 return testError(quiet); 349 } 350 351 CSSM_FREE(sig.Data); 352 sig.Data = NULL; 353 sig.Data = 0; 354 } 355 } 356 else { 357 if(doLookup && (lookUpPub != NULL)) { 358 printf("***Unexpected success on cspLookUpKeyByLabel(pub, not perm)\n"); 359 return testError(quiet); 360 } 361 } 362 363 /* 364 * Ensure proper behavior of extractable bit 365 */ 366 if(verbose) { 367 printf(" ...null wrap %s private key\n", 368 privIsExtractable ? "EXTRACTABLE" : "!EXTRACTABLE"); 369 } 370 crtn = cspNullWrapKey(cspHand, &privKey, &rawPrivKey); 371 if(privIsExtractable) { 372 if(crtn) { 373 printError("Null Wrap(extractable private key)", crtn); 374 return testError(quiet); 375 } 376 if(verbose) { 377 printf(" ...free rawPrivKey\n"); 378 } 379 cspFreeKey(cspHand, &rawPrivKey); 380 } 381 else { 382 if(crtn != CSSMERR_CSP_INVALID_KEYATTR_MASK) { 383 printError("Null Wrap of !extractable private key: expected " 384 "INVALID_KEYATTR_MASK, got", crtn); 385 if(crtn == CSSM_OK) { 386 cspFreeKey(cspHand, &rawPrivKey); 387 } 388 return testError(quiet); 389 } 390 } 391 /* lookUpPriv = lookup priv by label; ensure == privKey; */ 392 doLookup = CSSM_TRUE; 393 if(verbose) { 394 if(privIsPerm) { 395 printf(" ...lookup priv by label\n"); 396 } 397 else { 398 if(doFailedLookup) { 399 printf(" ...lookup (nonexistent) priv by label\n"); 400 } 401 else { 402 doLookup = CSSM_FALSE; 403 lookUpPriv = NULL; 404 } 405 } 406 } 407 if(doLookup) { 408 lookUpPriv = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Private); 409 } 410 if(privIsPerm) { 411 if(lookUpPriv == NULL) { 412 printf("lookup priv by label failed\n"); 413 return testError(quiet); 414 } 415 416 /* note we "know" that both keys are ref keys...*/ 417 if(lookUpPriv->KeyData.Length != privKey.KeyData.Length) { 418 printf("priv key data length mismatch\n"); 419 return testError(quiet); 420 } 421 #if DL_REF_KEYS_DIFFER 422 if(!memcmp(lookUpPriv->KeyData.Data, privKey.KeyData.Data, 423 privKey.KeyData.Length)) { 424 printf("priv key ref data mismatch\n"); 425 return testError(quiet); 426 } 427 #else /* DL_REF_KEYS_DIFFER */ 428 if(memcmp(lookUpPriv->KeyData.Data, privKey.KeyData.Data, 429 privKey.KeyData.Length)) { 430 printf("unexpected priv key ref data match\n"); 431 return testError(quiet); 432 } 433 #endif /* DL_REF_KEYS_DIFFER */ 434 435 /* verify header compare in any case */ 436 if(memcmp(&lookUpPriv->KeyHeader, &privKey.KeyHeader, 437 sizeof(CSSM_KEYHEADER))) { 438 printf("**privKey header miscompare\n"); 439 return testError(quiet); 440 } 441 442 /* sign with lookUpPriv, verify with pubKey */ 443 sig.Data = NULL; 444 sig.Length = 0; 445 if(doSignVerify) { 446 if(verbose) { 447 printf(" ...sign with lookup priv\n"); 448 } 449 if(cspSign(cspHand, 450 sigAlg, 451 lookUpPriv, 452 ptext, 453 &sig)) { 454 return testError(quiet); 455 } 456 if(verbose) { 457 printf(" ...verify with pub\n"); 458 } 459 if(cspSigVerify(cspHand, 460 sigAlg, 461 &pubKey, 462 ptext, 463 &sig, 464 CSSM_OK)) { 465 printf("***sign with lookUpPriv, vfy with pub FAILED\n"); 466 return testError(quiet); 467 } 468 CSSM_FREE(sig.Data); 469 sig.Data = NULL; 470 sig.Data = 0; 471 } 472 473 /* free lookUpPriv from cache, but it's permanent */ 474 if(verbose) { 475 printf(" ...free lookupPriv\n"); 476 } 477 if(cspFreeKey(cspHand, lookUpPriv)) { 478 printf("Error on cspFreeKey(lookUpPriv)\n"); 479 return testError(quiet); 480 } 481 CSSM_FREE(lookUpPriv); // mallocd during lookup 482 lookUpPriv = NULL; 483 484 #if DO_OBTAIN_FROM_PUB 485 /* obtainedPriv = obtainPubFromPriv(pub); ensure == priv; */ 486 if(verbose) { 487 printf(" ...ObtainPrivateKeyFromPublicKey\n"); 488 } 489 obtainedPriv.KeyData.Data = NULL; 490 obtainedPriv.KeyData.Length = 0; 491 crtn = CSSM_CSP_ObtainPrivateKeyFromPublicKey(cspHand, 492 lookUpPub, 493 &obtainedPriv); 494 if(crtn) { 495 printError("ObtainPrivateKeyFromPublicKey", crtn); 496 return testError(quiet); 497 } 498 499 /* free obtainedPriv from cache, but it's permanent */ 500 if(verbose) { 501 printf(" ...free obtainedPriv\n"); 502 } 503 if(cspFreeKey(cspHand, &obtainedPriv)) { 504 printf("Error on cspFreeKey(obtainedPriv)\n"); 505 return testError(quiet); 506 } 507 508 #endif /* DO_OBTAIN_FROM_PUB */ 509 510 if(!permKeys) { 511 /* delete priv - implies freeKey as well */ 512 if(verbose) { 513 printf(" ...delete privKey\n"); 514 } 515 crtn = cspDeleteKey(cspHand, dlHand, dbHand, &labelData, &privKey); 516 if(crtn) { 517 printf("Error deleting priv\n"); 518 return testError(quiet); 519 } 520 521 /* lookUpPriv = lookup priv by label; verify fail; */ 522 if(doFailedLookup) { 523 if(verbose) { 524 printf(" ...lookup (nonexistent) priv by label\n"); 525 } 526 lookUpPriv = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Private); 527 if(lookUpPriv != NULL) { 528 printf("Unexpected success on cspLookUpKeyByLabel(priv)\n"); 529 return testError(quiet); 530 } 531 } 532 else { 533 lookUpPriv = NULL; 534 } 535 } 536 } 537 else if(doLookup) { 538 /* !privIsPerm - just free it and it's all gone */ 539 if(lookUpPriv != NULL) { 540 printf("***Unexpected success on cspLookUpKeyByLabel(priv, not perm)\n"); 541 return testError(quiet); 542 } 543 if(verbose) { 544 printf(" ...free privKey\n"); 545 } 546 if(cspFreeKey(cspHand, &privKey)) { 547 printf("Error on cspFreeKey(privKey)\n"); 548 return testError(quiet); 549 } 550 } 551 /* CSP, DL have no knowledge of privKey or its variations */ 552 553 /* obtainedPriv = obtainPubFromPriv(pub); verify fail;*/ 554 /* Note this should be safe even if DO_OBTAIN_FROM_PUB == 0 */ 555 obtainedPriv.KeyData.Data = NULL; 556 obtainedPriv.KeyData.Length = 0; 557 if(verbose) { 558 printf(" ...obtain (nonexistent) priv by public\n"); 559 } 560 crtn = CSSM_CSP_ObtainPrivateKeyFromPublicKey(cspHand, 561 &pubKey, 562 &obtainedPriv); 563 switch(crtn) { 564 case CSSM_OK: 565 printf("Unexpected success on ObtainPrivateKeyFromPublicKey\n"); 566 return testError(quiet); 567 case CSSMERR_CSP_PRIVATE_KEY_NOT_FOUND: 568 break; 569 #if !CSPDL_OBTAIN_PRIV_FROM_PUB 570 case CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED: 571 /* OK */ 572 break; 573 #endif 574 default: 575 printf("Unexpected err ObtainPrivateKeyFromPublicKey\n"); 576 printError("got this", crtn); 577 return testError(quiet); 578 } 579 580 /* free one or both copies of pub as appropriate */ 581 if(verbose) { 582 printf(" ...free pubKey\n"); 583 } 584 crtn = cspFreeKey(cspHand, &pubKey); 585 if(crtn) { 586 printf("Error freeing pubKey\n"); 587 return testError(quiet); 588 } 589 if(pubIsPerm) { 590 if(verbose) { 591 printf(" ...free lookUpPub\n"); 592 } 593 crtn = cspFreeKey(cspHand, lookUpPub); 594 if(crtn) { 595 printf("Error freeing lookUpPub\n"); 596 return testError(quiet); 597 } 598 } 599 if(lookUpPub) { 600 CSSM_FREE(lookUpPub); // mallocd by lookup in any case 601 } 602 603 if(pubIsPerm) { 604 /* pub should still be there in DL */ 605 /* lookUpPub = lookup pub by label; verify OK; */ 606 if(verbose) { 607 printf(" ...lookup pub by label (2)\n"); 608 } 609 lookUpPub = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Public); 610 if(lookUpPub == NULL) { 611 printf("lookup pub by label (2) failed\n"); 612 return testError(quiet); 613 } 614 615 if(!permKeys) { 616 /* now really delete it */ 617 if(verbose) { 618 printf(" ...delete lookUpPub\n"); 619 } 620 crtn = cspDeleteKey(cspHand, dlHand, dbHand, &labelData, lookUpPub); 621 if(crtn) { 622 printf("Error deleting lookUpPub\n"); 623 return testError(quiet); 624 } 625 CSSM_FREE(lookUpPub); // mallocd by lookup 626 } 627 } 628 /* else freeKey should have removed all trace */ 629 630 if(!permKeys && doFailedLookup) { 631 /* lookUpPub = lookup pub by label; verify fail; */ 632 if(verbose) { 633 printf(" ...lookup (nonexistent) pub by label\n"); 634 } 635 lookUpPub = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Public); 636 if(lookUpPub != NULL) { 637 printf("Unexpected success on cspLookUpKeyByLabel(pub) (2)\n"); 638 return testError(quiet); 639 } 640 } 641 return 0; 642} 643 644int main(int argc, char **argv) 645{ 646 int arg; 647 char *argp; 648 unsigned loop; 649 CSSM_DATA ptext; 650 CSSM_CSP_HANDLE cspHand; 651 CSSM_DB_HANDLE dbHand; 652 CSSM_DL_HANDLE dlHand; 653 CSSM_BOOL pubIsPerm; 654 CSSM_BOOL privIsPerm; 655 CSSM_BOOL privIsExtractable; 656 uint32 keyGenAlg = CSSM_ALGID_FEE; 657 uint32 sigAlg = CSSM_ALGID_FEE_MD5; 658 int rtn = 0; 659 CSSM_RETURN crtn; 660 661 /* 662 * User-spec'd params 663 */ 664 unsigned loops = LOOPS_DEF; 665 CSSM_BOOL verbose = CSSM_FALSE; 666 CSSM_BOOL quiet = CSSM_FALSE; 667 CSSM_BOOL permKeys = CSSM_FALSE; 668 char dbName[100]; /* DB_NAME_pid */ 669 CSSM_BOOL useExistDb = CSSM_FALSE; 670 CSSM_BOOL doPause = CSSM_FALSE; 671 CSSM_BOOL doSignVerify = CSSM_TRUE; 672 CSSM_BOOL doFailedLookup = CSSM_TRUE; 673 CSSM_BOOL privAlwaysExtractable = CSSM_FALSE; 674 675 dbName[0] = '\0'; 676 677 for(arg=1; arg<argc; arg++) { 678 argp = argv[arg]; 679 switch(argp[0]) { 680 case 'l': 681 loops = atoi(&argp[2]); 682 break; 683 case 'v': 684 verbose = CSSM_TRUE; 685 break; 686 case 'q': 687 quiet = CSSM_TRUE; 688 break; 689 case 'p': 690 permKeys = CSSM_TRUE; 691 loops = 1; 692 break; 693 case 'r': 694 keyGenAlg = CSSM_ALGID_RSA; 695 sigAlg = CSSM_ALGID_MD5WithRSA; 696 break; 697 case 'k': 698 memmove(dbName, &argp[2], strlen(&argp[2]) + 1); 699 useExistDb = CSSM_TRUE; 700 break; 701 case 'P': 702 doPause = CSSM_TRUE; 703 break; 704 case 'n': 705 doSignVerify = CSSM_FALSE; 706 break; 707 case 'N': 708 doFailedLookup = CSSM_FALSE; 709 break; 710 case 'x': 711 privAlwaysExtractable = CSSM_TRUE; 712 break; 713 case 'h': 714 default: 715 usage(argv); 716 } 717 } 718 719 if(dbName[0] == '\0') { 720 sprintf(dbName, "%s_%d", DB_NAME, (int)getpid()); 721 } 722 723 ptext.Data = (uint8 *)CSSM_MALLOC(MAX_DATA_SIZE); 724 ptext.Length = MAX_DATA_SIZE; 725 /* data generated in test loop */ 726 if(ptext.Data == NULL) { 727 printf("Insufficient heap\n"); 728 exit(1); 729 } 730 731 testStartBanner("keyStore", argc, argv); 732 733 /* attach to CSP/DL */ 734 cspHand = cspDlDbStartup(CSSM_FALSE, NULL); 735 if(cspHand == 0) { 736 exit(1); 737 } 738 dlHand = dlStartup(); 739 if(dlHand == 0) { 740 exit(1); 741 } 742 if(useExistDb) { 743 /* this one may well require SecurityAgent UI */ 744 crtn = dbCreateOpen(dlHand, dbName, CSSM_FALSE, CSSM_FALSE, NULL, 745 &dbHand); 746 } 747 else { 748 /* hands-free test */ 749 crtn = dbCreateOpen(dlHand, dbName, CSSM_TRUE, CSSM_TRUE, dbName, 750 &dbHand); 751 } 752 if(crtn) { 753 exit(1); 754 } 755 for(loop=1; ; loop++) { 756 757 if(!quiet) { 758 printf("...loop %d\n", loop); 759 } 760 appGetRandomBytes(ptext.Data, ptext.Length); 761 762 if(permKeys) { 763 pubIsPerm = privIsPerm = CSSM_TRUE; 764 } 765 else { 766 #if CSPDL_ALL_KEYS_ARE_PERMANENT 767 pubIsPerm = CSSM_TRUE; 768 privIsPerm = CSSM_TRUE; 769 #else 770 771 /* mix up pubIsPerm, privIsPerm */ 772 pubIsPerm = (loop & 1) ? CSSM_TRUE : CSSM_FALSE; 773 privIsPerm = (loop & 2) ? CSSM_TRUE : CSSM_FALSE; 774 #if FORCE_PUB_PERMANENT 775 pubIsPerm = CSSM_TRUE; 776 #endif 777 #endif /* CSPDL_ALL_KEYS_ARE_PERMANENT */ 778 } 779 privIsExtractable = ((loop & 4) || privAlwaysExtractable) ? CSSM_TRUE : CSSM_FALSE; 780 if(doTest(cspHand, 781 dlHand, 782 dbHand, 783 pubIsPerm, 784 privIsPerm, 785 privIsExtractable, 786 permKeys, 787 doSignVerify, doFailedLookup, 788 &ptext, 789 verbose, 790 quiet, 791 keyGenAlg, 792 sigAlg)) { 793 rtn = 1; 794 break; 795 } 796 if(loops && (loop == loops)) { 797 break; 798 } 799 if(doPause) { 800 fpurge(stdin); 801 printf("CR to continue: "); 802 getchar(); 803 } 804 } 805 806 cspShutdown(cspHand, CSSM_FALSE); 807 /* FIXME - DB close? DL shutdown? */ 808 if((rtn == 0) && !quiet) { 809 printf("%s test complete\n", argv[0]); 810 } 811 if((rtn == 0) & !permKeys) { 812 /* be nice: if we ran OK delete the cruft DB we created */ 813 unlink(dbName); 814 } 815 return rtn; 816} 817