--- /dev/null
+/*
+ * sslThrash.cpp
+ *
+ * track down multithread SecureTransport memory smasher - this test
+ * does no network I/O
+ */
+#include "testParams.h"
+#include <Security/cssm.h>
+#include <utilLib/common.h>
+#include <utilLib/cspwrap.h>
+#include <clAppUtils/clutils.h>
+#include <clAppUtils/tpUtils.h>
+#include <security_cdsa_utils/cuFileIo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <Security/SecureTransport.h>
+
+#define DO_PAUSE 0
+
+#define NUM_INNER_LOOPS 10
+
+
+/*
+ * Derive a symmetric CSSM_KEY from the specified raw key material.
+ */
+static CSSM_RETURN cdsaDeriveKey(
+ CSSM_CSP_HANDLE cspHandle,
+ const void *rawKey,
+ size_t rawKeyLen,
+ CSSM_ALGORITHMS keyAlg, // e.g., CSSM_ALGID_AES
+ uint32 keySizeInBits,
+ CSSM_KEY_PTR key)
+{
+ CSSM_RETURN crtn;
+ CSSM_CC_HANDLE ccHand;
+ CSSM_DATA dummyLabel = {8, (uint8 *)"tempKey"};
+ CSSM_DATA saltData = {8, (uint8 *)"someSalt"};
+ CSSM_PKCS5_PBKDF2_PARAMS pbeParams;
+ CSSM_DATA pbeData;
+ CSSM_ACCESS_CREDENTIALS creds;
+
+ memset(key, 0, sizeof(CSSM_KEY));
+ memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+ crtn = CSSM_CSP_CreateDeriveKeyContext(cspHandle,
+ CSSM_ALGID_PKCS5_PBKDF2,
+ keyAlg,
+ keySizeInBits,
+ &creds,
+ NULL, // BaseKey
+ 1000, // iterationCount, 1000 is the minimum
+ &saltData,
+ NULL, // seed
+ &ccHand);
+ if(crtn) {
+ cssmPerror("CSSM_CSP_CreateDeriveKeyContext", crtn);
+ return crtn;
+ }
+
+ /* this is the caller's raw key bits, typically ASCII (though it
+ * could be anything) */
+ pbeParams.Passphrase.Data = (uint8 *)rawKey;
+ pbeParams.Passphrase.Length = rawKeyLen;
+ /* The only PRF supported by the CSP is HMACSHA1 */
+ pbeParams.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
+ pbeData.Data = (uint8 *)&pbeParams;
+ pbeData.Length = sizeof(pbeParams);
+ crtn = CSSM_DeriveKey(ccHand,
+ &pbeData,
+ CSSM_KEYUSE_ANY,
+ CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE,
+ &dummyLabel,
+ NULL, // cred and acl
+ key);
+ CSSM_DeleteContext(ccHand); // ignore error here
+ if(crtn) {
+ cssmPerror("CSSM_DeriveKey", crtn);
+ }
+ return crtn;
+}
+
+static CSSM_API_MEMORY_FUNCS memFuncs = {
+ appMalloc,
+ appFree,
+ appRealloc,
+ appCalloc,
+ NULL
+ };
+static CSSM_VERSION vers = {2, 0};
+
+/*
+ * Initialize CDSA and attach to the CSP.
+ */
+static CSSM_RETURN cdsaCspAttach(
+ CSSM_CSP_HANDLE *cspHandle)
+{
+ CSSM_CSP_HANDLE cspHand;
+ CSSM_RETURN crtn;
+
+ /* Load the CSP bundle into this app's memory space */
+ crtn = CSSM_ModuleLoad(&gGuidAppleCSP,
+ CSSM_KEY_HIERARCHY_NONE,
+ NULL, // eventHandler
+ NULL); // AppNotifyCallbackCtx
+ if(crtn) {
+ return crtn;
+ }
+
+ /* obtain a handle which will be used to refer to the CSP */
+ crtn = CSSM_ModuleAttach (&gGuidAppleCSP,
+ &vers,
+ &memFuncs, // memFuncs
+ 0, // SubserviceID
+ CSSM_SERVICE_CSP,
+ 0, // AttachFlags
+ CSSM_KEY_HIERARCHY_NONE,
+ NULL, // FunctionTable
+ 0, // NumFuncTable
+ NULL, // reserved
+ &cspHand);
+ if(crtn) {
+ return crtn;
+ }
+ *cspHandle = cspHand;
+ return CSSM_OK;
+}
+
+static bool thrashInit = false;
+static bool doSsl = true;
+static bool doKey = true;
+static bool doAttach = true;
+
+int sslThrashInit(TestParams *testParams)
+{
+ if(thrashInit) {
+ return 0;
+ }
+
+ char *opts = testParams->testOpts;
+ if(opts == NULL) {
+ thrashInit = true;
+ return 0;
+ }
+ while(*opts != '\0') {
+ switch(*opts) {
+ case 'k':
+ doKey = false;
+ printf("...sslThrash: doKey disabled\n");
+ break;
+ case 's':
+ doSsl = false;
+ printf("...sslThrash: doSsl disabled\n");
+ break;
+ case 'a':
+ doAttach = false;
+ printf("...sslThrash: doAttach disabled\n");
+ break;
+ default:
+ /* for other tests */
+ break;
+ }
+ opts++;
+ }
+ thrashInit = true;
+ return 0;
+}
+
+#define FAKE_SSL 0
+#define SSL_CTX_SIZE 600
+#define FAKE_DISPOSE 0
+
+int sslThrash(TestParams *testParams)
+{
+ CSSM_RETURN crtn;
+ unsigned loopNum;
+ SSLContextRef sslCtx;
+ unsigned dex;
+ CSSM_KEY ckey;
+ CSSM_HANDLE cspHand;
+
+ for(loopNum=0; loopNum<testParams->numLoops; loopNum++) {
+ if(testParams->verbose) {
+ printf("sslThrash loop %d\n", loopNum);
+ }
+ else if(!testParams->quiet) {
+ printChar(testParams->progressChar);
+ }
+
+ for(dex=0; dex<NUM_INNER_LOOPS; dex++) {
+ if(doAttach) {
+ crtn = cdsaCspAttach(&cspHand);
+ if(crtn) {
+ printf("cdsaCspAttach error\n");
+ return 1;
+ }
+ }
+ if(doSsl) {
+ #if FAKE_SSL
+ sslCtx = (SSLContext *)malloc(SSL_CTX_SIZE);
+ #else
+ OSStatus ortn = SSLNewContext(false, &sslCtx);
+ if(ortn) {
+ cssmPerror("SSLNewContext", ortn);
+ printf("SSLNewContext error %d\n", (int)ortn);
+ return 1;
+ }
+ #endif
+ }
+ if(doKey) {
+ crtn = cdsaDeriveKey(testParams->cspHand,
+ "some silly string",
+ 17,
+ CSSM_ALGID_AES,
+ 128,
+ &ckey);
+ if(crtn) {
+ printf("cdsaDeriveKey error\n");
+ return 1;
+ }
+ }
+ if(doSsl) {
+ #if FAKE_SSL || FAKE_DISPOSE
+ free(sslCtx);
+ #else
+ OSStatus ortn = SSLDisposeContext(sslCtx);
+ if(ortn) {
+ cssmPerror("SSLDisposeContext", ortn);
+ printf("SSLDisposeContext error %d\n", (int)ortn);
+ return 1;
+ }
+ #endif
+ }
+ if(doKey) {
+ crtn = CSSM_FreeKey(testParams->cspHand,
+ NULL, // access cred
+ &ckey,
+ CSSM_FALSE);
+ if(crtn) {
+ cssmPerror("CSSM_FreeKey", crtn);
+ printf("CSSM_FreeKey error\n");
+ return 1;
+ }
+ }
+ if(doAttach) {
+ crtn = CSSM_ModuleDetach(cspHand);
+ if(crtn) {
+ cssmPerror("CSSM_ModuleDetach", crtn);
+ printf("CSSM_ModuleDetach error\n");
+ return 1;
+ }
+ }
+ randomDelay();
+
+ /* leak debug */
+ #if DO_PAUSE
+ fpurge(stdin);
+ printf("Hit CR to continue: ");
+ getchar();
+ #endif
+ } /* inner loop */
+
+ } /* outer loop */
+ return 0;
+}