1 /* Copyright (c) 1997,2003-2005,2008 Apple Inc.
3 * common.c - Common CSP test code
7 * 4 May 2000 Doug Mitchell
9 * 6 Jul 1998 Doug Mitchell at Apple
11 * 12 Aug 1997 Doug Mitchell at Apple
18 #include <Security/cssm.h>
20 #include <Security/cssmapple.h> /* apple, not intel */
23 static CSSM_VERSION vers
= {2, 0};
24 //const static uint32 guidPrefix = 0xFADE;
25 const CSSM_GUID testGuid
= { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
28 * We can't enable this until all of these are fixed and integrated:
33 #define DETECT_MALLOC_ABUSE 1
35 #if DETECT_MALLOC_ABUSE
38 * This set of allocator functions detects when we free something
39 * which was mallocd by CDSA or a plugin using something other than
40 * our callback malloc/realloc/calloc. With proper runtime support
41 * (which is present in Jaguar 6C35), the reverse is also detected
42 * by malloc (i.e., we malloc something and CDSA or a plugin frees
45 #define APP_MALLOC_MAGIC 'Util'
47 void * appMalloc (CSSM_SIZE size
, void *allocRef
) {
50 /* scribble magic number in first four bytes */
51 ptr
= malloc(size
+ 4);
52 *(uint32
*)ptr
= APP_MALLOC_MAGIC
;
53 ptr
= (char *)ptr
+ 4;
58 void appFree (void *ptr
, void *allocRef
) {
62 ptr
= (char *)ptr
- 4;
63 if(*(uint32
*)ptr
!= APP_MALLOC_MAGIC
) {
64 printf("ERROR: appFree() freeing a block that we didn't allocate!\n");
65 return; // this free is not safe
71 /* Realloc - adjust both original pointer and size */
72 void * appRealloc (void *ptr
, CSSM_SIZE size
, void *allocRef
) {
74 /* no ptr, no existing magic number */
75 return appMalloc(size
, allocRef
);
77 ptr
= (char *)ptr
- 4;
78 if(*(uint32
*)ptr
!= APP_MALLOC_MAGIC
) {
79 printf("ERROR: appRealloc() on a block that we didn't allocate!\n");
82 ptr
= realloc(ptr
, size
+ 4);
83 *(uint32
*)ptr
= APP_MALLOC_MAGIC
;
84 ptr
= (char *)ptr
+ 4;
88 /* Have to do this manually */
89 void * appCalloc (uint32 num
, CSSM_SIZE size
, void *allocRef
) {
90 uint32 memSize
= num
* size
;
92 void *ptr
= appMalloc(memSize
, allocRef
);
93 memset(ptr
, 0, memSize
);
97 #else /* DETECT_MALLOC_ABUSE */
99 * Standard app-level memory functions required by CDSA.
101 void * appMalloc (CSSM_SIZE size
, void *allocRef
) {
102 return( malloc(size
) );
104 void appFree (void *mem_ptr
, void *allocRef
) {
108 void * appRealloc (void *ptr
, CSSM_SIZE size
, void *allocRef
) {
109 return( realloc( ptr
, size
) );
111 void * appCalloc (uint32 num
, CSSM_SIZE size
, void *allocRef
) {
112 return( calloc( num
, size
) );
114 #endif /* DETECT_MALLOC_ABUSE */
116 static CSSM_API_MEMORY_FUNCS memFuncs
= {
125 * Init CSSM; returns CSSM_FALSE on error. Reusable.
127 static CSSM_BOOL cssmInitd
= CSSM_FALSE
;
128 CSSM_BOOL
cssmStartup()
131 CSSM_PVC_MODE pvcPolicy
= CSSM_PVC_NONE
;
136 crtn
= CSSM_Init (&vers
,
137 CSSM_PRIVILEGE_SCOPE_NONE
,
139 CSSM_KEY_HIERARCHY_NONE
,
141 NULL
/* reserved */);
144 printError("CSSM_Init", crtn
);
148 cssmInitd
= CSSM_TRUE
;
154 * Init CSSM and establish a session with the Apple CSP.
156 CSSM_CSP_HANDLE
cspStartup()
158 return cspDlDbStartup(CSSM_TRUE
, NULL
);
161 /* like cspStartup, but also returns DB handle. If incoming dbHandPtr
162 * is NULL, no DB startup. */
163 CSSM_CSP_HANDLE
cspDbStartup(
164 CSSM_DB_HANDLE
*dbHandPtr
)
166 return cspDlDbStartup(CSSM_TRUE
, NULL
);
169 CSSM_CSP_HANDLE
cspDlDbStartup(
170 CSSM_BOOL bareCsp
, // true ==> CSP, false ==> CSP/DL
171 CSSM_DB_HANDLE
*dbHandPtr
) // optional - TO BE DELETED
173 CSSM_CSP_HANDLE cspHand
;
175 const CSSM_GUID
*guid
;
181 if(cssmStartup() == CSSM_FALSE
) {
185 guid
= &gGuidAppleCSP
;
186 modName
= (char*) "AppleCSP";
189 guid
= &gGuidAppleCSPDL
;
190 modName
= (char *) "AppleCSPDL";
192 crtn
= CSSM_ModuleLoad(guid
,
193 CSSM_KEY_HIERARCHY_NONE
,
194 NULL
, // eventHandler
195 NULL
); // AppNotifyCallbackCtx
198 sprintf(outStr
, "CSSM_ModuleLoad(%s)", modName
);
199 printError(outStr
, crtn
);
202 crtn
= CSSM_ModuleAttach (guid
,
204 &memFuncs
, // memFuncs
208 CSSM_KEY_HIERARCHY_NONE
,
209 NULL
, // FunctionTable
215 sprintf(outStr
, "CSSM_ModuleAttach(%s)", modName
);
216 printError(outStr
, crtn
);
223 * Detach and unload from a CSP.
225 CSSM_RETURN
cspShutdown(
226 CSSM_CSP_HANDLE cspHand
,
227 CSSM_BOOL bareCsp
) // true ==> CSP, false ==> CSP/DL
230 const CSSM_GUID
*guid
;
234 guid
= &gGuidAppleCSP
;
235 modName
= (char *) "AppleCSP";
238 guid
= &gGuidAppleCSPDL
;
239 modName
= (char *) "AppleCSPDL";
241 crtn
= CSSM_ModuleDetach(cspHand
);
243 printf("Error detaching from %s\n", modName
);
244 printError("CSSM_ModuleDetach", crtn
);
247 crtn
= CSSM_ModuleUnload(guid
, NULL
, NULL
);
249 printf("Error unloading %s\n", modName
);
250 printError("CSSM_ModuleUnload", crtn
);
255 /* Attach to DL side of CSPDL */
256 CSSM_DL_HANDLE
dlStartup()
258 CSSM_DL_HANDLE dlHand
= 0;
261 if(cssmStartup() == CSSM_FALSE
) {
264 crtn
= CSSM_ModuleLoad(&gGuidAppleCSPDL
,
265 CSSM_KEY_HIERARCHY_NONE
,
266 NULL
, // eventHandler
267 NULL
); // AppNotifyCallbackCtx
269 printError("CSSM_ModuleLoad(Apple CSPDL)", crtn
);
272 crtn
= CSSM_ModuleAttach (&gGuidAppleCSPDL
,
274 &memFuncs
, // memFuncs
278 CSSM_KEY_HIERARCHY_NONE
,
279 NULL
, // FunctionTable
284 printError("CSSM_ModuleAttach(Apple CSPDL)", crtn
);
293 #define DELETE_WITH_AUTHENT 0
294 CSSM_RETURN
dbDelete(
295 CSSM_DL_HANDLE dlHand
, // from dlStartup()
298 return CSSM_DL_DbDelete(dlHand
, dbName
, NULL
, NULL
);
302 * open a DB, ensure it's empty.
304 CSSM_DB_HANDLE
dbStartup(
305 CSSM_DL_HANDLE dlHand
, // from dlStartup()
308 CSSM_DB_HANDLE dbHand
= 0;
310 CSSM_RETURN crtn
= dbCreateOpen(dlHand
, dbName
,
315 if(crtn
== CSSM_OK
) {
325 * Attach to existing DB or create an empty new one.
327 CSSM_DB_HANDLE
dbStartupByName(CSSM_DL_HANDLE dlHand
,
332 CSSM_DB_HANDLE dbHand
;
334 /* try to open existing DB in either case */
336 crtn
= CSSM_DL_DbOpen(dlHand
,
339 CSSM_DB_ACCESS_READ
| CSSM_DB_ACCESS_WRITE
,
340 NULL
, // CSSM_ACCESS_CREDENTIALS *AccessCred
341 NULL
, // void *OpenParameters
347 printf("***no such data base (%s)\n", dbName
);
348 printError("CSSM_DL_DbOpen", crtn
);
351 /* have to create one */
352 return dbStartup(dlHand
, dbName
);
357 * routines which convert various types to untyped byte arrays.
359 void intToBytes(unsigned i
, unsigned char *buf
)
361 *buf
++ = (unsigned char)((i
>> 24) & 0xff);
362 *buf
++ = (unsigned char)((i
>> 16) & 0xff);
363 *buf
++ = (unsigned char)((i
>> 8) & 0xff);
364 *buf
= (unsigned char)(i
& 0xff);
366 void shortToBytes(unsigned short s
, unsigned char *buf
)
368 *buf
++ = (unsigned char)((s
>> 8) & 0xff);
369 *buf
= (unsigned char)(s
& 0xff);
371 unsigned bytesToInt(const unsigned char *buf
) {
373 result
= (((unsigned)buf
[0] << 24) & 0xff000000) |
374 (((unsigned)buf
[1] << 16) & 0x00ff0000) |
375 (((unsigned)buf
[2] << 8) & 0xff00) |
376 (((unsigned)buf
[3]) & 0xff);
379 unsigned short bytesToShort(const unsigned char *buf
) {
380 unsigned short result
;
381 result
= (((unsigned short)buf
[0] << 8) & 0xff00) |
382 (((unsigned short)buf
[1]) & 0xff);
387 * Given a context specified via a CSSM_CC_HANDLE, add a new
388 * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
389 * AttributeLength, and an untyped pointer.
391 * This is currently used to add a second CSSM_KEY attribute when performing
392 * ops with algorithm CSSM_ALGID_FEED and CSSM_ALGID_FEECFILE.
394 CSSM_RETURN
AddContextAttribute(CSSM_CC_HANDLE CCHandle
,
395 uint32 AttributeType
,
396 uint32 AttributeLength
,
397 ContextAttrType attrType
,
398 /* specify exactly one of these */
399 const void *AttributePtr
,
402 CSSM_CONTEXT_ATTRIBUTE newAttr
;
405 newAttr
.AttributeType
= AttributeType
;
406 newAttr
.AttributeLength
= AttributeLength
;
407 if(attrType
== CAT_Uint32
) {
408 newAttr
.Attribute
.Uint32
= attributeInt
;
411 newAttr
.Attribute
.Data
= (CSSM_DATA_PTR
)AttributePtr
;
413 crtn
= CSSM_UpdateContextAttributes(CCHandle
, 1, &newAttr
);
415 printError("CSSM_UpdateContextAttributes", crtn
);
421 * Set up a CSSM data.
423 CSSM_RETURN
appSetupCssmData(
428 printf("Hey! appSetupCssmData with NULL Data!\n");
429 return CSSMERR_CSSM_INTERNAL_ERROR
;
431 data
->Data
= (uint8
*)CSSM_MALLOC(numBytes
);
432 if(data
->Data
== NULL
) {
433 return CSSMERR_CSSM_MEMORY_ERROR
;
435 data
->Length
= numBytes
;
440 * Free the data referenced by a CSSM data, and optionally, the struct itself.
442 void appFreeCssmData(CSSM_DATA_PTR data
,
443 CSSM_BOOL freeStruct
)
448 if(data
->Length
!= 0) {
449 CSSM_FREE(data
->Data
);
461 * Copy src to dst, mallocing dst.
463 CSSM_RETURN
appCopyCssmData(const CSSM_DATA
*src
,
466 return appCopyData(src
->Data
, src
->Length
, dst
);
469 /* copy raw data to a CSSM_DATA, mallocing dst. */
470 CSSM_RETURN
appCopyData(const void *src
,
479 dst
->Data
= (uint8
*)CSSM_MALLOC(len
);
480 if(dst
->Data
== NULL
) {
481 return CSSM_ERRCODE_MEMORY_ERROR
;
484 memcpy(dst
->Data
, src
, len
);
488 CSSM_BOOL
appCompareCssmData(const CSSM_DATA
*d1
,
491 if(d1
->Length
!= d2
->Length
) {
494 if(memcmp(d1
->Data
, d2
->Data
, d1
->Length
)) {
500 /* min <= return <= max */
501 unsigned genRand(unsigned min
, unsigned max
)
507 appGetRandomBytes(&i
, 4);
508 return (min
+ (i
% (max
- min
+ 1)));
511 void simpleGenData(CSSM_DATA_PTR dbuf
, unsigned minBufSize
, unsigned maxBufSize
)
513 unsigned len
= genRand(minBufSize
, maxBufSize
);
514 appGetRandomBytes(dbuf
->Data
, len
);
519 #define MAX_OFFSET 99
520 #define MIN_ASCII 'a'
521 #define MAX_ASCII 'z'
524 * Calculate random data size, fill dataPool with that many random bytes.
526 * (10**minExp + MIN_OFFSET) <= size <= (10**maxExp + MAX_OFFSET)
528 unsigned genData(unsigned char *dataPool
,
541 * Calculate "random" size : (10 ** (random exponent)) + random offset
543 exp
= genRand(minExp
, maxExp
);
544 offset
= genRand(MIN_OFFSET
, MAX_OFFSET
);
546 while(exp
--) { // size = 10 ** exp
552 bzero(dataPool
, size
);
557 for(i
=0; i
<size
; i
++) {
564 cp
= (char *)dataPool
;
565 for(i
=0; i
<size
; i
++) {
573 appGetRandomBytes(dataPool
, size
);
580 const char *bufName
, // optional
587 printf("%s\n", bufName
);
590 for(i
=0; i
<len
; i
++) {
591 printf("%02X ", buf
[i
]);
599 int testError(CSSM_BOOL quiet
)
604 printf("\n***Test aborting.\n");
608 printf("a to abort, c to continue: ");
610 return (resp
== 'a');
613 void testStartBanner(
614 const char *testName
,
618 printf("Starting %s; args: ", testName
);
619 for(int i
=1; i
<argc
; i
++) {
620 printf("%s ", argv
[i
]);