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 * CSPAttacher.cpp - process-wide class which loads and attaches to CSP at most 21 * once, and detaches and unloads the CSP when this code is 22 * unloaded. 23 */ 24 25#include "CSPAttacher.h" 26#include "cldebugging.h" 27#include <security_utilities/globalizer.h> 28#include <security_utilities/threading.h> 29#include <security_utilities/alloc.h> 30#include <security_cdsa_utilities/cssmerrors.h> 31#include <Security/cssmapple.h> 32#include <Security/cssmtype.h> 33#include <Security/cssmapi.h> 34 35class CSPAttacher 36{ 37public: 38 CSPAttacher() : 39 mCspHand(CSSM_INVALID_HANDLE), 40 mCspDlHand(CSSM_INVALID_HANDLE) 41 { } 42 ~CSPAttacher(); 43 CSSM_CSP_HANDLE getCspHand(bool bareCsp); 44 45private: 46 /* connection to CSP and CSPDL, evaluated lazily */ 47 CSSM_HANDLE mCspHand; 48 CSSM_HANDLE mCspDlHand; 49 Mutex mLock; 50}; 51 52/* the single global thing */ 53static ModuleNexus<CSPAttacher> cspAttacher; 54 55static void *CL_malloc( 56 CSSM_SIZE size, 57 void *allocref) 58{ 59 return Allocator::standard().malloc(size); 60} 61 62static void CL_free( 63 void *memblock, 64 void *allocref) 65{ 66 Allocator::standard().free(memblock); 67} 68 69static void *CL_realloc( 70 void *memblock, 71 CSSM_SIZE size, 72 void *allocref) 73{ 74 return Allocator::standard().realloc(memblock, size); 75} 76 77static void *CL_calloc( 78 uint32 num, 79 CSSM_SIZE size, 80 void *allocref) 81{ 82 return Allocator::standard().calloc(num, size); 83} 84 85static const CSSM_API_MEMORY_FUNCS CL_memFuncs = { 86 CL_malloc, 87 CL_free, 88 CL_realloc, 89 CL_calloc, 90 NULL 91 }; 92 93 94/* 95 * This only gets called when cspAttacher get deleted, i.e., when this code 96 * is actually unloaded from the process's address space. 97 */ 98CSPAttacher::~CSPAttacher() 99{ 100 StLock<Mutex> _(mLock); 101 102 if(mCspHand != CSSM_INVALID_HANDLE) { 103 CSSM_ModuleDetach(mCspHand); 104 CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); 105 } 106 if(mCspDlHand != CSSM_INVALID_HANDLE) { 107 CSSM_ModuleDetach(mCspDlHand); 108 CSSM_ModuleUnload(&gGuidAppleCSPDL, NULL, NULL); 109 } 110} 111 112CSSM_CSP_HANDLE CSPAttacher::getCspHand(bool bareCsp) 113{ 114 const char *modName; 115 CSSM_RETURN crtn; 116 const CSSM_GUID *guid; 117 CSSM_VERSION vers = {2, 0}; 118 StLock<Mutex> _(mLock); 119 CSSM_CSP_HANDLE cspHand; 120 121 if(bareCsp) { 122 if(mCspHand != CSSM_INVALID_HANDLE) { 123 /* already connected */ 124 return mCspHand; 125 } 126 guid = &gGuidAppleCSP; 127 modName = "AppleCSP"; 128 } 129 else { 130 if(mCspDlHand != CSSM_INVALID_HANDLE) { 131 /* already connected */ 132 return mCspDlHand; 133 } 134 guid = &gGuidAppleCSPDL; 135 modName = "AppleCSPDL"; 136 } 137 crtn = CSSM_ModuleLoad(guid, 138 CSSM_KEY_HIERARCHY_NONE, 139 NULL, // eventHandler 140 NULL); // AppNotifyCallbackCtx 141 if(crtn) { 142 clErrorLog("AppleX509CLSession::cspAttach: error (%d) loading %s", 143 (int)crtn, modName); 144 CssmError::throwMe(crtn); 145 } 146 crtn = CSSM_ModuleAttach (guid, 147 &vers, 148 &CL_memFuncs, // memFuncs 149 0, // SubserviceID 150 CSSM_SERVICE_CSP, // SubserviceFlags 151 0, // AttachFlags 152 CSSM_KEY_HIERARCHY_NONE, 153 NULL, // FunctionTable 154 0, // NumFuncTable 155 NULL, // reserved 156 &cspHand); 157 if(crtn) { 158 clErrorLog("AppleX509CLSession::cspAttach: error (%d) attaching to %s", 159 (int)crtn, modName); 160 CssmError::throwMe(crtn); 161 } 162 if(bareCsp) { 163 mCspHand = cspHand; 164 } 165 else { 166 mCspDlHand = cspHand; 167 } 168 return cspHand; 169} 170 171/* 172 * Just one public function - "give me a CSP handle". 173 * bareCsp true: AppleCSP 174 * bareCsp false: AppleCSPDL 175 */ 176CSSM_CSP_HANDLE getGlobalCspHand(bool bareCsp) 177{ 178 return cspAttacher().getCspHand(bareCsp); 179} 180 181