2 * secTrustTime.cpp - measure performance of SecTrust and TP cert verify
9 #include <CoreFoundation/CoreFoundation.h>
10 #include <Security/Security.h>
11 #include <Security/TrustSettingsSchema.h>
12 #include <security_cdsa_utils/cuFileIo.h>
13 #include <utilLib/common.h>
14 #include <clAppUtils/clutils.h>
15 #include <clAppUtils/tpUtils.h>
19 const char *certFiles
[] = {
20 "keybank_v3.100.cer", "keybank_v3.101.cer", "keybank_v3.102.cer"
23 #define NUM_CERTS (sizeof(certFiles) / sizeof(certFiles[0]))
25 static void usage(char **argv
)
27 printf("usage: %s [options]\n", argv
[0]);
29 printf(" -l loops -- loops; default %d; 0=forever\n", LOOPS_DEF
);
30 printf(" -k -- open and hold keychains\n");
31 printf(" -t -- TP, not SecTrust\n");
32 printf(" -T -- TP, no Trust Settings\n");
33 printf(" -n -- don't include root in cert chain\n");
34 printf(" -K -- set empty KC list\n");
39 static SecCertificateRef
readCertFile(
42 unsigned char *cp
= NULL
;
47 if(readFile(fileName
, &cp
, &len
)) {
48 printf("***Error reading file %s\n", fileName
);
51 certData
.Length
= len
;
53 SecCertificateRef certRef
;
55 ortn
= SecCertificateCreateFromData(&certData
,
56 CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
, &certRef
);
58 cssmPerror("SecCertificateCreateFromData", ortn
);
65 /* perfrom one cert chain evaluation using SecTrust */
66 static OSStatus
doEval(
68 SecPolicyRef policyRef
,
74 ortn
= SecTrustCreateWithCertificates(certArray
, policyRef
, &trustRef
);
76 cssmPerror("SecTrustCreateWithCertificates", ortn
);
80 ortn
= SecTrustSetKeychains(trustRef
, kcList
);
82 cssmPerror("SecTrustCreateWithCertificates", ortn
);
86 SecTrustResultType secTrustResult
;
87 ortn
= SecTrustEvaluate(trustRef
, &secTrustResult
);
89 cssmPerror("SecTrustEvaluate", ortn
);
92 switch(secTrustResult
) {
93 case kSecTrustResultProceed
:
94 case kSecTrustResultUnspecified
:
97 printf("***Unexpected SecTrustResultType (%d)\n", (int)secTrustResult
);
104 /* cached CSSM anchors - simulate old SecTrustGetCSSMAnchorCertificates() */
105 static CFArrayRef cachedRootArray
= NULL
;
106 static CSSM_DATA
*cachedAnchors
= NULL
;
107 static unsigned cachedNumAnchors
= 0;
109 static OSStatus
getAnchors(
110 CSSM_DATA
**anchors
, /* RETURNED */
111 unsigned *numAnchors
) /* RETURNED */
113 if(cachedRootArray
== NULL
) {
115 OSStatus ortn
= getSystemAnchors(&cachedRootArray
, &cachedAnchors
,
121 *anchors
= cachedAnchors
;
122 *numAnchors
= cachedNumAnchors
;
126 /* perfrom one cert chain evaluation using CSSM_TP_CertGroupVerify */
127 static CSSM_RETURN
doTpEval(
128 CSSM_TP_HANDLE tpHand
,
129 CSSM_CL_HANDLE clHand
,
130 CSSM_CSP_HANDLE cspHand
,
133 bool useTrustSettings
)
137 policyId
.FieldOid
= CSSMOID_APPLE_X509_BASIC
;
138 policyId
.FieldValue
.Data
= NULL
;
139 policyId
.FieldValue
.Length
= 0;
141 CSSM_TP_CALLERAUTH_CONTEXT authCtx
;
142 memset(&authCtx
, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT
));
143 authCtx
.Policy
.NumberOfPolicyIds
= 1;
144 authCtx
.Policy
.PolicyIds
= &policyId
;
145 authCtx
.VerificationAbortOn
= CSSM_TP_STOP_ON_POLICY
;
146 if(!useTrustSettings
) {
147 OSStatus ortn
= getAnchors(&authCtx
.AnchorCerts
,
148 &authCtx
.NumberOfAnchorCerts
);
153 CSSM_APPLE_TP_ACTION_DATA tpAction
;
154 tpAction
.Version
= CSSM_APPLE_TP_ACTION_VERSION
;
155 if(useTrustSettings
) {
156 tpAction
.ActionFlags
= CSSM_TP_ACTION_TRUST_SETTINGS
;
159 tpAction
.ActionFlags
= 0;
162 CSSM_TP_VERIFY_CONTEXT vfyCtx
;
163 memset(&vfyCtx
, 0, sizeof(CSSM_TP_VERIFY_CONTEXT
));
164 vfyCtx
.ActionData
.Data
= (uint8
*)&tpAction
;
165 vfyCtx
.ActionData
.Length
= sizeof(tpAction
);
166 vfyCtx
.Action
= CSSM_TP_ACTION_DEFAULT
;
167 vfyCtx
.Cred
= &authCtx
;
169 CSSM_CERTGROUP cssmCerts
;
170 cssmCerts
.CertType
= CSSM_CERT_X_509v3
;
171 cssmCerts
.CertEncoding
= CSSM_CERT_ENCODING_DER
;
172 cssmCerts
.NumCerts
= numCerts
;
173 cssmCerts
.GroupList
.CertList
= certs
;
174 cssmCerts
.CertGroupType
= CSSM_CERTGROUP_DATA
;
176 CSSM_RETURN crtn
= CSSM_TP_CertGroupVerify(tpHand
, clHand
, cspHand
,
179 NULL
); /* no results */
181 cssmPerror("CSSM_TP_CertGroupVerify", crtn
);
186 int main(int argc
, char **argv
)
191 /* common SecTrust args */
192 CFMutableArrayRef kcList
= NULL
;
193 CFMutableArrayRef certArray
= NULL
;
194 SecPolicyRef policyRef
= NULL
;
195 unsigned numCerts
= NUM_CERTS
;
196 CFArrayRef emptyKCList
= NULL
;
199 CSSM_TP_HANDLE tpHand
;
200 CSSM_CL_HANDLE clHand
;
201 CSSM_CSP_HANDLE cspHand
;
202 CSSM_DATA cssmCerts
[NUM_CERTS
];
204 /* user-spec'd variables */
205 unsigned loops
= LOOPS_DEF
;
206 bool holdKeychains
= false; /* hold references to KC list during operation */
207 bool useTp
= false; /* TP, not SecTrust */
208 bool useTrustSettings
= true; /* TP w/TrustSettings; false = old school TP way */
209 bool noRoot
= false; /* don't include root in chain to be verified */
210 bool emptyList
= false; /* SecTrust only: specify empty KC list */
214 while ((arg
= getopt(argc
, argv
, "l:ktTnKh")) != -1) {
217 loops
= atoi(optarg
);
220 holdKeychains
= true;
227 useTrustSettings
= false;
235 emptyKCList
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
245 /* gather certs to verify */
246 certArray
= CFArrayCreateMutable(NULL
, 3, &kCFTypeArrayCallBacks
);
247 for(dex
=0; dex
<numCerts
; dex
++) {
248 SecCertificateRef certRef
= readCertFile(certFiles
[dex
]);
249 if(certRef
== NULL
) {
252 CFArrayInsertValueAtIndex(certArray
, dex
, certRef
);
256 /* prepare for one method or another */
258 for(dex
=0; dex
<numCerts
; dex
++) {
259 crtn
= SecCertificateGetData(
260 (SecCertificateRef
)CFArrayGetValueAtIndex(certArray
, dex
),
263 cssmPerror("SecCertificateGetData", crtn
);
267 tpHand
= tpStartup();
268 clHand
= clStartup();
269 cspHand
= cspStartup();
272 /* cook up reusable policy object */
273 SecPolicySearchRef policySearch
= NULL
;
274 OSStatus ortn
= SecPolicySearchCreate(CSSM_CERT_X_509v3
,
275 &CSSMOID_APPLE_X509_BASIC
,
279 cssmPerror("SecPolicySearchCreate", ortn
);
282 ortn
= SecPolicySearchCopyNext(policySearch
, &policyRef
);
284 cssmPerror("SecPolicySearchCopyNext", ortn
);
287 CFRelease(policySearch
);
290 /* the standard keychains */
291 ortn
= SecKeychainCopySearchList((CFArrayRef
*)&kcList
);
293 cssmPerror("SecKeychainCopySearchList", ortn
);
297 /* plus the ones TrustSettings needs */
298 SecKeychainRef rootKc
;
299 ortn
= SecKeychainOpen(SYSTEM_ROOT_STORE_PATH
, &rootKc
);
301 cssmPerror("SecKeychainOpen", ortn
);
304 CFArrayAppendValue(kcList
, rootKc
);
309 CFAbsoluteTime startTimeFirst
;
310 CFAbsoluteTime endTimeFirst
;
311 CFAbsoluteTime startTimeMulti
;
312 CFAbsoluteTime endTimeMulti
;
314 /* print a banner describing current test parameters */
315 printf("Starting test: mode = ");
317 if(useTrustSettings
) {
318 printf("TP w/TrustSettings");
321 printf("TP w/o TrustSettings");
327 printf("; hold KC refs");
330 printf("; empty KC list");
334 printf("; no root in input certs\n");
341 startTimeFirst
= CFAbsoluteTimeGetCurrent();
343 if(doTpEval(tpHand
, clHand
, cspHand
, cssmCerts
, numCerts
,
347 endTimeFirst
= CFAbsoluteTimeGetCurrent();
349 startTimeMulti
= CFAbsoluteTimeGetCurrent();
350 for(dex
=0; dex
<loops
; dex
++) {
351 if(doTpEval(tpHand
, clHand
, cspHand
, cssmCerts
, numCerts
,
358 if(doEval(certArray
, policyRef
, emptyKCList
)) {
361 endTimeFirst
= CFAbsoluteTimeGetCurrent();
363 startTimeMulti
= CFAbsoluteTimeGetCurrent();
364 for(dex
=0; dex
<loops
; dex
++) {
365 if(doEval(certArray
, policyRef
, emptyKCList
)) {
370 endTimeMulti
= CFAbsoluteTimeGetCurrent();
371 CFTimeInterval elapsed
= endTimeMulti
- startTimeMulti
;
373 printf("First eval = %4.1f ms\n", (endTimeFirst
- startTimeFirst
) * 1000.0);
374 printf("Next evals = %4.2f ms/op (%f s total for %u loops)\n",
375 elapsed
* 1000.0 / loops
, elapsed
, loops
);