X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/threadTest/cgConstructThr.cpp?ds=sidebyside diff --git a/SecurityTests/clxutils/threadTest/cgConstructThr.cpp b/SecurityTests/clxutils/threadTest/cgConstructThr.cpp new file mode 100644 index 00000000..4ef077bb --- /dev/null +++ b/SecurityTests/clxutils/threadTest/cgConstructThr.cpp @@ -0,0 +1,390 @@ +/* cgConstructThr.cpp - simple version CertGroupConstruct test */ + +#include "testParams.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* for memory leak debug only, with only one thread running */ +#define DO_PAUSE 0 + +/*** start of code directly copied from ../cgConstruct/cgConstruct.cpp ***/ +#define NUM_CERTS_MIN 4 +#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" +#define CG_KEY_SIZE_DEFAULT CSP_RSA_KEY_SIZE_DEFAULT +#define SECONDS_TO_LIVE (60 * 60 * 24) /* certs are valid for this long */ + +#define CG_CONSTRUCT_TP_DB 0 + +static int testError() +{ + char resp; + + fpurge(stdin); + printf("Attach via debugger for more info.\n"); + printf("a to abort, c to continue: "); + resp = getchar(); + return (resp == 'a'); +} + +#if CG_CONSTRUCT_TP_DB +static int doOpenDbs( + CSSM_DL_HANDLE dlHand, + 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 CG_CONSTRUCT_TP_DB + dbList, + #else + NULL, + #endif + certs, + certsToUse, + &certGroupFrag, + CSSM_TRUE, // firstCertIsSubject + verbose, + allInDbs, + skipFirstDb)) { + printf("\nError in tpMakeRandCertGroup\n"); + return testError(); + } + + if(certGroupFrag.NumCerts > certsToUse) { + printf("Error NOMAD sterlize\n"); + exit(1); + } + + #if CG_CONSTRUCT_TP_DB + 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"); + if(testError()) { + return 1; + } + } + } + if(verbose) { + printf(" ...opening DBs read-only\n"); + } + if(doOpenDbs(0, + DB_NAME_BASE, + 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(); + } + + /* 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("\n***cgConstruct: resultGroup->NumCerts was %u, expected %u\n", + (unsigned)resultGroup->NumCerts, (unsigned)certsToUse); + rtn = testError(); + goto abort; + } + for(certDex=0; certDexGroupList.CertList[certDex])) { + printf("\ncgConstruct: ***certs[%d] miscompare\n", certDex); + rtn = testError(); + 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 CG_CONSTRUCT_TP_DB + if(dbList != NULL) { + int 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"); + if(testError()) { + return 1; + } + } + } + } + } + #endif + return rtn; +} +/*** end of code directly copied from ../cgConstruct/cgConstruct.cpp ***/ + +/* + * key pairs - created in cgConstructInit, stored in testParams->perThread + */ +typedef struct { + CSSM_KEY_PTR pubKeys; + CSSM_KEY_PTR privKeys; + unsigned numKeys; + char *notBeforeStr; // to use thread-safe tpGenCerts() + char *notAfterStr; // to use thread-safe tpGenCerts() +} TT_KeyPairs; + +int cgConstructInit(TestParams *testParams) +{ + unsigned numKeys = NUM_CERTS_MIN + testParams->threadNum; + TT_KeyPairs *keyPairs; + + if(testParams->verbose) { + printf("cgConstruct thread %d: generating keys...\n", + testParams->threadNum); + } + keyPairs = (TT_KeyPairs *)CSSM_MALLOC(sizeof(TT_KeyPairs)); + keyPairs->numKeys = numKeys; + keyPairs->pubKeys = (CSSM_KEY_PTR)CSSM_CALLOC(numKeys, sizeof(CSSM_KEY)); + keyPairs->privKeys = (CSSM_KEY_PTR)CSSM_CALLOC(numKeys, sizeof(CSSM_KEY)); + CSSM_DL_DB_HANDLE nullDb = {0, 0}; + if(tpGenKeys(testParams->cspHand, + nullDb, // dbHand + numKeys, + KEYGEN_ALG_DEF, + CG_KEY_SIZE_DEFAULT, + "cgConstruct", // keyLabelBase + keyPairs->pubKeys, + keyPairs->privKeys)) { + goto abort; + } + keyPairs->notBeforeStr = genTimeAtNowPlus(0); + keyPairs->notAfterStr = genTimeAtNowPlus(SECONDS_TO_LIVE); + + testParams->perThread = keyPairs; + return 0; + +abort: + printf("Error generating keys; aborting\n"); + CSSM_FREE(keyPairs->pubKeys); + CSSM_FREE(keyPairs->privKeys); + CSSM_FREE(keyPairs); + return 1; +} + +int cgConstruct(TestParams *testParams) +{ + unsigned loopNum; + int status = -1; // exit status, default = error + TT_KeyPairs *keyPairs = (TT_KeyPairs *)testParams->perThread; + unsigned dex; + + /* all three of these are arrays with numCert elements */ + CSSM_KEY_PTR pubKeys = keyPairs->pubKeys; + CSSM_KEY_PTR privKeys = keyPairs->privKeys; + CSSM_DATA_PTR certs = NULL; + + unsigned numCerts = keyPairs->numKeys; + uint32 sigAlg = SIG_ALG_DEF; + CSSM_DL_DB_LIST dbList = {0, NULL}; /* for storing certs */ + CSSM_DL_DB_LIST_PTR dbListPtr; /* pts to dbList or NULL */ + CSSM_BOOL publicRead = CSSM_FALSE; + CSSM_BOOL allInDbs = CSSM_FALSE; + CSSM_BOOL skipFirstDb = CSSM_FALSE; + + /* malloc empty certs */ + certs = (CSSM_DATA_PTR)CSSM_CALLOC(numCerts, sizeof(CSSM_DATA)); + if(certs == NULL) { + printf("not enough memory for %u certs.\n", numCerts); + goto abort; + } + memset(certs, 0, numCerts * sizeof(CSSM_DATA)); + + dbList.NumHandles = 0; + dbList.DLDBHandle = NULL; + dbListPtr = &dbList; + for(loopNum=0; loopNumnumLoops; loopNum++) { + + /* generate certs */ + if(testParams->verbose) { + printf("cgConstruct thread %d: generating certs...\n", + testParams->threadNum); + } + else if(!testParams->quiet) { + printChar(testParams->progressChar); + } + if(tpGenCerts(testParams->cspHand, + testParams->clHand, + numCerts, + sigAlg, + "cgConstruct", // nameBase + pubKeys, + privKeys, + certs, + keyPairs->notBeforeStr, + keyPairs->notAfterStr)) { + status = 1; + goto abort; + } + + status = doTest(testParams->tpHand, + testParams->clHand, + testParams->cspHand, + dbListPtr, + certs, + numCerts, + testParams->verbose, + allInDbs, + skipFirstDb, + publicRead); + if(status) { + break; + } + + /* free certs */ + for(dex=0; dexpubKeys); + CSSM_FREE(keyPairs->privKeys); + CSSM_FREE(keyPairs); + return status; +} +