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