]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/threadTest/cgConstructThr.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / threadTest / cgConstructThr.cpp
1 /* cgConstructThr.cpp - simple version CertGroupConstruct test */
2
3 #include "testParams.h"
4 #include <Security/cssm.h>
5 #include <utilLib/common.h>
6 #include <utilLib/cspwrap.h>
7 #include <clAppUtils/clutils.h>
8 #include <clAppUtils/tpUtils.h>
9 #include <clAppUtils/timeStr.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <time.h>
13 #include <string.h>
14
15 /* for memory leak debug only, with only one thread running */
16 #define DO_PAUSE 0
17
18 /*** start of code directly copied from ../cgConstruct/cgConstruct.cpp ***/
19 #define NUM_CERTS_MIN 4
20 #define NUM_DBS_DEF 3
21 #define KEYGEN_ALG_DEF CSSM_ALGID_RSA
22 #define SIG_ALG_DEF CSSM_ALGID_SHA1WithRSA
23 #define LOOPS_DEF 10
24 #define DB_NAME_BASE "cgConstruct"
25 #define CG_KEY_SIZE_DEFAULT CSP_RSA_KEY_SIZE_DEFAULT
26 #define SECONDS_TO_LIVE (60 * 60 * 24) /* certs are valid for this long */
27
28 #define CG_CONSTRUCT_TP_DB 0
29
30 static int testError()
31 {
32 char resp;
33
34 fpurge(stdin);
35 printf("Attach via debugger for more info.\n");
36 printf("a to abort, c to continue: ");
37 resp = getchar();
38 return (resp == 'a');
39 }
40
41 #if CG_CONSTRUCT_TP_DB
42 static int doOpenDbs(
43 CSSM_DL_HANDLE dlHand,
44 char *dbNameBase,
45 CSSM_DL_DB_HANDLE_PTR dlDbPtr,
46 unsigned numDbs,
47 CSSM_BOOL publicReadOnly, // ignored if !PUBLIC_READ_ENABLE
48 CSSM_BOOL quiet)
49 {
50 unsigned i;
51 char dbName[20];
52 CSSM_BOOL doCreate = (publicReadOnly ? CSSM_FALSE : CSSM_TRUE);
53
54 for(i=0; i<numDbs; i++) {
55 sprintf(dbName, "%s%d", dbNameBase, i);
56 CSSM_RETURN crtn = tpKcOpen(dbName,
57 &dlDbPtr[i],
58 doCreate,
59 dlHand);
60 if(crtn) {
61 printf("Can't create %d DBs\n", numDbs);
62 return testError(quiet);
63 }
64 }
65 return 0;
66 }
67 #endif
68
69 static int doTest(
70 CSSM_TP_HANDLE tpHand,
71 CSSM_CL_HANDLE clHand,
72 CSSM_CSP_HANDLE cspHand,
73 CSSM_DL_DB_LIST_PTR dbList,
74 CSSM_DATA_PTR certs,
75 unsigned numCerts,
76 CSSM_BOOL verbose,
77 CSSM_BOOL allInDbs,
78 CSSM_BOOL skipFirstDb,
79 CSSM_BOOL publicRead) // close/open with public access
80 {
81 unsigned certsToUse; // # of certs we actually use
82 CSSM_CERTGROUP certGroupFrag; // INPUT to CertGroupConstruct
83 CSSM_CERTGROUP_PTR resultGroup; // OUTPUT from "
84 unsigned certDex;
85 int rtn = 0;
86 CSSM_RETURN crtn;
87
88 #if CG_CONSTRUCT_TP_DB
89 if(publicRead && (dbList != NULL)) {
90 /* DBs are closed on entry, open r/w */
91 if(doOpenDbs(0,
92 DB_NAME_BASE,
93 dbList->DLDBHandle,
94 dbList->NumHandles,
95 CSSM_FALSE,
96 quiet)) { // publicReadOnly: this is create/write
97 return 1;
98 }
99 }
100 /* else DBs are already open and stay that way */
101 #endif
102
103 /*
104 * Pick a random spot to break the cert chain - half the time use the
105 * whole chain, half the time break it.
106 */
107 certsToUse = genRand(1, numCerts * 2);
108 if(certsToUse > numCerts) {
109 /* use the whole chain */
110 certsToUse = numCerts;
111 }
112 if(verbose) {
113 printf(" ...numCerts %d certsToUse %d\n", numCerts, certsToUse);
114 }
115
116 if(tpMakeRandCertGroup(clHand,
117 #if CG_CONSTRUCT_TP_DB
118 dbList,
119 #else
120 NULL,
121 #endif
122 certs,
123 certsToUse,
124 &certGroupFrag,
125 CSSM_TRUE, // firstCertIsSubject
126 verbose,
127 allInDbs,
128 skipFirstDb)) {
129 printf("\nError in tpMakeRandCertGroup\n");
130 return testError();
131 }
132
133 if(certGroupFrag.NumCerts > certsToUse) {
134 printf("Error NOMAD sterlize\n");
135 exit(1);
136 }
137
138 #if CG_CONSTRUCT_TP_DB
139 if(publicRead) {
140 /* close existing DBs and open again read-only */
141
142 unsigned i;
143 CSSM_RETURN crtn;
144
145 if(verbose) {
146 printf(" ...closing DBs\n");
147 }
148 for(i=0; i<dbList->NumHandles; i++) {
149 crtn = CSSM_DL_DbClose(dbList->DLDBHandle[i]);
150 if(crtn) {
151 printError("CSSM_DL_DbClose");
152 if(testError()) {
153 return 1;
154 }
155 }
156 }
157 if(verbose) {
158 printf(" ...opening DBs read-only\n");
159 }
160 if(doOpenDbs(0,
161 DB_NAME_BASE,
162 dbList->DLDBHandle,
163 dbList->NumHandles,
164 CSSM_TRUE, // publicReadOnly: this is read only
165 quiet)) {
166 return 1;
167 }
168 }
169 #endif
170
171 /*
172 * Okay, some of the certs we were given are in the DB, some are in
173 * random places in certGroupFrag, some are nowhere (if certsToUse is
174 * less than numCerts). Have the TP construct us an ordered verified
175 * group.
176 */
177 crtn = CSSM_TP_CertGroupConstruct(
178 tpHand,
179 clHand,
180 cspHand,
181 dbList,
182 NULL, // ConstructParams
183 &certGroupFrag,
184 &resultGroup);
185 if(crtn) {
186 printError("CSSM_TP_CertGroupConstruct", crtn);
187 return testError();
188 }
189
190 /* vfy resultGroup is identical to unbroken part of chain */
191 if(verbose) {
192 printf(" ...CSSM_TP_CertGroupConstruct returned %u certs\n",
193 (unsigned)resultGroup->NumCerts);
194 }
195 if(resultGroup->NumCerts != certsToUse) {
196 printf("\n***cgConstruct: resultGroup->NumCerts was %u, expected %u\n",
197 (unsigned)resultGroup->NumCerts, (unsigned)certsToUse);
198 rtn = testError();
199 goto abort;
200 }
201 for(certDex=0; certDex<certsToUse; certDex++) {
202 if(!appCompareCssmData(&certs[certDex],
203 &resultGroup->GroupList.CertList[certDex])) {
204 printf("\ncgConstruct: ***certs[%d] miscompare\n", certDex);
205 rtn = testError();
206 goto abort;
207 }
208 }
209 abort:
210 /* free resurces */
211 tpFreeCertGroup(&certGroupFrag,
212 CSSM_FALSE, // caller malloc'd the actual certs
213 CSSM_FALSE); // struct is on stack
214 tpFreeCertGroup(resultGroup,
215 CSSM_TRUE, // mallocd by TP
216 CSSM_TRUE); // ditto
217 #if CG_CONSTRUCT_TP_DB
218 if(dbList != NULL) {
219 int i;
220 CSSM_RETURN crtn;
221
222 if(verbose) {
223 printf(" ...deleting all certs from DBs\n");
224 }
225 for(i=0; i<dbList->NumHandles; i++) {
226 clDeleteAllCerts(dbList->DLDBHandle[i]);
227 }
228 if(publicRead) {
229 if(verbose) {
230 printf(" ...closing DBs\n");
231 }
232 for(i=0; i<dbList->NumHandles; i++) {
233 crtn = CSSM_DL_DbClose(dbList->DLDBHandle[i]);
234 if(crtn) {
235 printError("CSSM_DL_DbClose");
236 if(testError()) {
237 return 1;
238 }
239 }
240 }
241 }
242 }
243 #endif
244 return rtn;
245 }
246 /*** end of code directly copied from ../cgConstruct/cgConstruct.cpp ***/
247
248 /*
249 * key pairs - created in cgConstructInit, stored in testParams->perThread
250 */
251 typedef struct {
252 CSSM_KEY_PTR pubKeys;
253 CSSM_KEY_PTR privKeys;
254 unsigned numKeys;
255 char *notBeforeStr; // to use thread-safe tpGenCerts()
256 char *notAfterStr; // to use thread-safe tpGenCerts()
257 } TT_KeyPairs;
258
259 int cgConstructInit(TestParams *testParams)
260 {
261 unsigned numKeys = NUM_CERTS_MIN + testParams->threadNum;
262 TT_KeyPairs *keyPairs;
263
264 if(testParams->verbose) {
265 printf("cgConstruct thread %d: generating keys...\n",
266 testParams->threadNum);
267 }
268 keyPairs = (TT_KeyPairs *)CSSM_MALLOC(sizeof(TT_KeyPairs));
269 keyPairs->numKeys = numKeys;
270 keyPairs->pubKeys = (CSSM_KEY_PTR)CSSM_CALLOC(numKeys, sizeof(CSSM_KEY));
271 keyPairs->privKeys = (CSSM_KEY_PTR)CSSM_CALLOC(numKeys, sizeof(CSSM_KEY));
272 CSSM_DL_DB_HANDLE nullDb = {0, 0};
273 if(tpGenKeys(testParams->cspHand,
274 nullDb, // dbHand
275 numKeys,
276 KEYGEN_ALG_DEF,
277 CG_KEY_SIZE_DEFAULT,
278 "cgConstruct", // keyLabelBase
279 keyPairs->pubKeys,
280 keyPairs->privKeys)) {
281 goto abort;
282 }
283 keyPairs->notBeforeStr = genTimeAtNowPlus(0);
284 keyPairs->notAfterStr = genTimeAtNowPlus(SECONDS_TO_LIVE);
285
286 testParams->perThread = keyPairs;
287 return 0;
288
289 abort:
290 printf("Error generating keys; aborting\n");
291 CSSM_FREE(keyPairs->pubKeys);
292 CSSM_FREE(keyPairs->privKeys);
293 CSSM_FREE(keyPairs);
294 return 1;
295 }
296
297 int cgConstruct(TestParams *testParams)
298 {
299 unsigned loopNum;
300 int status = -1; // exit status, default = error
301 TT_KeyPairs *keyPairs = (TT_KeyPairs *)testParams->perThread;
302 unsigned dex;
303
304 /* all three of these are arrays with numCert elements */
305 CSSM_KEY_PTR pubKeys = keyPairs->pubKeys;
306 CSSM_KEY_PTR privKeys = keyPairs->privKeys;
307 CSSM_DATA_PTR certs = NULL;
308
309 unsigned numCerts = keyPairs->numKeys;
310 uint32 sigAlg = SIG_ALG_DEF;
311 CSSM_DL_DB_LIST dbList = {0, NULL}; /* for storing certs */
312 CSSM_DL_DB_LIST_PTR dbListPtr; /* pts to dbList or NULL */
313 CSSM_BOOL publicRead = CSSM_FALSE;
314 CSSM_BOOL allInDbs = CSSM_FALSE;
315 CSSM_BOOL skipFirstDb = CSSM_FALSE;
316
317 /* malloc empty certs */
318 certs = (CSSM_DATA_PTR)CSSM_CALLOC(numCerts, sizeof(CSSM_DATA));
319 if(certs == NULL) {
320 printf("not enough memory for %u certs.\n", numCerts);
321 goto abort;
322 }
323 memset(certs, 0, numCerts * sizeof(CSSM_DATA));
324
325 dbList.NumHandles = 0;
326 dbList.DLDBHandle = NULL;
327 dbListPtr = &dbList;
328 for(loopNum=0; loopNum<testParams->numLoops; loopNum++) {
329
330 /* generate certs */
331 if(testParams->verbose) {
332 printf("cgConstruct thread %d: generating certs...\n",
333 testParams->threadNum);
334 }
335 else if(!testParams->quiet) {
336 printChar(testParams->progressChar);
337 }
338 if(tpGenCerts(testParams->cspHand,
339 testParams->clHand,
340 numCerts,
341 sigAlg,
342 "cgConstruct", // nameBase
343 pubKeys,
344 privKeys,
345 certs,
346 keyPairs->notBeforeStr,
347 keyPairs->notAfterStr)) {
348 status = 1;
349 goto abort;
350 }
351
352 status = doTest(testParams->tpHand,
353 testParams->clHand,
354 testParams->cspHand,
355 dbListPtr,
356 certs,
357 numCerts,
358 testParams->verbose,
359 allInDbs,
360 skipFirstDb,
361 publicRead);
362 if(status) {
363 break;
364 }
365
366 /* free certs */
367 for(dex=0; dex<numCerts; dex++) {
368 CSSM_FREE(certs[dex].Data);
369 }
370 memset(certs, 0, numCerts * sizeof(CSSM_DATA));
371
372 #if DO_PAUSE
373 fpurge(stdin);
374 printf("Hit CR to proceed: ");
375 getchar();
376 #endif
377 }
378 abort:
379 /* free resources */
380 for(dex=0; dex<numCerts; dex++) {
381 if(certs[dex].Data) {
382 CSSM_FREE(certs[dex].Data);
383 }
384 }
385 CSSM_FREE(keyPairs->pubKeys);
386 CSSM_FREE(keyPairs->privKeys);
387 CSSM_FREE(keyPairs);
388 return status;
389 }
390