2 * keyDate.cpp - test handling of KeyHeader.{StartDate,EndDate}
4 #include <Security/Security.h>
5 #include <security_cdsa_utilities/cssmdates.h>
11 #include <CoreFoundation/CoreFoundation.h>
14 * Enumerate algs our own way to allow iteration.
16 typedef unsigned privAlg
;
25 #define SYM_FIRST ALG_ASC
26 #define SYM_LAST ALG_BFISH
27 #define ASYM_FIRST ALG_RSA
28 #define ASYM_LAST ALG_RSA
30 #define KD_DB_NAME "keyDate.db"
31 #define KD_KEY_LABEL "keyStoreKey"
33 static CSSM_DATA keyLabelData
= {12, (uint8
*)KD_KEY_LABEL
};
35 static void usage(char **argv
)
37 printf("usage: %s [options]\n", argv
[0]);
38 printf(" Options:\n");
39 printf(" s(ymmetric only)\n");
40 printf(" a(symmetric only)\n");
41 printf(" t (key store only)\n");
42 printf(" D (CSPDL; default is bare CSP)\n");
49 #pragma mark --- Utilities ---
52 * Set a CSSM_DATE to "today plus delta days". Delta can be positive
59 CFAbsoluteTime cfTime
= CFAbsoluteTimeGetCurrent();
60 float fdelta
= 60.0 * 60.0 * 24.0 * deltaDays
;
62 CFDateRef cfDate
= CFDateCreate(NULL
, cfTime
);
63 CssmUniformDate
cud(cfDate
);
69 * Compare two CSSM_DATEs. Returns nonzero on error.
71 static int compareDates(
72 const CSSM_DATE
*refDate
, // what we tried to set, or NULL
73 const CSSM_DATE
*keyDate
,
78 /* make sure key date is empty */
80 unsigned char *cp
= (unsigned char *)keyDate
;
81 for(unsigned i
=0; i
<sizeof(CSSM_DATE
); i
++) {
88 printf("%s: refDate NULL, non-empty keyDate\n", op
);
89 return testError(quiet
);
95 if(memcmp(refDate
, keyDate
, sizeof(CSSM_DATE
))) {
96 printf("%s: refDate/keyDate MISCOMPARE\n", op
);
97 return testError(quiet
);
105 #pragma mark -- Key generation ---
108 * symmetric key generator with startDate/endDate
110 static int genSymKey(
111 CSSM_CSP_HANDLE cspHand
,
114 const char *keyAlgStr
,
115 uint32 keySizeInBits
,
116 CSSM_KEYATTR_FLAGS keyAttr
,
117 CSSM_KEYUSE keyUsage
,
123 CSSM_DL_DB_HANDLE
*dlDbHand
= NULL
) // optional
126 CSSM_CC_HANDLE ccHand
;
131 setDate(startDate
, startDeltaDays
);
134 setDate(endDate
, endDeltaDays
);
137 memset(symKey
, 0, sizeof(CSSM_KEY
));
138 crtn
= CSSM_CSP_CreateKeyGenContext(cspHand
,
140 keySizeInBits
, // keySizeInBits
143 setStartDate
? &startDate
: NULL
,
144 setEndDate
? &endDate
: NULL
,
148 printError("CSSM_CSP_CreateKeyGenContext", crtn
);
149 return testError(quiet
);
152 /* add in DL/DB to context */
153 crtn
= cspAddDlDbToContext(ccHand
, dlDbHand
->DLHandle
,
156 return testError(quiet
);
159 crtn
= CSSM_GenerateKey(ccHand
,
166 printError("CSSM_GenerateKey", crtn
);
167 return testError(quiet
);
169 CSSM_DeleteContext(ccHand
);
171 CSSM_KEYHEADER
&hdr
= symKey
->KeyHeader
;
172 CSSM_DATE
*cdp
= NULL
;
176 if(compareDates(cdp
, &hdr
.StartDate
, keyAlgStr
, quiet
)) {
185 if(compareDates(cdp
, &hdr
.EndDate
, keyAlgStr
, quiet
)) {
192 * Common, flexible, error-tolerant key pair generator.
194 static int genKeyPair(
195 CSSM_CSP_HANDLE cspHand
,
197 const char *keyAlgStr
,
198 uint32 keySizeInBits
,
200 CSSM_KEYATTR_FLAGS pubKeyAttr
,
201 CSSM_KEYUSE pubKeyUsage
,
202 CSSM_KEY_PTR privKey
,
203 CSSM_KEYATTR_FLAGS privKeyAttr
,
204 CSSM_KEYUSE privKeyUsage
,
210 CSSM_DL_DB_HANDLE
*dlDbHand
= NULL
) // optional
213 CSSM_CC_HANDLE ccHand
;
218 setDate(startDate
, startDeltaDays
);
221 setDate(endDate
, endDeltaDays
);
224 memset(pubKey
, 0, sizeof(CSSM_KEY
));
225 memset(privKey
, 0, sizeof(CSSM_KEY
));
227 crtn
= CSSM_CSP_CreateKeyGenContext(cspHand
,
232 setStartDate
? &startDate
: NULL
,
233 setEndDate
? &endDate
: NULL
,
237 printError("CSSM_CSP_CreateKeyGenContext", crtn
);
238 return testError(quiet
);
242 /* add in DL/DB to context */
243 crtn
= cspAddDlDbToContext(ccHand
, dlDbHand
->DLHandle
,
246 return testError(quiet
);
250 crtn
= CSSM_GenerateKeyPair(ccHand
,
257 &keyLabelData
, // same labels
258 NULL
, // CredAndAclEntry
261 printError("CSSM_GenerateKeyPair", crtn
);
262 return testError(quiet
);
264 CSSM_DeleteContext(ccHand
);
265 CSSM_KEYHEADER
&pubHdr
= pubKey
->KeyHeader
;
266 CSSM_KEYHEADER
&privHdr
= privKey
->KeyHeader
;
267 CSSM_DATE
*cdp
= NULL
;
271 if(compareDates(cdp
, &pubHdr
.StartDate
, keyAlgStr
, quiet
)) {
274 if(compareDates(cdp
, &privHdr
.StartDate
, keyAlgStr
, quiet
)) {
283 if(compareDates(cdp
, &pubHdr
.EndDate
, keyAlgStr
, quiet
)) {
286 if(compareDates(cdp
, &privHdr
.EndDate
, keyAlgStr
, quiet
)) {
292 /* map one of our private privAlgs (ALG_DES, etc.) to associated CSSM info. */
295 CSSM_ALGORITHMS
*keyAlg
,
296 CSSM_ALGORITHMS
*signAlg
, // CSSM_ALGID_NONE means incapable
298 CSSM_ALGORITHMS
*encrAlg
, // CSSM_ALGID_NONE means incapable
299 CSSM_ENCRYPT_MODE
*encrMode
,
300 CSSM_PADDING
*encrPad
,
301 uint32
*keySizeInBits
,
302 const char **keyAlgStr
)
304 *signAlg
= *encrAlg
= CSSM_ALGID_NONE
; // default
305 *encrMode
= CSSM_ALGMODE_NONE
;
306 *encrPad
= CSSM_PADDING_NONE
;
309 *encrAlg
= *keyAlg
= CSSM_ALGID_ASC
;
310 *keySizeInBits
= CSP_ASC_KEY_SIZE_DEFAULT
;
314 *encrAlg
= *keyAlg
= CSSM_ALGID_DES
;
315 *keySizeInBits
= CSP_DES_KEY_SIZE_DEFAULT
;
317 *encrMode
= CSSM_ALGMODE_CBCPadIV8
;
318 *encrPad
= CSSM_PADDING_PKCS7
;
321 *encrAlg
= *keyAlg
= CSSM_ALGID_AES
;
322 *keySizeInBits
= CSP_AES_KEY_SIZE_DEFAULT
;
324 *encrMode
= CSSM_ALGMODE_CBCPadIV8
;
325 *encrPad
= CSSM_PADDING_PKCS7
;
328 *encrAlg
= *keyAlg
= CSSM_ALGID_BLOWFISH
;
329 *keySizeInBits
= CSP_BFISH_KEY_SIZE_DEFAULT
;
330 *keyAlgStr
= "Blowfish";
331 *encrMode
= CSSM_ALGMODE_CBCPadIV8
;
332 *encrPad
= CSSM_PADDING_PKCS7
;
335 *keyAlg
= CSSM_ALGID_RSA
;
336 *encrAlg
= CSSM_ALGID_RSA
;
337 *signAlg
= CSSM_ALGID_SHA1WithRSA
;
338 *keySizeInBits
= 512;
340 *encrPad
= CSSM_PADDING_PKCS1
;
343 printf("***BRRZAP! privAlgToCssm needs work\n");
350 #pragma mark --- basic ops to detect INVALID_KEY_{START,END}_DATE ---
352 #define PTEXT_SIZE 64
355 static int doEncrypt(
356 CSSM_CSP_HANDLE cspHand
,
358 CSSM_KEY_PTR key
, // session, public
359 CSSM_ALGORITHMS encrAlg
,
360 CSSM_ENCRYPT_MODE encrMode
,
361 CSSM_PADDING encrPad
,
362 CSSM_RETURN expRtn
, // expected result
365 uint8 ptextData
[PTEXT_SIZE
];
366 CSSM_DATA ptext
= {PTEXT_SIZE
, ptextData
};
367 uint8 someIvData
[IV_SIZE
];
368 CSSM_DATA someIv
= {IV_SIZE
, someIvData
};
370 simpleGenData(&ptext
, PTEXT_SIZE
, PTEXT_SIZE
);
371 simpleGenData(&someIv
, IV_SIZE
, IV_SIZE
);
373 CSSM_CC_HANDLE cryptHand
= 0;
375 CSSM_ACCESS_CREDENTIALS creds
;
377 memset(&creds
, 0, sizeof(CSSM_ACCESS_CREDENTIALS
));
379 if(key
->KeyHeader
.KeyClass
== CSSM_KEYCLASS_SESSION_KEY
) {
380 crtn
= CSSM_CSP_CreateSymmetricContext(cspHand
,
390 printError("CSSM_CSP_CreateSymmetricContext", crtn
);
391 return testError(quiet
);
394 else if(key
->KeyHeader
.KeyClass
== CSSM_KEYCLASS_PUBLIC_KEY
) {
395 crtn
= CSSM_CSP_CreateAsymmetricContext(cspHand
,
402 printError("CSSM_CSP_CreateAsymmetricContext", crtn
);
403 return testError(quiet
);
407 printf("***BRRZAP! Only encrypt with session and public keys\n");
411 CSSM_DATA ctext
= {0, NULL
};
412 CSSM_DATA remData
= {0, NULL
};
416 crtn
= CSSM_EncryptData(cryptHand
,
424 if(expRtn
== CSSM_OK
) {
425 printError("CSSM_EncryptData", crtn
);
426 printf("Unexpected error encrypting with %s\n", algStr
);
429 printf("***Encrypt with %s: expected %s, got %s.\n",
430 algStr
, cssmErrToStr(expRtn
),
433 irtn
= testError(quiet
);
435 appFreeCssmData(&ctext
, CSSM_FALSE
);
436 appFreeCssmData(&remData
, CSSM_FALSE
);
437 CSSM_DeleteContext(cryptHand
);
442 * Decrypt bad cipher text. If the key is bad the CSP won't even get
443 * to the ciphertext. Bad ciphertext can result in a number of errors,
444 * in some cases it can even result in complete success, which we handle
445 * OK if the key is supposed to be good.
449 DR_BadStartDate
, // must be CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE
450 DR_BadEndDate
, // must be CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE
451 DR_BadData
// CSSMERR_CSP_INVALID_DATA. etc.
454 #define CTEXT_SIZE (PTEXT_SIZE )
456 static int doDecrypt(
457 CSSM_CSP_HANDLE cspHand
,
459 CSSM_KEY_PTR key
, // session, private
460 CSSM_ALGORITHMS encrAlg
,
461 CSSM_ENCRYPT_MODE encrMode
,
462 CSSM_PADDING encrPad
,
463 DecrResult expResult
,
466 uint8 ctextData
[CTEXT_SIZE
];
467 CSSM_DATA ctext
= {CTEXT_SIZE
, ctextData
};
468 uint8 someIvData
[IV_SIZE
];
469 CSSM_DATA someIv
= {IV_SIZE
, someIvData
};
472 * I have not found a way to guarantee decrypt failure here, no matter
473 * what ctext and IV I specify. We can't just do an encrypt and
474 * munge because we might be testing a bad (expired) key.
475 * We might have to redesign, first generating a good key, then an
476 * expired key from it...? Until then this test is loose about
477 * handling "key is good" detection.
479 memset(ctextData
, 0, CTEXT_SIZE
); // guaranteed bad padding
480 memset(someIvData
, 0, IV_SIZE
);
482 CSSM_CC_HANDLE cryptHand
= 0;
484 CSSM_ACCESS_CREDENTIALS creds
;
486 memset(&creds
, 0, sizeof(CSSM_ACCESS_CREDENTIALS
));
488 if(key
->KeyHeader
.KeyClass
== CSSM_KEYCLASS_SESSION_KEY
) {
489 crtn
= CSSM_CSP_CreateSymmetricContext(cspHand
,
499 printError("CSSM_CSP_CreateSymmetricContext", crtn
);
500 return testError(quiet
);
503 else if(key
->KeyHeader
.KeyClass
== CSSM_KEYCLASS_PRIVATE_KEY
) {
504 crtn
= CSSM_CSP_CreateAsymmetricContext(cspHand
,
511 printError("CSSM_CSP_CreateAsymmetricContext", crtn
);
512 return testError(quiet
);
516 printf("***BRRZAP! Only decrypt with session and private"
521 CSSM_DATA ptext
= {0, NULL
};
522 CSSM_DATA remData
= {0, NULL
};
526 crtn
= CSSM_DecryptData(cryptHand
,
534 case DR_BadStartDate
:
535 if(crtn
!= CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE
) {
536 printf("***Decrypt with %s: expected INVALID_KEY_START_DATE, "
537 "got %s.\n", algStr
, cssmErrToStr(crtn
));
538 irtn
= testError(quiet
);
542 if(crtn
!= CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE
) {
543 printf("***Decrypt with %s: expected INVALID_KEY_END_DATE, "
544 "got %s.\n", algStr
, cssmErrToStr(crtn
));
545 irtn
= testError(quiet
);
550 case CSSM_OK
: // good data, seen sometimes
551 case CSSMERR_CSP_INVALID_DATA
: // common case
552 case CSSMERR_CSP_INTERNAL_ERROR
: // default case in CSP's
556 printf("***Decrypt with %s: expected INVALID_DATA or OK, "
558 algStr
, cssmErrToStr(crtn
));
559 irtn
= testError(quiet
);
564 appFreeCssmData(&ptext
, CSSM_FALSE
);
565 appFreeCssmData(&remData
, CSSM_FALSE
);
566 CSSM_DeleteContext(cryptHand
);
571 CSSM_CSP_HANDLE cspHand
,
573 CSSM_KEY_PTR key
, // private
574 CSSM_ALGORITHMS sigAlg
,
575 CSSM_RETURN expRtn
, // expected result
578 uint8 ptextData
[PTEXT_SIZE
];
579 CSSM_DATA ptext
= {PTEXT_SIZE
, ptextData
};
580 CSSM_DATA sig
= {0, NULL
};
582 simpleGenData(&ptext
, PTEXT_SIZE
, PTEXT_SIZE
);
584 CSSM_CC_HANDLE cryptHand
= 0;
587 crtn
= CSSM_CSP_CreateSignatureContext(cspHand
,
593 printError("CSSM_CSP_CreateSignatureContext (1)", crtn
);
594 return testError(quiet
);
597 crtn
= CSSM_SignData(cryptHand
,
603 if(expRtn
== CSSM_OK
) {
604 printError("CSSM_SignData", crtn
);
605 printf("Unexpected error signing with %s\n", algStr
);
608 printf("***Sign with %s: expected %s, got %s.\n",
609 algStr
, cssmErrToStr(expRtn
),
612 irtn
= testError(quiet
);
614 appFreeCssmData(&sig
, CSSM_FALSE
);
615 CSSM_DeleteContext(cryptHand
);
620 * Verify bad signature. If the key is bad the CSP won't even get
621 * to the sig verify. Otherwise expect KD_VERIFY_FAIL_ERR.
623 #define KD_VERIFY_FAIL_ERR CSSMERR_CSP_VERIFY_FAILED
626 CSSM_CSP_HANDLE cspHand
,
628 CSSM_KEY_PTR key
, // private
629 CSSM_ALGORITHMS sigAlg
,
630 CSSM_RETURN expRtn
, // expected result
633 uint8 ptextData
[PTEXT_SIZE
];
634 CSSM_DATA ptext
= {PTEXT_SIZE
, ptextData
};
635 uint8 sigData
[PTEXT_SIZE
];
636 CSSM_DATA sig
= {PTEXT_SIZE
, sigData
};
638 simpleGenData(&ptext
, PTEXT_SIZE
, PTEXT_SIZE
);
639 memset(sigData
, 0, PTEXT_SIZE
);
641 CSSM_CC_HANDLE cryptHand
= 0;
644 crtn
= CSSM_CSP_CreateSignatureContext(cspHand
,
650 printError("CSSM_CSP_CreateSignatureContext (2)", crtn
);
651 return testError(quiet
);
654 crtn
= CSSM_VerifyData(cryptHand
,
660 if(expRtn
== CSSM_OK
) {
661 printError("CSSM_VerifyData", crtn
);
662 printf("Unexpected error verifying with %s\n", algStr
);
665 printf("***Verify with %s: expected %s, got %s.\n",
666 algStr
, cssmErrToStr(expRtn
),
669 irtn
= testError(quiet
);
671 CSSM_DeleteContext(cryptHand
);
677 #pragma mark -- test suites ---
680 CSSM_CSP_HANDLE cspHand
,
685 CSSM_ALGORITHMS keyAlg
;
686 CSSM_ALGORITHMS signAlg
;
687 CSSM_ALGORITHMS encrAlg
;
688 CSSM_ENCRYPT_MODE encrMode
;
689 CSSM_PADDING encrPad
;
690 uint32 keySizeInBits
;
691 const char *keyAlgStr
;
693 privAlgToCssm(palg
, &keyAlg
, &signAlg
, &encrAlg
, &encrMode
,
694 &encrPad
, &keySizeInBits
, &keyAlgStr
);
698 CSSM_KEYATTR_FLAGS keyAttr
;
700 keyAttr
= CSSM_KEYATTR_RETURN_REF
;
703 keyAttr
= CSSM_KEYATTR_RETURN_DATA
| CSSM_KEYATTR_EXTRACTABLE
;
707 printf("...testing %s with %s keys\n", keyAlgStr
,
708 refKeys
? "Ref" : "Raw");
709 printf(" ...verifying empty Dates\n");
711 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
, keySizeInBits
,
712 keyAttr
, CSSM_KEYUSE_ANY
, quiet
,
713 CSSM_FALSE
, 0, // no StartDate
714 CSSM_FALSE
, 0); // no EndDate
718 irtn
= doEncrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
719 encrPad
, CSSM_OK
, quiet
);
721 printf("***Failure on encrypting with empty Key Dates\n");
724 irtn
= doDecrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
725 encrPad
, DR_BadData
, quiet
);
727 printf("***Failure on decrypting with empty Key Dates\n");
730 cspFreeKey(cspHand
, &symKey
);
733 printf(" ...verifying Good Dates\n");
735 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
, keySizeInBits
,
736 keyAttr
, CSSM_KEYUSE_ANY
, quiet
,
737 CSSM_TRUE
, 0, // StartDate = today
738 CSSM_TRUE
, 1); // EndDate = tomorrow
742 irtn
= doEncrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
743 encrPad
, CSSM_OK
, quiet
);
745 printf("***Failure on encrypting with good Key Dates\n");
748 irtn
= doDecrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
749 encrPad
, DR_BadData
, quiet
);
751 printf("***Failure on decrypting with good Key Dates\n");
754 cspFreeKey(cspHand
, &symKey
);
757 printf(" ...verifying Bad StartDate\n");
759 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
, keySizeInBits
,
760 keyAttr
, CSSM_KEYUSE_ANY
, quiet
,
761 CSSM_TRUE
, 1, // StartDate = tomorrow
762 CSSM_TRUE
, 1); // EndDate = tomorrow
766 irtn
= doEncrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
767 encrPad
, CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE
, quiet
);
769 printf("***Failure on encrypting with bad StartDate\n");
772 irtn
= doDecrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
773 encrPad
, DR_BadStartDate
, quiet
);
775 printf("***Failure on decrypting with bad StartDate\n");
778 cspFreeKey(cspHand
, &symKey
);
781 printf(" ...verifying Bad EndDate\n");
783 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
, keySizeInBits
,
784 keyAttr
, CSSM_KEYUSE_ANY
, quiet
,
785 CSSM_TRUE
, 0, // StartDate = today
786 CSSM_TRUE
, -1); // EndDate = yesterday
790 irtn
= doEncrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
791 encrPad
, CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE
, quiet
);
793 printf("***Failure on encrypting with bad StartDate\n");
796 irtn
= doDecrypt(cspHand
, keyAlgStr
, &symKey
, encrAlg
, encrMode
,
797 encrPad
, DR_BadEndDate
, quiet
);
799 printf("***Failure on decrypting with bad EndDate\n");
802 cspFreeKey(cspHand
, &symKey
);
808 CSSM_CSP_HANDLE cspHand
,
813 CSSM_ALGORITHMS keyAlg
;
814 CSSM_ALGORITHMS sigAlg
;
815 CSSM_ALGORITHMS encrAlg
;
816 CSSM_ENCRYPT_MODE encrMode
;
817 CSSM_PADDING encrPad
;
818 uint32 keySizeInBits
;
819 const char *keyAlgStr
;
821 privAlgToCssm(palg
, &keyAlg
, &sigAlg
, &encrAlg
, &encrMode
,
822 &encrPad
, &keySizeInBits
, &keyAlgStr
);
827 CSSM_KEYATTR_FLAGS pubKeyAttr
= CSSM_KEYATTR_EXTRACTABLE
;
828 CSSM_KEYATTR_FLAGS privKeyAttr
= CSSM_KEYATTR_EXTRACTABLE
;
830 pubKeyAttr
|= CSSM_KEYATTR_RETURN_REF
;
831 privKeyAttr
|= CSSM_KEYATTR_RETURN_REF
;
834 pubKeyAttr
|= CSSM_KEYATTR_RETURN_DATA
;
835 privKeyAttr
|= CSSM_KEYATTR_RETURN_DATA
;
839 printf("...testing %s with %s keys\n", keyAlgStr
,
840 refKeys
? "Ref" : "Raw");
841 printf(" ...verifying empty Dates\n");
843 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
844 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
845 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
847 CSSM_FALSE
, 0, // no StartDate
848 CSSM_FALSE
, 0); // no EndDate
852 irtn
= doEncrypt(cspHand
, keyAlgStr
, &pubKey
, encrAlg
, encrMode
,
853 encrPad
, CSSM_OK
, quiet
);
855 printf("***Failure on encrypting with empty Key Dates\n");
858 irtn
= doDecrypt(cspHand
, keyAlgStr
, &privKey
, encrAlg
, encrMode
,
859 encrPad
, DR_BadData
, quiet
);
861 printf("***Failure on decrypting with empty Key Dates\n");
864 irtn
= doSign(cspHand
, keyAlgStr
, &privKey
, sigAlg
,
867 printf("***Failure on signing with empty Key Dates\n");
870 irtn
= doVerify(cspHand
, keyAlgStr
, &pubKey
, sigAlg
,
871 KD_VERIFY_FAIL_ERR
, quiet
);
873 printf("***Failure on verifying with empty Key Dates\n");
876 cspFreeKey(cspHand
, &pubKey
);
877 cspFreeKey(cspHand
, &privKey
);
880 printf(" ...verifying Good Dates\n");
882 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
883 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
884 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
886 CSSM_TRUE
, 0, // StartDate = today
887 CSSM_TRUE
, 1); // EndDate = tomorrow
891 irtn
= doEncrypt(cspHand
, keyAlgStr
, &pubKey
, encrAlg
, encrMode
,
892 encrPad
, CSSM_OK
, quiet
);
894 printf("***Failure on encrypting with good Key Dates\n");
897 irtn
= doDecrypt(cspHand
, keyAlgStr
, &privKey
, encrAlg
, encrMode
,
898 encrPad
, DR_BadData
, quiet
);
900 printf("***Failure on decrypting with Good Key Dates\n");
903 irtn
= doSign(cspHand
, keyAlgStr
, &privKey
, sigAlg
,
906 printf("***Failure on signing with Good Key Dates\n");
909 irtn
= doVerify(cspHand
, keyAlgStr
, &pubKey
, sigAlg
,
910 KD_VERIFY_FAIL_ERR
, quiet
);
912 printf("***Failure on verifying with Good Key Dates\n");
915 cspFreeKey(cspHand
, &pubKey
);
916 cspFreeKey(cspHand
, &privKey
);
919 printf(" ...verifying Bad StartDate\n");
921 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
922 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
923 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
925 CSSM_TRUE
, 1, // StartDate = tomorrow
926 CSSM_TRUE
, 1); // EndDate = tomorrow
930 irtn
= doEncrypt(cspHand
, keyAlgStr
, &pubKey
, encrAlg
, encrMode
,
931 encrPad
, CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE
, quiet
);
933 printf("***Failure on encrypting with bad StartDate\n");
936 irtn
= doDecrypt(cspHand
, keyAlgStr
, &privKey
, encrAlg
, encrMode
,
937 encrPad
, DR_BadStartDate
, quiet
);
939 printf("***Failure on decrypting with bad StartDate\n");
942 irtn
= doSign(cspHand
, keyAlgStr
, &privKey
, sigAlg
,
943 CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE
, quiet
);
945 printf("***Failure on signing with bad StartDate\n");
948 irtn
= doVerify(cspHand
, keyAlgStr
, &pubKey
, sigAlg
,
949 CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE
, quiet
);
951 printf("***Failure on verifying with bad StartDate\n");
954 cspFreeKey(cspHand
, &pubKey
);
955 cspFreeKey(cspHand
, &privKey
);
958 printf(" ...verifying Bad EndDate\n");
960 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
961 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
962 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
964 CSSM_TRUE
, 0, // StartDate = today
965 CSSM_TRUE
, -1); // EndDate = yesterday
969 irtn
= doEncrypt(cspHand
, keyAlgStr
, &pubKey
, encrAlg
, encrMode
,
970 encrPad
, CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE
, quiet
);
972 printf("***Failure on encrypting with bad EndDate\n");
975 irtn
= doDecrypt(cspHand
, keyAlgStr
, &privKey
, encrAlg
, encrMode
,
976 encrPad
, DR_BadEndDate
, quiet
);
978 printf("***Failure on decrypting with bad EndDate\n");
981 irtn
= doSign(cspHand
, keyAlgStr
, &privKey
, sigAlg
,
982 CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE
, quiet
);
984 printf("***Failure on signing with bad EndDate\n");
987 irtn
= doVerify(cspHand
, keyAlgStr
, &pubKey
, sigAlg
,
988 CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE
, quiet
);
990 printf("***Failure on verifying with bad EndDate\n");
993 cspFreeKey(cspHand
, &pubKey
);
994 cspFreeKey(cspHand
, &privKey
);
1000 * fetch stored key from DB, ensure it has same start/end date
1002 static int fetchStoredKey(
1003 CSSM_DL_DB_HANDLE dlDbHand
,
1004 CT_KeyType lookupType
,
1005 CSSM_KEY_PTR compareKey
,
1008 CSSM_KEY_PTR
*lookupKey
) // RETURNED
1010 CSSM_KEY_PTR lookup
= cspLookUpKeyByLabel(dlDbHand
.DLHandle
,
1014 if(lookup
== NULL
) {
1015 printf("%s: Error looking up key in DB\n", op
);
1016 return testError(quiet
);
1018 if(compareDates(&compareKey
->KeyHeader
.StartDate
,
1019 &lookup
->KeyHeader
.StartDate
,
1023 *lookupKey
= lookup
;
1028 CSSM_CSP_HANDLE cspHand
, // must be CSPDL
1029 CSSM_DL_DB_HANDLE dlDbHand
,
1034 CSSM_ALGORITHMS keyAlg
;
1035 CSSM_ALGORITHMS signAlg
;
1036 CSSM_ALGORITHMS encrAlg
;
1037 CSSM_ENCRYPT_MODE encrMode
;
1038 CSSM_PADDING encrPad
;
1039 uint32 keySizeInBits
;
1040 const char *keyAlgStr
;
1042 privAlgToCssm(palg
, &keyAlg
, &signAlg
, &encrAlg
, &encrMode
,
1043 &encrPad
, &keySizeInBits
, &keyAlgStr
);
1049 CSSM_KEY_PTR lookupKey
= NULL
; // obtained from DB
1050 CSSM_KEY_PTR compareKey
; // &symKey or &pubKey
1051 CT_KeyType lookupType
;
1052 CSSM_KEYATTR_FLAGS pubKeyAttr
=
1053 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_EXTRACTABLE
|
1054 CSSM_KEYATTR_PERMANENT
;
1055 CSSM_KEYATTR_FLAGS privKeyAttr
=
1056 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_PERMANENT
;
1059 printf("...testing %s key storage\n", keyAlgStr
);
1060 printf(" ...verifying empty Dates\n");
1063 lookupType
= CKT_Public
;
1064 compareKey
= &pubKey
;
1065 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
1066 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
1067 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
1069 CSSM_FALSE
, 0, // no StartDate
1070 CSSM_FALSE
, 0, // no EndDate
1074 lookupType
= CKT_Session
;
1075 compareKey
= &symKey
;
1076 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
,
1078 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_PERMANENT
,
1079 CSSM_KEYUSE_ANY
, quiet
,
1080 CSSM_FALSE
, 0, // no StartDate
1081 CSSM_FALSE
, 0, // no EndDate
1089 * fetch stored key from DB, ensure it has same start/end date
1091 if(fetchStoredKey(dlDbHand
, lookupType
,
1092 compareKey
, "Store key with empty Dates", quiet
,
1097 /* quickie test, use it for encrypt */
1098 irtn
= doEncrypt(cspHand
, keyAlgStr
, lookupKey
, encrAlg
, encrMode
,
1099 encrPad
, CSSM_OK
, quiet
);
1101 printf("***Failure on encrypt, lookup with empty Key Dates\n");
1105 /* free and delete everything */
1107 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1108 &keyLabelData
, &pubKey
);
1109 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1110 &keyLabelData
, &privKey
);
1113 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1114 &keyLabelData
, &symKey
);
1116 cspFreeKey(cspHand
, lookupKey
);
1118 /*********************/
1121 printf(" ...verifying Good Dates\n");
1124 lookupType
= CKT_Public
;
1125 compareKey
= &pubKey
;
1126 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
1127 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
1128 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
1130 CSSM_TRUE
, 0, // StartDate = today
1131 CSSM_TRUE
, 1, // EndDate = tomorrow
1135 lookupType
= CKT_Session
;
1136 compareKey
= &symKey
;
1137 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
,
1139 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_PERMANENT
,
1140 CSSM_KEYUSE_ANY
, quiet
,
1141 CSSM_TRUE
, 0, // StartDate = today
1142 CSSM_TRUE
, 1, // EndDate = tomorrow
1150 * fetch stored key from DB, ensure it has same start/end date
1152 if(fetchStoredKey(dlDbHand
, lookupType
,
1153 compareKey
, "Store key with Good Dates", quiet
,
1158 /* quickie test, use it for encrypt */
1159 irtn
= doEncrypt(cspHand
, keyAlgStr
, lookupKey
, encrAlg
, encrMode
,
1160 encrPad
, CSSM_OK
, quiet
);
1162 printf("***Failure on encrypt, lookup with Good Key Dates\n");
1166 /* free and delete everything */
1168 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1169 &keyLabelData
, &pubKey
);
1170 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1171 &keyLabelData
, &privKey
);
1174 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1175 &keyLabelData
, &symKey
);
1177 cspFreeKey(cspHand
, lookupKey
);
1179 /*********************/
1182 printf(" ...verifying Bad StartDate\n");
1185 lookupType
= CKT_Public
;
1186 compareKey
= &pubKey
;
1187 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
1188 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
1189 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
1191 CSSM_TRUE
, 1, // StartDate = tomorrow
1192 CSSM_TRUE
, 1, // EndDate = tomorrow
1196 lookupType
= CKT_Session
;
1197 compareKey
= &symKey
;
1198 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
,
1200 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_PERMANENT
,
1201 CSSM_KEYUSE_ANY
, quiet
,
1202 CSSM_TRUE
, 1, // StartDate = tomorrow
1203 CSSM_TRUE
, 1, // EndDate = tomorrow
1211 * fetch stored key from DB, ensure it has same start/end date
1213 if(fetchStoredKey(dlDbHand
, lookupType
,
1214 compareKey
, "Store key with Bad StartDate", quiet
,
1219 /* quickie test, use it for encrypt */
1220 irtn
= doEncrypt(cspHand
, keyAlgStr
, lookupKey
, encrAlg
, encrMode
,
1221 encrPad
, CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE
, quiet
);
1223 printf("***Failure on encrypt, lookup with Bad Start Dates\n");
1227 /* free and delete everything */
1229 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1230 &keyLabelData
, &pubKey
);
1231 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1232 &keyLabelData
, &privKey
);
1235 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1236 &keyLabelData
, &symKey
);
1238 cspFreeKey(cspHand
, lookupKey
);
1240 /*********************/
1243 printf(" ...verifying Bad EndDate\n");
1246 lookupType
= CKT_Public
;
1247 compareKey
= &pubKey
;
1248 irtn
= genKeyPair(cspHand
, keyAlg
, keyAlgStr
, keySizeInBits
,
1249 &pubKey
, pubKeyAttr
, CSSM_KEYUSE_ANY
,
1250 &privKey
, privKeyAttr
, CSSM_KEYUSE_ANY
,
1252 CSSM_TRUE
, 0, // StartDate = today
1253 CSSM_TRUE
, -1, // EndDate = yesterday
1257 lookupType
= CKT_Session
;
1258 compareKey
= &symKey
;
1259 irtn
= genSymKey(cspHand
, &symKey
, keyAlg
, keyAlgStr
,
1261 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_PERMANENT
,
1262 CSSM_KEYUSE_ANY
, quiet
,
1263 CSSM_TRUE
, 0, // StartDate = today
1264 CSSM_TRUE
, -1, // EndDate = yesterday
1272 * fetch stored key from DB, ensure it has same start/end date
1274 if(fetchStoredKey(dlDbHand
, lookupType
,
1275 compareKey
, "Store key with Bad EndDate", quiet
,
1280 /* quickie test, use it for encrypt */
1281 irtn
= doEncrypt(cspHand
, keyAlgStr
, lookupKey
, encrAlg
, encrMode
,
1282 encrPad
, CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE
, quiet
);
1284 printf("***Failure on encrypt, lookup with Bad End Dates\n");
1288 /* free and delete everything */
1290 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1291 &keyLabelData
, &pubKey
);
1292 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1293 &keyLabelData
, &privKey
);
1296 cspDeleteKey(cspHand
, dlDbHand
.DLHandle
, dlDbHand
.DBHandle
,
1297 &keyLabelData
, &symKey
);
1299 cspFreeKey(cspHand
, lookupKey
);
1305 int main(int argc
, char **argv
)
1307 CSSM_CSP_HANDLE cspHand
;
1309 CSSM_DL_DB_HANDLE dlDbHand
= {0, 0};
1310 char dbName
[100]; /* KD_DB_NAME_pid */
1312 /* user-spec'd variables */
1313 CSSM_BOOL quiet
= CSSM_FALSE
;
1314 CSSM_BOOL doSym
= CSSM_TRUE
;
1315 CSSM_BOOL doAsym
= CSSM_TRUE
;
1316 CSSM_BOOL doKeyStore
= CSSM_TRUE
;
1317 CSSM_BOOL bareCsp
= CSSM_TRUE
;
1320 for(arg
=1; arg
<argc
; arg
++) {
1321 switch(argv
[arg
][0]) {
1323 doAsym
= doKeyStore
= CSSM_FALSE
;
1329 bareCsp
= CSSM_FALSE
;
1340 sprintf(dbName
, "%s_%d", KD_DB_NAME
, (int)getpid());
1342 testStartBanner("keyDate", argc
, argv
);
1343 cspHand
= cspDlDbStartup(bareCsp
, NULL
);
1348 dlDbHand
.DLHandle
= dlStartup();
1349 if(dlDbHand
.DLHandle
== 0) {
1352 CSSM_RETURN crtn
= dbCreateOpen(dlDbHand
.DLHandle
,
1353 dbName
, CSSM_TRUE
, CSSM_TRUE
, dbName
,
1354 &dlDbHand
.DBHandle
);
1356 printf("Error creating %s. Aborting.\n", dbName
);
1362 for(palg
=SYM_FIRST
; palg
<=SYM_LAST
; palg
++) {
1363 /* once with ref keys */
1364 irtn
= doSymTests(cspHand
, palg
, CSSM_TRUE
, quiet
);
1369 /* and once with raw keys for bare CSP only */
1370 irtn
= doSymTests(cspHand
, palg
, CSSM_FALSE
, quiet
);
1376 /* test store/retrieve */
1377 irtn
= doStoreTests(cspHand
, dlDbHand
,
1378 palg
, CSSM_FALSE
, quiet
);
1386 for(palg
=ASYM_FIRST
; palg
<=ASYM_LAST
; palg
++) {
1387 /* once with ref keys */
1388 irtn
= doAsymTests(cspHand
, palg
, CSSM_TRUE
, quiet
);
1393 /* and once with raw keys for bare CSP only */
1394 irtn
= doAsymTests(cspHand
, palg
, CSSM_TRUE
, quiet
);
1399 else if(doKeyStore
) {
1400 /* test store/retrieve */
1401 irtn
= doStoreTests(cspHand
, dlDbHand
,
1402 palg
, CSSM_TRUE
, quiet
);
1411 /* be nice: if we ran OK delete the cruft DB we created */