2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
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.
26 #include "ModuleAttacher.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>
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
),
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
58 CSSM_CSP_HANDLE
&cspDlHand
63 /* on all private member functions, mLock held on entry and exit */
65 CSSM_HANDLE
loadModule(
66 CSSM_SERVICE_TYPE svcType
, // CSSM_SERVICE_CSP, etc.
67 const CSSM_GUID
*guid
,
71 const CSSM_GUID
*guid
);
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
;
84 /* the single global thing */
85 static ModuleNexus
<ModuleAttacher
> moduleAttacher
;
87 static const CSSM_API_MEMORY_FUNCS CA_memFuncs
= {
97 * This only gets called when cspAttacher get deleted, i.e., when this code
98 * is actually unloaded from the process's address space.
100 ModuleAttacher::~ModuleAttacher()
102 StLock
<Mutex
> _(mLock
);
104 if(mCspHand
!= CSSM_INVALID_HANDLE
) {
105 unloadModule(mCspHand
, &gGuidAppleCSP
);
107 if(mTpHand
!= CSSM_INVALID_HANDLE
) {
108 unloadModule(mTpHand
, &gGuidAppleX509TP
);
110 if(mClHand
!= CSSM_INVALID_HANDLE
) {
111 unloadModule(mClHand
, &gGuidAppleX509CL
);
113 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
114 if(mCspDlHand
!= CSSM_INVALID_HANDLE
) {
115 unloadModule(mCspDlHand
, &gGuidAppleCSPDL
);
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 }};
123 bool ModuleAttacher::initCssm()
126 CSSM_PVC_MODE pvcPolicy
= CSSM_PVC_NONE
;
131 crtn
= CSSM_Init (&cssmVers
,
132 CSSM_PRIVILEGE_SCOPE_NONE
,
134 CSSM_KEY_HIERARCHY_NONE
,
136 NULL
/* reserved */);
137 if(crtn
!= CSSM_OK
) {
138 errorLog1("CSSM_Init returned %s", stCssmErrToStr(crtn
));
147 CSSM_HANDLE
ModuleAttacher::loadModule(
148 CSSM_SERVICE_TYPE svcType
, // CSSM_SERVICE_CSP, etc.
149 const CSSM_GUID
*guid
,
156 return CSSM_INVALID_HANDLE
;
158 crtn
= CSSM_ModuleLoad(guid
,
159 CSSM_KEY_HIERARCHY_NONE
,
160 NULL
, // eventHandler
161 NULL
); // AppNotifyCallbackCtx
163 errorLog2("ModuleAttacher::loadModule: error (%s) loading %s\n",
164 stCssmErrToStr(crtn
), modName
);
165 return CSSM_INVALID_HANDLE
;
167 crtn
= CSSM_ModuleAttach (guid
,
169 &CA_memFuncs
, // memFuncs
171 svcType
, // SubserviceFlags
173 CSSM_KEY_HIERARCHY_NONE
,
174 NULL
, // FunctionTable
179 errorLog2("ModuleAttacher::loadModule: error (%s) attaching to %s\n",
180 stCssmErrToStr(crtn
), modName
);
181 return CSSM_INVALID_HANDLE
;
186 void ModuleAttacher::unloadModule(
188 const CSSM_GUID
*guid
)
190 CSSM_ModuleDetach(hand
);
191 CSSM_ModuleUnload(guid
, NULL
, NULL
);
194 CSSM_CSP_HANDLE
ModuleAttacher::getCspHand()
196 StLock
<Mutex
> _(mLock
);
198 if(mCspHand
!= CSSM_INVALID_HANDLE
) {
199 /* already connected */
202 mCspHand
= loadModule(CSSM_SERVICE_CSP
, &gGuidAppleCSP
, "AppleCSP");
206 CSSM_CL_HANDLE
ModuleAttacher::getClHand()
208 StLock
<Mutex
> _(mLock
);
210 if(mClHand
!= CSSM_INVALID_HANDLE
) {
211 /* already connected */
214 mClHand
= loadModule(CSSM_SERVICE_CL
, &gGuidAppleX509CL
, "AppleCL");
218 CSSM_TP_HANDLE
ModuleAttacher::getTpHand()
220 StLock
<Mutex
> _(mLock
);
222 if(mTpHand
!= CSSM_INVALID_HANDLE
) {
223 /* already connected */
226 mTpHand
= loadModule(CSSM_SERVICE_TP
, &gGuidAppleX509TP
, "AppleTP");
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
236 CSSM_CSP_HANDLE
&cspDlHand
240 StLock
<Mutex
> _(mLock
);
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
;
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
;
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
;
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
;
267 cspDlHand
= mCspDlHand
;
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
282 CSSM_CSP_HANDLE
*cspDlHand
286 return moduleAttacher().loadAllModules(*cspHand
, *clHand
, *tpHand
287 #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE