1/*
2 * attach/creatContext/deleteContext/detach test
3 */
4#include "testParams.h"
5#include <Security/cssm.h>
6#include <stdlib.h>
7#include <stdio.h>
8#include <time.h>
9#include <string.h>
10#include <utilLib/common.h>
11#include <utilLib/cspwrap.h>
12
13/* for memory leak debug only, with only one thread running */
14#define DO_PAUSE			0
15
16#define ATTACHES_PER_LOOP	100
17#define ATTACH_EACH_LOOP	1		/* 1 ==> ATTACHES_PER_LOOP moduleAttaches */
18									/* 0 ==> all thru testParams->cspHand */
19#define CONTEXT_EACH_LOOP	1		/* 1 ==> CSSM_CSP_Create*Context for each attach */
20									/* 0 ==> just do attach/detach */
21#define CSPDL_ENABLE		1		/* attach to CSP and DL sides of CSPDL */
22#define DO_UNLOAD           0       /* enable CSSM_ModuleUnload() */
23
24#if		(!ATTACH_EACH_LOOP && !CONTEXT_EACH_LOOP)
25#error	Hey! Must configure for attach and/or createContext!
26#endif
27
28static CSSM_API_MEMORY_FUNCS memFuncs = {
29	appMalloc,
30	appFree,
31	appRealloc,
32 	appCalloc,
33 	NULL
34 };
35
36int attachTestInit(TestParams *testParams)
37{
38	/* nothing for now */
39	return 0;
40}
41
42static uint8 bogusKeyBits[] = {0, 1, 2, 3};
43static CSSM_VERSION vers = {2, 0};
44
45static CSSM_RETURN attachMod(
46	const CSSM_GUID *guid,
47	CSSM_SERVICE_TYPE svc,
48	CSSM_MODULE_HANDLE_PTR hand)
49{
50	CSSM_RETURN crtn = CSSM_ModuleLoad(guid,
51		CSSM_KEY_HIERARCHY_NONE,
52		NULL,			// eventHandler
53		NULL);			// AppNotifyCallbackCtx
54	if(crtn) {
55		return crtn;
56	}
57	return CSSM_ModuleAttach(guid,
58		&vers,
59		&memFuncs,					// memFuncs
60		0,							// SubserviceID
61		svc,						// SubserviceFlags
62		0,							// AttachFlags
63		CSSM_KEY_HIERARCHY_NONE,
64		NULL,						// FunctionTable
65		0,							// NumFuncTable
66		NULL,						// reserved
67		hand);
68}
69
70static int detachUnload(
71	CSSM_HANDLE hand,
72	const CSSM_GUID *guid)
73{
74	CSSM_RETURN crtn = CSSM_ModuleDetach(hand);
75	if(crtn) {
76		cssmPerror("CSSM_ModuleDetach", crtn);
77		return crtn;
78	}
79    #if DO_UNLOAD
80	crtn = CSSM_ModuleUnload(guid, NULL, NULL);
81	if(crtn) {
82		cssmPerror("CSSM_ModuleUnload", crtn);
83	}
84    #endif
85	return crtn;
86}
87
88int attachTest(TestParams *testParams)
89{
90	unsigned 			loop;
91	CSSM_RETURN 		crtn;
92	CSSM_CSP_HANDLE		cspHand[ATTACHES_PER_LOOP];
93	CSSM_CL_HANDLE		clHand[ATTACHES_PER_LOOP];
94	CSSM_TP_HANDLE		tpHand[ATTACHES_PER_LOOP];
95	#if CSPDL_ENABLE
96	CSSM_DL_HANDLE		dlHand[ATTACHES_PER_LOOP];
97	CSSM_CSP_HANDLE		cspDlHand[ATTACHES_PER_LOOP];
98	#endif
99	CSSM_CC_HANDLE		ccHand[ATTACHES_PER_LOOP];
100	unsigned			dex;
101	CSSM_KEY			bogusKey;
102
103	memset(cspHand, 0, ATTACHES_PER_LOOP * sizeof(CSSM_CSP_HANDLE));
104	memset(ccHand,  0, ATTACHES_PER_LOOP * sizeof(CSSM_CC_HANDLE));
105
106	/* set up a bogus key�which the CSP won't even see */
107	memset(&bogusKey, 0, sizeof(CSSM_KEY));
108	bogusKey.KeyData.Data = bogusKeyBits;
109	bogusKey.KeyData.Length = sizeof(bogusKeyBits);
110
111	for(loop=0; loop<testParams->numLoops; loop++) {
112		if(testParams->verbose) {
113			printf("attachTest thread %d: loop %d\n",
114				testParams->threadNum, loop);
115		}
116		else if(!testParams->quiet) {
117			printChar(testParams->progressChar);
118		}
119
120		if(ATTACH_EACH_LOOP) {
121			/* 'n' attaches, skipping load (which has known leaks) */
122			for(dex=0; dex<ATTACHES_PER_LOOP; dex++) {
123				crtn = attachMod(&gGuidAppleCSP,
124					CSSM_SERVICE_CSP, &cspHand[dex]);
125				if(crtn) {
126					printError("CSSM_ModuleAttach(CSP)", crtn);
127					return 1;
128				}
129				crtn = attachMod(&gGuidAppleX509CL,
130					CSSM_SERVICE_CL, &clHand[dex]);
131				if(crtn) {
132					printError("CSSM_ModuleAttach(CL)", crtn);
133					return 1;
134				}
135				crtn = attachMod(&gGuidAppleX509TP,
136					CSSM_SERVICE_TP, &tpHand[dex]);
137				if(crtn) {
138					printError("CSSM_ModuleAttach(TP)", crtn);
139					return 1;
140				}
141				#if CSPDL_ENABLE
142				crtn = attachMod(&gGuidAppleCSPDL,
143					CSSM_SERVICE_DL, &dlHand[dex]);
144				if(crtn) {
145					printError("CSSM_ModuleAttach(DL)", crtn);
146					return 1;
147				}
148				crtn = attachMod(&gGuidAppleCSPDL,
149					CSSM_SERVICE_CSP, &cspDlHand[dex]);
150				if(crtn) {
151					printError("CSSM_ModuleAttach(CSPDL)", crtn);
152					return 1;
153				}
154				#endif
155			}
156		}
157
158		/* now one of various crypt handles */
159		if(CONTEXT_EACH_LOOP) {
160			for(dex=0; dex<ATTACHES_PER_LOOP; dex++) {
161				CSSM_CSP_HANDLE curCspHand;
162				if(ATTACH_EACH_LOOP) {
163					curCspHand = cspHand[dex];
164				}
165				else {
166					curCspHand = testParams->cspHand;
167				}
168
169				switch(dex & 3) {
170					case 0:
171						/* symmetric context */
172						ccHand[dex] = genCryptHandle(curCspHand,
173							CSSM_ALGID_DES,
174							CSSM_ALGMODE_NONE,
175							CSSM_PADDING_NONE,
176							&bogusKey,
177							NULL,			// key2
178							NULL,			// IV
179							0,				// effectiveKeySizeInBits
180							0);				// rounds
181						break;
182					case 1:
183						/* asymmetric context */
184						ccHand[dex] = genCryptHandle(curCspHand,
185							CSSM_ALGID_RSA,
186							CSSM_ALGMODE_NONE,
187							CSSM_PADDING_NONE,
188							&bogusKey,
189							NULL,			// key2
190							NULL,			// IV
191							0,				// effectiveKeySizeInBits
192							0);				// rounds
193						break;
194					case 2:
195						/* Digest */
196						crtn = CSSM_CSP_CreateDigestContext(curCspHand,
197							CSSM_ALGID_SHA1,
198							&ccHand[dex]);
199						if(crtn) {
200							printError("CSSM_CSP_CreateDigestContext", crtn);
201							ccHand[dex] = CSSM_INVALID_HANDLE;
202						}
203						break;
204					case 3:
205						/* Digest */
206						crtn = CSSM_CSP_CreateSignatureContext(curCspHand,
207							CSSM_ALGID_SHA1WithRSA,
208							NULL,			// AccessCred
209							&bogusKey,
210							&ccHand[dex]);
211						if(crtn) {
212							printError("CSSM_CSP_CreateSignatureContext", crtn);
213							ccHand[dex] = CSSM_INVALID_HANDLE;
214						}
215						break;
216				}
217				if(curCspHand == CSSM_INVALID_HANDLE) {
218					return 1;
219				}
220			}
221
222			/* free handles */
223			for(dex=0; dex<ATTACHES_PER_LOOP; dex++) {
224				crtn = CSSM_DeleteContext(ccHand[dex]);
225				if(crtn) {
226					printError("CSSM_DeleteContext", crtn);
227					return 1;
228				}
229			}
230		}
231
232		if(ATTACH_EACH_LOOP) {
233			/* detach */
234			for(dex=0; dex<ATTACHES_PER_LOOP; dex++) {
235
236				crtn = detachUnload(cspHand[dex], &gGuidAppleCSP);
237				if(crtn) {
238					return 1;
239				}
240				crtn = detachUnload(clHand[dex], &gGuidAppleX509CL);
241				if(crtn) {
242					return 1;
243				}
244				crtn = detachUnload(tpHand[dex], &gGuidAppleX509TP);
245				if(crtn) {
246					return 1;
247				}
248				#if CSPDL_ENABLE
249				crtn = detachUnload(dlHand[dex], &gGuidAppleCSPDL);
250				if(crtn) {
251					return 1;
252				}
253				crtn = detachUnload(cspDlHand[dex], &gGuidAppleCSPDL);
254				if(crtn) {
255					return 1;
256				}
257				#endif
258			}
259		}
260		randomDelay();
261
262		#if DO_PAUSE
263		fpurge(stdin);
264		printf("Hit CR to proceed: ");
265		getchar();
266		#endif
267	}
268	return 0;
269}
270
271