1 /* Copyright (c) 2002-2004,2006,2008 Apple Inc.
5 * Test CSSMOID_APPLE_TP_SMIME and CSSMOID_APPLE_TP_ICHAT TP policies.
9 #include <utilLib/common.h>
10 #include <utilLib/cspwrap.h>
11 #include <clAppUtils/clutils.h>
12 #include <clAppUtils/certVerify.h>
13 #include <clAppUtils/BlobList.h>
17 #include <Security/cssm.h>
18 #include <Security/x509defs.h>
19 #include <Security/oidsattr.h>
20 #include <Security/oidscert.h>
21 #include <Security/oidsalg.h>
22 #include <Security/certextensions.h>
23 #include <Security/cssmapple.h>
24 #include <security_cdsa_utils/cuPrintCert.h>
28 #define SUBJ_KEY_LABEL "subjectKey"
29 #define ROOT_KEY_LABEL "rootKey"
31 /* key and signature algorithm - shouldn't matter for this test */
32 #define SIG_ALG_DEFAULT CSSM_ALGID_SHA1WithRSA
33 #define SIG_OID_DEFAULT CSSMOID_SHA1WithRSA
34 #define KEY_ALG_DEFAULT CSSM_ALGID_RSA
36 #define KEY_SIZE_DEFAULT 512
38 static void usage(char **argv
)
40 printf("Usage: %s [options]\n", argv
[0]);
42 printf(" p(rint leaf certs)\n");
43 printf(" P(ause for MallocDebug)\n");
45 printf(" v(erbose)\n");
50 * RDN components for root
52 CSSM_APPLE_TP_NAME_OID rootRdn
[] =
54 { "Apple Computer", &CSSMOID_OrganizationName
},
55 { "The Big Cheese", &CSSMOID_Title
}
57 #define NUM_ROOT_NAMES (sizeof(rootRdn) / sizeof(CSSM_APPLE_TP_NAME_OID))
63 /* test description */
66 /* policy: CVP_SMIME or CVP_iChat */
67 CertVerifyPolicy policy
;
69 /* email addrs for leaf cert - zero, one, or two of these */
70 const char *subjNameEmail
; // CSSMOID_EmailAddress
71 const char *subjAltNameEmail
; // RFC822Name
72 CSSM_BOOL subjAltNameCritical
;
74 /* common name portion of Subject Name, optional */
75 const char *subjNameCommon
;
77 /* email addrs for CertGroupVerify */
78 const char *vfyEmailAddrs
;
80 /* Key Usage - if zero, no KU extension */
81 CE_KeyUsage certKeyUse
;
82 CSSM_BOOL keyUseCritical
;
84 /* key usage specified in CertGroupVerify */
85 CE_KeyUsage vfyKeyUse
;
87 /* ExtendedKeyUSage OID - NULL means no EKU */
88 const CSSM_OID
*ekuOid
;
90 /* expected error - NULL or e.g. "CSSMERR_TP_VERIFY_ACTION_FAILED" */
91 const char *expectErrStr
;
93 /* one optional per-cert error string */
94 /* e.g., "0:CSSMERR_APPLETP_SMIME_BAD_KEY_USE" */
95 const char *certErrorStr
;
97 /* addenda - at end so we don't have to update every existing test case.
98 * For iChat, orgUnit and org fields in SubjectName.
101 const char *orgName
; /* nominally either Apple Computer, Inc. */
106 * upper case char in each component to make sure both ends get
107 * normalized as appropriate
109 #define GOOD_EMAIL "Alice@Apple.com"
110 #define BAD_EMAIL "bob@apple.com" /* always bad */
111 #define CASE_EMAIL_GOOD "Alice@APPLE.com" /* always good */
114 * SMIME, emailAddrs in subjAltName: bad
115 * SMIME, emailAddrs in SUbjectName RDN: good
117 #define CASE_EMAIL_BAD "ALice@Apple.com"
118 #define COMMON_NAME "Alice"
120 /* for Apple-custom iChat name encoding */
121 /* first the constant org field, case sensitive */
122 #define ICHAT_ORG "Apple Computer, Inc." /* reference */
123 #define ICHAT_ORG_CASE "APPLE Computer, Inc." /* should fail */
124 #define ICHAT_ORG_BAD "Apple Computer, Inc"
126 /* commonName = name, orgUnit = domain, case insensitive */
127 #define ICHAT_NAME "Alice" /* commonName */
128 #define ICHAT_DOMAIN "mac.com" /* orgUnit */
129 #define ICHAT_HANDLE "Alice@mac.com" /* what we pass in */
131 #define ICHAT_HANDLE_CASE1 "ALice@mac.com"
132 #define ICHAT_HANDLE_CASE2 "Alice@mAc.com"
133 #define ICHAT_NAME_CASE "ALice"
134 #define ICHAT_DOMAIN_CASE "maC.com"
135 #define ICHAT_NAME_BAD "Alice_"
136 #define ICHAT_DOMAIN_BAD "mac.co"
137 #define ICHAT_HANDLE_BAD1 "Alice@mac.co"
138 #define ICHAT_HANDLE_BAD2 "Alicg@mac.com"
139 #define ICHAT_HANDLE_BAD3 "Alicemac.com"
140 #define ICHAT_HANDLE_BAD4 "Alice@mac@com"
142 #define KEYUSE_NONE 0
144 SP_TestCase testCases
[] =
146 /* move these to end after we debug 'em */
147 /* custom iChat name encoding */
151 NULL
, NULL
, CSSM_FALSE
, // no email address
152 ICHAT_NAME
, ICHAT_HANDLE
,
153 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
154 &CSSMOID_APPLE_EKU_ICHAT_SIGNING
,
156 ICHAT_DOMAIN
, ICHAT_ORG
161 NULL
, NULL
, CSSM_FALSE
, // no email address
162 ICHAT_NAME
, ICHAT_HANDLE
,
163 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
164 /* verify this EKU */
165 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
167 ICHAT_DOMAIN
, ICHAT_ORG
172 NULL
, NULL
, CSSM_FALSE
, // no email address
173 ICHAT_NAME
, ICHAT_HANDLE
,
174 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
175 /* verify this EKU */
176 &CSSMOID_ExtendedKeyUsageAny
,
178 ICHAT_DOMAIN
, ICHAT_ORG
181 "iChat custom, alt case in name",
183 NULL
, NULL
, CSSM_FALSE
, // no email address
184 ICHAT_NAME_CASE
, ICHAT_HANDLE
,
185 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
186 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
188 ICHAT_DOMAIN
, ICHAT_ORG
191 "iChat custom, alt case in domain",
193 NULL
, NULL
, CSSM_FALSE
, // no email address
194 ICHAT_NAME
, ICHAT_HANDLE
,
195 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
196 &CSSMOID_APPLE_EKU_ICHAT_SIGNING
,
198 ICHAT_DOMAIN_CASE
, ICHAT_ORG
201 "iChat custom, alt case in org, expect fail",
203 NULL
, NULL
, CSSM_FALSE
, // no email address
204 ICHAT_NAME
, ICHAT_HANDLE
,
205 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
206 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
207 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
208 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
209 ICHAT_DOMAIN
, ICHAT_ORG_CASE
212 "iChat custom, bad name",
214 NULL
, NULL
, CSSM_FALSE
, // no email address
215 ICHAT_NAME_BAD
, ICHAT_HANDLE
,
216 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
217 &CSSMOID_APPLE_EKU_ICHAT_SIGNING
,
218 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
219 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
220 ICHAT_DOMAIN
, ICHAT_ORG
223 "iChat custom, bad name",
225 NULL
, NULL
, CSSM_FALSE
, // no email address
226 ICHAT_NAME_BAD
, ICHAT_HANDLE
,
227 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
228 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
229 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
230 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
231 ICHAT_DOMAIN
, ICHAT_ORG
234 "iChat custom, bad domain",
236 NULL
, NULL
, CSSM_FALSE
, // no email address
237 ICHAT_NAME
, ICHAT_HANDLE
,
238 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
239 &CSSMOID_ExtendedKeyUsageAny
,
240 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
241 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
242 ICHAT_DOMAIN_BAD
, ICHAT_ORG
245 "iChat custom, bad org",
247 NULL
, NULL
, CSSM_FALSE
, // no email address
248 ICHAT_NAME
, ICHAT_HANDLE
,
249 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
250 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
251 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
252 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
253 ICHAT_DOMAIN
, ICHAT_ORG_BAD
256 "iChat custom, bad handle (short)",
258 NULL
, NULL
, CSSM_FALSE
, // no email address
259 ICHAT_NAME
, ICHAT_HANDLE_BAD1
,
260 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
261 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
262 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
263 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
264 ICHAT_DOMAIN
, ICHAT_ORG
267 "iChat custom, bad handle (bad name component)",
269 NULL
, NULL
, CSSM_FALSE
, // no email address
270 ICHAT_NAME
, ICHAT_HANDLE_BAD2
,
271 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
272 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
273 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
274 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
275 ICHAT_DOMAIN
, ICHAT_ORG
278 "iChat custom, bad handle (no @)",
280 NULL
, NULL
, CSSM_FALSE
, // no email address
281 ICHAT_NAME
, ICHAT_HANDLE_BAD3
,
282 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
283 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
284 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
285 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
286 ICHAT_DOMAIN
, ICHAT_ORG
289 "iChat custom, bad handle (two @s)",
291 NULL
, NULL
, CSSM_FALSE
, // no email address
292 ICHAT_NAME
, ICHAT_HANDLE_BAD4
,
293 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
294 &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
,
295 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
296 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
297 ICHAT_DOMAIN
, ICHAT_ORG
300 "iChat custom, no EKU",
302 NULL
, NULL
, CSSM_FALSE
, // no email address
303 ICHAT_NAME
, ICHAT_HANDLE
,
304 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
306 "CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
307 "0:CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
308 ICHAT_DOMAIN
, ICHAT_ORG
311 "iChat custom, bad EKU",
313 NULL
, NULL
, CSSM_FALSE
, // no email address
314 ICHAT_NAME
, ICHAT_HANDLE
,
315 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
316 &CSSMOID_TimeStamping
,
317 "CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
318 "0:CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
319 ICHAT_DOMAIN
, ICHAT_ORG
322 /* end of move to end */
324 "Email addrs in subjAltName, S/MIME",
326 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
327 COMMON_NAME
, GOOD_EMAIL
,
328 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
333 "Email addrs in subjAltName, iChat",
335 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
336 COMMON_NAME
, GOOD_EMAIL
,
337 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
338 &CSSMOID_EmailProtection
,
342 "Email addrs in subject name, S/MIME",
344 GOOD_EMAIL
, NULL
, CSSM_FALSE
,
345 COMMON_NAME
, GOOD_EMAIL
,
346 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
351 "Email addrs in subject name, iChat",
353 GOOD_EMAIL
, NULL
, CSSM_FALSE
,
354 COMMON_NAME
, GOOD_EMAIL
,
355 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
356 &CSSMOID_EmailProtection
,
361 * The spec (RFC 2632) says that if there is no email address
362 * in the cert at all, then the TP doesn't have to
363 * enforce a match. So this one works, since we're not
364 * putting any email addresses in the cert.
366 "No Email addrs, S/MIME",
368 NULL
, NULL
, CSSM_FALSE
,
369 COMMON_NAME
, GOOD_EMAIL
,
370 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
376 * For iChat the same scenario fails; it requires an email address in
377 * the cert if we pass one in.
379 "No Email addrs, iChat",
381 NULL
, NULL
, CSSM_FALSE
,
382 COMMON_NAME
, GOOD_EMAIL
,
383 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
384 &CSSMOID_EmailProtection
,
385 "CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS",
386 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS"
389 "Wrong email addrs in SubjectName, S/MIME",
391 BAD_EMAIL
, NULL
, CSSM_FALSE
,
392 COMMON_NAME
, GOOD_EMAIL
,
393 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
395 "CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND",
396 "0:CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND"
399 "Wrong email addrs in SubjectName, iChat",
401 BAD_EMAIL
, NULL
, CSSM_FALSE
,
402 COMMON_NAME
, GOOD_EMAIL
,
403 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
404 &CSSMOID_EmailProtection
,
405 "CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND",
406 "0:CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND"
409 "Wrong email addrs in SubjectAltName, S/MIME",
411 NULL
, BAD_EMAIL
, CSSM_FALSE
,
412 COMMON_NAME
, GOOD_EMAIL
,
413 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
415 "CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND",
416 "0:CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND"
419 "Wrong email addrs in SubjectAltName, iChat",
421 NULL
, BAD_EMAIL
, CSSM_FALSE
,
422 COMMON_NAME
, GOOD_EMAIL
,
423 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
424 &CSSMOID_EmailProtection
,
425 "CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND",
426 "0:CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND"
430 * The presence of an incorrect email address is not supposed
431 * be an error as long as the right one is in there somewhere.
434 "Wrong addrs in subj name, correct in subjAltName, S/MIME",
436 BAD_EMAIL
, GOOD_EMAIL
, CSSM_FALSE
,
437 COMMON_NAME
, GOOD_EMAIL
,
438 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
443 "Wrong addrs in subj name, correct in subjAltName, iChat",
445 BAD_EMAIL
, GOOD_EMAIL
, CSSM_FALSE
,
446 COMMON_NAME
, GOOD_EMAIL
,
447 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
448 &CSSMOID_EmailProtection
,
452 "Wrong addrs in subjAltname, correct in subjName, S/MIME",
454 GOOD_EMAIL
, BAD_EMAIL
, CSSM_FALSE
,
455 COMMON_NAME
, GOOD_EMAIL
,
456 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
461 "Wrong addrs in subjAltname, correct in subjName, iChat",
463 GOOD_EMAIL
, BAD_EMAIL
, CSSM_FALSE
,
464 COMMON_NAME
, GOOD_EMAIL
,
465 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
466 &CSSMOID_EmailProtection
,
469 /* empty subject name processing - S/MIME only*/
471 "Empty subj name, correct subjAltName, no search",
473 NULL
, GOOD_EMAIL
, CSSM_TRUE
,
475 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
480 "Empty subj name, correct subjAltName, good search",
482 NULL
, GOOD_EMAIL
, CSSM_TRUE
,
484 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
489 "Empty subj name, correct subjAltName, not critical, no search",
491 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
493 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
495 "CSSMERR_TP_VERIFY_ACTION_FAILED",
496 "0:CSSMERR_APPLETP_SMIME_SUBJ_ALT_NAME_NOT_CRIT"
499 "Empty subj name, correct subjAltName, not critical, good search",
501 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
503 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
505 "CSSMERR_TP_VERIFY_ACTION_FAILED",
506 "0:CSSMERR_APPLETP_SMIME_SUBJ_ALT_NAME_NOT_CRIT"
509 "Empty subj name, empty subjAltName, no search",
511 NULL
, NULL
, CSSM_FALSE
,
513 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
515 "CSSMERR_TP_VERIFY_ACTION_FAILED",
516 "0:CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS"
519 /* case sensitivity handling */
521 "Different case domain in subjAltName, S/MIME",
523 NULL
, CASE_EMAIL_GOOD
, CSSM_FALSE
,
524 COMMON_NAME
, GOOD_EMAIL
,
525 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
530 "Different case domain in subjAltName, iChat",
532 NULL
, CASE_EMAIL_GOOD
, CSSM_FALSE
,
533 COMMON_NAME
, GOOD_EMAIL
,
534 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
535 &CSSMOID_EmailProtection
,
539 "Different case domain in subjectName, S/MIME",
541 CASE_EMAIL_GOOD
, NULL
, CSSM_FALSE
,
542 COMMON_NAME
, GOOD_EMAIL
,
543 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
548 "Different case domain in subjectName, iChat",
550 CASE_EMAIL_GOOD
, NULL
, CSSM_FALSE
,
551 COMMON_NAME
, GOOD_EMAIL
,
552 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
553 &CSSMOID_EmailProtection
,
558 * SMIME, emailAddrs in SubjectName - case insensitive
559 * SMIME, emailAddrs in SubjectAltName - case sensitive
560 * iChat, anywhere - case insensitive
563 /* the only time local-part is case sensitive */
564 "Different case local-part in subjAltName, SMIME",
566 NULL
, CASE_EMAIL_BAD
, CSSM_FALSE
,
567 COMMON_NAME
, GOOD_EMAIL
,
568 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
570 "CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND",
571 "0:CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND"
574 "Different case local-part in subjAltName, iChat",
576 NULL
, CASE_EMAIL_BAD
, CSSM_FALSE
,
577 COMMON_NAME
, GOOD_EMAIL
,
578 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
579 &CSSMOID_EmailProtection
,
583 "Different case local-part in SubjectName, S/MIME",
585 CASE_EMAIL_BAD
, NULL
, CSSM_FALSE
,
586 COMMON_NAME
, GOOD_EMAIL
,
587 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
592 "Different case local-part in SubjectName, iChat",
594 CASE_EMAIL_BAD
, NULL
, CSSM_FALSE
,
595 COMMON_NAME
, GOOD_EMAIL
,
596 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
597 &CSSMOID_EmailProtection
,
601 /* just to test a corner case of tpNormalizeAddrSpec */
602 "local-part missing @ in SubjectName",
604 "alice_apple.com", NULL
, CSSM_FALSE
,
605 COMMON_NAME
, GOOD_EMAIL
,
606 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
608 "CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND",
609 "0:CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND"
613 *** Key Usage testing
615 *** All leaf certs have good email addrs in subjectAltName
620 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
621 COMMON_NAME
, GOOD_EMAIL
,
622 CE_KU_DigitalSignature
, CSSM_TRUE
, CE_KU_DigitalSignature
,
629 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
630 COMMON_NAME
, GOOD_EMAIL
,
631 CE_KU_DigitalSignature
| CE_KU_NonRepudiation
, CSSM_TRUE
,
632 CE_KU_DigitalSignature
,
637 "KeyUsage in cert but not verified",
639 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
640 COMMON_NAME
, GOOD_EMAIL
,
641 CE_KU_DigitalSignature
| CE_KU_NonRepudiation
, CSSM_TRUE
,
642 KEYUSE_NONE
, // no use specified
649 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
650 COMMON_NAME
, GOOD_EMAIL
,
651 CE_KU_DigitalSignature
, CSSM_TRUE
, CE_KU_NonRepudiation
,
653 "CSSMERR_TP_VERIFY_ACTION_FAILED",
654 "0:CSSMERR_APPLETP_SMIME_BAD_KEY_USE"
659 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
660 COMMON_NAME
, GOOD_EMAIL
,
661 CE_KU_DigitalSignature
| CE_KU_NonRepudiation
, CSSM_TRUE
,
664 "CSSMERR_TP_VERIFY_ACTION_FAILED",
665 "0:CSSMERR_APPLETP_SMIME_BAD_KEY_USE"
668 /* obsolete per radar 3523221 */
670 "Key Usage not critical",
671 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
672 COMMON_NAME
, GOOD_EMAIL
,
673 CE_KU_DigitalSignature
, CSSM_FALSE
, CE_KU_DigitalSignature
,
675 "CSSMERR_TP_VERIFY_ACTION_FAILED",
676 "0:CSSMERR_APPLETP_SMIME_KEYUSAGE_NOT_CRITICAL"
680 * The tricky ones involving KeyAgreement
683 "Key Usage KeyAgreement good 1",
685 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
686 COMMON_NAME
, GOOD_EMAIL
,
687 CE_KU_KeyAgreement
| CE_KU_EncipherOnly
, CSSM_TRUE
,
688 CE_KU_KeyAgreement
| CE_KU_EncipherOnly
,
693 "Key Usage KeyAgreement good 2",
695 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
696 COMMON_NAME
, GOOD_EMAIL
,
697 CE_KU_KeyAgreement
| CE_KU_DecipherOnly
, CSSM_TRUE
,
698 CE_KU_KeyAgreement
| CE_KU_DecipherOnly
,
703 "Key Usage KeyAgreement no {En,De}CipherOnly",
705 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
706 COMMON_NAME
, GOOD_EMAIL
,
707 CE_KU_KeyAgreement
| CE_KU_DecipherOnly
, CSSM_TRUE
,
710 "CSSMERR_TP_VERIFY_ACTION_FAILED",
711 "0:CSSMERR_APPLETP_SMIME_BAD_KEY_USE"
714 "Key Usage KeyAgreement bad EncipherOnly",
716 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
717 COMMON_NAME
, GOOD_EMAIL
,
718 CE_KU_KeyAgreement
| CE_KU_DecipherOnly
, CSSM_TRUE
,
719 CE_KU_KeyAgreement
| CE_KU_EncipherOnly
,
721 "CSSMERR_TP_VERIFY_ACTION_FAILED",
722 "0:CSSMERR_APPLETP_SMIME_BAD_KEY_USE"
725 "Key Usage KeyAgreement bad DecipherOnly",
727 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
728 COMMON_NAME
, GOOD_EMAIL
,
729 CE_KU_KeyAgreement
| CE_KU_EncipherOnly
, CSSM_TRUE
,
730 CE_KU_KeyAgreement
| CE_KU_DecipherOnly
,
732 "CSSMERR_TP_VERIFY_ACTION_FAILED",
733 "0:CSSMERR_APPLETP_SMIME_BAD_KEY_USE"
736 /* Extended Key Usage tests */
738 "Extended Key Usage EmailProtection, S/MIME",
740 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
741 COMMON_NAME
, GOOD_EMAIL
,
742 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
743 &CSSMOID_EmailProtection
,
747 "Extended Key Usage EmailProtection, iChat",
749 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
750 COMMON_NAME
, GOOD_EMAIL
,
751 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
752 &CSSMOID_EmailProtection
,
756 "Extended Key Usage ExtendedKeyUsageAny, S/MIME",
758 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
759 COMMON_NAME
, GOOD_EMAIL
,
760 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
761 &CSSMOID_ExtendedKeyUsageAny
,
765 "Extended Key Usage ExtendedKeyUsageAny, iChat",
767 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
768 COMMON_NAME
, GOOD_EMAIL
,
769 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
770 &CSSMOID_ExtendedKeyUsageAny
,
774 "Extended Key Usage TimeStamping (bad), S/MIME",
776 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
777 COMMON_NAME
, GOOD_EMAIL
,
778 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
779 &CSSMOID_TimeStamping
,
780 "CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
781 "0:CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE"
784 "Extended Key Usage TimeStamping (bad), iChat",
786 NULL
, GOOD_EMAIL
, CSSM_FALSE
,
787 COMMON_NAME
, GOOD_EMAIL
,
788 KEYUSE_NONE
, CSSM_FALSE
, KEYUSE_NONE
,
789 &CSSMOID_TimeStamping
,
790 "CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
791 "0:CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE"
794 "iChat custom, missing ICHAT_SIGNING EKU",
796 NULL
, NULL
, CSSM_FALSE
, // no email address
797 ICHAT_NAME
, ICHAT_HANDLE
,
798 CE_KU_DigitalSignature
, CSSM_TRUE
, CE_KU_DigitalSignature
,
799 NULL
, // requires &CSSMOID_APPLE_EKU_ICHAT_SIGNING,
800 "CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
801 "0:CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
802 ICHAT_DOMAIN
, ICHAT_ORG
805 "iChat custom, missing ICHAT_ENCRYPTION EKU",
807 NULL
, NULL
, CSSM_FALSE
, // no email address
808 ICHAT_NAME
, ICHAT_HANDLE
,
809 CE_KU_DataEncipherment
, CSSM_TRUE
, CE_KU_DataEncipherment
,
810 NULL
, // requires &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION,
811 "CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
812 "0:CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE",
813 ICHAT_DOMAIN
, ICHAT_ORG
817 #define NUM_TEST_CASES (sizeof(testCases) / sizeof(SP_TestCase))
820 * Generate a pair of certs. Root is standard, we never mess with
823 static CSSM_RETURN
genCerts(
824 CSSM_CL_HANDLE clHand
,
825 CSSM_CSP_HANDLE cspHand
,
826 CSSM_TP_HANDLE tpHand
,
827 CSSM_KEY_PTR rootPrivKey
,
828 CSSM_KEY_PTR rootPubKey
,
829 CSSM_KEY_PTR subjPubKey
,
831 /* all five SubjectName components are optional */
832 const char *subjNameEmail
, // CSSMOID_EmailAddress
833 const char *subjAltNameEmail
, // RFC822Name
834 const char *subjNameCommon
,
835 CSSM_BOOL subjAltNameCritical
,
836 const char *subjOrgUnit
,
837 const char *subjOrgName
,
839 /* Key Usage - if zero, no KU extension */
840 CE_KeyUsage certKeyUse
,
841 CSSM_BOOL keyUseCritical
,
843 /* ExtendedKeyUSage OID - if NULL, no EKU extension */
844 const CSSM_OID
*ekuOid
,
846 CSSM_DATA
&rootCert
, // RETURNED
847 CSSM_DATA
&subjCert
) // RETURNED
851 // mallocd by CSSM_TP_SubmitCredRequest
853 CSSM_APPLE_TP_CERT_REQUEST certReq
;
854 CSSM_TP_REQUEST_SET reqSet
;
856 CSSM_BOOL confirmRequired
;
857 CSSM_TP_RESULT_SET_PTR resultSet
;
858 CSSM_ENCODED_CERT
*encCert
;
859 CSSM_TP_CALLERAUTH_CONTEXT CallerAuthContext
;
861 CE_GeneralNames genNames
;
862 CE_GeneralName genName
;
863 CE_ExtendedKeyUsage extendedKeyUse
;
866 * Subject has zero, one, two, or three extensions (KeyUsage,
867 * subjectAltName, extendedKeyUsage); root has two: KeyUsage and
870 CE_DataAndType rootExts
[2];
871 CE_DataAndType leafExts
[3];
872 unsigned numLeafExts
= 0;
878 rootExts
[0].type
= DT_KeyUsage
;
879 rootExts
[0].critical
= CSSM_TRUE
;
880 rootExts
[0].extension
.keyUsage
=
881 CE_KU_DigitalSignature
| CE_KU_KeyCertSign
;
884 * 2. BasicConstraints
886 rootExts
[1].type
= DT_BasicConstraints
;
887 rootExts
[1].critical
= CSSM_TRUE
;
888 rootExts
[1].extension
.basicConstraints
.cA
= CSSM_TRUE
;
889 rootExts
[1].extension
.basicConstraints
.pathLenConstraintPresent
=
891 rootExts
[1].extension
.basicConstraints
.pathLenConstraint
= 2;
894 * Leaf extensions - all are optional
897 leafExts
[0].type
= DT_KeyUsage
;
898 leafExts
[0].critical
= keyUseCritical
;
899 leafExts
[0].extension
.keyUsage
= certKeyUse
;
902 if(subjAltNameEmail
) {
903 leafExts
[numLeafExts
].type
= DT_SubjectAltName
;
904 leafExts
[numLeafExts
].critical
= subjAltNameCritical
;
906 genName
.berEncoded
= CSSM_FALSE
;
907 genName
.name
.Data
= (uint8
*)subjAltNameEmail
;
908 genName
.nameType
= GNT_RFC822Name
;
909 genName
.name
.Length
= strlen(subjAltNameEmail
);
911 genNames
.numNames
= 1;
912 genNames
.generalName
= &genName
;
913 leafExts
[numLeafExts
].extension
.subjectAltName
= genNames
;
917 leafExts
[numLeafExts
].type
= DT_ExtendedKeyUsage
;
918 leafExts
[numLeafExts
].critical
= CSSM_FALSE
; // don't care - right?
919 extendedKeyUse
.numPurposes
= 1;
920 extendedKeyUse
.purposes
= (CSSM_OID_PTR
)ekuOid
;
921 leafExts
[numLeafExts
].extension
.extendedKeyUsage
= extendedKeyUse
;
926 * Variable length subject name for leaf
928 CSSM_APPLE_TP_NAME_OID subjRdn
[4];
929 unsigned numSubjNames
= 0;
931 subjRdn
[0].string
= subjNameEmail
;
932 subjRdn
[0].oid
= &CSSMOID_EmailAddress
;
936 subjRdn
[numSubjNames
].string
= subjNameCommon
;
937 subjRdn
[numSubjNames
].oid
= &CSSMOID_CommonName
;
941 subjRdn
[numSubjNames
].string
= subjOrgUnit
;
942 subjRdn
[numSubjNames
].oid
= &CSSMOID_OrganizationalUnitName
;
946 subjRdn
[numSubjNames
].string
= subjOrgName
;
947 subjRdn
[numSubjNames
].oid
= &CSSMOID_OrganizationName
;
951 /* certReq for root */
952 memset(&certReq
, 0, sizeof(CSSM_APPLE_TP_CERT_REQUEST
));
953 certReq
.cspHand
= cspHand
;
954 certReq
.clHand
= clHand
;
955 certReq
.serialNumber
= 0x12345678;
956 certReq
.numSubjectNames
= NUM_ROOT_NAMES
;
957 certReq
.subjectNames
= rootRdn
;
958 certReq
.numIssuerNames
= 0;
959 certReq
.issuerNames
= NULL
;
960 certReq
.certPublicKey
= rootPubKey
;
961 certReq
.issuerPrivateKey
= rootPrivKey
;
962 certReq
.signatureAlg
= SIG_ALG_DEFAULT
;
963 certReq
.signatureOid
= SIG_OID_DEFAULT
;
964 certReq
.notBefore
= 0; // now
965 certReq
.notAfter
= 10000; // seconds from now
966 certReq
.numExtensions
= 2;
967 certReq
.extensions
= rootExts
;
969 reqSet
.NumberOfRequests
= 1;
970 reqSet
.Requests
= &certReq
;
972 /* a big CSSM_TP_CALLERAUTH_CONTEXT just to specify an OID */
973 memset(&CallerAuthContext
, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT
));
974 memset(&policyId
, 0, sizeof(CSSM_FIELD
));
975 policyId
.FieldOid
= CSSMOID_APPLE_TP_LOCAL_CERT_GEN
;
976 CallerAuthContext
.Policy
.NumberOfPolicyIds
= 1;
977 CallerAuthContext
.Policy
.PolicyIds
= &policyId
;
979 /* generate root cert */
980 crtn
= CSSM_TP_SubmitCredRequest(tpHand
,
981 NULL
, // PreferredAuthority
982 CSSM_TP_AUTHORITY_REQUEST_CERTISSUE
,
988 printError("CSSM_TP_SubmitCredRequest", crtn
);
991 crtn
= CSSM_TP_RetrieveCredResult(tpHand
,
993 NULL
, // CallerAuthCredentials
998 printError("CSSM_TP_RetrieveCredResult", crtn
);
1001 if(resultSet
== NULL
) {
1002 printf("***CSSM_TP_RetrieveCredResult returned NULL result set.\n");
1005 encCert
= (CSSM_ENCODED_CERT
*)resultSet
->Results
;
1006 rootCert
= encCert
->CertBlob
;
1008 CSSM_FREE(resultSet
);
1010 /* now a subject cert signed by the root cert */
1011 certReq
.serialNumber
= 0x8765;
1012 certReq
.numSubjectNames
= numSubjNames
;
1013 certReq
.subjectNames
= subjRdn
;
1014 certReq
.numIssuerNames
= NUM_ROOT_NAMES
;
1015 certReq
.issuerNames
= rootRdn
;
1016 certReq
.certPublicKey
= subjPubKey
;
1017 certReq
.issuerPrivateKey
= rootPrivKey
;
1018 certReq
.numExtensions
= numLeafExts
;
1019 certReq
.extensions
= leafExts
;
1021 crtn
= CSSM_TP_SubmitCredRequest(tpHand
,
1022 NULL
, // PreferredAuthority
1023 CSSM_TP_AUTHORITY_REQUEST_CERTISSUE
,
1029 printError("CSSM_TP_SubmitCredRequest (2)", crtn
);
1032 crtn
= CSSM_TP_RetrieveCredResult(tpHand
,
1034 NULL
, // CallerAuthCredentials
1037 &resultSet
); // leaks.....
1039 printError("CSSM_TP_RetrieveCredResult (2)", crtn
);
1042 if(resultSet
== NULL
) {
1043 printf("***CSSM_TP_RetrieveCredResult (2) returned NULL "
1047 encCert
= (CSSM_ENCODED_CERT
*)resultSet
->Results
;
1048 subjCert
= encCert
->CertBlob
;
1050 CSSM_FREE(resultSet
);
1055 static void copyToBlob(
1056 const CSSM_DATA
&src
,
1059 blob
.Data
= (uint8
*)malloc(src
.Length
);
1060 blob
.Length
= src
.Length
;
1061 memmove(blob
.Data
, src
.Data
, src
.Length
);
1064 int main(int argc
, char **argv
)
1066 CSSM_CL_HANDLE clHand
; // CL handle
1067 CSSM_CSP_HANDLE cspHand
; // CSP handle
1068 CSSM_TP_HANDLE tpHand
; // TP handle
1071 CSSM_KEY subjPubKey
; // subject's RSA public key blob
1072 CSSM_KEY subjPrivKey
; // subject's RSA private key - ref format
1073 CSSM_KEY rootPubKey
; // root's RSA public key blob
1074 CSSM_KEY rootPrivKey
; // root's RSA private key - ref format
1075 CSSM_RETURN crtn
= CSSM_OK
;
1078 SP_TestCase
*testCase
;
1081 CSSM_BOOL printLeafCerts
= CSSM_FALSE
;
1082 CSSM_BOOL quiet
= CSSM_FALSE
;
1083 CSSM_BOOL verbose
= CSSM_FALSE
;
1084 CSSM_BOOL doPause
= CSSM_FALSE
;
1086 for(arg
=1; arg
<argc
; arg
++) {
1087 char *argp
= argv
[arg
];
1090 printLeafCerts
= CSSM_TRUE
;
1093 doPause
= CSSM_TRUE
;
1099 verbose
= CSSM_TRUE
;
1106 testStartBanner("smimePolicy", argc
, argv
);
1108 /* connect to CL, TP, and CSP */
1109 clHand
= clStartup();
1113 tpHand
= tpStartup();
1117 cspHand
= cspStartup();
1122 /* subsequent errors to abort: to detach */
1124 /* cook up an RSA key pair for the subject */
1125 crtn
= cspGenKeyPair(cspHand
,
1128 strlen(SUBJ_KEY_LABEL
),
1131 CSSM_FALSE
, // pubIsRef
1133 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
1135 CSSM_TRUE
, // privIsRef - doesn't matter
1137 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
1144 crtn
= cspGenKeyPair(cspHand
,
1147 strlen(ROOT_KEY_LABEL
),
1150 CSSM_FALSE
, // pubIsRef
1152 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
1154 CSSM_TRUE
, // privIsRef - doesn't matter
1156 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
1162 for(testNum
=0; testNum
<NUM_TEST_CASES
; testNum
++) {
1163 testCase
= &testCases
[testNum
];
1165 printf("%s\n", testCase
->testDesc
);
1167 crtn
= genCerts(clHand
, cspHand
, tpHand
,
1168 &rootPrivKey
, &rootPubKey
, &subjPubKey
,
1169 testCase
->subjNameEmail
, testCase
->subjAltNameEmail
,
1170 testCase
->subjNameCommon
, testCase
->subjAltNameCritical
,
1171 testCase
->orgUnit
, testCase
->orgName
,
1172 testCase
->certKeyUse
, testCase
->keyUseCritical
, testCase
->ekuOid
,
1173 rootCert
, subjCert
);
1174 if(printLeafCerts
) {
1175 printCert(subjCert
.Data
, subjCert
.Length
, CSSM_FALSE
);
1179 /* BlobList uses regular free() on the referent of the blobs */
1181 copyToBlob(subjCert
, blob
);
1182 CSSM_FREE(subjCert
.Data
);
1184 copyToBlob(rootCert
, blob
);
1185 CSSM_FREE(rootCert
.Data
);
1188 if(testError(quiet
)) {
1192 vfyRtn
= certVerifySimple(tpHand
, clHand
, cspHand
,
1194 CSSM_FALSE
, // useSystemAnchors
1195 CSSM_FALSE
, // leafCertIsCA
1196 CSSM_FALSE
, // allow expired root
1199 CSSM_FALSE
, // sslClient
1200 testCase
->vfyEmailAddrs
,
1201 testCase
->vfyKeyUse
,
1202 testCase
->expectErrStr
,
1203 testCase
->certErrorStr
? 1 : 0,
1204 testCase
->certErrorStr
? (const char **)&testCase
->certErrorStr
:
1206 0, NULL
, // certStatus
1207 CSSM_FALSE
, // trustSettings
1211 if(testError(quiet
)) {
1215 /* cert data freed by ~BlobList */
1219 printf("Pausing for mallocDebug. CR to continue: ");
1225 cspFreeKey(cspHand
, &rootPubKey
);
1226 cspFreeKey(cspHand
, &rootPrivKey
);
1227 cspFreeKey(cspHand
, &subjPubKey
);
1228 cspFreeKey(cspHand
, &subjPrivKey
);
1232 CSSM_ModuleDetach(cspHand
);
1235 CSSM_ModuleDetach(clHand
);
1238 CSSM_ModuleDetach(tpHand
);
1240 if(!vfyRtn
&& !crtn
&& !quiet
) {
1241 printf("...test passed\n");