]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ModuleAttacher.cpp
Security-179.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 mCssmInitd(false)
44 { }
45 ~ModuleAttacher();
46 CSSM_CSP_HANDLE getCspHand();
47 CSSM_CL_HANDLE getClHand();
48 CSSM_TP_HANDLE getTpHand();
49 CSSM_RETURN loadAllModules(
50 CSSM_CSP_HANDLE &cspHand,
51 CSSM_CL_HANDLE &clHand,
52 CSSM_TP_HANDLE &tpHand);
53
54 private:
55 /* on all private member functions, mLock held on entry and exit */
56 bool initCssm();
57 CSSM_HANDLE loadModule(
58 CSSM_SERVICE_TYPE svcType, // CSSM_SERVICE_CSP, etc.
59 const CSSM_GUID *guid,
60 const char *modName);
61 void unloadModule(
62 CSSM_HANDLE hand,
63 const CSSM_GUID *guid);
64
65 /* connection to modules, evaluated lazily */
66 CSSM_CSP_HANDLE mCspHand;
67 CSSM_TP_HANDLE mClHand;
68 CSSM_TP_HANDLE mTpHand;
69 bool mCssmInitd;
70 Mutex mLock;
71 };
72
73 /* the single global thing */
74 static ModuleNexus<ModuleAttacher> moduleAttacher;
75
76 static const CSSM_API_MEMORY_FUNCS CA_memFuncs = {
77 stAppMalloc,
78 stAppFree,
79 stAppRealloc,
80 stAppCalloc,
81 NULL
82 };
83
84
85 /*
86 * This only gets called when cspAttacher get deleted, i.e., when this code
87 * is actually unloaded from the process's address space.
88 */
89 ModuleAttacher::~ModuleAttacher()
90 {
91 StLock<Mutex> _(mLock);
92
93 if(mCspHand != CSSM_INVALID_HANDLE) {
94 unloadModule(mCspHand, &gGuidAppleCSP);
95 }
96 if(mTpHand != CSSM_INVALID_HANDLE) {
97 unloadModule(mTpHand, &gGuidAppleX509TP);
98 }
99 if(mClHand != CSSM_INVALID_HANDLE) {
100 unloadModule(mClHand, &gGuidAppleX509CL);
101 }
102 }
103
104 static const CSSM_VERSION cssmVers = {2, 0};
105 static const CSSM_GUID testGuid = { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
106
107 bool ModuleAttacher::initCssm()
108 {
109 CSSM_RETURN crtn;
110 CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE;
111
112 if(mCssmInitd) {
113 return true;
114 }
115 crtn = CSSM_Init (&cssmVers,
116 CSSM_PRIVILEGE_SCOPE_NONE,
117 &testGuid,
118 CSSM_KEY_HIERARCHY_NONE,
119 &pvcPolicy,
120 NULL /* reserved */);
121 if(crtn != CSSM_OK) {
122 #ifndef NDEBUG
123 sslErrorLog("CSSM_Init returned %s", stCssmErrToStr(crtn));
124 #endif
125 return false;
126 }
127 else {
128 mCssmInitd = true;
129 return true;
130 }
131 }
132
133 CSSM_HANDLE ModuleAttacher::loadModule(
134 CSSM_SERVICE_TYPE svcType, // CSSM_SERVICE_CSP, etc.
135 const CSSM_GUID *guid,
136 const char *modName)
137 {
138 CSSM_RETURN crtn;
139 CSSM_HANDLE hand;
140
141 if(!initCssm()) {
142 return CSSM_INVALID_HANDLE;
143 }
144 crtn = CSSM_ModuleLoad(guid,
145 CSSM_KEY_HIERARCHY_NONE,
146 NULL, // eventHandler
147 NULL); // AppNotifyCallbackCtx
148 if(crtn) {
149 #ifndef NDEBUG
150 sslErrorLog("ModuleAttacher::loadModule: error (%s) loading %s\n",
151 stCssmErrToStr(crtn), modName);
152 #endif
153 return CSSM_INVALID_HANDLE;
154 }
155 crtn = CSSM_ModuleAttach (guid,
156 &cssmVers,
157 &CA_memFuncs, // memFuncs
158 0, // SubserviceID
159 svcType, // SubserviceFlags
160 0, // AttachFlags
161 CSSM_KEY_HIERARCHY_NONE,
162 NULL, // FunctionTable
163 0, // NumFuncTable
164 NULL, // reserved
165 &hand);
166 if(crtn) {
167 #ifndef NDEBUG
168 sslErrorLog("ModuleAttacher::loadModule: error (%s) attaching to %s\n",
169 stCssmErrToStr(crtn), modName);
170 #endif
171 return CSSM_INVALID_HANDLE;
172 }
173 return hand;
174 }
175
176 void ModuleAttacher::unloadModule(
177 CSSM_HANDLE hand,
178 const CSSM_GUID *guid)
179 {
180 CSSM_ModuleDetach(hand);
181 CSSM_ModuleUnload(guid, NULL, NULL);
182 }
183
184 CSSM_CSP_HANDLE ModuleAttacher::getCspHand()
185 {
186 StLock<Mutex> _(mLock);
187
188 if(mCspHand != CSSM_INVALID_HANDLE) {
189 /* already connected */
190 return mCspHand;
191 }
192 mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
193 return mCspHand;
194 }
195
196 CSSM_CL_HANDLE ModuleAttacher::getClHand()
197 {
198 StLock<Mutex> _(mLock);
199
200 if(mClHand != CSSM_INVALID_HANDLE) {
201 /* already connected */
202 return mClHand;
203 }
204 mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
205 return mClHand;
206 }
207
208 CSSM_TP_HANDLE ModuleAttacher::getTpHand()
209 {
210 StLock<Mutex> _(mLock);
211
212 if(mTpHand != CSSM_INVALID_HANDLE) {
213 /* already connected */
214 return mTpHand;
215 }
216 mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
217 return mTpHand;
218 }
219
220 CSSM_RETURN ModuleAttacher::loadAllModules(
221 CSSM_CSP_HANDLE &cspHand,
222 CSSM_CL_HANDLE &clHand,
223 CSSM_TP_HANDLE &tpHand)
224 {
225 StLock<Mutex> _(mLock);
226
227 if(mCspHand == CSSM_INVALID_HANDLE) {
228 mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
229 if(mCspHand == CSSM_INVALID_HANDLE) {
230 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
231 }
232 }
233 if(mClHand == CSSM_INVALID_HANDLE) {
234 mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
235 if(mClHand == CSSM_INVALID_HANDLE) {
236 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
237 }
238 }
239 if(mTpHand == CSSM_INVALID_HANDLE) {
240 mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
241 if(mTpHand == CSSM_INVALID_HANDLE) {
242 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
243 }
244 }
245 cspHand = mCspHand;
246 clHand = mClHand;
247 tpHand = mTpHand;
248 return CSSM_OK;
249 }
250
251 /* public C function to load and attach to all three modules */
252 CSSM_RETURN attachToModules(
253 CSSM_CSP_HANDLE *cspHand,
254 CSSM_CL_HANDLE *clHand,
255 CSSM_TP_HANDLE *tpHand)
256 {
257 return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand);
258 }
259