]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/threadTest/cgConstructThr.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / threadTest / cgConstructThr.cpp
diff --git a/SecurityTests/clxutils/threadTest/cgConstructThr.cpp b/SecurityTests/clxutils/threadTest/cgConstructThr.cpp
new file mode 100644 (file)
index 0000000..4ef077b
--- /dev/null
@@ -0,0 +1,390 @@
+/* cgConstructThr.cpp - simple version CertGroupConstruct test */
+
+#include "testParams.h"
+#include <Security/cssm.h>
+#include <utilLib/common.h>
+#include <utilLib/cspwrap.h>
+#include <clAppUtils/clutils.h>
+#include <clAppUtils/tpUtils.h>
+#include <clAppUtils/timeStr.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+/* 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; i<numDbs; i++) {
+               sprintf(dbName, "%s%d", dbNameBase, i);
+               CSSM_RETURN crtn = tpKcOpen(dbName, 
+                       &dlDbPtr[i],
+                       doCreate,
+                       dlHand);
+               if(crtn) {
+                       printf("Can't create %d DBs\n", numDbs);
+                       return testError(quiet);
+               }
+       }
+       return 0;
+}
+#endif
+
+static int doTest(
+       CSSM_TP_HANDLE          tpHand,
+       CSSM_CL_HANDLE          clHand,
+       CSSM_CSP_HANDLE         cspHand,
+       CSSM_DL_DB_LIST_PTR     dbList,
+       CSSM_DATA_PTR           certs,
+       unsigned                        numCerts,
+       CSSM_BOOL                       verbose,
+       CSSM_BOOL                       allInDbs,
+       CSSM_BOOL                       skipFirstDb,
+       CSSM_BOOL                       publicRead)             // close/open with public access
+{
+       unsigned                                certsToUse;             // # of certs we actually use
+       CSSM_CERTGROUP                  certGroupFrag;  // INPUT to CertGroupConstruct
+       CSSM_CERTGROUP_PTR              resultGroup;    // OUTPUT from "
+       unsigned                                certDex;
+       int                                             rtn = 0;
+       CSSM_RETURN                             crtn;
+       
+       #if     CG_CONSTRUCT_TP_DB
+       if(publicRead && (dbList != NULL)) {
+               /* DBs are closed on entry, open r/w */
+               if(doOpenDbs(0,
+                               DB_NAME_BASE,
+                               dbList->DLDBHandle,
+                               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; i<dbList->NumHandles; 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; certDex<certsToUse; certDex++) {
+               if(!appCompareCssmData(&certs[certDex], 
+                                       &resultGroup->GroupList.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; i<dbList->NumHandles; i++) {           
+                       clDeleteAllCerts(dbList->DLDBHandle[i]);
+               }
+               if(publicRead) {
+                       if(verbose) {
+                               printf("   ...closing DBs\n");
+                       }
+                       for(i=0; i<dbList->NumHandles; 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; loopNum<testParams->numLoops; 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; dex<numCerts; dex++) {
+                       CSSM_FREE(certs[dex].Data);
+               }
+               memset(certs, 0, numCerts * sizeof(CSSM_DATA));
+               
+               #if DO_PAUSE
+               fpurge(stdin);
+               printf("Hit CR to proceed: ");
+               getchar();
+               #endif
+       }
+abort:
+       /* free resources */
+       for(dex=0; dex<numCerts; dex++) {
+               if(certs[dex].Data) {
+                       CSSM_FREE(certs[dex].Data);
+               }
+       }
+       CSSM_FREE(keyPairs->pubKeys);
+       CSSM_FREE(keyPairs->privKeys);
+       CSSM_FREE(keyPairs);
+       return status;
+}
+