]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_x509_cl/lib/CSPAttacher.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_apple_x509_cl / lib / CSPAttacher.cpp
1 /*
2 * Copyright (c) 2000-2001,2011,2014 Apple 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
35 class CSPAttacher
36 {
37 public:
38 CSPAttacher() :
39 mCspHand(CSSM_INVALID_HANDLE),
40 mCspDlHand(CSSM_INVALID_HANDLE)
41 { }
42 ~CSPAttacher();
43 CSSM_CSP_HANDLE getCspHand(bool bareCsp);
44
45 private:
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 */
53 static ModuleNexus<CSPAttacher> cspAttacher;
54
55 static void *CL_malloc(
56 CSSM_SIZE size,
57 void *allocref)
58 {
59 return Allocator::standard().malloc(size);
60 }
61
62 static void CL_free(
63 void *memblock,
64 void *allocref)
65 {
66 Allocator::standard().free(memblock);
67 }
68
69 static void *CL_realloc(
70 void *memblock,
71 CSSM_SIZE size,
72 void *allocref)
73 {
74 return Allocator::standard().realloc(memblock, size);
75 }
76
77 static void *CL_calloc(
78 uint32 num,
79 CSSM_SIZE size,
80 void *allocref)
81 {
82 return Allocator::standard().calloc(num, size);
83 }
84
85 static 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 */
98 CSPAttacher::~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
112 CSSM_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 */
176 CSSM_CSP_HANDLE getGlobalCspHand(bool bareCsp)
177 {
178 return cspAttacher().getCspHand(bareCsp);
179 }
180