]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/badattr/badattr.c
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / cspxutils / badattr / badattr.c
1 /*
2 * badattr.c - verify proper rejection of bad key attribute bits
3 */
4
5 #ifdef pcode
6
7 partial description...
8
9 for each asymmetric alg {
10 gen pub key with KEYUSE_ENCRYPT
11 make sure you cannot use it for vfy or decrypt
12 make sure you cannot use it for encrypting with other alg
13 gen priv key with KEYUSE_DECRYPT
14 make sure you cannot use it for sign or decrypt
15 make sure you cannot use it for decrypting with other alg
16 gen priv key with KEYUSE_SIGN
17 make sure you cannot use it for encrypt or decrypt
18 gen pub with KEYUSE_VERIFY
19 make sure you cannot use it for encrypt or decrypt
20
21 }
22
23 #endif
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <time.h>
29 #include <Security/cssm.h>
30 #include <Security/cssmapple.h>
31 #include "cspwrap.h"
32 #include "common.h"
33 #include "cspdlTesting.h"
34 /*
35 * Enumerate algs our own way to allow iteration.
36 */
37 typedef unsigned privAlg;
38 enum {
39 ALG_ASC = 1,
40 ALG_DES,
41 ALG_RC2,
42 ALG_RC4,
43 ALG_RC5,
44 ALG_3DES,
45 ALG_AES,
46 ALG_RSA,
47 ALG_FEE,
48 ALG_ECDSA,
49 ALG_DSA
50 };
51
52 #define SYM_FIRST ALG_ASC
53 #define SYM_LAST ALG_AES
54 #define ASYM_FIRST ALG_RSA
55 #define ASYM_LAST ALG_ECDSA /* DSA if we're patient */
56
57 /*
58 * ops expressed at bitfields
59 */
60 #define OP_SIGN 0x0001
61 #define OP_VERIFY 0x0002
62 #define OP_ENCRYPT 0x0004
63 #define OP_DECRYPT 0x0008
64 #define OP_GENMAC 0x0010
65 #define OP_VFYMAC 0x0020
66
67 static void usage(char **argv)
68 {
69 printf("usage: %s [options]\n", argv[0]);
70 printf(" Options:\n");
71 printf(" s(ymmetric only)\n");
72 printf(" a(symmetric only)\n");
73 printf(" q(uiet)\n");
74 printf(" h(elp)\n");
75 exit(1);
76 }
77
78 /*
79 * Common, flexible, error-tolerant symmetric key generator.
80 */
81 static int genSymKey(
82 CSSM_CSP_HANDLE cspHand,
83 CSSM_KEY_PTR symKey,
84 uint32 alg,
85 const char *keyAlgStr,
86 uint32 keySizeInBits,
87 CSSM_KEYATTR_FLAGS keyAttr,
88 CSSM_KEYUSE keyUsage,
89 CSSM_RETURN expectRtn,
90 CSSM_BOOL quiet,
91 CSSM_BOOL freeKey, // true: free the key on exit
92 const char *testStr)
93 {
94 CSSM_RETURN crtn;
95 CSSM_CC_HANDLE ccHand;
96 CSSM_DATA dummyLabel = {4, (uint8 *)"foo"};
97 int irtn;
98
99 memset(symKey, 0, sizeof(CSSM_KEY));
100 crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
101 alg,
102 keySizeInBits, // keySizeInBits
103 NULL, // Seed
104 NULL, // Salt
105 NULL, // StartDate
106 NULL, // EndDate
107 NULL, // Params
108 &ccHand);
109 if(crtn) {
110 printError("CSSM_CSP_CreateKeyGenContext", crtn);
111 return testError(quiet);
112 }
113 crtn = CSSM_GenerateKey(ccHand,
114 keyUsage,
115 keyAttr,
116 &dummyLabel,
117 NULL, // ACL
118 symKey);
119 if(crtn != expectRtn) {
120 printf("***Testing %s for alg %s:\n", testStr, keyAlgStr);
121 printf(" CSSM_GenerateKey: expect %s\n", cssmErrToStr(expectRtn));
122 printf(" CSSM_GenerateKey: got %s\n", cssmErrToStr(crtn));
123 irtn = testError(quiet);
124 }
125 else {
126 irtn = 0;
127 }
128 CSSM_DeleteContext(ccHand);
129 if(freeKey && (crtn == CSSM_OK)) {
130 cspFreeKey(cspHand, symKey);
131 }
132 return irtn;
133 }
134
135 /*
136 * Common, flexible, error-tolerant key pair generator.
137 */
138 static int genKeyPair(
139 CSSM_CSP_HANDLE cspHand,
140 uint32 algorithm,
141 const char *keyAlgStr,
142 uint32 keySizeInBits,
143 CSSM_KEY_PTR pubKey,
144 CSSM_KEYATTR_FLAGS pubKeyAttr,
145 CSSM_KEYUSE pubKeyUsage,
146 CSSM_KEY_PTR privKey,
147 CSSM_KEYATTR_FLAGS privKeyAttr,
148 CSSM_KEYUSE privKeyUsage,
149 CSSM_RETURN expectRtn,
150 CSSM_BOOL quiet,
151 CSSM_BOOL freeKeys, // true: free the keys on exit
152 const char *testStr)
153 {
154 CSSM_RETURN crtn;
155 CSSM_CC_HANDLE ccHand;
156 CSSM_DATA keyLabelData = {4, (uint8 *)"foo"};
157 int irtn;
158
159 memset(pubKey, 0, sizeof(CSSM_KEY));
160 memset(privKey, 0, sizeof(CSSM_KEY));
161
162 crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
163 algorithm,
164 keySizeInBits,
165 NULL, // Seed
166 NULL, // Salt
167 NULL, // StartDate
168 NULL, // EndDate
169 NULL, // Params
170 &ccHand);
171 if(crtn) {
172 printError("CSSM_CSP_CreateKeyGenContext", crtn);
173 return testError(quiet);
174 }
175
176 /* post-context-create algorithm-specific stuff */
177 switch(algorithm) {
178 case CSSM_ALGID_RSA:
179 break;
180
181 case CSSM_ALGID_DSA:
182 /*
183 * extra step - generate params - this just adds some
184 * info to the context
185 */
186 {
187 CSSM_DATA dummy = {0, NULL};
188 crtn = CSSM_GenerateAlgorithmParams(ccHand,
189 keySizeInBits, &dummy);
190 if(crtn) {
191 printError("CSSM_GenerateAlgorithmParams", crtn);
192 return testError(quiet);
193 }
194 appFreeCssmData(&dummy, CSSM_FALSE);
195 }
196 break;
197 default:
198 break;
199 }
200
201 crtn = CSSM_GenerateKeyPair(ccHand,
202 pubKeyUsage,
203 pubKeyAttr,
204 &keyLabelData,
205 pubKey,
206 privKeyUsage,
207 privKeyAttr,
208 &keyLabelData, // same labels
209 NULL, // CredAndAclEntry
210 privKey);
211 if(crtn != expectRtn) {
212 printf("***Testing %s for alg %s:\n", testStr, keyAlgStr);
213 printf(" CSSM_GenerateKeyPair: expect %s\n", cssmErrToStr(expectRtn));
214 printf(" CSSM_GenerateKeyPair: got %s\n", cssmErrToStr(crtn));
215 irtn = testError(quiet);
216 }
217 else {
218 irtn = 0;
219 }
220 CSSM_DeleteContext(ccHand);
221 if(freeKeys && (crtn == CSSM_OK)) {
222 cspFreeKey(cspHand, pubKey);
223 cspFreeKey(cspHand, privKey);
224 }
225 return irtn;
226 }
227
228 /*
229 * Perform NULL wrap, generally expecting an error (either
230 * CSSMERR_CSP_INVALID_KEYATTR_MASK, if the raw key bits should be inaccessible,
231 * or CSSMERR_CSP_INVALID_KEY_REFERENCE, if the key's header has been munged.)
232 */
233 int nullWrapTest(
234 CSSM_CSP_HANDLE cspHand,
235 CSSM_KEY_PTR key,
236 CSSM_BOOL quiet,
237 CSSM_RETURN expectRtn,
238 const char *keyAlgStr,
239 const char *testStr)
240 {
241 CSSM_CC_HANDLE ccHand;
242 CSSM_RETURN crtn;
243 CSSM_ACCESS_CREDENTIALS creds;
244 CSSM_KEY wrappedKey; // should not get created
245 int irtn;
246
247 memset(&wrappedKey, 0, sizeof(CSSM_KEY));
248 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
249 crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
250 CSSM_ALGID_NONE,
251 CSSM_ALGMODE_NONE,
252 &creds, // passPhrase,
253 NULL, // wrappingKey,
254 NULL, // IV
255 CSSM_PADDING_NONE,
256 0, // Params
257 &ccHand);
258 if(crtn) {
259 printError("cspWrapKey/CreateContext", crtn);
260 return testError(quiet);
261 }
262 crtn = CSSM_WrapKey(ccHand,
263 &creds,
264 key,
265 NULL, // DescriptiveData
266 &wrappedKey);
267 if(crtn != expectRtn) {
268 printf("***Testing %s for alg %s:\n", testStr, keyAlgStr);
269 printf(" CSSM_WrapKey: expect %s\n", cssmErrToStr(expectRtn));
270 printf(" CSSM_WrapKey: got %s\n", cssmErrToStr(crtn));
271 irtn = testError(quiet);
272 }
273 else {
274 irtn = 0;
275 }
276 CSSM_DeleteContext(ccHand);
277 return irtn;
278 }
279
280 /*
281 * Attempt to wrap incoming key with a DES key that we generate. Expect
282 * CSSMERR_CSP_INVALID_KEYATTR_MASK since the unwrapped key is marked
283 * !EXTRACTABLE.
284 */
285 #define WRAPPING_KEY_ALG CSSM_ALGID_DES
286 #define WRAPPING_KEY_SIZE CSP_DES_KEY_SIZE_DEFAULT
287
288 static int badWrapTest(
289 CSSM_CSP_HANDLE cspHand,
290 CSSM_KEY_PTR unwrappedKey,
291 CSSM_KEYBLOB_FORMAT wrapForm,
292 CSSM_BOOL quiet,
293 const char *keyAlgStr,
294 const char *testStr)
295 {
296 CSSM_CC_HANDLE ccHand;
297 CSSM_RETURN crtn;
298 CSSM_ACCESS_CREDENTIALS creds;
299 CSSM_KEY wrappedKey; // should not get created
300 CSSM_KEY wrappingKey;
301 int irtn;
302
303 /* first generate a DES wrapping key */
304 if(genSymKey(cspHand, &wrappingKey, CSSM_ALGID_DES, "DES",
305 CSP_DES_KEY_SIZE_DEFAULT,
306 CSSM_KEYATTR_RETURN_REF,
307 CSSM_KEYUSE_ANY, CSSM_OK, quiet,
308 CSSM_FALSE, "not a test case")) {
309 return 1;
310 }
311
312 memset(&wrappedKey, 0, sizeof(CSSM_KEY));
313 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
314
315 /* symmetric wrapping context */
316 crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
317 CSSM_ALGID_DES,
318 CSSM_ALGMODE_CBCPadIV8,
319 &creds, // passPhrase,
320 &wrappingKey,
321 NULL, // IV
322 CSSM_PADDING_PKCS5,
323 0, // Params
324 &ccHand);
325 if(crtn) {
326 printError("cspWrapKey/CreateContext", crtn);
327 return testError(quiet);
328 }
329
330 /* do it, demand error */
331 crtn = CSSM_WrapKey(ccHand,
332 &creds,
333 unwrappedKey,
334 NULL, // DescriptiveData
335 &wrappedKey);
336 if(crtn != CSSMERR_CSP_INVALID_KEYATTR_MASK) {
337 printf("***Testing %s for alg %s:\n", testStr, keyAlgStr);
338 printf(" CSSM_WrapKey: expect CSSMERR_CSP_INVALID_KEYATTR_MASK, got %s\n",
339 cssmErrToStr(crtn));
340 irtn = testError(quiet);
341 }
342 else {
343 irtn = 0;
344 }
345 CSSM_DeleteContext(ccHand);
346 cspFreeKey(cspHand, &wrappingKey);
347 return irtn;
348 }
349
350
351 /*
352 * Note for these op stubs, the data, mode, padding, etc. are unimportant as
353 * the ops are expected to fail during key extraction.
354 */
355 static int badEncrypt(
356 CSSM_CSP_HANDLE cspHand,
357 CSSM_KEY_PTR key,
358 const char *keyAlgStr,
359 CSSM_ALGORITHMS opAlg,
360 CSSM_RETURN expectRtn,
361 CSSM_BOOL quiet,
362 const char *goodUseStr,
363 const char *badUseStr)
364 {
365 CSSM_CC_HANDLE cryptHand;
366 CSSM_DATA ptext = {4, (uint8 *)"foo"};
367 CSSM_DATA ctext = {0, NULL};
368 CSSM_DATA remData = {0, NULL};
369 CSSM_RETURN crtn;
370 CSSM_SIZE bytesEncrypted;
371 int irtn;
372
373 cryptHand = genCryptHandle(cspHand, opAlg, CSSM_ALGMODE_NONE, CSSM_PADDING_NONE,
374 key, NULL /* key2 */, NULL /* iv */, 0, 0);
375 if(cryptHand == 0) {
376 return testError(quiet);
377 }
378 crtn = CSSM_EncryptData(cryptHand, &ptext, 1, &ctext, 1, &bytesEncrypted, &remData);
379 if(crtn != expectRtn) {
380 printf("***Testing %s key w/%s during %s:\n", keyAlgStr, goodUseStr, badUseStr);
381 printf(" CSSM_EncryptData: expect %s\n", cssmErrToStr(expectRtn));
382 printf(" CSSM_EncryptData: got %s\n", cssmErrToStr(crtn));
383 irtn = testError(quiet);
384 }
385 else {
386 irtn = 0;
387 }
388 /* assume no ctext or remdata - OK? */
389 CSSM_DeleteContext(cryptHand);
390 return irtn;
391 }
392
393 static int badDecrypt(
394 CSSM_CSP_HANDLE cspHand,
395 CSSM_KEY_PTR key,
396 const char *keyAlgStr,
397 CSSM_ALGORITHMS opAlg,
398 CSSM_RETURN expectRtn,
399 CSSM_BOOL quiet,
400 const char *goodUseStr,
401 const char *badUseStr)
402 {
403 CSSM_CC_HANDLE cryptHand;
404 CSSM_DATA ctext = {4, (uint8 *)"foo"};
405 CSSM_DATA ptext = {0, NULL};
406 CSSM_DATA remData = {0, NULL};
407 CSSM_RETURN crtn;
408 CSSM_SIZE bytesDecrypted;
409 int irtn;
410
411
412 cryptHand = genCryptHandle(cspHand, opAlg, CSSM_ALGMODE_NONE, CSSM_PADDING_NONE,
413 key, NULL /* key2 */, NULL /* iv */, 0, 0);
414 if(cryptHand == 0) {
415 return testError(quiet);
416 }
417 crtn = CSSM_DecryptData(cryptHand, &ctext, 1, &ptext, 1, &bytesDecrypted, &remData);
418 if(crtn != expectRtn) {
419 printf("***Testing %s key w/%s during %s:\n", keyAlgStr, goodUseStr, badUseStr);
420 printf(" CSSM_DecryptData: expect %s\n", cssmErrToStr(expectRtn));
421 printf(" CSSM_DecryptData: got %s\n", cssmErrToStr(crtn));
422 irtn = testError(quiet);
423 }
424 else {
425 irtn = 0;
426 }
427 /* assume no ptext or remdata - OK? */
428 CSSM_DeleteContext(cryptHand);
429 return irtn;
430 }
431
432 /*
433 * Given a reference key (any class, any alg), attempt to perform null wrap after
434 * munging various fields in the header. Every attempt should result in
435 * CSSMERR_CSP_INVALID_KEY_REFERENCE.
436 */
437 static int badHdrTest(
438 CSSM_CSP_HANDLE cspHand,
439 CSSM_KEY_PTR key,
440 CSSM_BOOL quiet,
441 const char *keyAlgStr)
442 {
443 CSSM_KEYHEADER *hdr = &key->KeyHeader;
444 CSSM_KEYHEADER savedHdr = *hdr;
445
446 hdr->HeaderVersion++;
447 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
448 keyAlgStr, "Munged hdr(HeaderVersion)")) {
449 return 1;
450 }
451 *hdr = savedHdr;
452
453 hdr->CspId.Data1++;
454 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
455 keyAlgStr, "Munged hdr(CspId.Data1)")) {
456 return 1;
457 }
458 *hdr = savedHdr;
459
460 /* can't test BlobType for Format, they're known to differ */
461
462 hdr->AlgorithmId++;
463 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
464 keyAlgStr, "Munged hdr(AlgorithmId)")) {
465 return 1;
466 }
467 *hdr = savedHdr;
468
469 /* have to come up with valid KeyClass here */
470 switch(hdr->KeyClass) {
471 case CSSM_KEYCLASS_PUBLIC_KEY:
472 hdr->KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; break;
473 case CSSM_KEYCLASS_PRIVATE_KEY:
474 hdr->KeyClass = CSSM_KEYCLASS_SESSION_KEY; break;
475 case CSSM_KEYCLASS_SESSION_KEY:
476 hdr->KeyClass = CSSM_KEYCLASS_PUBLIC_KEY; break;
477 default:
478 printf("***BRZZAP! badHdrTest needs work\n");
479 exit(1);
480 }
481 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
482 keyAlgStr, "Munged hdr(KeyClass)")) {
483 return 1;
484 }
485 *hdr = savedHdr;
486
487 hdr->LogicalKeySizeInBits++;
488 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
489 keyAlgStr, "Munged hdr(LogicalKeySizeInBits)")) {
490 return 1;
491 }
492 *hdr = savedHdr;
493
494 hdr->KeyAttr++;
495 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
496 keyAlgStr, "Munged hdr(KeyAttr)")) {
497 return 1;
498 }
499 *hdr = savedHdr;
500
501 hdr->StartDate.Day[0]++;
502 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
503 keyAlgStr, "Munged hdr(StartDate.Day)")) {
504 return 1;
505 }
506 *hdr = savedHdr;
507
508 hdr->EndDate.Year[1]++;
509 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
510 keyAlgStr, "Munged hdr(EndDate.Year)")) {
511 return 1;
512 }
513 *hdr = savedHdr;
514
515 hdr->WrapAlgorithmId++;
516 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
517 keyAlgStr, "Munged hdr(WrapAlgorithmId)")) {
518 return 1;
519 }
520 *hdr = savedHdr;
521
522 hdr->WrapMode++;
523 if(nullWrapTest(cspHand, key, quiet, CSSMERR_CSP_INVALID_KEY_REFERENCE,
524 keyAlgStr, "Munged hdr(WrapMode)")) {
525 return 1;
526 }
527 *hdr = savedHdr;
528
529 return 0;
530 }
531
532 /*
533 * Given some op alg, return a different op alg which is of the same class
534 * but should not work with an opAlg-related key.
535 */
536 CSSM_ALGORITHMS badOpAlg(
537 CSSM_ALGORITHMS opAlg)
538 {
539 switch(opAlg) {
540 /* symmetric block ciphers */
541 case CSSM_ALGID_DES: return CSSM_ALGID_3DES_3KEY_EDE;
542 case CSSM_ALGID_3DES_3KEY_EDE: return CSSM_ALGID_RC2;
543 case CSSM_ALGID_RC2: return CSSM_ALGID_RC5;
544 case CSSM_ALGID_RC5: return CSSM_ALGID_AES;
545 case CSSM_ALGID_AES: return CSSM_ALGID_DES;
546
547 /* symmetric stream ciphers */
548 case CSSM_ALGID_ASC: return CSSM_ALGID_RC4;
549 case CSSM_ALGID_RC4: return CSSM_ALGID_ASC;
550
551 /* asymmetric ciphers */
552 case CSSM_ALGID_RSA: return CSSM_ALGID_FEEDEXP;
553 case CSSM_ALGID_FEEDEXP: return CSSM_ALGID_RSA;
554
555 /* digital signature */
556 case CSSM_ALGID_SHA1WithRSA: return CSSM_ALGID_SHA1WithDSA;
557 case CSSM_ALGID_SHA1WithDSA: return CSSM_ALGID_SHA1WithECDSA;
558 case CSSM_ALGID_SHA1WithECDSA: return CSSM_ALGID_SHA1WithRSA;
559
560 default: printf("***BRRZAP! badOpAlg needs work.\n"); exit(1);
561 }
562 /* NOT REACHED */
563 return 0;
564 }
565
566 /*
567 * -- Generate symmetric key with specified alg and usage;
568 * -- Verify that it can't be used for any of the ops specified
569 * in badOpFlags using goodEncrAlg/goodSignAlg;
570 * -- Verify that it can't be used for goodOp/badAlg;
571 *
572 * Used by symUsageTest().
573 *
574 */
575 #define SYM_USAGE_ENABLE 1
576
577 static int badSymUsage(
578 CSSM_CSP_HANDLE cspHand,
579 CSSM_ALGORITHMS keyAlg, // alg of the key
580 const char *keyAlgStr,
581 uint32 keySizeInBits,
582 CSSM_KEYUSE keyUse, // gen key with this usage
583 CSSM_ALGORITHMS goodEncrAlg, // key is good for this encryption alg
584 CSSM_ALGORITHMS goodSignAlg, // key is good for this sign alg (may not be used)
585 unsigned badOpFlags, // array of (OP_DECRYPT,...)
586 unsigned goodOp, // one good op...
587 CSSM_ALGORITHMS badAlg, // ..which fails for this alg
588 CSSM_BOOL quiet,
589 const char *useStr)
590 {
591 CSSM_KEY symKey;
592 int irtn;
593
594 if(genSymKey(cspHand, &symKey, keyAlg, keyAlgStr, keySizeInBits,
595 CSSM_KEYATTR_RETURN_REF, keyUse, CSSM_OK, quiet, CSSM_FALSE, useStr)) {
596 return 1;
597 }
598 #if SYM_USAGE_ENABLE
599 if(!quiet) {
600 printf(" ...testing key usage\n");
601 }
602 if(badOpFlags & OP_ENCRYPT) {
603 irtn = badEncrypt(cspHand, &symKey, keyAlgStr, goodEncrAlg,
604 CSSMERR_CSP_KEY_USAGE_INCORRECT, quiet, useStr, "ENCRYPT");
605 if(irtn) {
606 goto abort;
607 }
608 }
609 if(badOpFlags & OP_DECRYPT) {
610 irtn = badDecrypt(cspHand, &symKey, keyAlgStr, goodEncrAlg,
611 CSSMERR_CSP_KEY_USAGE_INCORRECT, quiet, useStr, "DECRYPT");
612 if(irtn) {
613 goto abort;
614 }
615 }
616 #endif /* SYM_USAGE_ENABLE */
617
618 /* now do a good op with an incorrect algorithm */
619 if(!quiet) {
620 printf(" ...testing key/algorithm match\n");
621 }
622 if(goodOp & OP_ENCRYPT) {
623 irtn = badEncrypt(cspHand, &symKey, keyAlgStr, badAlg,
624 CSSMERR_CSP_ALGID_MISMATCH, quiet, useStr, "ENCRYPT w/bad alg");
625 if(irtn) {
626 goto abort;
627 }
628 }
629 if(goodOp & OP_DECRYPT) {
630 irtn = badDecrypt(cspHand, &symKey, keyAlgStr, badAlg,
631 CSSMERR_CSP_ALGID_MISMATCH, quiet, useStr, "DECRYPT w/bad alg");
632 if(irtn) {
633 goto abort;
634 }
635 }
636 abort:
637 cspFreeKey(cspHand, &symKey);
638 return irtn;
639 }
640
641 /*
642 * Verify symmetric key usage behavior:
643 *
644 * gen key with KEYUSE_ENCRYPT
645 * make sure you can't use it for decrypt
646 * make sure you can't use it for encrypting with other alg
647 * gen key with KEYUSE_DECRYPT
648 * make sure you can't use it for encrypt
649 * make sure you can't use it for decrypting with other alg
650 * gen key with KEYUSE_SIGN (mac)
651 * make sure you can't use it for encrypt or decrypt
652 * gen key with KEYUSE_VERIFY (mac verify)
653 * make sure you can't use it for encrypt or decrypt
654 */
655 int symUsageTest(
656 CSSM_CSP_HANDLE cspHand,
657 CSSM_ALGORITHMS keyAlg,
658 const char *keyAlgStr,
659 CSSM_ALGORITHMS encrAlg,
660 CSSM_ALGORITHMS signAlg,
661 uint32 keySizeInBits,
662 CSSM_BOOL quiet)
663 {
664 if(!quiet) {
665 printf(" ...testing encrypt-enabled key\n");
666 }
667 if(badSymUsage(cspHand, keyAlg, keyAlgStr, keySizeInBits, CSSM_KEYUSE_ENCRYPT,
668 encrAlg, signAlg, OP_DECRYPT, OP_ENCRYPT, badOpAlg(encrAlg),
669 quiet, "ENCRYPT")) {
670 return 1;
671 }
672 if(!quiet) {
673 printf(" ...testing decrypt-enabled key\n");
674 }
675 if(badSymUsage(cspHand, keyAlg, keyAlgStr, keySizeInBits, CSSM_KEYUSE_DECRYPT,
676 encrAlg, signAlg, OP_ENCRYPT, OP_DECRYPT, badOpAlg(encrAlg),
677 quiet, "DECRYPT")) {
678 return 1;
679 }
680 return 0;
681 }
682
683 /*
684 * Verify symmetric key attribute behavior:
685 *
686 * check that you can not gen a key with {
687 * CSSM_KEYATTR_ALWAYS_SENSITIVE
688 * CSSM_KEYATTR_NEVER_EXTRACTABLE
689 * CSSM_KEYATTR_PERMANENT
690 * CSSM_KEYATTR_PRIVATE
691 * CSSM_KEYATTR_RETURN_DATA | !CSSM_KEYATTR_EXTRACTABLE
692 * CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_SENSITIVE
693 * CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_RETURN_REF
694 * }
695 */
696 int symAttrTest(
697 CSSM_CSP_HANDLE cspHand,
698 CSSM_ALGORITHMS alg,
699 const char *keyAlgStr,
700 uint32 keySizeInBits,
701 CSSM_BOOL bareCsp,
702 CSSM_BOOL quiet)
703 {
704 CSSM_KEY key;
705
706 if(!quiet) {
707 printf(" ...testing key attr\n");
708 }
709 if(bareCsp || CSPDL_ALWAYS_SENSITIVE_CHECK) {
710 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
711 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_ALWAYS_SENSITIVE,
712 CSSM_KEYUSE_ANY, CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
713 CSSM_TRUE, "ALWAYS_SENSITIVE")) {
714 return 1;
715 }
716 }
717 if(bareCsp || CSPDL_NEVER_EXTRACTABLE_CHECK) {
718 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
719 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_NEVER_EXTRACTABLE,
720 CSSM_KEYUSE_ANY, CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
721 CSSM_TRUE, "NEVER_EXTRACTABLE")) {
722 return 1;
723 }
724 }
725 /*
726 * bare CSP : CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK
727 * CSPDL : CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE
728 */
729 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
730 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT,
731 CSSM_KEYUSE_ANY,
732 bareCsp ? CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK :
733 CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE,
734 quiet,
735 CSSM_TRUE, "PERMANENT")) {
736 return 1;
737 }
738 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
739 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PRIVATE,
740 CSSM_KEYUSE_ANY, CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK, quiet,
741 CSSM_TRUE, "PRIVATE")) {
742 return 1;
743 }
744 if(bareCsp) {
745 /* CSPDL doesn't support RETURN_DATA */
746 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
747 CSSM_KEYATTR_RETURN_DATA /* and !extractable */,
748 CSSM_KEYUSE_ANY,
749 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
750 CSSM_TRUE, "RETURN_DATA | !EXTRACTABLE")) {
751 return 1;
752 }
753 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
754 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_SENSITIVE,
755 CSSM_KEYUSE_ANY, CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
756 CSSM_TRUE, "RETURN_DATA | SENSITIVE")) {
757 return 1;
758 }
759 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
760 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_RETURN_REF,
761 CSSM_KEYUSE_ANY, CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
762 CSSM_TRUE, "RETURN_DATA | RETURN_REF")) {
763 return 1;
764 }
765 }
766 return 0;
767 }
768
769 /*
770 * Verify proper symmetric key null wrap operation.
771 *
772 * gen ref key, CSSM_KEYATTR_SENSITIVE, vfy you can't do null wrap;
773 * gen ref key, !CSSM_KEYATTR_EXTRACTABLE, vfy you can't do null wrap;
774 */
775 int symNullWrapTest(
776 CSSM_CSP_HANDLE cspHand,
777 CSSM_ALGORITHMS alg,
778 const char *keyAlgStr,
779 uint32 keySizeInBits,
780 CSSM_BOOL quiet)
781 {
782 CSSM_KEY key;
783
784 if(!quiet) {
785 printf(" ...testing access to inaccessible key bits via NULL wrap\n");
786 }
787
788 /* gen ref key, CSSM_KEYATTR_SENSITIVE, vfy you can't do null wrap */
789 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
790 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE,
791 CSSM_KEYUSE_ANY, CSSM_OK, quiet,
792 CSSM_FALSE, "SENSITIVE | RETURN_REF")) {
793 return 1;
794 }
795 if(nullWrapTest(cspHand, &key, quiet, CSSMERR_CSP_INVALID_KEYATTR_MASK,
796 keyAlgStr, "KEYATTR_SENSITIVE")) {
797 return 1;
798 }
799 cspFreeKey(cspHand, &key);
800
801 /* gen ref key, !CSSM_KEYATTR_EXTRACTABLE, vfy you can't do null wrap */
802 if(genSymKey(cspHand, &key, alg, keyAlgStr, keySizeInBits,
803 CSSM_KEYATTR_RETURN_REF /* !CSSM_KEYATTR_EXTRACTABLE */,
804 CSSM_KEYUSE_ANY, CSSM_OK, quiet,
805 CSSM_FALSE, "!EXTRACTABLE | RETURN_REF")) {
806 return 1;
807 }
808 if(nullWrapTest(cspHand, &key, quiet, CSSMERR_CSP_INVALID_KEYATTR_MASK,
809 keyAlgStr, "!EXTRACTABLE")) {
810 return 1;
811 }
812 cspFreeKey(cspHand, &key);
813
814 return 0;
815 }
816
817 /*
818 * Verify proper symmetric key wrap !EXTRACTABLE handling.
819 *
820 * Gen unwrapped ref key, !CSSM_KEYATTR_EXTRACTABLE;
821 * Gen wrapping key - a simple DES key;
822 * vfy you can't wrap unwrappedKey with wrappingKey;
823 */
824 int symBadWrapTest(
825 CSSM_CSP_HANDLE cspHand,
826 CSSM_ALGORITHMS alg,
827 const char *keyAlgStr,
828 uint32 keySizeInBits,
829 CSSM_BOOL quiet)
830 {
831 CSSM_KEY unwrappedKey;
832
833 if(!quiet) {
834 printf(" ...testing access to !EXTRACTABLE key bits via PKCS7 wrap\n");
835 }
836
837 /* gen ref key, CSSM_KEYATTR_SENSITIVE, !EXTRACTABLE */
838 if(genSymKey(cspHand, &unwrappedKey, alg, keyAlgStr, keySizeInBits,
839 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE,
840 CSSM_KEYUSE_ANY, CSSM_OK, quiet,
841 CSSM_FALSE, "SENSITIVE | RETURN_REF")) {
842 return 1;
843 }
844 if(badWrapTest(cspHand,
845 &unwrappedKey,
846 CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7,
847 quiet, keyAlgStr,
848 "!EXTRACTABLE wrap")) {
849 return 1;
850 }
851 cspFreeKey(cspHand, &unwrappedKey);
852 return 0;
853 }
854
855 /*
856 * Verify proper asymmetric key wrap !EXTRACTABLE handling.
857 *
858 * Gen unwrapped ref key, !CSSM_KEYATTR_EXTRACTABLE;
859 * Gen wrapping key - a simple DES key;
860 * vfy you can't wrap unwrappedKey with wrappingKey;
861 */
862 int asymBadWrapTest(
863 CSSM_CSP_HANDLE cspHand,
864 CSSM_ALGORITHMS alg,
865 const char *keyAlgStr,
866 uint32 keySizeInBits,
867 CSSM_BOOL quiet)
868 {
869 CSSM_KEY pubKey;
870 CSSM_KEY privKey;
871
872 if(!quiet) {
873 printf(" ...testing access to !EXTRACTABLE key bits via CUSTOM wrap\n");
874 }
875
876 /* gen ref key, CSSM_KEYATTR_SENSITIVE, !EXTRACTABLE */
877 if(genKeyPair(cspHand, alg, keyAlgStr, keySizeInBits,
878 &pubKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE,
879 CSSM_KEYUSE_ANY,
880 &privKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE,
881 CSSM_KEYUSE_ANY,
882 CSSM_OK, quiet, CSSM_FALSE, "RETURN_REF | SENSITIVE")) {
883 return 1;
884 }
885 if(badWrapTest(cspHand,
886 &privKey,
887 CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM,
888 quiet, keyAlgStr,
889 "!EXTRACTABLE wrap")) {
890 return 1;
891 }
892 cspFreeKey(cspHand, &privKey);
893 cspFreeKey(cspHand, &pubKey);
894 return 0;
895 }
896
897 /*
898 * Generate a ref key, munge various fields in the header, verify that attempts
899 * to use the munged key result in CSSMERR_CSP_INVALID_KEY_REFERENCE.
900 */
901 int symHeaderTest(
902 CSSM_CSP_HANDLE cspHand,
903 CSSM_ALGORITHMS keyAlg,
904 const char *keyAlgStr,
905 CSSM_ALGORITHMS encrAlg,
906 CSSM_ALGORITHMS signAlg,
907 uint32 keySizeInBits,
908 CSSM_BOOL quiet)
909 {
910 CSSM_KEY key;
911
912 if(!quiet) {
913 printf(" ...testing munged ref key header\n");
914 }
915 if(genSymKey(cspHand, &key, keyAlg, keyAlgStr, keySizeInBits,
916 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE,
917 CSSM_KEYUSE_ANY, CSSM_OK, quiet,
918 CSSM_FALSE, "RETURN_REF")) {
919 return 1;
920 }
921 if(badHdrTest(cspHand, &key, quiet, keyAlgStr)) {
922 return 1;
923 }
924 cspFreeKey(cspHand, &key);
925 return 0;
926 }
927
928 /*
929 * Generate key pair, specified pub key attr and expected result, standard
930 * "good" priv key attr. Used by asymAttrTest().
931 */
932 static int pubKeyAttrTest(
933 CSSM_CSP_HANDLE cspHand,
934 CSSM_ALGORITHMS alg,
935 const char *keyAlgStr,
936 uint32 keySizeInBits,
937 CSSM_KEYATTR_FLAGS pubKeyAttr,
938 CSSM_RETURN expectRtn,
939 CSSM_BOOL quiet,
940 const char *testStr)
941 {
942 CSSM_KEY pubKey;
943 CSSM_KEY privKey;
944
945 return genKeyPair(cspHand, alg, keyAlgStr, keySizeInBits,
946 &pubKey, pubKeyAttr, CSSM_KEYUSE_ANY,
947 &privKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE, CSSM_KEYUSE_ANY,
948 expectRtn, quiet, CSSM_TRUE, testStr);
949 }
950
951 /*
952 * Generate key pair, specified priv key attr and expected result, standard
953 * "good" pub key attr. Used by asymAttrTest().
954 */
955 static int privKeyAttrTest(
956 CSSM_CSP_HANDLE cspHand,
957 CSSM_ALGORITHMS alg,
958 const char *keyAlgStr,
959 uint32 keySizeInBits,
960 CSSM_KEYATTR_FLAGS privKeyAttr,
961 CSSM_RETURN expectRtn,
962 CSSM_BOOL quiet,
963 const char *testStr)
964 {
965 CSSM_KEY pubKey;
966 CSSM_KEY privKey;
967
968 return genKeyPair(cspHand, alg, keyAlgStr, keySizeInBits,
969 &pubKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE,
970 CSSM_KEYUSE_ANY,
971 &privKey, privKeyAttr, CSSM_KEYUSE_ANY,
972 expectRtn, quiet, CSSM_TRUE, testStr);
973 }
974
975 /*
976 * Verify asymmetric key attribute behavior.
977 *
978 * check that you can't gen pub key with {
979 * CSSM_KEYATTR_ALWAYS_SENSITIVE
980 * CSSM_KEYATTR_NEVER_EXTRACTABLE
981 * CSSM_KEYATTR_PERMANENT
982 * CSSM_KEYATTR_PRIVATE
983 * CSSM_KEYATTR_RETURN_DATA | !CSSM_KEYATTR_EXTRACTABLE
984 * CSSM_KEYATTR_RETURN_REF | !CSSM_KEYATTR_EXTRACTABLE
985 * CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_SENSITIVE
986 * CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE
987 * }
988 * check that you can't gen priv key with {
989 * CSSM_KEYATTR_ALWAYS_SENSITIVE
990 * CSSM_KEYATTR_NEVER_EXTRACTABLE
991 * CSSM_KEYATTR_PERMANENT
992 * CSSM_KEYATTR_PRIVATE
993 * CSSM_KEYATTR_RETURN_DATA | !CSSM_KEYATTR_EXTRACTABLE
994 * CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_SENSITIVE
995 * }
996 */
997 static int asymAttrTest(
998 CSSM_CSP_HANDLE cspHand,
999 CSSM_ALGORITHMS alg,
1000 const char *keyAlgStr,
1001 uint32 keySizeInBits,
1002 CSSM_BOOL bareCsp,
1003 CSSM_BOOL quiet)
1004 {
1005 #if CSPDL_ALL_KEYS_ARE_PERMANENT
1006 printf(" ...SKIPING asymAttrTest due to Radar 3732910\n");
1007 return 0;
1008 #endif
1009 if(!quiet) {
1010 printf(" ...testing key attr\n");
1011 }
1012 if(bareCsp || CSPDL_ALWAYS_SENSITIVE_CHECK) {
1013 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1014 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_ALWAYS_SENSITIVE,
1015 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet, "ALWAYS_SENSITIVE pub")) {
1016 return 1;
1017 }
1018 }
1019 if(bareCsp || CSPDL_NEVER_EXTRACTABLE_CHECK) {
1020 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1021 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_NEVER_EXTRACTABLE,
1022 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet, "NEVER_EXTRACTABLE pub")) {
1023 return 1;
1024 }
1025 }
1026 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1027 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT |
1028 CSSM_KEYATTR_EXTRACTABLE,
1029 bareCsp ?
1030 /* bare CSP - permanent is checked first, this is the error */
1031 CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK :
1032 /* CSPDL - SS strips off permanent, then does key gen (so we'd
1033 * better specify EXTRACTABLE!), *then* checks for DLDB. */
1034 CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE,
1035 quiet, "PERMANENT pub")) {
1036 return 1;
1037 }
1038 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1039 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PRIVATE |
1040 CSSM_KEYATTR_EXTRACTABLE,
1041 CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK, quiet, "PRIVATE pub")) {
1042 return 1;
1043 }
1044 if(bareCsp) {
1045 /* CSPDL doesn't support RETURN_DATA */
1046 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1047 CSSM_KEYATTR_RETURN_DATA /* | !CSSM_KEYATTR_EXTRACTABLE */,
1048 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
1049 "RETURN_DATA | !EXTRACTABLE pub")) {
1050 return 1;
1051 }
1052 }
1053 /* pub key should always be extractable */
1054 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1055 CSSM_KEYATTR_RETURN_REF /* | !CSSM_KEYATTR_EXTRACTABLE */,
1056 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
1057 "RETURN_REF | !EXTRACTABLE pub")) {
1058 return 1;
1059 }
1060 /* pub keys can't be sensitive */
1061 if(bareCsp) {
1062 /* CSPDL doesn't support RETURN_DATA */
1063 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1064 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_SENSITIVE,
1065 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet, "RETURN_DATA | SENSITIVE pub")) {
1066 return 1;
1067 }
1068 }
1069 if(pubKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1070 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE,
1071 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet, "RETURN_REF | !SENSITIVE pub")) {
1072 return 1;
1073 }
1074
1075 /* priv key attr tests */
1076 if(bareCsp || CSPDL_ALWAYS_SENSITIVE_CHECK) {
1077 if(privKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1078 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_ALWAYS_SENSITIVE,
1079 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet, "ALWAYS_SENSITIVE priv")) {
1080 return 1;
1081 }
1082 }
1083 if(bareCsp || CSPDL_NEVER_EXTRACTABLE_CHECK) {
1084 if(privKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1085 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_NEVER_EXTRACTABLE,
1086 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet, "NEVER_EXTRACTABLE priv")) {
1087 return 1;
1088 }
1089 }
1090 if(privKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1091 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT,
1092 bareCsp ? CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK :
1093 CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE,
1094 quiet, "PERMANENT priv")) {
1095 return 1;
1096 }
1097 if(privKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1098 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PRIVATE,
1099 CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK, quiet, "PRIVATE priv")) {
1100 return 1;
1101 }
1102 if(bareCsp) {
1103 /* CSPDL doesn't support RETURN_DATA */
1104 if(privKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1105 CSSM_KEYATTR_RETURN_DATA /* | CSSM_KEYATTR_EXTRACTABLE */,
1106 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet,
1107 "RETURN_DATA | !EXTRACTABLE priv")) {
1108 return 1;
1109 }
1110 if(privKeyAttrTest(cspHand, alg, keyAlgStr, keySizeInBits,
1111 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_SENSITIVE,
1112 CSSMERR_CSP_INVALID_KEYATTR_MASK, quiet, "RETURN_DATA | SENSITIVE priv")) {
1113 return 1;
1114 }
1115 }
1116 return 0;
1117 }
1118
1119 /*
1120 * Verify asymmetric key null wrap behavior:
1121 * gen ref key, CSSM_KEYATTR_SENSITIVE, vfy you can't do null wrap;
1122 * gen ref key, !CSSM_KEYATTR_EXTRACTABLE, vfy you can't do null wrap;
1123 */
1124 static int asymNullWrapTest(
1125 CSSM_CSP_HANDLE cspHand,
1126 CSSM_ALGORITHMS alg,
1127 const char *keyAlgStr,
1128 uint32 keySizeInBits,
1129 CSSM_BOOL quiet)
1130 {
1131 CSSM_KEY pubKey;
1132 CSSM_KEY privKey;
1133
1134 if(!quiet) {
1135 printf(" ...testing access to inaccessible key bits via NULL wrap\n");
1136 }
1137 /* gen priv ref key, CSSM_KEYATTR_SENSITIVE, vfy you can't do null wrap */
1138 if(genKeyPair(cspHand, alg, keyAlgStr, keySizeInBits,
1139 &pubKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE,
1140 CSSM_KEYUSE_ANY,
1141 &privKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE,
1142 CSSM_KEYUSE_ANY,
1143 CSSM_OK, quiet, CSSM_FALSE, "RETURN_REF | SENSITIVE")) {
1144 return 1;
1145 }
1146 if(nullWrapTest(cspHand, &privKey, quiet, CSSMERR_CSP_INVALID_KEYATTR_MASK,
1147 keyAlgStr, "SENSITIVE")) {
1148 return 1;
1149 }
1150 cspFreeKey(cspHand, &privKey);
1151 cspFreeKey(cspHand, &pubKey);
1152
1153 /* gen priv ref key, !CSSM_KEYATTR_EXTRACTABLE, vfy you can't do null wrap */
1154 if(genKeyPair(cspHand, alg, keyAlgStr, keySizeInBits,
1155 &pubKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE,
1156 CSSM_KEYUSE_ANY,
1157 &privKey, CSSM_KEYATTR_RETURN_REF /* | !EXTRACTABLE */, CSSM_KEYUSE_ANY,
1158 CSSM_OK, quiet, CSSM_FALSE, "RETURN_REF | !EXTRACTABLE")) {
1159 return 1;
1160 }
1161 if(nullWrapTest(cspHand, &privKey, quiet, CSSMERR_CSP_INVALID_KEYATTR_MASK,
1162 keyAlgStr, "!EXTRACTABLE")) {
1163 return 1;
1164 }
1165 cspFreeKey(cspHand, &privKey);
1166 cspFreeKey(cspHand, &pubKey);
1167 return 0;
1168 }
1169
1170 /*
1171 * Generate public and private ref keys, munge various fields in the header,
1172 * verify that attempts to use the munged key result in
1173 * CSSMERR_CSP_INVALID_KEY_REFERENCE.
1174 */
1175 int asymHeaderTest(
1176 CSSM_CSP_HANDLE cspHand,
1177 CSSM_ALGORITHMS keyAlg,
1178 const char *keyAlgStr,
1179 CSSM_ALGORITHMS encrAlg,
1180 CSSM_ALGORITHMS signAlg,
1181 uint32 keySizeInBits,
1182 CSSM_BOOL quiet)
1183 {
1184 CSSM_KEY privKey;
1185 CSSM_KEY pubKey;
1186
1187 if(!quiet) {
1188 printf(" ...testing munged ref key header\n");
1189 }
1190 if(genKeyPair(cspHand, keyAlg, keyAlgStr, keySizeInBits,
1191 &pubKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE,
1192 CSSM_KEYUSE_ANY,
1193 &privKey, CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE,
1194 CSSM_KEYUSE_ANY,
1195 CSSM_OK, quiet, CSSM_FALSE, "RETURN_REF")) {
1196 return 1;
1197 }
1198 if(badHdrTest(cspHand, &privKey, quiet, keyAlgStr)) {
1199 return 1;
1200 }
1201 if(badHdrTest(cspHand, &pubKey, quiet, keyAlgStr)) {
1202 return 1;
1203 }
1204 cspFreeKey(cspHand, &privKey);
1205 cspFreeKey(cspHand, &pubKey);
1206 return 0;
1207 }
1208
1209 /* map one of our private privAlgs (ALG_DES, etc.) to associated CSSM info. */
1210 void privAlgToCssm(
1211 privAlg palg,
1212 CSSM_ALGORITHMS *keyAlg,
1213 CSSM_ALGORITHMS *signAlg, // CSSM_ALGID_NONE means incapable (e.g., DES)
1214 CSSM_ALGORITHMS *encrAlg, // CSSM_ALGID_NONE means incapable (e.g., DSA)
1215 uint32 *keySizeInBits,
1216 const char **keyAlgStr)
1217 {
1218 *signAlg = *encrAlg = CSSM_ALGID_NONE; // default
1219 switch(palg) {
1220 case ALG_ASC:
1221 *encrAlg = *keyAlg = CSSM_ALGID_ASC;
1222 *keySizeInBits = CSP_ASC_KEY_SIZE_DEFAULT;
1223 *keyAlgStr = "ASC";
1224 break;
1225 case ALG_DES:
1226 *encrAlg = *keyAlg = CSSM_ALGID_DES;
1227 *keySizeInBits = CSP_DES_KEY_SIZE_DEFAULT;
1228 *keyAlgStr = "DES";
1229 break;
1230 case ALG_3DES:
1231 *encrAlg = CSSM_ALGID_3DES_3KEY_EDE;
1232 *keyAlg = CSSM_ALGID_3DES_3KEY;
1233 *keySizeInBits = CSP_DES3_KEY_SIZE_DEFAULT;
1234 *keyAlgStr = "3DES";
1235 break;
1236 case ALG_RC2:
1237 *encrAlg = *keyAlg = CSSM_ALGID_RC2;
1238 *keySizeInBits = CSP_RC2_KEY_SIZE_DEFAULT;
1239 *keyAlgStr = "RC2";
1240 break;
1241 case ALG_RC4:
1242 *encrAlg = *keyAlg = CSSM_ALGID_RC4;
1243 *keySizeInBits = CSP_RC4_KEY_SIZE_DEFAULT;
1244 *keyAlgStr = "RC4";
1245 break;
1246 case ALG_RC5:
1247 *encrAlg = *keyAlg = CSSM_ALGID_RC5;
1248 *keySizeInBits = CSP_RC5_KEY_SIZE_DEFAULT;
1249 *keyAlgStr = "RC5";
1250 break;
1251 case ALG_AES:
1252 *encrAlg = *keyAlg = CSSM_ALGID_AES;
1253 *keySizeInBits = CSP_AES_KEY_SIZE_DEFAULT;
1254 *keyAlgStr = "AES";
1255 break;
1256 case ALG_RSA:
1257 *keyAlg = CSSM_ALGID_RSA;
1258 *encrAlg = CSSM_ALGID_RSA;
1259 *signAlg = CSSM_ALGID_SHA1WithRSA;
1260 *keySizeInBits = CSP_RSA_KEY_SIZE_DEFAULT;
1261 *keyAlgStr = "RSA";
1262 break;
1263 case ALG_DSA:
1264 *keyAlg = CSSM_ALGID_DSA;
1265 *signAlg = CSSM_ALGID_SHA1WithDSA;
1266 *keySizeInBits = CSP_DSA_KEY_SIZE_DEFAULT;
1267 *keyAlgStr = "DSA";
1268 break;
1269 case ALG_FEE:
1270 *keyAlg = CSSM_ALGID_FEE;
1271 *signAlg = CSSM_ALGID_SHA1WithECDSA;
1272 *encrAlg = CSSM_ALGID_FEEDEXP;
1273 *keySizeInBits = CSP_FEE_KEY_SIZE_DEFAULT;
1274 *keyAlgStr = "FEE";
1275 break;
1276 case ALG_ECDSA:
1277 *keyAlg = CSSM_ALGID_ECDSA;
1278 *signAlg = CSSM_ALGID_SHA1WithECDSA;
1279 *keySizeInBits = CSP_ECDSA_KEY_SIZE_DEFAULT;
1280 *keyAlgStr = "ECDSA";
1281 break;
1282 default:
1283 printf("***BRRZAP! privAlgToCssm needs work\n");
1284 exit(1);
1285 }
1286 return;
1287 }
1288
1289 int main(int argc, char **argv)
1290 {
1291 int arg;
1292 char *argp;
1293 CSSM_CSP_HANDLE cspHand;
1294 CSSM_ALGORITHMS keyAlg; // CSSM_ALGID_xxx of the key
1295 CSSM_ALGORITHMS signAlg; // CSSM_ALGID_xxx of the associated signing op
1296 CSSM_ALGORITHMS encrAlg; // CSSM_ALGID_xxx of the associated encrypt op
1297 privAlg palg;
1298 uint32 keySizeInBits;
1299 int rtn;
1300 int i;
1301 const char *keyAlgStr;
1302
1303 /*
1304 * User-spec'd params
1305 */
1306 CSSM_BOOL quiet = CSSM_FALSE;
1307 CSSM_BOOL doSym = CSSM_TRUE;
1308 CSSM_BOOL doAsym = CSSM_TRUE;
1309 CSSM_BOOL bareCsp = CSSM_TRUE;
1310
1311 for(arg=1; arg<argc; arg++) {
1312 argp = argv[arg];
1313 switch(argp[0]) {
1314 case 'q':
1315 quiet = CSSM_TRUE;
1316 break;
1317 case 's':
1318 doAsym = CSSM_FALSE;
1319 break;
1320 case 'a':
1321 doSym = CSSM_FALSE;
1322 break;
1323 case 'D':
1324 bareCsp = CSSM_FALSE;
1325 break;
1326 case 'h':
1327 default:
1328 usage(argv);
1329 }
1330 }
1331 cspHand = cspDlDbStartup(bareCsp, NULL);
1332 if(cspHand == 0) {
1333 exit(1);
1334 }
1335 printf("Starting badattr; args: ");
1336 for(i=1; i<argc; i++) {
1337 printf("%s ", argv[i]);
1338 }
1339 printf("\n");
1340
1341 if(doSym) {
1342 for(palg=SYM_FIRST; palg<=SYM_LAST; palg++) {
1343 privAlgToCssm(palg, &keyAlg, &signAlg, &encrAlg, &keySizeInBits, &keyAlgStr);
1344 if(!quiet) {
1345 printf(" ...alg %s\n", keyAlgStr);
1346 }
1347 rtn = symAttrTest(cspHand, keyAlg, keyAlgStr, keySizeInBits, bareCsp,
1348 quiet);
1349 if(rtn) {
1350 goto abort;
1351 }
1352 rtn = symNullWrapTest(cspHand, keyAlg, keyAlgStr, keySizeInBits, quiet);
1353 if(rtn) {
1354 goto abort;
1355 }
1356 rtn = symBadWrapTest(cspHand, keyAlg, keyAlgStr, keySizeInBits, quiet);
1357 if(rtn) {
1358 goto abort;
1359 }
1360 rtn = symUsageTest(cspHand, keyAlg, keyAlgStr, encrAlg, signAlg,
1361 keySizeInBits, quiet);
1362 if(rtn) {
1363 goto abort;
1364 }
1365 if(bareCsp || CSPDL_MUNGE_HEADER_CHECK) {
1366 rtn = symHeaderTest(cspHand, keyAlg, keyAlgStr, encrAlg, signAlg,
1367 keySizeInBits, quiet);
1368 if(rtn) {
1369 goto abort;
1370 }
1371 }
1372 else if(!quiet) {
1373 printf(" ...SKIPPING munged ref key header test\n");
1374 }
1375 }
1376 }
1377
1378 if(doAsym) {
1379 for(palg=ASYM_FIRST; palg<=ASYM_LAST; palg++) {
1380 privAlgToCssm(palg, &keyAlg, &signAlg, &encrAlg, &keySizeInBits,
1381 &keyAlgStr);
1382 if(!quiet) {
1383 printf(" ...alg %s\n", keyAlgStr);
1384 }
1385 rtn = asymAttrTest(cspHand, keyAlg, keyAlgStr, keySizeInBits,
1386 bareCsp, quiet);
1387 if(rtn) {
1388 goto abort;
1389 }
1390 rtn = asymNullWrapTest(cspHand, keyAlg, keyAlgStr, keySizeInBits, quiet);
1391 if(rtn) {
1392 goto abort;
1393 }
1394 rtn = asymBadWrapTest(cspHand, keyAlg, keyAlgStr, keySizeInBits, quiet);
1395 if(rtn) {
1396 goto abort;
1397 }
1398 if(bareCsp || CSPDL_MUNGE_HEADER_CHECK) {
1399 rtn = asymHeaderTest(cspHand, keyAlg, keyAlgStr, encrAlg, signAlg,
1400 keySizeInBits, quiet);
1401 if(rtn) {
1402 goto abort;
1403 }
1404 }
1405 else if(!quiet) {
1406 printf(" ...SKIPPING munged ref key header test\n");
1407 }
1408 }
1409 }
1410 abort:
1411 cspShutdown(cspHand, bareCsp);
1412 if((rtn == 0) && !quiet) {
1413 printf("%s complete\n", argv[0]);
1414 }
1415 return rtn;
1416 }
1417