1/*
2 * clutils.c - common CL app-level routines, X version
3 */
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <Security/cssm.h>
8#include "clutils.h"
9#include <Security/cssmapple.h>		/* apple, not intel */
10#include <utilLib/common.h>
11
12static CSSM_API_MEMORY_FUNCS memFuncs = {
13	appMalloc,
14	appFree,
15	appRealloc,
16 	appCalloc,
17 	NULL
18 };
19
20static CSSM_VERSION vers = {2, 0};
21
22/*
23 * Init CSSM and establish a session with the Apple CL.
24 */
25CSSM_CL_HANDLE clStartup()
26{
27	CSSM_CL_HANDLE clHand;
28	CSSM_RETURN crtn;
29
30	if(cssmStartup() == CSSM_FALSE) {
31		return 0;
32	}
33	crtn = CSSM_ModuleLoad(&gGuidAppleX509CL,
34		CSSM_KEY_HIERARCHY_NONE,
35		NULL,			// eventHandler
36		NULL);			// AppNotifyCallbackCtx
37	if(crtn) {
38		printError("CSSM_ModuleLoad(AppleCL)", crtn);
39		return 0;
40	}
41	crtn = CSSM_ModuleAttach (&gGuidAppleX509CL,
42		&vers,
43		&memFuncs,				// memFuncs
44		0,						// SubserviceID
45		CSSM_SERVICE_CL,		// SubserviceFlags - Where is this used?
46		0,						// AttachFlags
47		CSSM_KEY_HIERARCHY_NONE,
48		NULL,					// FunctionTable
49		0,						// NumFuncTable
50		NULL,					// reserved
51		&clHand);
52	if(crtn) {
53		printError("CSSM_ModuleAttach(AppleCL)", crtn);
54		return 0;
55	}
56	else {
57		return clHand;
58	}
59}
60
61void clShutdown(
62	CSSM_CL_HANDLE clHand)
63{
64	CSSM_RETURN crtn;
65
66	crtn = CSSM_ModuleDetach(clHand);
67	if(crtn) {
68		printf("Error detaching from AppleCL\n");
69		printError("CSSM_ModuleDetach", crtn);
70		return;
71	}
72	crtn = CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL);
73	if(crtn) {
74		printf("Error unloading AppleCL\n");
75		printError("CSSM_ModuleUnload", crtn);
76	}
77}
78
79/*
80 * Init CSSM and establish a session with the Apple TP.
81 */
82CSSM_TP_HANDLE tpStartup()
83{
84	CSSM_TP_HANDLE tpHand;
85	CSSM_RETURN crtn;
86
87	if(cssmStartup() == CSSM_FALSE) {
88		return 0;
89	}
90	crtn = CSSM_ModuleLoad(&gGuidAppleX509TP,
91		CSSM_KEY_HIERARCHY_NONE,
92		NULL,			// eventHandler
93		NULL);			// AppNotifyCallbackCtx
94	if(crtn) {
95		printError("CSSM_ModuleLoad(AppleTP)", crtn);
96		return 0;
97	}
98	crtn = CSSM_ModuleAttach (&gGuidAppleX509TP,
99		&vers,
100		&memFuncs,				// memFuncs
101		0,						// SubserviceID
102		CSSM_SERVICE_TP,		// SubserviceFlags
103		0,						// AttachFlags
104		CSSM_KEY_HIERARCHY_NONE,
105		NULL,					// FunctionTable
106		0,						// NumFuncTable
107		NULL,					// reserved
108		&tpHand);
109	if(crtn) {
110		printError("CSSM_ModuleAttach(AppleTP)", crtn);
111		return 0;
112	}
113	else {
114		return tpHand;
115	}
116}
117
118void tpShutdown(
119	CSSM_TP_HANDLE tpHand)
120{
121	CSSM_RETURN crtn;
122
123	crtn = CSSM_ModuleDetach(tpHand);
124	if(crtn) {
125		printf("Error detaching from AppleTP\n");
126		printError("CSSM_ModuleDetach", crtn);
127		return;
128	}
129	crtn = CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL);
130	if(crtn) {
131		printf("Error unloading AppleTP\n");
132		printError("CSSM_ModuleUnload", crtn);
133	}
134}
135
136
137/*
138 * Cook up a CSSM_DATA with specified integer, DER style (minimum number of
139 * bytes, big-endian).
140 */
141CSSM_DATA_PTR intToDER(unsigned theInt)
142{
143	CSSM_DATA_PTR DER_Data = (CSSM_DATA_PTR)CSSM_MALLOC(sizeof(CSSM_DATA));
144
145	if(theInt < 0x100) {
146		DER_Data->Length = 1;
147		DER_Data->Data = (uint8 *)CSSM_MALLOC(1);
148		DER_Data->Data[0] = (unsigned char)(theInt);
149	}
150	else if(theInt < 0x10000) {
151		DER_Data->Length = 2;
152		DER_Data->Data = (uint8 *)CSSM_MALLOC(2);
153		DER_Data->Data[0] = (unsigned char)(theInt >> 8);
154		DER_Data->Data[1] = (unsigned char)(theInt);
155	}
156	else if(theInt < 0x1000000) {
157		DER_Data->Length = 3;
158		DER_Data->Data = (uint8 *)CSSM_MALLOC(3);
159		DER_Data->Data[0] = (unsigned char)(theInt >> 16);
160		DER_Data->Data[1] = (unsigned char)(theInt >> 8);
161		DER_Data->Data[2] = (unsigned char)(theInt);
162	}
163	else  {
164		DER_Data->Length = 4;
165		DER_Data->Data = (uint8 *)CSSM_MALLOC(4);
166		DER_Data->Data[0] = (unsigned char)(theInt >> 24);
167		DER_Data->Data[1] = (unsigned char)(theInt >> 16);
168		DER_Data->Data[2] = (unsigned char)(theInt >> 8);
169		DER_Data->Data[3] = (unsigned char)(theInt);
170	}
171	return DER_Data;
172}
173
174/*
175 * Convert a CSSM_DATA_PTR, referring to a DER-encoded int, to a
176 * uint32.
177 */
178uint32 DER_ToInt(const CSSM_DATA *DER_Data)
179{
180	uint32		rtn = 0;
181	unsigned	i = 0;
182
183	while(i < DER_Data->Length) {
184		rtn |= DER_Data->Data[i];
185		if(++i == DER_Data->Length) {
186			break;
187		}
188		rtn <<= 8;
189	}
190	return rtn;
191}
192
193