]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ModuleAttacher.cpp
42378a73754f667cb625f25c388cf8690dacdc8e
[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 errorLog1("CSSM_Init returned %s", stCssmErrToStr(crtn));
123 return false;
124 }
125 else {
126 mCssmInitd = true;
127 return true;
128 }
129 }
130
131 CSSM_HANDLE ModuleAttacher::loadModule(
132 CSSM_SERVICE_TYPE svcType, // CSSM_SERVICE_CSP, etc.
133 const CSSM_GUID *guid,
134 const char *modName)
135 {
136 CSSM_RETURN crtn;
137 CSSM_HANDLE hand;
138
139 if(!initCssm()) {
140 return CSSM_INVALID_HANDLE;
141 }
142 crtn = CSSM_ModuleLoad(guid,
143 CSSM_KEY_HIERARCHY_NONE,
144 NULL, // eventHandler
145 NULL); // AppNotifyCallbackCtx
146 if(crtn) {
147 errorLog2("AppleX509CLSession::cspAttach: error (%s) loading %s\n",
148 stCssmErrToStr(crtn), modName);
149 return CSSM_INVALID_HANDLE;
150 }
151 crtn = CSSM_ModuleAttach (guid,
152 &cssmVers,
153 &CA_memFuncs, // memFuncs
154 0, // SubserviceID
155 svcType, // SubserviceFlags
156 0, // AttachFlags
157 CSSM_KEY_HIERARCHY_NONE,
158 NULL, // FunctionTable
159 0, // NumFuncTable
160 NULL, // reserved
161 &hand);
162 if(crtn) {
163 errorLog2("AppleX509CLSession::cspAttach: error (%s) attaching to %s\n",
164 stCssmErrToStr(crtn), modName);
165 return CSSM_INVALID_HANDLE;
166 }
167 return hand;
168 }
169
170 void ModuleAttacher::unloadModule(
171 CSSM_HANDLE hand,
172 const CSSM_GUID *guid)
173 {
174 CSSM_ModuleDetach(hand);
175 CSSM_ModuleUnload(guid, NULL, NULL);
176 }
177
178 CSSM_CSP_HANDLE ModuleAttacher::getCspHand()
179 {
180 StLock<Mutex> _(mLock);
181
182 if(mCspHand != CSSM_INVALID_HANDLE) {
183 /* already connected */
184 return mCspHand;
185 }
186 mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
187 return mCspHand;
188 }
189
190 CSSM_CL_HANDLE ModuleAttacher::getClHand()
191 {
192 StLock<Mutex> _(mLock);
193
194 if(mClHand != CSSM_INVALID_HANDLE) {
195 /* already connected */
196 return mClHand;
197 }
198 mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
199 return mClHand;
200 }
201
202 CSSM_TP_HANDLE ModuleAttacher::getTpHand()
203 {
204 StLock<Mutex> _(mLock);
205
206 if(mTpHand != CSSM_INVALID_HANDLE) {
207 /* already connected */
208 return mTpHand;
209 }
210 mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
211 return mTpHand;
212 }
213
214 CSSM_RETURN ModuleAttacher::loadAllModules(
215 CSSM_CSP_HANDLE &cspHand,
216 CSSM_CL_HANDLE &clHand,
217 CSSM_TP_HANDLE &tpHand)
218 {
219 StLock<Mutex> _(mLock);
220
221 if(mCspHand == CSSM_INVALID_HANDLE) {
222 mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
223 if(mCspHand == CSSM_INVALID_HANDLE) {
224 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
225 }
226 }
227 if(mClHand == CSSM_INVALID_HANDLE) {
228 mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
229 if(mClHand == CSSM_INVALID_HANDLE) {
230 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
231 }
232 }
233 if(mTpHand == CSSM_INVALID_HANDLE) {
234 mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
235 if(mTpHand == CSSM_INVALID_HANDLE) {
236 return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
237 }
238 }
239 cspHand = mCspHand;
240 clHand = mClHand;
241 tpHand = mTpHand;
242 return CSSM_OK;
243 }
244
245 /* public C function to load and attach to all three modules */
246 CSSM_RETURN attachToModules(
247 CSSM_CSP_HANDLE *cspHand,
248 CSSM_CL_HANDLE *clHand,
249 CSSM_TP_HANDLE *tpHand)
250 {
251 return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand);
252 }
253