ModuleAttacher.cpp [plain text]
#include "ModuleAttacher.h"
#include "sslDebug.h"
#include "appleCdsa.h"
#include <Security/globalizer.h>
#include <Security/threading.h>
#include <Security/cssmalloc.h>
#include <Security/cssmapple.h>
#include <Security/cssmtype.h>
#include <Security/cssmapi.h>
class ModuleAttacher
{
public:
ModuleAttacher() :
mCspHand(CSSM_INVALID_HANDLE),
mClHand(CSSM_INVALID_HANDLE),
mTpHand(CSSM_INVALID_HANDLE),
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
mCspDlHand(CSSM_INVALID_HANDLE),
#endif
mCssmInitd(false)
{ }
~ModuleAttacher();
CSSM_CSP_HANDLE getCspHand();
CSSM_CL_HANDLE getClHand();
CSSM_TP_HANDLE getTpHand();
CSSM_RETURN loadAllModules(
CSSM_CSP_HANDLE &cspHand,
CSSM_CL_HANDLE &clHand,
CSSM_TP_HANDLE &tpHand
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
,
CSSM_CSP_HANDLE &cspDlHand
#endif
);
private:
bool initCssm();
CSSM_HANDLE loadModule(
CSSM_SERVICE_TYPE svcType, const CSSM_GUID *guid,
const char *modName);
void unloadModule(
CSSM_HANDLE hand,
const CSSM_GUID *guid);
CSSM_CSP_HANDLE mCspHand;
CSSM_TP_HANDLE mClHand;
CSSM_TP_HANDLE mTpHand;
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
CSSM_CSP_HANDLE mCspDlHand;
#endif
bool mCssmInitd;
Mutex mLock;
};
static ModuleNexus<ModuleAttacher> moduleAttacher;
static const CSSM_API_MEMORY_FUNCS CA_memFuncs = {
stAppMalloc,
stAppFree,
stAppRealloc,
stAppCalloc,
NULL
};
ModuleAttacher::~ModuleAttacher()
{
StLock<Mutex> _(mLock);
if(mCspHand != CSSM_INVALID_HANDLE) {
unloadModule(mCspHand, &gGuidAppleCSP);
}
if(mTpHand != CSSM_INVALID_HANDLE) {
unloadModule(mTpHand, &gGuidAppleX509TP);
}
if(mClHand != CSSM_INVALID_HANDLE) {
unloadModule(mClHand, &gGuidAppleX509CL);
}
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
if(mCspDlHand != CSSM_INVALID_HANDLE) {
unloadModule(mCspDlHand, &gGuidAppleCSPDL);
}
#endif
}
static const CSSM_VERSION cssmVers = {2, 0};
static const CSSM_GUID testGuid = { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
bool ModuleAttacher::initCssm()
{
CSSM_RETURN crtn;
CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE;
if(mCssmInitd) {
return true;
}
crtn = CSSM_Init (&cssmVers,
CSSM_PRIVILEGE_SCOPE_NONE,
&testGuid,
CSSM_KEY_HIERARCHY_NONE,
&pvcPolicy,
NULL );
if(crtn != CSSM_OK) {
errorLog1("CSSM_Init returned %s", stCssmErrToStr(crtn));
return false;
}
else {
mCssmInitd = true;
return true;
}
}
CSSM_HANDLE ModuleAttacher::loadModule(
CSSM_SERVICE_TYPE svcType, const CSSM_GUID *guid,
const char *modName)
{
CSSM_RETURN crtn;
CSSM_HANDLE hand;
if(!initCssm()) {
return CSSM_INVALID_HANDLE;
}
crtn = CSSM_ModuleLoad(guid,
CSSM_KEY_HIERARCHY_NONE,
NULL, NULL); if(crtn) {
errorLog2("ModuleAttacher::loadModule: error (%s) loading %s\n",
stCssmErrToStr(crtn), modName);
return CSSM_INVALID_HANDLE;
}
crtn = CSSM_ModuleAttach (guid,
&cssmVers,
&CA_memFuncs, 0, svcType, 0, CSSM_KEY_HIERARCHY_NONE,
NULL, 0, NULL, &hand);
if(crtn) {
errorLog2("ModuleAttacher::loadModule: error (%s) attaching to %s\n",
stCssmErrToStr(crtn), modName);
return CSSM_INVALID_HANDLE;
}
return hand;
}
void ModuleAttacher::unloadModule(
CSSM_HANDLE hand,
const CSSM_GUID *guid)
{
CSSM_ModuleDetach(hand);
CSSM_ModuleUnload(guid, NULL, NULL);
}
CSSM_CSP_HANDLE ModuleAttacher::getCspHand()
{
StLock<Mutex> _(mLock);
if(mCspHand != CSSM_INVALID_HANDLE) {
return mCspHand;
}
mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
return mCspHand;
}
CSSM_CL_HANDLE ModuleAttacher::getClHand()
{
StLock<Mutex> _(mLock);
if(mClHand != CSSM_INVALID_HANDLE) {
return mClHand;
}
mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
return mClHand;
}
CSSM_TP_HANDLE ModuleAttacher::getTpHand()
{
StLock<Mutex> _(mLock);
if(mTpHand != CSSM_INVALID_HANDLE) {
return mTpHand;
}
mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
return mTpHand;
}
CSSM_RETURN ModuleAttacher::loadAllModules(
CSSM_CSP_HANDLE &cspHand,
CSSM_CL_HANDLE &clHand,
CSSM_TP_HANDLE &tpHand
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
,
CSSM_CSP_HANDLE &cspDlHand
#endif
)
{
StLock<Mutex> _(mLock);
if(mCspHand == CSSM_INVALID_HANDLE) {
mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
if(mCspHand == CSSM_INVALID_HANDLE) {
return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
}
}
if(mClHand == CSSM_INVALID_HANDLE) {
mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
if(mClHand == CSSM_INVALID_HANDLE) {
return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
}
}
if(mTpHand == CSSM_INVALID_HANDLE) {
mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
if(mTpHand == CSSM_INVALID_HANDLE) {
return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
}
}
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
if(mCspDlHand == CSSM_INVALID_HANDLE) {
mCspDlHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSPDL, "AppleCSPDL");
if(mCspDlHand == CSSM_INVALID_HANDLE) {
return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
}
}
cspDlHand = mCspDlHand;
#endif
cspHand = mCspHand;
clHand = mClHand;
tpHand = mTpHand;
return CSSM_OK;
}
CSSM_RETURN attachToModules(
CSSM_CSP_HANDLE *cspHand,
CSSM_CL_HANDLE *clHand,
CSSM_TP_HANDLE *tpHand
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
,
CSSM_CSP_HANDLE *cspDlHand
#endif
)
{
return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand
#if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
,
*cspDlHand
#endif
);
}