]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ModuleAttacher.cpp
Security-54.tar.gz
[apple/security.git] / SecureTransport / ModuleAttacher.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * ModuleAttacher.cpp
21 *
22 * Process-wide class which loads and attaches to {CSP, TP, CL} at most
23 * once, and detaches and unloads the modules when this code is unloaded.
24 */
25
26 #include "ModuleAttacher.h"
27 #include "sslDebug.h"
28 #include "appleCdsa.h"
29 #include <Security/globalizer.h>
30 #include <Security/threading.h>
31 #include <Security/cssmalloc.h>
32 #include <Security/cssmapple.h>
33 #include <Security/cssmtype.h>
34 #include <Security/cssmapi.h>
35
36 class ModuleAttacher
37 {
38 public:
39 ModuleAttacher() :
40 mCspHand(CSSM_INVALID_HANDLE),
41 mClHand(CSSM_INVALID_HANDLE),
42 mTpHand(CSSM_INVALID_HANDLE),
43 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
44 mCspDlHand(CSSM_INVALID_HANDLE),
45 #endif
46 mCssmInitd(false)
47 { }
48 ~ModuleAttacher();
49 CSSM_CSP_HANDLE getCspHand();
50 CSSM_CL_HANDLE getClHand();
51 CSSM_TP_HANDLE getTpHand();
52 CSSM_RETURN loadAllModules(
53 CSSM_CSP_HANDLE &cspHand,
54 CSSM_CL_HANDLE &clHand,
55 CSSM_TP_HANDLE &tpHand
56 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
57 ,
58 CSSM_CSP_HANDLE &cspDlHand
59 #endif
60 );
61
62 private:
63 /* on all private member functions, mLock held on entry and exit */
64 bool initCssm();
65 CSSM_HANDLE loadModule(
66 CSSM_SERVICE_TYPE svcType, // CSSM_SERVICE_CSP, etc.
67 const CSSM_GUID *guid,
68 const char *modName);
69 void unloadModule(
70 CSSM_HANDLE hand,
71 const CSSM_GUID *guid);
72
73 /* connection to modules, evaluated lazily */
74 CSSM_CSP_HANDLE mCspHand;
75 CSSM_TP_HANDLE mClHand;
76 CSSM_TP_HANDLE mTpHand;
77 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
78 CSSM_CSP_HANDLE mCspDlHand;
79 #endif
80 bool mCssmInitd;
81 Mutex mLock;
82 };
83
84 /* the single global thing */
85 static ModuleNexus<ModuleAttacher> moduleAttacher;
86
87 static const CSSM_API_MEMORY_FUNCS CA_memFuncs = {
88 stAppMalloc,
89 stAppFree,
90 stAppRealloc,
91 stAppCalloc,
92 NULL
93 };
94
95
96 /*
97 * This only gets called when cspAttacher get deleted, i.e., when this code
98 * is actually unloaded from the process's address space.
99 */
100 ModuleAttacher::~ModuleAttacher()
101 {
102 StLock<Mutex> _(mLock);
103
104 if(mCspHand != CSSM_INVALID_HANDLE) {
105 unloadModule(mCspHand, &gGuidAppleCSP);
106 }
107 if(mTpHand != CSSM_INVALID_HANDLE) {
108 unloadModule(mTpHand, &gGuidAppleX509TP);
109 }
110 if(mClHand != CSSM_INVALID_HANDLE) {
111 unloadModule(mClHand, &gGuidAppleX509CL);
112 }
113 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
114 if(mCspDlHand != CSSM_INVALID_HANDLE) {
115 unloadModule(mCspDlHand, &gGuidAppleCSPDL);
116 }
117 #endif
118 }
119
120 static const CSSM_VERSION cssmVers = {2, 0};
121 static const CSSM_GUID testGuid = { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
122
123 bool ModuleAttacher::initCssm()
124 {
125 CSSM_RETURN crtn;
126 CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE;
127
128 if(mCssmInitd) {
129 return true;
130 }
131 crtn = CSSM_Init (&cssmVers,
132 CSSM_PRIVILEGE_SCOPE_NONE,
133 &testGuid,
134 CSSM_KEY_HIERARCHY_NONE,
135 &pvcPolicy,
136 NULL /* reserved */);
137 if(crtn != CSSM_OK) {
138 errorLog1("CSSM_Init returned %s", stCssmErrToStr(crtn));
139 return false;
140 }
141 else {
142 mCssmInitd = true;
143 return true;
144 }
145 }
146
147 CSSM_HANDLE ModuleAttacher::loadModule(
148 CSSM_SERVICE_TYPE svcType, // CSSM_SERVICE_CSP, etc.
149 const CSSM_GUID *guid,
150 const char *modName)
151 {
152 CSSM_RETURN crtn;
153 CSSM_HANDLE hand;
154
155 if(!initCssm()) {
156 return CSSM_INVALID_HANDLE;
157 }
158 crtn = CSSM_ModuleLoad(guid,
159 CSSM_KEY_HIERARCHY_NONE,
160 NULL, // eventHandler
161 NULL); // AppNotifyCallbackCtx
162 if(crtn) {
163 errorLog2("ModuleAttacher::loadModule: error (%s) loading %s\n",
164 stCssmErrToStr(crtn), modName);
165 return CSSM_INVALID_HANDLE;
166 }
167 crtn = CSSM_ModuleAttach (guid,
168 &cssmVers,
169 &CA_memFuncs, // memFuncs
170 0, // SubserviceID
171 svcType, // SubserviceFlags
172 0, // AttachFlags
173 CSSM_KEY_HIERARCHY_NONE,
174 NULL, // FunctionTable
175 0, // NumFuncTable
176 NULL, // reserved
177 &hand);
178 if(crtn) {
179 errorLog2("ModuleAttacher::loadModule: error (%s) attaching to %s\n",
180 stCssmErrToStr(crtn), modName);
181 return CSSM_INVALID_HANDLE;
182 }
183 return hand;
184 }
185
186 void ModuleAttacher::unloadModule(
187 CSSM_HANDLE hand,
188 const CSSM_GUID *guid)
189 {
190 CSSM_ModuleDetach(hand);
191 CSSM_ModuleUnload(guid, NULL, NULL);
192 }
193
194 CSSM_CSP_HANDLE ModuleAttacher::getCspHand()
195 {
196 StLock<Mutex> _(mLock);
197
198 if(mCspHand != CSSM_INVALID_HANDLE) {
199 /* already connected */
200 return mCspHand;
201 }
202 mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
203 return mCspHand;
204 }
205
206 CSSM_CL_HANDLE ModuleAttacher::getClHand()
207 {
208 StLock<Mutex> _(mLock);
209
210 if(mClHand != CSSM_INVALID_HANDLE) {
211 /* already connected */
212 return mClHand;
213 }
214 mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
215 return mClHand;
216 }
217
218 CSSM_TP_HANDLE ModuleAttacher::getTpHand()
219 {
220 StLock<Mutex> _(mLock);
221
222 if(mTpHand != CSSM_INVALID_HANDLE) {
223 /* already connected */
224 return mTpHand;
225 }
226 mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
227 return mTpHand;
228 }
229
230 CSSM_RETURN ModuleAttacher::loadAllModules(
231 CSSM_CSP_HANDLE &cspHand,
232 CSSM_CL_HANDLE &clHand,
233 CSSM_TP_HANDLE &tpHand
234 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
235 ,
236 CSSM_CSP_HANDLE &cspDlHand
237 #endif
238 )
239 {
240 StLock<Mutex> _(mLock);
241
242 if(mCspHand == CSSM_INVALID_HANDLE) {
243 mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
244 if(mCspHand == CSSM_INVALID_HANDLE) {
245 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
246 }
247 }
248 if(mClHand == CSSM_INVALID_HANDLE) {
249 mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
250 if(mClHand == CSSM_INVALID_HANDLE) {
251 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
252 }
253 }
254 if(mTpHand == CSSM_INVALID_HANDLE) {
255 mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
256 if(mTpHand == CSSM_INVALID_HANDLE) {
257 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
258 }
259 }
260 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
261 if(mCspDlHand == CSSM_INVALID_HANDLE) {
262 mCspDlHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSPDL, "AppleCSPDL");
263 if(mCspDlHand == CSSM_INVALID_HANDLE) {
264 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
265 }
266 }
267 cspDlHand = mCspDlHand;
268 #endif
269 cspHand = mCspHand;
270 clHand = mClHand;
271 tpHand = mTpHand;
272 return CSSM_OK;
273 }
274
275 /* public C function to load and attach to all three modules */
276 CSSM_RETURN attachToModules(
277 CSSM_CSP_HANDLE *cspHand,
278 CSSM_CL_HANDLE *clHand,
279 CSSM_TP_HANDLE *tpHand
280 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
281 ,
282 CSSM_CSP_HANDLE *cspDlHand
283 #endif
284 )
285 {
286 return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand
287 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
288 ,
289 *cspDlHand
290 #endif
291 );
292 }
293