]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/miniWrap/miniWrap.c
Security-57740.31.2.tar.gz
[apple/security.git] / SecurityTests / cspxutils / miniWrap / miniWrap.c
1 /* Copyright (c) 1998,2003-2005 Apple Computer, Inc.
2 *
3 * miniWrap.c - simple key wrap/unwrap exerciser.
4 *
5 * Revision History
6 * ----------------
7 * 4 May 2000 Doug Mitchell
8 * Ported to X/CDSA2.
9 * 22 May 1998 Doug Mitchell at Apple
10 * Created.
11 */
12
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <time.h>
16 #include <string.h>
17 #include <Security/cssm.h>
18 #include "cspwrap.h"
19 #include "common.h"
20 #include "cspdlTesting.h"
21
22 /*
23 * Temporary hack to use CSSM_KEYBLOB_WRAPPED_FORMAT_{PKCS7,PKCS8}, which
24 * are no longer supported as of 7/28/00
25 */
26 #define PKCS8_FORMAT_ENABLE 1
27 #define PKCS7_FORMAT_ENABLE 0
28
29 #define ENCR_USAGE_NAME "noLabel"
30 #define ENCR_USAGE_NAME_LEN (strlen(ENCR_USAGE_NAME))
31 #define WRAP_USAGE_NAME "noWrapLabel"
32 #define WRAP_USAGE_NAME_LEN (strlen(WRAP_USAGE_NAME))
33 #define LOOPS_DEF 10
34 #define MAX_PTEXT_SIZE 1000
35 #define LOOP_PAUSE 10
36
37 /*
38 * A new restriction for X: when wrapping using an RSA key, you can't
39 * wrap a key which is bigger than the RSA key itself because the
40 * wrap (Encrypt) is a one-shot deal, unlike the OS9 CSP which
41 * handled multiple chunks. This only effectively restricts the
42 * use of an RSA key to wrap symmetric keys, which doesn't seem like
43 * an unreasonable restriction.
44 */
45 #define RSA_WRAP_RESTRICTION 1
46
47 /*
48 * Currently the CSP can use wrapping keys flagged exclusively for wrapping
49 * (CSSM_KEYUSE_{WRAP,UNWRAP} for the actual wrap sinceƊthe wrap/unwrap op is
50 * done with an encrypt/decrypt op. The WrapKey op doesn't even see the
51 * wrapping key - it's in the context we pass it. Thus for now wrap/unwrap
52 * keys have to be marked with CSSM_KEYUSE_ANY.
53 */
54 #define WRAP_USAGE_ANY 0
55
56 static void usage(char **argv)
57 {
58 printf("usage: %s [options]\n", argv[0]);
59 printf(" Options:\n");
60 printf(" f (only wrap RSA private key)\n");
61 printf(" d (only wrap DES key)\n");
62 printf(" S (do symmetric wrap only)\n");
63 printf(" a (do asymmetric wrap only)\n");
64 printf(" n (do null wrap only)\n");
65 printf(" m (dump malloc info)\n");
66 printf(" r (ref keys only)\n");
67 printf(" w (wrap only)\n");
68 printf(" e (export)\n");
69 printf(" q (quiet)\n");
70 printf(" k (force PKCS7/8)\n");
71 #if PKCS7_FORMAT_ENABLE || PKCS8_FORMAT_ENABLE
72 printf(" K (skip PKCS7/8) (pkcs normally enable)\n");
73 #else
74 printf(" K (allow PKCS7/8) (pkcs normally disabled)\n");
75 #endif /* PKCS_FORMAT_ENABLE */
76 printf(" D (CSP/DL; default = bare CSP)\n");
77 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
78 printf(" p(ause every %d loops)\n", LOOP_PAUSE);
79 printf(" h(elp)\n");
80 exit(1);
81 }
82
83 /* not all algs need this, pass it in anyway */
84 CSSM_DATA initVector = {8, (uint8 *)"someVect"};
85
86 /*
87 * local verbose wrap/unwrap functions.
88 */
89 /* wrap key function. */
90 static CSSM_RETURN wrapKey(CSSM_CSP_HANDLE cspHand,
91 const CSSM_KEY_PTR unwrappedKey, // must be ref
92 const CSSM_KEY_PTR wrappingKey,
93 CSSM_ALGORITHMS wrapAlg,
94 CSSM_ENCRYPT_MODE wrapMode,
95 CSSM_KEYBLOB_FORMAT wrapFormat, // NONE, PKCS7, PKCS8
96 CSSM_PADDING wrapPad,
97 CSSM_KEY_PTR wrappedKey) // RETURNED
98 {
99 CSSM_CC_HANDLE ccHand;
100 CSSM_RETURN crtn;
101 CSSM_RETURN crtn2;
102 #if WRAP_KEY_REQUIRES_CREDS
103 CSSM_ACCESS_CREDENTIALS creds;
104 #endif
105
106 #if 0
107 if(unwrappedKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
108 printf("Hey! you can only wrap a reference key!\n");
109 return CSSM_ERRCODE_INTERNAL_ERROR;
110 }
111 #endif
112 memset(wrappedKey, 0, sizeof(CSSM_KEY));
113 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
114 /* special case for NULL wrap - no wrapping key */
115 if((wrappingKey == NULL) ||
116 (wrappingKey->KeyHeader.KeyClass == CSSM_KEYCLASS_SESSION_KEY)) {
117 crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
118 wrapAlg,
119 wrapMode,
120 &creds, // accessCred
121 wrappingKey,
122 &initVector,
123 wrapPad, // Padding
124 NULL, // Reserved
125 &ccHand);
126 if(crtn) {
127 printError("cspWrapKey/CreateContext", crtn);
128 return CSSM_ERRCODE_INTERNAL_ERROR;
129 }
130 }
131 else {
132 crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
133 wrapAlg,
134 &creds, // passPhrase
135 wrappingKey,
136 wrapPad, // Padding
137 &ccHand);
138 if(crtn) {
139 printError("cspWrapKey/CreateContext", crtn);
140 return CSSM_ERRCODE_INTERNAL_ERROR;
141 }
142 /* CMS requires 8-byte IV */
143 crtn = AddContextAttribute(ccHand,
144 CSSM_ATTRIBUTE_INIT_VECTOR,
145 sizeof(CSSM_DATA),
146 CAT_Ptr,
147 &initVector,
148 0);
149 if(crtn) {
150 printError("CSSM_UpdateContextAttributes", crtn);
151 return crtn;
152 }
153 }
154 if(wrapFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) {
155 /* only add this attribute if it's not the default */
156 CSSM_CONTEXT_ATTRIBUTE attr;
157 attr.AttributeType = CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT;
158 attr.AttributeLength = sizeof(uint32);
159 attr.Attribute.Uint32 = wrapFormat;
160 crtn = CSSM_UpdateContextAttributes(
161 ccHand,
162 1,
163 &attr);
164 if(crtn) {
165 printError("CSSM_UpdateContextAttributes", crtn);
166 return crtn;
167 }
168 }
169 crtn = CSSM_WrapKey(ccHand,
170 #if WRAP_KEY_REQUIRES_CREDS
171 &creds,
172 #else
173 NULL, // AccessCred
174 #endif
175 unwrappedKey,
176 NULL, // DescriptiveData
177 wrappedKey);
178 if(crtn != CSSM_OK) {
179 printError("CSSM_WrapKey", crtn);
180 }
181 if((crtn2 = CSSM_DeleteContext(ccHand))) {
182 printError("CSSM_DeleteContext", crtn2);
183 }
184 return crtn;
185 }
186
187 /* unwrap key function. */
188 static CSSM_RETURN unwrapKey(CSSM_CSP_HANDLE cspHand,
189 const CSSM_KEY_PTR wrappedKey,
190 const CSSM_KEY_PTR unwrappingKey,
191 CSSM_ALGORITHMS unwrapAlg,
192 CSSM_ENCRYPT_MODE unwrapMode,
193 CSSM_PADDING unwrapPad,
194 CSSM_KEY_PTR unwrappedKey, // RETURNED
195 const unsigned char *keyLabel,
196 unsigned keyLabelLen)
197 {
198 CSSM_CC_HANDLE ccHand;
199 CSSM_RETURN crtn;
200 CSSM_RETURN crtn2;
201 CSSM_DATA labelData;
202 uint32 keyAttr;
203 CSSM_DATA descData = { 0, NULL };
204 CSSM_ACCESS_CREDENTIALS creds;
205
206 memset(unwrappedKey, 0, sizeof(CSSM_KEY));
207 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
208 if((unwrappingKey == NULL) ||
209 (unwrappingKey->KeyHeader.KeyClass == CSSM_KEYCLASS_SESSION_KEY)) {
210 crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
211 unwrapAlg,
212 unwrapMode,
213 &creds, // accessCreds
214 unwrappingKey,
215 &initVector,
216 unwrapPad, // Padding
217 0, // Reserved
218 &ccHand);
219 if(crtn) {
220 printError("cspUnwrapKey/CreateContext", crtn);
221 return CSSM_ERRCODE_INTERNAL_ERROR;
222 }
223 }
224 else {
225 crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
226 unwrapAlg,
227 &creds, // passPhrase,
228 unwrappingKey,
229 unwrapPad, // Padding
230 &ccHand);
231 if(crtn) {
232 printError("cspUnwrapKey/CreateContext", crtn);
233 return CSSM_ERRCODE_INTERNAL_ERROR;
234 }
235 /* CMS requires 8-byte IV */
236 crtn = AddContextAttribute(ccHand,
237 CSSM_ATTRIBUTE_INIT_VECTOR,
238 sizeof(CSSM_DATA),
239 CAT_Ptr,
240 &initVector,
241 0);
242 if(crtn) {
243 printError("CSSM_UpdateContextAttributes", crtn);
244 return crtn;
245 }
246 }
247 labelData.Data = (uint8 *)keyLabel;
248 labelData.Length = keyLabelLen;
249
250 /*
251 * New keyAttr - clear some old bits, make sure we ask for ref key
252 */
253 keyAttr = wrappedKey->KeyHeader.KeyAttr;
254 keyAttr &= ~(CSSM_KEYATTR_ALWAYS_SENSITIVE | CSSM_KEYATTR_NEVER_EXTRACTABLE);
255 keyAttr |= CSSM_KEYATTR_RETURN_REF;
256 crtn = CSSM_UnwrapKey(ccHand,
257 NULL, // PublicKey
258 wrappedKey,
259 CSSM_KEYUSE_ANY, // FIXME
260 keyAttr,
261 &labelData,
262 NULL, // CredAndAclEntry
263 unwrappedKey,
264 &descData); // required
265 if(crtn != CSSM_OK) {
266 printError("CSSM_UnwrapKey", crtn);
267 }
268 if((crtn2 = CSSM_DeleteContext(ccHand))) {
269 printError("CSSM_DeleteContext", crtn2);
270 }
271 return crtn;
272 }
273
274 #define UNWRAPPED_LABEL "unwrapped thing"
275 #define NULL_TEST 0
276 #if NULL_TEST
277
278 static int doTest(CSSM_CSP_HANDLE cspHand,
279 CSSM_KEY_PTR encrKey,
280 CSSM_KEY_PTR decrKey, // we wrap this one
281 CSSM_KEY_PTR wrappingKey, // ...using this key, NULL for null wrap
282 CSSM_KEY_PTR unwrappingKey,
283 CSSM_ALGORITHMS wrapAlg,
284 CSSM_ENCRYPT_MODE wrapMode,
285 CSSM_PADDING wrapPad,
286 CSSM_ALGORITHMS encrAlg,
287 CSSM_ENCRYPT_MODE encrMode,
288 CSSM_PADDING encrPad,
289 CSSM_BOOL wrapOnly,
290 uint32 maxPtextSize, // max size to encrypt
291 CSSM_BOOL quiet)
292 {
293 return 0;
294 }
295 #else /* NULL_TEST */
296 /*
297 * NULL Wrapping decrKey - a private key - only works for DEBUG CSPs.
298 * We'll always wrap decrKey, except for NULL wrap when
299 * NULL_WRAP_DECR_KEY is false.
300 */
301 #define NULL_WRAP_DECR_KEY 1
302
303 static int doTest(CSSM_CSP_HANDLE cspHand,
304 CSSM_KEY_PTR encrKey, // we wrap this one
305 CSSM_KEY_PTR decrKey, // ...or this one, depending on WRAP_DECR_KEY
306 CSSM_KEY_PTR wrappingKey, // ...using this key, NULL for null wrap
307 CSSM_KEY_PTR unwrappingKey,
308 CSSM_ALGORITHMS wrapAlg,
309 CSSM_ENCRYPT_MODE wrapMode,
310 CSSM_KEYBLOB_FORMAT wrapFormat, // NONE, PKCS7, PKCS8
311 CSSM_PADDING wrapPad,
312 CSSM_ALGORITHMS encrAlg,
313 CSSM_ENCRYPT_MODE encrMode,
314 CSSM_PADDING encrPad,
315 CSSM_BOOL wrapOnly,
316 uint32 maxPtextSize, // max size to encrypt
317 CSSM_BOOL quiet)
318 {
319 CSSM_DATA ptext;
320 CSSM_DATA ctext;
321 CSSM_DATA rptext;
322 CSSM_KEY wrappedKey;
323 CSSM_KEY unwrappedKey;
324 CSSM_RETURN crtn;
325 CSSM_KEY_PTR realEncrKey; // encrKey or &unwrappedKey
326 CSSM_KEY_PTR realDecrKey; // decrKey or &unwrappedKey
327
328 /* wrap decrKey or encrKey using wrappingKey ==> wrappedKey */
329 if((wrappingKey == NULL) && !NULL_WRAP_DECR_KEY) {
330 /* NULL wrap of pub key */
331 crtn = wrapKey(cspHand,
332 encrKey,
333 wrappingKey,
334 wrapAlg,
335 wrapMode,
336 wrapFormat,
337 wrapPad,
338 &wrappedKey);
339 realEncrKey = &unwrappedKey;
340 realDecrKey = decrKey;
341 }
342 else {
343 /* normal case, wrap priv key (may be NULL if NULL_WRAP_DECR_KEY) */
344 crtn = wrapKey(cspHand,
345 decrKey,
346 wrappingKey,
347 wrapAlg,
348 wrapMode,
349 wrapFormat,
350 wrapPad,
351 &wrappedKey);
352 realEncrKey = encrKey;
353 realDecrKey = &unwrappedKey;
354 }
355
356 if(crtn) {
357 return testError(quiet);
358 }
359 if((wrappingKey != NULL) && // skip for NULL wrap
360 (wrapFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE)) {
361 /* don't want default, verify we got what we want */
362 if(wrappedKey.KeyHeader.Format != wrapFormat) {
363 printf("wrapped key format mismatch: expect %u; got %u\n",
364 (unsigned)wrapFormat, (unsigned)wrappedKey.KeyHeader.Format);
365 if(testError(quiet)) {
366 return 1;
367 }
368 }
369 }
370 if(wrapOnly) {
371 cspFreeKey(cspHand, &wrappedKey);
372 goto done;
373 }
374 /* unwrap wrappedKey using unwrappingKey ==> unwrappedKey; */
375 crtn = unwrapKey(cspHand,
376 &wrappedKey,
377 unwrappingKey,
378 wrapAlg,
379 wrapMode,
380 wrapPad,
381 &unwrappedKey,
382 (uint8 *)UNWRAPPED_LABEL,
383 15);
384 if(crtn) {
385 return testError(quiet);
386 }
387
388 /* cook up ptext */
389 ptext.Data = (uint8 *)CSSM_MALLOC(maxPtextSize);
390 simpleGenData(&ptext, 1, maxPtextSize);
391 /* encrypt using realEncrKey ==> ctext */
392 ctext.Data = NULL;
393 ctext.Length = 0;
394 crtn = cspEncrypt(cspHand,
395 encrAlg,
396 encrMode,
397 encrPad,
398 realEncrKey,
399 NULL, // no 2nd key
400 0, // effectiveKeySize
401 0, // rounds
402 &initVector,
403 &ptext,
404 &ctext,
405 CSSM_TRUE); // mallocCtext
406 if(crtn) {
407 return testError(quiet);
408 }
409
410 /* decrypt ctext with realDecrKey ==> rptext; */
411 rptext.Data = NULL;
412 rptext.Length = 0;
413 crtn = cspDecrypt(cspHand,
414 encrAlg,
415 encrMode,
416 encrPad,
417 realDecrKey,
418 NULL, // no 2nd key
419 0, // effectiveKeySize
420 0, // rounds
421 &initVector,
422 &ctext,
423 &rptext,
424 CSSM_TRUE);
425 if(crtn) {
426 return testError(quiet);
427 }
428
429 /* compare ptext vs. rptext; */
430 if(ptext.Length != rptext.Length) {
431 printf("ptext length mismatch\n");
432 return testError(quiet);
433 }
434 if(memcmp(ptext.Data, rptext.Data, ptext.Length)) {
435 printf("***data miscompare\n");
436 return testError(quiet);
437 }
438 /* free resources */
439 cspFreeKey(cspHand, &wrappedKey);
440 cspFreeKey(cspHand, &unwrappedKey);
441 CSSM_FREE(ptext.Data);
442 CSSM_FREE(ctext.Data);
443 CSSM_FREE(rptext.Data);
444 done:
445 return 0;
446 }
447 #endif /* NULL_TEST */
448
449 int main(int argc, char **argv)
450 {
451 int arg;
452 char *argp;
453 int i;
454 CSSM_CSP_HANDLE cspHand;
455 CSSM_RETURN crtn;
456 CSSM_KEY origPub; // we generate if !desSubj
457 CSSM_KEY origPriv;
458 CSSM_KEY_PTR origSess; // we generate if desSubj
459 CSSM_KEY_PTR origEncrKey; // pts to origPub or origSess
460 CSSM_KEY_PTR origDecrKey; // pts to origPriv or origSess
461 CSSM_ALGORITHMS encrAlg;
462 CSSM_ENCRYPT_MODE encrMode;
463 CSSM_PADDING encrPad;
464 int rtn = 0;
465 CSSM_BOOL genRsaKey;
466 uint32 maxPtextSize;
467 CSSM_BOOL encrIsRef = CSSM_TRUE;
468 CSSM_BOOL decrIsRef = CSSM_TRUE;
469 CSSM_KEYBLOB_FORMAT wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE;
470 unsigned loop;
471
472 /* user-specified vars */
473 unsigned loops = LOOPS_DEF;
474 CSSM_BOOL pause = CSSM_FALSE;
475 CSSM_BOOL doSymmWrap = CSSM_TRUE;
476 CSSM_BOOL doAsymmWrap = CSSM_TRUE;
477 CSSM_BOOL doNullWrap = CSSM_TRUE;
478 CSSM_BOOL doSymmEncrOnly = CSSM_FALSE;
479 CSSM_BOOL doAsymmEncrOnly = CSSM_FALSE;
480 CSSM_BOOL wrapOnly = CSSM_FALSE;
481 CSSM_BOOL quiet = CSSM_FALSE;
482 CSSM_BOOL bareCsp = CSSM_TRUE;
483 CSSM_BOOL forcePkcs = CSSM_FALSE;
484 CSSM_BOOL refKeysOnly = CSSM_FALSE;
485 #if PKCS_FORMAT_ENABLE
486 CSSM_BOOL skipPkcs = CSSM_FALSE;
487 #else
488 CSSM_BOOL skipPkcs = CSSM_TRUE;
489 #endif
490
491 for(arg=1; arg<argc; arg++) {
492 argp = argv[arg];
493 switch(argp[0]) {
494 case 'S':
495 doAsymmWrap = CSSM_FALSE;
496 doNullWrap = CSSM_FALSE;
497 break;
498 case 'a':
499 doSymmWrap = CSSM_FALSE;
500 doNullWrap = CSSM_FALSE;
501 break;
502 case 'n':
503 doSymmWrap = CSSM_FALSE;
504 doAsymmWrap = CSSM_FALSE;
505 break;
506 case 'f':
507 doAsymmEncrOnly = CSSM_TRUE;
508 break;
509 case 'd': // symmetric encrypt only option
510 case 'e': // export option - avoids asymetric encrypt/decrypt
511 doSymmEncrOnly = CSSM_TRUE;
512 break;
513 case 'l':
514 loops = atoi(&argp[2]);
515 break;
516 case 'w':
517 wrapOnly = CSSM_TRUE;
518 break;
519 case 'p':
520 pause = CSSM_TRUE;
521 break;
522 case 'D':
523 bareCsp = CSSM_FALSE;
524 #if CSPDL_ALL_KEYS_ARE_REF
525 refKeysOnly = CSSM_TRUE;
526 #endif
527 break;
528 case 'k':
529 forcePkcs = CSSM_TRUE;
530 break;
531 case 'K':
532 #if PKCS7_FORMAT_ENABLE || PKCS8_FORMAT_ENABLE
533 skipPkcs = CSSM_TRUE;
534 #else
535 skipPkcs = CSSM_FALSE;
536 #endif
537 break;
538 case 'r':
539 refKeysOnly = CSSM_TRUE;
540 break;
541 case 'q':
542 quiet = CSSM_TRUE;
543 break;
544 default:
545 usage(argv);
546 }
547 }
548
549 #if 0
550 #if !PKCS_FORMAT_ENABLE
551 if(skipPkcs) {
552 if(doAsymmEncrOnly) {
553 printf("Asymmetric keys can only be wrapped via PKCS; aborting\n");
554 usage(argv);
555 }
556 else if(!doSymmWrap) {
557 printf("AsymmetricWrapping can only be done via PKCS; aborting\n");
558 usage(argv);
559 }
560 doSymmEncrOnly = CSSM_TRUE;
561 doSymmWrap = CSSM_TRUE;
562 doAsymmWrap = CSSM_FALSE;
563 }
564 #endif /* !PKCS_FORMAT_ENABLE */
565 #endif
566
567 cspHand = cspDlDbStartup(bareCsp, NULL);
568 if(cspHand == 0) {
569 exit(1);
570 }
571
572 printf("Starting miniWrap; args: ");
573 for(i=1; i<argc; i++) {
574 printf("%s ", argv[i]);
575 }
576 printf("\n");
577
578 for(loop=1; ; loop++) {
579 if((loop % LOOP_PAUSE) == 0) {
580 if(!quiet) {
581 printf("...loop %d\n", loop);
582 }
583 if(pause) {
584 fpurge(stdin);
585 printf("Hit CR to proceed: ");
586 getchar();
587 }
588 }
589
590 /* mix up ref and raw keys - with X, we can wrap a raw key */
591 if(!refKeysOnly) {
592 encrIsRef = (loop & 2) ? CSSM_TRUE : CSSM_FALSE;
593 decrIsRef = (loop & 4) ? CSSM_TRUE : CSSM_FALSE;
594 }
595
596 /* first generate key to be wrapped */
597 if(!doAsymmEncrOnly && (doSymmEncrOnly || ((loop & 1) == 0))) {
598 if(!quiet) {
599 printf("...wrapping DES key (%s)\n",
600 encrIsRef ? "ref" : "raw");
601 }
602 origSess = cspGenSymKey(cspHand,
603 CSSM_ALGID_DES,
604 ENCR_USAGE_NAME,
605 ENCR_USAGE_NAME_LEN,
606 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
607 CSP_KEY_SIZE_DEFAULT,
608 encrIsRef);
609 if(origSess == NULL) {
610 rtn = 1;
611 goto testDone;
612 }
613 origDecrKey = origEncrKey = origSess;
614 encrAlg = CSSM_ALGID_DES;
615 encrMode = CSSM_ALGMODE_CBCPadIV8;
616 encrPad = CSSM_PADDING_PKCS5;
617 maxPtextSize = MAX_PTEXT_SIZE; // i.e., unlimited
618 }
619 else {
620 origSess = NULL;
621 }
622 if(!doSymmEncrOnly && (doAsymmEncrOnly || ((loop & 1) == 1))) {
623 if(!quiet) {
624 printf("...wrapping RSA key (pub %s priv %s)\n",
625 (encrIsRef ? "ref" : "raw"),
626 (decrIsRef ? "ref" : "raw"));
627 }
628 crtn = cspGenKeyPair(cspHand,
629 CSSM_ALGID_RSA,
630 ENCR_USAGE_NAME,
631 ENCR_USAGE_NAME_LEN,
632 CSP_KEY_SIZE_DEFAULT,
633 &origPub,
634 encrIsRef, // pubIsRef
635 CSSM_KEYUSE_ENCRYPT,
636 CSSM_KEYBLOB_RAW_FORMAT_NONE,
637 &origPriv,
638 decrIsRef, // privIsRef
639 CSSM_KEYUSE_DECRYPT,
640 CSSM_KEYBLOB_RAW_FORMAT_NONE,
641 CSSM_FALSE); // genSeed
642 if(crtn) {
643 rtn = 1;
644 goto testDone;
645 }
646 origDecrKey = &origPriv;
647 origEncrKey = &origPub;
648 encrAlg = CSSM_ALGID_RSA;
649 encrMode = CSSM_ALGMODE_NONE;
650 encrPad = CSSM_PADDING_PKCS1;
651 genRsaKey = CSSM_TRUE;
652 maxPtextSize = origPriv.KeyHeader.LogicalKeySizeInBits / 8;
653 // a weird BSAFE requirement which is not documented
654 maxPtextSize -= 11;
655 }
656 else {
657 genRsaKey = CSSM_FALSE;
658 }
659
660 /* now the tests, symmetric and/or asymmetric wrapping */
661 if(doSymmWrap) {
662 CSSM_KEY_PTR wrapKey;
663 if(!quiet) {
664 printf(" ...Doing symmetric wrap\n");
665 }
666 wrapKey = cspGenSymKey(cspHand,
667 CSSM_ALGID_DES,
668 WRAP_USAGE_NAME,
669 WRAP_USAGE_NAME_LEN,
670 /* for now, wrapping keys have to have keyuse_any */
671 /* CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP, */
672 WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY :
673 CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP,
674 CSP_KEY_SIZE_DEFAULT,
675 CSSM_TRUE); // FIXME - try both
676 if(wrapKey == NULL) {
677 rtn = 1;
678 goto testDone;
679 }
680 if(forcePkcs) {
681 /* symmetric wrapping key ==> PKCS7 */
682 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7;
683 }
684 else {
685 /* default */
686 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE;
687 }
688 if(doTest(cspHand,
689 origEncrKey,
690 origDecrKey,
691 wrapKey,
692 wrapKey,
693 CSSM_ALGID_DES, // wrapAlg
694 CSSM_ALGMODE_CBCPadIV8, // wrapMode
695 wrapFormat,
696 CSSM_PADDING_PKCS5, // wrapPad
697 encrAlg,
698 encrMode,
699 encrPad,
700 wrapOnly,
701 maxPtextSize,
702 quiet)) {
703 rtn = 1;
704 goto testDone;
705 }
706 cspFreeKey(cspHand, wrapKey);
707 CSSM_FREE(wrapKey); // mallocd by cspGenSymKey
708 wrapKey = NULL;
709 }
710 if(doAsymmWrap &&
711 !(RSA_WRAP_RESTRICTION && (origEncrKey != origDecrKey))) {
712 /* skip wrapping asymmetric key with asymmetric key */
713 CSSM_KEY wrapPrivKey;
714 CSSM_KEY wrapPubKey;
715
716 if(!quiet) {
717 printf(" ...Doing asymmetric wrap\n");
718 }
719 crtn = cspGenKeyPair(cspHand,
720 CSSM_ALGID_RSA,
721 WRAP_USAGE_NAME,
722 WRAP_USAGE_NAME_LEN,
723 CSP_RSA_KEY_SIZE_DEFAULT,
724 &wrapPubKey,
725 CSSM_TRUE, // both are ref
726 WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_WRAP,
727 CSSM_KEYBLOB_RAW_FORMAT_NONE,
728 &wrapPrivKey,
729 CSSM_TRUE, // FIXME privIsRef
730 WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_UNWRAP,
731 CSSM_KEYBLOB_RAW_FORMAT_NONE,
732 CSSM_FALSE); // genSeed
733 if(crtn) {
734 rtn = 1;
735 goto testDone;
736 }
737 if(forcePkcs) {
738 /* asymmetric wrapping key ==> PKCS8 */
739 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8;
740 }
741 else {
742 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE;
743 }
744 if(doTest(cspHand,
745 origEncrKey,
746 origDecrKey,
747 &wrapPubKey,
748 &wrapPrivKey,
749 CSSM_ALGID_RSA, // wrapAlg
750 CSSM_ALGMODE_NONE, // wrapMode
751 wrapFormat,
752 CSSM_PADDING_PKCS1, // wrapPad
753 encrAlg,
754 encrMode,
755 encrPad,
756 wrapOnly,
757 maxPtextSize,
758 quiet)) {
759 rtn = 1;
760 goto testDone;
761 }
762 cspFreeKey(cspHand, &wrapPubKey);
763 cspFreeKey(cspHand, &wrapPrivKey);
764 }
765 //if(doNullWrap && (origDecrKey != origEncrKey)) {
766 if(doNullWrap) {
767 /* with X, we can do NULL wrap/unwrap of any key */
768 if(!quiet) {
769 printf(" ...Doing NULL wrap\n");
770 }
771 if(doTest(cspHand,
772 origEncrKey,
773 origDecrKey,
774 NULL,
775 NULL,
776 CSSM_ALGID_NONE, // wrapAlg
777 CSSM_ALGMODE_NONE, // wrapMode
778 CSSM_KEYBLOB_WRAPPED_FORMAT_NONE,
779 CSSM_PADDING_NONE, // wrapPad
780 encrAlg,
781 encrMode,
782 encrPad,
783 wrapOnly,
784 maxPtextSize,
785 quiet)) {
786 rtn = 1;
787 goto testDone;
788 }
789 }
790
791 if(origSess != NULL) {
792 cspFreeKey(cspHand, origSess);
793 CSSM_FREE(origSess);
794 }
795 if(genRsaKey) {
796 cspFreeKey(cspHand, &origPub);
797 cspFreeKey(cspHand, &origPriv);
798 }
799 if(loops && (loop == loops)) {
800 break;
801 }
802 }
803 testDone:
804 CSSM_ModuleDetach(cspHand);
805 if((rtn == 0) && !quiet) {
806 printf("%s test complete\n", argv[0]);
807 }
808 return rtn;
809 }