]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
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), | |
29654253 A |
43 | #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE |
44 | mCspDlHand(CSSM_INVALID_HANDLE), | |
45 | #endif | |
bac41a7b A |
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, | |
29654253 A |
55 | CSSM_TP_HANDLE &tpHand |
56 | #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE | |
57 | , | |
58 | CSSM_CSP_HANDLE &cspDlHand | |
59 | #endif | |
60 | ); | |
bac41a7b A |
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; | |
29654253 A |
77 | #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE |
78 | CSSM_CSP_HANDLE mCspDlHand; | |
79 | #endif | |
bac41a7b A |
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 | } | |
29654253 A |
113 | #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE |
114 | if(mCspDlHand != CSSM_INVALID_HANDLE) { | |
115 | unloadModule(mCspDlHand, &gGuidAppleCSPDL); | |
116 | } | |
117 | #endif | |
bac41a7b A |
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) { | |
29654253 | 163 | errorLog2("ModuleAttacher::loadModule: error (%s) loading %s\n", |
bac41a7b A |
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) { | |
29654253 | 179 | errorLog2("ModuleAttacher::loadModule: error (%s) attaching to %s\n", |
bac41a7b A |
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, | |
29654253 A |
233 | CSSM_TP_HANDLE &tpHand |
234 | #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE | |
235 | , | |
236 | CSSM_CSP_HANDLE &cspDlHand | |
237 | #endif | |
238 | ) | |
bac41a7b A |
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 | } | |
29654253 A |
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 | |
bac41a7b A |
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, | |
29654253 A |
279 | CSSM_TP_HANDLE *tpHand |
280 | #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE | |
281 | , | |
282 | CSSM_CSP_HANDLE *cspDlHand | |
283 | #endif | |
284 | ) | |
bac41a7b | 285 | { |
29654253 A |
286 | return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand |
287 | #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE | |
288 | , | |
289 | *cspDlHand | |
290 | #endif | |
291 | ); | |
bac41a7b A |
292 | } |
293 |