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
), 
  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
); 
  55         /* on all private member functions, mLock held on entry and exit */ 
  57         CSSM_HANDLE                             
loadModule( 
  58                                                                 CSSM_SERVICE_TYPE svcType
,      // CSSM_SERVICE_CSP, etc. 
  59                                                                 const CSSM_GUID 
*guid
, 
  63                                                                 const CSSM_GUID 
*guid
); 
  65         /* connection to modules, evaluated lazily */ 
  66         CSSM_CSP_HANDLE                 mCspHand
; 
  67         CSSM_TP_HANDLE                  mClHand
; 
  68         CSSM_TP_HANDLE                  mTpHand
; 
  73 /* the single global thing */ 
  74 static ModuleNexus
<ModuleAttacher
> moduleAttacher
; 
  76 static const CSSM_API_MEMORY_FUNCS CA_memFuncs 
= { 
  86  * This only gets called when cspAttacher get deleted, i.e., when this code 
  87  * is actually unloaded from the process's address space. 
  89 ModuleAttacher::~ModuleAttacher() 
  91         StLock
<Mutex
>   _(mLock
); 
  93         if(mCspHand 
!= CSSM_INVALID_HANDLE
) { 
  94                 unloadModule(mCspHand
, &gGuidAppleCSP
); 
  96         if(mTpHand 
!= CSSM_INVALID_HANDLE
) { 
  97                 unloadModule(mTpHand
, &gGuidAppleX509TP
); 
  99         if(mClHand 
!= CSSM_INVALID_HANDLE
) { 
 100                 unloadModule(mClHand
, &gGuidAppleX509CL
); 
 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 }}; 
 107 bool ModuleAttacher::initCssm() 
 110     CSSM_PVC_MODE pvcPolicy 
= CSSM_PVC_NONE
; 
 115         crtn 
= CSSM_Init (&cssmVers
,  
 116                 CSSM_PRIVILEGE_SCOPE_NONE
, 
 118                 CSSM_KEY_HIERARCHY_NONE
, 
 120                 NULL 
/* reserved */); 
 121         if(crtn 
!= CSSM_OK
) { 
 123                 sslErrorLog("CSSM_Init returned %s", stCssmErrToStr(crtn
)); 
 133 CSSM_HANDLE 
ModuleAttacher::loadModule( 
 134         CSSM_SERVICE_TYPE svcType
,      // CSSM_SERVICE_CSP, etc. 
 135         const CSSM_GUID 
*guid
, 
 142                 return CSSM_INVALID_HANDLE
; 
 144         crtn 
= CSSM_ModuleLoad(guid
, 
 145                 CSSM_KEY_HIERARCHY_NONE
, 
 146                 NULL
,                   // eventHandler 
 147                 NULL
);                  // AppNotifyCallbackCtx 
 150                 sslErrorLog("ModuleAttacher::loadModule: error (%s) loading %s\n", 
 151                         stCssmErrToStr(crtn
), modName
); 
 153                 return CSSM_INVALID_HANDLE
; 
 155         crtn 
= CSSM_ModuleAttach (guid
, 
 157                 &CA_memFuncs
,                   // memFuncs 
 159                 svcType
,                                // SubserviceFlags  
 161                 CSSM_KEY_HIERARCHY_NONE
, 
 162                 NULL
,                                   // FunctionTable 
 168                 sslErrorLog("ModuleAttacher::loadModule: error (%s) attaching to %s\n", 
 169                         stCssmErrToStr(crtn
), modName
); 
 171                 return CSSM_INVALID_HANDLE
; 
 176 void ModuleAttacher::unloadModule( 
 178         const CSSM_GUID 
*guid
) 
 180         CSSM_ModuleDetach(hand
); 
 181         CSSM_ModuleUnload(guid
, NULL
, NULL
); 
 184 CSSM_CSP_HANDLE 
ModuleAttacher::getCspHand() 
 186         StLock
<Mutex
>   _(mLock
); 
 188         if(mCspHand 
!= CSSM_INVALID_HANDLE
) { 
 189                 /* already connected */ 
 192         mCspHand 
= loadModule(CSSM_SERVICE_CSP
, &gGuidAppleCSP
, "AppleCSP"); 
 196 CSSM_CL_HANDLE 
ModuleAttacher::getClHand() 
 198         StLock
<Mutex
>   _(mLock
); 
 200         if(mClHand 
!= CSSM_INVALID_HANDLE
) { 
 201                 /* already connected */ 
 204         mClHand 
= loadModule(CSSM_SERVICE_CL
, &gGuidAppleX509CL
, "AppleCL"); 
 208 CSSM_TP_HANDLE 
ModuleAttacher::getTpHand() 
 210         StLock
<Mutex
>   _(mLock
); 
 212         if(mTpHand 
!= CSSM_INVALID_HANDLE
) { 
 213                 /* already connected */ 
 216         mTpHand 
= loadModule(CSSM_SERVICE_TP
, &gGuidAppleX509TP
, "AppleTP");  
 220 CSSM_RETURN 
ModuleAttacher::loadAllModules( 
 221         CSSM_CSP_HANDLE 
&cspHand
, 
 222         CSSM_CL_HANDLE  
&clHand
, 
 223         CSSM_TP_HANDLE  
&tpHand
) 
 225         StLock
<Mutex
>   _(mLock
); 
 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
; 
 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
; 
 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
; 
 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
) 
 257         return moduleAttacher().loadAllModules(*cspHand
, *clHand
, *tpHand
);