]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/secTrustTime/secTrustTime.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / secTrustTime / secTrustTime.cpp
1 /*
2 * secTrustTime.cpp - measure performance of SecTrust and TP cert verify
3 */
4
5 #include <stdlib.h>
6 #include <strings.h>
7 #include <stdio.h>
8 #include <unistd.h>
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>
16
17 #define LOOPS_DEF 100
18
19 const char *certFiles[] = {
20 "keybank_v3.100.cer", "keybank_v3.101.cer", "keybank_v3.102.cer"
21 };
22
23 #define NUM_CERTS (sizeof(certFiles) / sizeof(certFiles[0]))
24
25 static void usage(char **argv)
26 {
27 printf("usage: %s [options]\n", argv[0]);
28 printf("Options:\n");
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");
35 /* etc. */
36 exit(1);
37 }
38
39 static SecCertificateRef readCertFile(
40 const char *fileName)
41 {
42 unsigned char *cp = NULL;
43 unsigned len = 0;
44 CSSM_DATA certData;
45 OSStatus ortn;
46
47 if(readFile(fileName, &cp, &len)) {
48 printf("***Error reading file %s\n", fileName);
49 return NULL;
50 }
51 certData.Length = len;
52 certData.Data = cp;
53 SecCertificateRef certRef;
54
55 ortn = SecCertificateCreateFromData(&certData,
56 CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &certRef);
57 if(ortn) {
58 cssmPerror("SecCertificateCreateFromData", ortn);
59 return NULL;
60 }
61 free(cp);
62 return certRef;
63 }
64
65 /* perfrom one cert chain evaluation using SecTrust */
66 static OSStatus doEval(
67 CFArrayRef certArray,
68 SecPolicyRef policyRef,
69 CFArrayRef kcList)
70 {
71 OSStatus ortn;
72 SecTrustRef trustRef;
73
74 ortn = SecTrustCreateWithCertificates(certArray, policyRef, &trustRef);
75 if(ortn) {
76 cssmPerror("SecTrustCreateWithCertificates", ortn);
77 return ortn;
78 }
79 if(kcList) {
80 ortn = SecTrustSetKeychains(trustRef, kcList);
81 if(ortn) {
82 cssmPerror("SecTrustCreateWithCertificates", ortn);
83 return ortn;
84 }
85 }
86 SecTrustResultType secTrustResult;
87 ortn = SecTrustEvaluate(trustRef, &secTrustResult);
88 if(ortn) {
89 cssmPerror("SecTrustEvaluate", ortn);
90 return ortn;
91 }
92 switch(secTrustResult) {
93 case kSecTrustResultProceed:
94 case kSecTrustResultUnspecified:
95 break;
96 default:
97 printf("***Unexpected SecTrustResultType (%d)\n", (int)secTrustResult);
98 ortn = -1;
99 }
100 CFRelease(trustRef);
101 return ortn;
102 }
103
104 /* cached CSSM anchors - simulate old SecTrustGetCSSMAnchorCertificates() */
105 static CFArrayRef cachedRootArray = NULL;
106 static CSSM_DATA *cachedAnchors = NULL;
107 static unsigned cachedNumAnchors = 0;
108
109 static OSStatus getAnchors(
110 CSSM_DATA **anchors, /* RETURNED */
111 unsigned *numAnchors) /* RETURNED */
112 {
113 if(cachedRootArray == NULL) {
114 /* fetch, once */
115 OSStatus ortn = getSystemAnchors(&cachedRootArray, &cachedAnchors,
116 &cachedNumAnchors);
117 if(ortn) {
118 return ortn;
119 }
120 }
121 *anchors = cachedAnchors;
122 *numAnchors = cachedNumAnchors;
123 return noErr;
124 }
125
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,
131 CSSM_DATA_PTR certs,
132 uint32 numCerts,
133 bool useTrustSettings)
134 {
135 CSSM_FIELD policyId;
136
137 policyId.FieldOid = CSSMOID_APPLE_X509_BASIC;
138 policyId.FieldValue.Data = NULL;
139 policyId.FieldValue.Length = 0;
140
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);
149 if(ortn) {
150 return ortn;
151 }
152 }
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;
157 }
158 else {
159 tpAction.ActionFlags = 0;
160 }
161
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;
168
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;
175
176 CSSM_RETURN crtn = CSSM_TP_CertGroupVerify(tpHand, clHand, cspHand,
177 &cssmCerts,
178 &vfyCtx,
179 NULL); /* no results */
180 if(crtn) {
181 cssmPerror("CSSM_TP_CertGroupVerify", crtn);
182 }
183 return crtn;
184 }
185
186 int main(int argc, char **argv)
187 {
188 unsigned dex;
189 CSSM_RETURN crtn;
190
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;
197
198 /* common TP args */
199 CSSM_TP_HANDLE tpHand;
200 CSSM_CL_HANDLE clHand;
201 CSSM_CSP_HANDLE cspHand;
202 CSSM_DATA cssmCerts[NUM_CERTS];
203
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 */
211
212 extern char *optarg;
213 int arg;
214 while ((arg = getopt(argc, argv, "l:ktTnKh")) != -1) {
215 switch (arg) {
216 case 'l':
217 loops = atoi(optarg);
218 break;
219 case 'k':
220 holdKeychains = true;
221 break;
222 case 't':
223 useTp = true;
224 break;
225 case 'T':
226 useTp = true;
227 useTrustSettings = false;
228 break;
229 case 'n':
230 numCerts--;
231 noRoot = true;
232 break;
233 case 'K':
234 emptyList = true;
235 emptyKCList = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
236 break;
237 case 'h':
238 usage(argv);
239 }
240 }
241 if(optind != argc) {
242 usage(argv);
243 }
244
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) {
250 exit(1);
251 }
252 CFArrayInsertValueAtIndex(certArray, dex, certRef);
253 CFRelease(certRef);
254 }
255
256 /* prepare for one method or another */
257 if(useTp) {
258 for(dex=0; dex<numCerts; dex++) {
259 crtn = SecCertificateGetData(
260 (SecCertificateRef)CFArrayGetValueAtIndex(certArray, dex),
261 &cssmCerts[dex]);
262 if(crtn) {
263 cssmPerror("SecCertificateGetData", crtn);
264 exit(1);
265 }
266 }
267 tpHand = tpStartup();
268 clHand = clStartup();
269 cspHand = cspStartup();
270 }
271 else {
272 /* cook up reusable policy object */
273 SecPolicySearchRef policySearch = NULL;
274 OSStatus ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3,
275 &CSSMOID_APPLE_X509_BASIC,
276 NULL, // policy opts
277 &policySearch);
278 if(ortn) {
279 cssmPerror("SecPolicySearchCreate", ortn);
280 exit(1);
281 }
282 ortn = SecPolicySearchCopyNext(policySearch, &policyRef);
283 if(ortn) {
284 cssmPerror("SecPolicySearchCopyNext", ortn);
285 exit(1);
286 }
287 CFRelease(policySearch);
288
289 if(holdKeychains) {
290 /* the standard keychains */
291 ortn = SecKeychainCopySearchList((CFArrayRef *)&kcList);
292 if(ortn) {
293 cssmPerror("SecKeychainCopySearchList", ortn);
294 exit(1);
295 }
296
297 /* plus the ones TrustSettings needs */
298 SecKeychainRef rootKc;
299 ortn = SecKeychainOpen(SYSTEM_ROOT_STORE_PATH, &rootKc);
300 if(ortn) {
301 cssmPerror("SecKeychainOpen", ortn);
302 exit(1);
303 }
304 CFArrayAppendValue(kcList, rootKc);
305 CFRelease(rootKc);
306 }
307 }
308
309 CFAbsoluteTime startTimeFirst;
310 CFAbsoluteTime endTimeFirst;
311 CFAbsoluteTime startTimeMulti;
312 CFAbsoluteTime endTimeMulti;
313
314 /* print a banner describing current test parameters */
315 printf("Starting test: mode = ");
316 if(useTp) {
317 if(useTrustSettings) {
318 printf("TP w/TrustSettings");
319 }
320 else {
321 printf("TP w/o TrustSettings");
322 }
323 }
324 else {
325 printf("SecTrust");
326 if(holdKeychains) {
327 printf("; hold KC refs");
328 }
329 if(emptyList) {
330 printf("; empty KC list");
331 }
332 }
333 if(noRoot) {
334 printf("; no root in input certs\n");
335 }
336 else {
337 printf("\n");
338 }
339
340 /* GO */
341 startTimeFirst = CFAbsoluteTimeGetCurrent();
342 if(useTp) {
343 if(doTpEval(tpHand, clHand, cspHand, cssmCerts, numCerts,
344 useTrustSettings)) {
345 exit(1);
346 }
347 endTimeFirst = CFAbsoluteTimeGetCurrent();
348
349 startTimeMulti = CFAbsoluteTimeGetCurrent();
350 for(dex=0; dex<loops; dex++) {
351 if(doTpEval(tpHand, clHand, cspHand, cssmCerts, numCerts,
352 useTrustSettings)) {
353 exit(1);
354 }
355 }
356 }
357 else {
358 if(doEval(certArray, policyRef, emptyKCList)) {
359 exit(1);
360 }
361 endTimeFirst = CFAbsoluteTimeGetCurrent();
362
363 startTimeMulti = CFAbsoluteTimeGetCurrent();
364 for(dex=0; dex<loops; dex++) {
365 if(doEval(certArray, policyRef, emptyKCList)) {
366 exit(1);
367 }
368 }
369 }
370 endTimeMulti = CFAbsoluteTimeGetCurrent();
371 CFTimeInterval elapsed = endTimeMulti - startTimeMulti;
372
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);
376
377 return 0;
378 }