]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_client/lib/cssmclient.h
Security-57740.51.3.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_client / lib / cssmclient.h
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 // cssmclient - common client interface to CSSM and MDS
21 //
22 #ifndef _H_CDSA_CLIENT_CSSMCLIENT
23 #define _H_CDSA_CLIENT_CSSMCLIENT 1
24
25 #include <security_utilities/threading.h>
26 #include <security_utilities/globalizer.h>
27 #include <security_utilities/refcount.h>
28 #include <security_cdsa_utilities/cssmalloc.h>
29 #include <security_cdsa_utilities/cssmpods.h>
30 #include <map>
31
32 namespace Security {
33 namespace CssmClient {
34
35
36 //
37 // Forward declarations
38 //
39 class Cssm;
40 class Module;
41 class Attachment;
42
43
44 //
45 // An mixin for objects that have (store) GUIDs.
46 // The GUID value is meant to be set-once constant, and can be lock-handled accordingly.
47 //
48 class HasGuid {
49 public:
50 HasGuid(const Guid &guid) { mGuid = guid; }
51 HasGuid() { }
52
53 const Guid &guid() const { return mGuid; }
54
55 protected:
56 void setGuid(const Guid &guid) { mGuid = guid; }
57
58 private:
59 Guid mGuid;
60 };
61
62
63 //
64 // Exceptions are based on the CssmError utility class. We add our own class of client-side exceptions.
65 //
66 class Error : public CssmError {
67 public:
68 Error(CSSM_RETURN err) : CssmError(err) { }
69 virtual const char *what () const throw();
70
71 enum {
72 objectBusy = -1,
73 };
74 };
75
76
77 //
78 // The CssmObject abstract class models features common to different Cssm objects.
79 // It handles a tree hierarchy of objects (parent/children) safely.
80 //
81 class Object;
82
83 class ObjectImpl : virtual public RefCount
84 {
85 public:
86 explicit ObjectImpl(); // Constructor for Impl objects without a parent.
87 explicit ObjectImpl(const Object &parent);
88 virtual ~ObjectImpl();
89
90 bool isActive() const { return mActive; }
91
92 virtual Allocator &allocator() const;
93 virtual void allocator(Allocator &alloc);
94
95 // Pointer comparison by default. Subclasses may override.
96 virtual bool operator <(const ObjectImpl &other) const;
97 virtual bool operator ==(const ObjectImpl &other) const;
98
99 static void check(CSSM_RETURN status);
100 bool isIdle() const { return mChildCount == 0; }
101
102 protected:
103 bool mActive; // loaded, attached, etc.
104 RecursiveMutex mActivateMutex;
105 mutable Allocator *mAllocator; // allocator hierarchy (NULL => TBD)
106 mutable RecursiveMutex mAllocatorMutex; // protects allocator creation
107
108 template <class Obj> Obj parent() const
109 { assert(mParent); return Obj(static_cast<typename Obj::Impl *>(&(*mParent))); }
110
111 void addChild();
112 void removeChild();
113
114 // {de,}activate() assume you have locked *this
115 virtual void activate() = 0;
116 virtual void deactivate() = 0;
117
118 private:
119 RefPointer<ObjectImpl> mParent; // parent object
120 AtomicCounter<uint32> mChildCount;
121 };
122
123
124 class Object
125 {
126 friend class ObjectImpl;
127 public:
128 typedef ObjectImpl Impl;
129 explicit Object(Impl *impl) : mImpl(impl) {}
130
131 protected:
132 // @@@ CSPDL subclass breaks if the is a static_cast
133 template <class _Impl> _Impl &impl() const
134 { return dynamic_cast<_Impl &>(*mImpl); }
135
136 public:
137 Impl *operator ->() const { return &(*mImpl); }
138 Impl &operator *() const { return *mImpl; }
139
140 // @@@ Why is this needed. DbCursor which inheirits from Object wants to call this.
141 template <class _Impl> _Impl &checkedImpl() const
142 { return dynamic_cast<_Impl &>(*mImpl); }
143
144 bool operator !() const { return !mImpl; }
145 operator bool() const { return mImpl; }
146
147 bool isActive() const { return mImpl && mImpl->isActive(); }
148 Allocator &allocator() const { return mImpl->allocator(); }
149 void release() { mImpl = NULL; }
150
151 bool operator <(const Object &other) const
152 { return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl < other.mImpl; }
153 bool operator ==(const Object &other) const
154 { return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl == other.mImpl; }
155
156 Impl* get() {return mImpl;}
157
158 private:
159 RefPointer<Impl> mImpl;
160 };
161
162
163 //
164 // Event callback mix-in class
165 //
166 class ModuleImpl;
167
168 class RawModuleEvents {
169 friend class ModuleImpl;
170 public:
171 virtual ~RawModuleEvents();
172
173 virtual void notify(uint32 subService,
174 CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event) = 0;
175
176 private:
177 static CSSM_RETURN sendNotify(const CSSM_GUID *, void *context, uint32 subService,
178 CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event);
179 };
180
181 class ModuleEvents : public RawModuleEvents {
182 public:
183 virtual void insertion(uint32 subService, CSSM_SERVICE_TYPE type);
184 virtual void removal(uint32 subService, CSSM_SERVICE_TYPE type);
185 virtual void fault(uint32 subService, CSSM_SERVICE_TYPE type);
186
187 protected:
188 void notify(uint32 subService, CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event);
189 };
190
191
192 //
193 // A CSSM loadable module.
194 // You rarely directly interact with these objects, but if you need to,
195 // here they are.
196 //
197 class ModuleImpl : public ObjectImpl, public HasGuid
198 {
199 public:
200 ModuleImpl(const Guid &guid);
201 ModuleImpl(const Guid &guid, const Cssm &session);
202 virtual ~ModuleImpl();
203
204 void load() { activate(); }
205 void unload() { deactivate(); }
206 bool isLoaded() const { return isActive(); }
207
208 Cssm session() const;
209
210 void appNotifyCallback(CSSM_API_ModuleEventHandler appNotifyCallback, void *appNotifyCallbackCtx);
211 void appNotifyCallback(RawModuleEvents *handler);
212
213 protected:
214 void activate();
215 void deactivate();
216
217 CSSM_API_ModuleEventHandler mAppNotifyCallback;
218 void *mAppNotifyCallbackCtx;
219 };
220
221 class Module : public Object
222 {
223 public:
224 typedef ModuleImpl Impl;
225 explicit Module(Impl *impl) : Object(impl) {}
226 Module() : Object(NULL) {} // XXX This might break operator <
227 Module(const Guid &guid) : Object(new Impl(guid)) {}
228 Module(const Guid &guid, const Cssm &session) : Object(new Impl(guid, session)) {}
229
230 Impl *operator ->() const { return &impl<Impl>(); }
231 Impl &operator *() const { return impl<Impl>(); }
232 };
233
234
235 //
236 // An Attachment object. This is the base class of all typed attachment classes.
237 //
238 class AttachmentImpl : public ObjectImpl
239 {
240 public:
241 AttachmentImpl(const Guid &guid, CSSM_SERVICE_TYPE subserviceType);
242 AttachmentImpl(const Module &module, CSSM_SERVICE_TYPE subserviceType);
243 //AttachmentImpl(... mds reference ...);
244 virtual ~AttachmentImpl();
245
246 // Virtual so that subclasses can return there true mask.
247 virtual CSSM_SERVICE_MASK subserviceMask() const;
248
249 CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; }
250 CSSM_VERSION version() const { return mVersion; }
251 void version(const CSSM_VERSION &v) { mVersion = v; }
252 uint32 subserviceId() const { return mSubserviceId; }
253 virtual void subserviceId(uint32 id);
254 CSSM_ATTACH_FLAGS flags() const { return mAttachFlags; }
255 void flags(CSSM_ATTACH_FLAGS f) { mAttachFlags = f; }
256
257 void attach() { activate(); }
258 void detach() { deactivate(); }
259 bool attached() const { return isActive(); }
260
261 Module module() const;
262 const Guid &guid() const { return module()->guid(); }
263 CSSM_MODULE_HANDLE handle() { attach(); return mHandle; }
264
265 CssmSubserviceUid subserviceUid() const;
266
267 protected:
268 void activate();
269 void deactivate();
270
271 private:
272 void make(CSSM_SERVICE_TYPE subserviceType); // common constructor
273
274 CSSM_MODULE_HANDLE mHandle;
275
276 CSSM_SERVICE_TYPE mSubserviceType; // set by constructor
277 CSSM_VERSION mVersion;
278 uint32 mSubserviceId;
279 CSSM_ATTACH_FLAGS mAttachFlags;
280
281 CssmAllocatorMemoryFunctions mMemoryFunctions; // set on attach()
282 };
283
284 class Attachment : public Object
285 {
286 public:
287 typedef AttachmentImpl Impl;
288 explicit Attachment(Impl *impl) : Object(impl) {}
289 Attachment(const Guid &guid, CSSM_SERVICE_TYPE subserviceType)
290 : Object(new Impl(guid, subserviceType)) {}
291 Attachment(const Module &module, CSSM_SERVICE_TYPE subserviceType)
292 : Object(new Impl(module, subserviceType)) {}
293 //Attachment(... mds reference ...);
294
295 Impl *operator ->() const { return &impl<Impl>(); }
296 Impl &operator *() const { return impl<Impl>(); }
297 };
298
299
300 //
301 // A CSSM session object.
302 // You usually only have one per program, or library, or what-not.
303 //
304 class Cssm;
305
306 class CssmImpl : public ObjectImpl {
307 class StandardCssm; friend class StandardCssm;
308 public:
309 CssmImpl();
310 virtual ~CssmImpl();
311
312 void init() { activate(); }
313 void terminate() { deactivate(); }
314
315 CSSM_PRIVILEGE_SCOPE scope() const { return mScope; }
316 void scope(CSSM_PRIVILEGE_SCOPE sc) { mScope = sc; }
317 const Guid &callerGuid() const { return mCallerGuid; }
318 void callerGuid(const CSSM_GUID &guid) { mCallerGuid = Guid::overlay(guid); }
319
320 Module autoModule(const Guid &guid);
321
322 protected:
323 explicit CssmImpl(bool); // internal constructor
324
325 void setup(); // constructor setup
326
327 void activate();
328 void deactivate();
329
330 private:
331 // CSSM global configuration -- picked up on each Init
332 CSSM_VERSION mVersion;
333 CSSM_PRIVILEGE_SCOPE mScope;
334 Guid mCallerGuid;
335
336 // module repository: modules by guid (protected by self)
337 typedef map<Guid, Module> ModuleMap;
338 ModuleMap moduleMap;
339 Mutex mapLock;
340
341 public:
342 static Cssm standard();
343 static void catchExit();
344
345 private:
346 static void atExitHandler();
347
348 class StandardCssm : public Mutex {
349 public:
350 StandardCssm() : mCssm(NULL) { }
351 ~StandardCssm();
352 void setCssm(CssmImpl *cssm);
353 void unsetCssm(CssmImpl *cssm);
354 Cssm get();
355
356 private:
357 RefPointer<CssmImpl> mCssm; // 'Leaks' this object (in that it won't ever be deleted after creation), but
358 // there's no safe way to vend and re-create this object in a multi-threaded environment
359 // without an implementation of WeakRefPointer<>.
360 };
361 static ModuleNexus<StandardCssm> mStandard;
362 };
363
364 class Cssm : public Object
365 {
366 public:
367 typedef CssmImpl Impl;
368 explicit Cssm(Impl *impl) : Object(impl) {}
369 explicit Cssm() : Object(new Impl()) {}
370
371 Impl *operator ->() const { return &impl<Impl>(); }
372 Impl &operator *() const { return impl<Impl>(); }
373
374 static Cssm standard() { return CssmImpl::standard(); }
375 };
376
377 } // end namespace CssmClient
378
379 } // end namespace Security
380
381 #endif // _H_CDSA_CLIENT_CSSMCLIENT