/* * cgConstruct.c - basic test of TP's CertGroupConstruct * * cook up array of n key pairs; * cook up cert chain to go with them; * main test loop { * pick a random spot to break the cert chain - half the time use the * whole chain, half the time break it; * cook up CertGroup frag big enough for the unbroken part of the chain; * put cert[0] in certGroup[0]; * for each cert from cert[1] to break point { * roll the dice and put the cert in either a random place * in certGroup or in DB; * } * resultGroup = certGroupConstruct(); * vfy result Grp is identical to unbroken part of chain; * delete certs from DB; * } */ #include #include #include #include #include #include #include #include #include #include #define NUM_CERTS_DEF 10 #define NUM_DBS_DEF 3 #define KEYGEN_ALG_DEF CSSM_ALGID_RSA #define SIG_ALG_DEF CSSM_ALGID_SHA1WithRSA #define LOOPS_DEF 10 #define DB_NAME_BASE "cgConstruct" /* default */ #define SECONDS_TO_LIVE (60 * 60 * 24) /* certs are valid for this long */ /* Read-only access not supported */ #define PUBLIC_READ_ENABLE 0 static void usage(char **argv) { printf("Usage: %s [options]\n", argv[0]); printf(" Options:\n"); printf(" n=numCerts; default = %d\n", NUM_CERTS_DEF); printf(" l=loops; default=%d; 0=forever\n", LOOPS_DEF); printf(" a=alg (f=FEE/MD5, f=FEE/SHA1, e=FEE/ECDSA, r=RSA, E=ANSI ECDSA; default = RSA\n"); printf(" K=keySizeInBits\n"); #if TP_DB_ENABLE printf(" d=numDBs, default = %d\n", NUM_DBS_DEF); printf(" A(ll certs to DBs)\n"); printf(" k (skip first DB when storing)\n"); #if PUBLIC_READ_ENABLE printf(" p(ublic access open on read)\n"); #endif #endif printf(" f=fileNameBase (default = %s)\n", DB_NAME_BASE); printf(" P(ause on each loop)\n"); printf(" v(erbose)\n"); printf(" q(uiet)\n"); printf(" h(elp)\n"); exit(1); } #if TP_DB_ENABLE static int doOpenDbs( CSSM_DL_HANDLE dlHand, const char *dbNameBase, CSSM_DL_DB_HANDLE_PTR dlDbPtr, unsigned numDbs, CSSM_BOOL publicReadOnly, // ignored if !PUBLIC_READ_ENABLE CSSM_BOOL quiet) { unsigned i; char dbName[20]; CSSM_BOOL doCreate = (publicReadOnly ? CSSM_FALSE : CSSM_TRUE); for(i=0; iDLDBHandle, dbList->NumHandles, CSSM_FALSE, quiet)) { // publicReadOnly: this is create/write return 1; } } /* else DBs are already open and stay that way */ #endif /* * Pick a random spot to break the cert chain - half the time use the * whole chain, half the time break it. */ certsToUse = genRand(1, numCerts * 2); if(certsToUse > numCerts) { /* use the whole chain */ certsToUse = numCerts; } if(verbose) { printf(" ...numCerts %d certsToUse %d\n", numCerts, certsToUse); } if(tpMakeRandCertGroup(clHand, #if TP_DB_ENABLE dbList, #else NULL, #endif certs, certsToUse, &certGroupFrag, CSSM_TRUE, // firstCertIsSubject verbose, allInDbs, skipFirstDb)) { printf("Error in tpMakeRandCertGroup\n"); return testError(quiet); } if(certGroupFrag.NumCerts > certsToUse) { printf("Error NOMAD sterlize\n"); exit(1); } #if TP_DB_ENABLE if(publicRead) { /* close existing DBs and open again read-only */ unsigned i; CSSM_RETURN crtn; if(verbose) { printf(" ...closing DBs\n"); } for(i=0; iNumHandles; i++) { crtn = CSSM_DL_DbClose(dbList->DLDBHandle[i]); if(crtn) { printError("CSSM_DL_DbClose", crtn); if(testError(quiet)) { return 1; } } } if(verbose) { printf(" ...opening DBs read-only\n"); } if(doOpenDbs(dlHand, fileBaseName, dbList->DLDBHandle, dbList->NumHandles, CSSM_TRUE, // publicReadOnly: this is read only quiet)) { return 1; } } #endif /* * Okay, some of the certs we were given are in the DB, some are in * random places in certGroupFrag, some are nowhere (if certsToUse is * less than numCerts). Have the TP construct us an ordered verified * group. */ crtn = CSSM_TP_CertGroupConstruct( tpHand, clHand, cspHand, dbList, NULL, // ConstructParams &certGroupFrag, &resultGroup); if(crtn) { printError("CSSM_TP_CertGroupConstruct", crtn); return testError(quiet); } /* vfy resultGroup is identical to unbroken part of chain */ if(verbose) { printf(" ...CSSM_TP_CertGroupConstruct returned %u certs\n", (unsigned)resultGroup->NumCerts); } if(resultGroup->NumCerts != certsToUse) { printf("***resultGroup->NumCerts was %u, expected %u\n", (unsigned)resultGroup->NumCerts, (unsigned)certsToUse); rtn = testError(quiet); goto abort; } for(certDex=0; certDexGroupList.CertList[certDex])) { printf("***certs[%d] miscompare\n", certDex); rtn = testError(quiet); goto abort; } } abort: /* free resurces */ tpFreeCertGroup(&certGroupFrag, CSSM_FALSE, // caller malloc'd the actual certs CSSM_FALSE); // struct is on stack tpFreeCertGroup(resultGroup, CSSM_TRUE, // mallocd by TP CSSM_TRUE); // ditto #if TP_DB_ENABLE if(dbList != NULL) { unsigned i; CSSM_RETURN crtn; if(verbose) { printf(" ...deleting all certs from DBs\n"); } for(i=0; iNumHandles; i++) { clDeleteAllCerts(dbList->DLDBHandle[i]); } if(publicRead) { if(verbose) { printf(" ...closing DBs\n"); } for(i=0; iNumHandles; i++) { crtn = CSSM_DL_DbClose(dbList->DLDBHandle[i]); if(crtn) { printError("CSSM_DL_DbClose", crtn); if(testError(quiet)) { return 1; } } } } } #endif return rtn; } int main(int argc, char **argv) { int arg; char *argp; unsigned loop; CSSM_TP_HANDLE tpHand = 0; CSSM_CL_HANDLE clHand = 0; CSSM_CSP_HANDLE cspHand = 0; CSSM_DL_DB_LIST dbList = {0, NULL}; /* for storing certs */ CSSM_DL_DB_LIST_PTR dbListPtr; /* pts to dbList or NULL */ unsigned i; char *notAfterStr; char *notBeforeStr; CSSM_DL_HANDLE dlHand; /* all three of these are arrays with numCert elements */ CSSM_KEY_PTR pubKeys = NULL; CSSM_KEY_PTR privKeys = NULL; CSSM_DATA_PTR certs = NULL; /* Keys do NOT go in the cert DB */ CSSM_DL_DB_HANDLE keyDb = {0, 0}; /* * User-spec'd params */ unsigned loops = LOOPS_DEF; CSSM_BOOL verbose = CSSM_FALSE; CSSM_BOOL quiet = CSSM_FALSE; unsigned numCerts = NUM_CERTS_DEF; uint32 keyGenAlg = KEYGEN_ALG_DEF; uint32 sigAlg = SIG_ALG_DEF; unsigned numDBs = NUM_DBS_DEF; CSSM_BOOL allInDbs = CSSM_FALSE; CSSM_BOOL skipFirstDb = CSSM_FALSE; CSSM_BOOL publicRead = CSSM_FALSE; CSSM_BOOL doPause = CSSM_FALSE; uint32 keySizeInBits = CSP_KEY_SIZE_DEFAULT; const char *fileBaseName = DB_NAME_BASE; for(arg=1; arg