2 * cgConstruct.c - basic test of TP's CertGroupConstruct
4 * cook up array of n key pairs;
5 * cook up cert chain to go with them;
7 * pick a random spot to break the cert chain - half the time use the
8 * whole chain, half the time break it;
9 * cook up CertGroup frag big enough for the unbroken part of the chain;
10 * put cert[0] in certGroup[0];
11 * for each cert from cert[1] to break point {
12 * roll the dice and put the cert in either a random place
13 * in certGroup or in DB;
15 * resultGroup = certGroupConstruct();
16 * vfy result Grp is identical to unbroken part of chain;
17 * delete certs from DB;
21 #include <Security/cssm.h>
22 #include <utilLib/common.h>
23 #include <utilLib/cspwrap.h>
24 #include <clAppUtils/clutils.h>
25 #include <clAppUtils/tpUtils.h>
26 #include <clAppUtils/timeStr.h>
32 #define NUM_CERTS_DEF 10
34 #define KEYGEN_ALG_DEF CSSM_ALGID_RSA
35 #define SIG_ALG_DEF CSSM_ALGID_SHA1WithRSA
37 #define DB_NAME_BASE "cgConstruct" /* default */
38 #define SECONDS_TO_LIVE (60 * 60 * 24) /* certs are valid for this long */
40 /* Read-only access not supported */
41 #define PUBLIC_READ_ENABLE 0
43 static void usage(char **argv
)
45 printf("Usage: %s [options]\n", argv
[0]);
46 printf(" Options:\n");
47 printf(" n=numCerts; default = %d\n", NUM_CERTS_DEF
);
48 printf(" l=loops; default=%d; 0=forever\n", LOOPS_DEF
);
49 printf(" a=alg (f=FEE/MD5, f=FEE/SHA1, e=FEE/ECDSA, r=RSA, E=ANSI ECDSA; default = RSA\n");
50 printf(" K=keySizeInBits\n");
52 printf(" d=numDBs, default = %d\n", NUM_DBS_DEF
);
53 printf(" A(ll certs to DBs)\n");
54 printf(" k (skip first DB when storing)\n");
55 #if PUBLIC_READ_ENABLE
56 printf(" p(ublic access open on read)\n");
59 printf(" f=fileNameBase (default = %s)\n", DB_NAME_BASE
);
60 printf(" P(ause on each loop)\n");
61 printf(" v(erbose)\n");
69 CSSM_DL_HANDLE dlHand
,
70 const char *dbNameBase
,
71 CSSM_DL_DB_HANDLE_PTR dlDbPtr
,
73 CSSM_BOOL publicReadOnly
, // ignored if !PUBLIC_READ_ENABLE
78 CSSM_BOOL doCreate
= (publicReadOnly
? CSSM_FALSE
: CSSM_TRUE
);
80 for(i
=0; i
<numDbs
; i
++) {
81 dlDbPtr
[i
].DLHandle
= dlHand
;
82 sprintf(dbName
, "%s%d", dbNameBase
, i
);
83 CSSM_RETURN crtn
= tpKcOpen(dlHand
, dbName
,
84 dbName
, // file name as pwd
86 &dlDbPtr
[i
].DBHandle
);
88 printf("Can't create %d DBs\n", numDbs
);
89 return testError(quiet
);
97 CSSM_TP_HANDLE tpHand
,
98 CSSM_CL_HANDLE clHand
,
99 CSSM_CSP_HANDLE cspHand
,
100 CSSM_DL_HANDLE dlHand
,
101 CSSM_DL_DB_LIST_PTR dbList
,
106 CSSM_BOOL skipFirstDb
,
107 CSSM_BOOL publicRead
, // close/open with public access
108 const char *fileBaseName
,
111 unsigned certsToUse
; // # of certs we actually use
112 CSSM_CERTGROUP certGroupFrag
; // INPUT to CertGroupConstruct
113 CSSM_CERTGROUP_PTR resultGroup
; // OUTPUT from "
119 if(publicRead
&& (dbList
!= NULL
)) {
120 /* DBs are closed on entry, open r/w */
126 quiet
)) { // publicReadOnly: this is create/write
130 /* else DBs are already open and stay that way */
134 * Pick a random spot to break the cert chain - half the time use the
135 * whole chain, half the time break it.
137 certsToUse
= genRand(1, numCerts
* 2);
138 if(certsToUse
> numCerts
) {
139 /* use the whole chain */
140 certsToUse
= numCerts
;
143 printf(" ...numCerts %d certsToUse %d\n", numCerts
, certsToUse
);
146 if(tpMakeRandCertGroup(clHand
,
155 CSSM_TRUE
, // firstCertIsSubject
159 printf("Error in tpMakeRandCertGroup\n");
160 return testError(quiet
);
163 if(certGroupFrag
.NumCerts
> certsToUse
) {
164 printf("Error NOMAD sterlize\n");
170 /* close existing DBs and open again read-only */
176 printf(" ...closing DBs\n");
178 for(i
=0; i
<dbList
->NumHandles
; i
++) {
179 crtn
= CSSM_DL_DbClose(dbList
->DLDBHandle
[i
]);
181 printError("CSSM_DL_DbClose", crtn
);
182 if(testError(quiet
)) {
188 printf(" ...opening DBs read-only\n");
194 CSSM_TRUE
, // publicReadOnly: this is read only
202 * Okay, some of the certs we were given are in the DB, some are in
203 * random places in certGroupFrag, some are nowhere (if certsToUse is
204 * less than numCerts). Have the TP construct us an ordered verified
207 crtn
= CSSM_TP_CertGroupConstruct(
212 NULL
, // ConstructParams
216 printError("CSSM_TP_CertGroupConstruct", crtn
);
217 return testError(quiet
);
220 /* vfy resultGroup is identical to unbroken part of chain */
222 printf(" ...CSSM_TP_CertGroupConstruct returned %u certs\n",
223 (unsigned)resultGroup
->NumCerts
);
225 if(resultGroup
->NumCerts
!= certsToUse
) {
226 printf("***resultGroup->NumCerts was %u, expected %u\n",
227 (unsigned)resultGroup
->NumCerts
, (unsigned)certsToUse
);
228 rtn
= testError(quiet
);
231 for(certDex
=0; certDex
<certsToUse
; certDex
++) {
232 if(!appCompareCssmData(&certs
[certDex
],
233 &resultGroup
->GroupList
.CertList
[certDex
])) {
234 printf("***certs[%d] miscompare\n", certDex
);
235 rtn
= testError(quiet
);
241 tpFreeCertGroup(&certGroupFrag
,
242 CSSM_FALSE
, // caller malloc'd the actual certs
243 CSSM_FALSE
); // struct is on stack
244 tpFreeCertGroup(resultGroup
,
245 CSSM_TRUE
, // mallocd by TP
253 printf(" ...deleting all certs from DBs\n");
255 for(i
=0; i
<dbList
->NumHandles
; i
++) {
256 clDeleteAllCerts(dbList
->DLDBHandle
[i
]);
260 printf(" ...closing DBs\n");
262 for(i
=0; i
<dbList
->NumHandles
; i
++) {
263 crtn
= CSSM_DL_DbClose(dbList
->DLDBHandle
[i
]);
265 printError("CSSM_DL_DbClose", crtn
);
266 if(testError(quiet
)) {
277 int main(int argc
, char **argv
)
282 CSSM_TP_HANDLE tpHand
= 0;
283 CSSM_CL_HANDLE clHand
= 0;
284 CSSM_CSP_HANDLE cspHand
= 0;
285 CSSM_DL_DB_LIST dbList
= {0, NULL
}; /* for storing certs */
286 CSSM_DL_DB_LIST_PTR dbListPtr
; /* pts to dbList or NULL */
290 CSSM_DL_HANDLE dlHand
;
292 /* all three of these are arrays with numCert elements */
293 CSSM_KEY_PTR pubKeys
= NULL
;
294 CSSM_KEY_PTR privKeys
= NULL
;
295 CSSM_DATA_PTR certs
= NULL
;
297 /* Keys do NOT go in the cert DB */
298 CSSM_DL_DB_HANDLE keyDb
= {0, 0};
303 unsigned loops
= LOOPS_DEF
;
304 CSSM_BOOL verbose
= CSSM_FALSE
;
305 CSSM_BOOL quiet
= CSSM_FALSE
;
306 unsigned numCerts
= NUM_CERTS_DEF
;
307 uint32 keyGenAlg
= KEYGEN_ALG_DEF
;
308 uint32 sigAlg
= SIG_ALG_DEF
;
309 unsigned numDBs
= NUM_DBS_DEF
;
310 CSSM_BOOL allInDbs
= CSSM_FALSE
;
311 CSSM_BOOL skipFirstDb
= CSSM_FALSE
;
312 CSSM_BOOL publicRead
= CSSM_FALSE
;
313 CSSM_BOOL doPause
= CSSM_FALSE
;
314 uint32 keySizeInBits
= CSP_KEY_SIZE_DEFAULT
;
315 const char *fileBaseName
= DB_NAME_BASE
;
317 for(arg
=1; arg
<argc
; arg
++) {
321 loops
= atoi(&argp
[2]);
324 numCerts
= atoi(&argp
[2]);
327 keySizeInBits
= atoi(&argp
[2]);
338 keyGenAlg
= CSSM_ALGID_FEE
;
339 sigAlg
= CSSM_ALGID_FEE_MD5
;
342 keyGenAlg
= CSSM_ALGID_FEE
;
343 sigAlg
= CSSM_ALGID_FEE_SHA1
;
346 keyGenAlg
= CSSM_ALGID_FEE
;
347 sigAlg
= CSSM_ALGID_SHA1WithECDSA
;
350 keyGenAlg
= CSSM_ALGID_ECDSA
;
351 sigAlg
= CSSM_ALGID_SHA1WithECDSA
;
360 numDBs
= atoi(&argp
[2]);
363 allInDbs
= CSSM_TRUE
;
366 skipFirstDb
= CSSM_TRUE
;
368 #if PUBLIC_READ_ENABLE
370 publicRead
= CSSM_TRUE
;
374 fileBaseName
= &argp
[2];
385 /* attach to all the modules we need */
386 cspHand
= cspStartup();
393 clHand
= clStartup();
397 tpHand
= tpStartup();
402 /* malloc empty keys and certs */
403 pubKeys
= (CSSM_KEY_PTR
)CSSM_CALLOC(numCerts
, sizeof(CSSM_KEY
));
404 privKeys
= (CSSM_KEY_PTR
)CSSM_CALLOC(numCerts
, sizeof(CSSM_KEY
));
405 certs
= (CSSM_DATA_PTR
)CSSM_CALLOC(numCerts
, sizeof(CSSM_DATA
));
406 if((pubKeys
== NULL
) || (privKeys
== NULL
) || (certs
== NULL
)) {
407 printf("not enough memory for %u keys pairs and certs.\n",
412 printf("Starting cgConstruct; args: ");
413 for(i
=1; i
<(unsigned)argc
; i
++) {
414 printf("%s ", argv
[i
]);
418 /* generate key pairs */
420 printf("generating keys...\n");
422 if(tpGenKeys(cspHand
,
427 "cgConstruct", // keyLabelBase
432 notBeforeStr
= genTimeAtNowPlus(0);
433 notAfterStr
= genTimeAtNowPlus(SECONDS_TO_LIVE
);
436 /* create numDbs new DBs */
438 dlHand
= dlStartup();
442 dbList
.NumHandles
= numDBs
;
444 (CSSM_DL_DB_HANDLE_PTR
)CSSM_CALLOC(numDBs
, sizeof(CSSM_DL_DB_HANDLE
));
447 * In this case, this is the only time we open these DBs - they
448 * stay open for the duration of the test
451 printf(" ...opening DBs read/write\n");
457 CSSM_FALSE
, // publicReadOnly: this is create/write
465 /* it's required anyway... */
466 dbList
.NumHandles
= 0;
467 dbList
.DLDBHandle
= NULL
;
471 /* it's required anyway... */
472 dbList
.NumHandles
= 0;
473 dbList
.DLDBHandle
= NULL
;
477 for(loop
=1; ; loop
++) {
479 printf("...loop %d\n", loop
);
481 if(tpGenCerts(cspHand
,
485 "cgConstruct", // nameBase
508 for(i
=0; i
<numCerts
; i
++) {
509 appFreeCssmData(&certs
[i
], CSSM_FALSE
);
511 memset(certs
, 0, numCerts
* sizeof(CSSM_DATA
));
513 if(loops
&& (loop
== loops
)) {
517 printf("Hit CR to continue: ");
524 /* free keys and certs */
525 if(privKeys
!= NULL
) {
526 for(i
=0; i
<numCerts
; i
++) {
527 if(privKeys
[i
].KeyData
.Data
!= NULL
) {
528 cspFreeKey(cspHand
, &privKeys
[i
]);
533 if(pubKeys
!= NULL
) {
534 for(i
=0; i
<numCerts
; i
++) {
535 if(pubKeys
[i
].KeyData
.Data
!= NULL
) {
536 cspFreeKey(cspHand
, &pubKeys
[i
]);
542 for(i
=0; i
<numCerts
; i
++) {
543 appFreeCssmData(&certs
[i
], CSSM_FALSE
);
547 if(dbList
.DLDBHandle
!= NULL
) {
548 /* don't have to close, detach should do that */
549 CSSM_FREE(dbList
.DLDBHandle
);
552 CSSM_ModuleDetach(cspHand
);
555 CSSM_ModuleDetach(clHand
);
558 CSSM_ModuleDetach(tpHand
);
562 printf("%s test complete\n", argv
[0]);