]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2000-2001,2011-2012,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 | // CSPsession.h - Framework for CSP plugin modules | |
21 | // | |
22 | #ifndef _H_CSPSESSION | |
23 | #define _H_CSPSESSION | |
24 | ||
25 | #include <security_cdsa_plugin/CSPabstractsession.h> | |
26 | #include <map> | |
27 | ||
28 | ||
29 | namespace Security { | |
30 | ||
31 | // | |
32 | // The CSPPluginSession provides a general bed for CSP plugin session objects. | |
33 | // Derive from this if you want to write your CSP, effectively, from scratch. | |
34 | // We still provide a framework for managing local cryptographic contexts and | |
35 | // (module) logins. | |
36 | // | |
37 | class CSPPluginSession : public PluginSession, public CSPAbstractPluginSession { | |
38 | public: | |
39 | CSPPluginSession(CSSM_MODULE_HANDLE theHandle, | |
40 | CssmPlugin &plug, | |
41 | const CSSM_VERSION &version, | |
42 | uint32 subserviceId, | |
43 | CSSM_SERVICE_TYPE subserviceType, | |
44 | CSSM_ATTACH_FLAGS attachFlags, | |
45 | const CSSM_UPCALLS &upcalls) | |
46 | : PluginSession(theHandle, plug, version, subserviceId, subserviceType, attachFlags, upcalls) { } | |
47 | ||
48 | // methods implemented here that you should not override in a subclass | |
49 | void EventNotify(CSSM_CONTEXT_EVENT e, | |
50 | CSSM_CC_HANDLE ccHandle, const Context &context); | |
51 | CSSM_MODULE_FUNCS_PTR construct(); | |
52 | ||
53 | public: | |
54 | class PluginContext { | |
55 | public: | |
56 | virtual bool changed(const Context &context); | |
57 | virtual ~PluginContext(); | |
58 | }; | |
59 | ||
60 | public: | |
61 | bool loggedIn() const { return mLoggedIn; } | |
62 | bool loggedIn(bool li) { bool old = mLoggedIn; mLoggedIn = li; return old; } | |
63 | ||
64 | template <class Ctx> Ctx *getContext(CSSM_CC_HANDLE handle) | |
65 | { StLock<Mutex> _(contextMapLock); return safe_cast<Ctx *>(contextMap[handle]); } | |
66 | ||
67 | void setContext(CSSM_CC_HANDLE handle, PluginContext *ctx) | |
68 | { StLock<Mutex> _(contextMapLock); contextMap[handle] = ctx; } | |
69 | ||
70 | public: | |
71 | // context management methods - override as needed | |
72 | virtual PluginContext *contextCreate(CSSM_CC_HANDLE handle, const Context &context); | |
73 | virtual void contextUpdate(CSSM_CC_HANDLE handle, | |
74 | const Context &context, PluginContext * &ctx); | |
75 | virtual void contextDelete(CSSM_CC_HANDLE handle, const Context &context, PluginContext *ctx); | |
76 | ||
77 | private: | |
78 | bool mLoggedIn; | |
79 | ||
80 | map<CSSM_CC_HANDLE, PluginContext *> contextMap; | |
81 | Mutex contextMapLock; | |
82 | }; | |
83 | ||
84 | ||
85 | // | |
86 | // On the other hand, for most CSP modules, this subclass of CSPPluginSession provides | |
87 | // much more convenient embedding facilities. The theory of operation is too complicated | |
88 | // to explain here; refer to the accompanying documentation. | |
89 | // | |
90 | class CSPFullPluginSession : public CSPPluginSession { | |
91 | public: | |
92 | class CSPContext; | |
93 | class AlgorithmFactory; | |
94 | ||
95 | CSPFullPluginSession(CSSM_MODULE_HANDLE theHandle, | |
96 | CssmPlugin &plug, | |
97 | const CSSM_VERSION &version, | |
98 | uint32 subserviceId, | |
99 | CSSM_SERVICE_TYPE subserviceType, | |
100 | CSSM_ATTACH_FLAGS attachFlags, | |
101 | const CSSM_UPCALLS &upcalls) | |
102 | : CSPPluginSession(theHandle, plug, version, | |
103 | subserviceId, subserviceType, attachFlags, upcalls) { } | |
104 | ||
105 | // final context preparation (called by secondary transition layer) | |
106 | CSPContext *init(CSSM_CC_HANDLE ccHandle, CSSM_CONTEXT_TYPE type, | |
107 | const Context &context, bool encoding = true); | |
108 | ||
109 | // verify proper state on continuation (update/final) calls | |
110 | CSPContext *getStagedContext(CSSM_CC_HANDLE ccHandle, | |
111 | CSSM_CONTEXT_TYPE type, bool encoding = true); | |
112 | ||
113 | static const uint32 CSSM_ALGCLASS_CRYPT = 1001; // internally added to CONTEXT_TYPE | |
114 | ||
115 | protected: | |
116 | // validate operation type against context class | |
117 | void checkOperation(CSSM_CONTEXT_TYPE ctxType, CSSM_CONTEXT_TYPE opType); | |
118 | ||
119 | protected: | |
120 | // | |
121 | // The Writer class encapsulates staged-output destinations with optional overflow | |
122 | // | |
123 | class Writer { | |
124 | public: | |
125 | Writer(CssmData *v, uint32 n, CssmData *rem = NULL); | |
126 | ||
127 | // can this buffer be extended? | |
128 | bool isExtensible() const | |
129 | { return !*vec || (remData && !*remData); } | |
130 | ||
131 | // increase size if necessary (and possible) | |
132 | void allocate(size_t needed, Allocator &alloc); | |
133 | ||
134 | // straight-forward buffer writing | |
135 | void put(void *addr, size_t size); | |
136 | ||
137 | // locate-mode output (deliver buffer mode) | |
138 | void nextBlock(void * &p, size_t &sz); | |
139 | void use(size_t sz); | |
140 | ||
141 | // wrap up and return total number of bytes written | |
142 | size_t close(); | |
143 | ||
144 | private: | |
145 | CssmData *vec; // current buffer descriptor (the one in use) | |
146 | CssmData *firstVec; // first buffer descriptor | |
147 | CssmData *lastVec; // last buffer descriptor (NOT one past it) | |
148 | CssmData *remData; // overflow buffer, if any | |
149 | ||
150 | void *currentBuffer; // next free byte in vec | |
151 | size_t currentSize; // free bytes in vec | |
152 | ||
153 | size_t written; // bytes written | |
154 | ||
155 | void useData(CssmData *data) | |
156 | { currentBuffer = data->data(); currentSize = data->length(); } | |
157 | }; | |
158 | ||
159 | public: | |
160 | // internal utilities (used by our own subclasses) | |
161 | static CssmData makeBuffer(size_t size, Allocator &alloc); | |
162 | static size_t totalBufferSize(const CssmData *data, uint32 count); | |
163 | void setKey(CssmKey &key, | |
164 | const Context &context, CSSM_KEYCLASS keyClass, | |
165 | CSSM_KEYATTR_FLAGS attrs, CSSM_KEYUSE use); | |
166 | ||
167 | public: | |
168 | // | |
169 | // All contexts from CSPFullPluginSession's subclasses must derive from CSPContext. | |
170 | // CSPFullPluginSession reformulates CSSM operations in terms of virtual methods of | |
171 | // the context class. | |
172 | // | |
173 | class CSPContext : public PluginContext { | |
174 | friend class CSPFullPluginSession; | |
175 | public: | |
176 | CSSM_CONTEXT_TYPE type() const { return mType; } | |
177 | bool encoding() const { return mDirection; } | |
178 | ||
179 | // init() is called for all algorithms | |
180 | virtual void init(const Context &context, bool encoding = true); | |
181 | ||
182 | // the following methods will be called for some but not all algorithms | |
183 | virtual void update(const CssmData &data); // all block-input algorithms | |
184 | virtual void update(void *inp, size_t &inSize, void *outp, size_t &outSize); // cryption algs | |
185 | virtual void final(CssmData &out); // output-data producing algorithms | |
186 | virtual void final(const CssmData &in); // verifying algorithms | |
187 | virtual void generate(const Context &context, CssmKey &pubKey, CssmKey &privKey); | |
188 | virtual void generate(const Context &context, uint32, | |
189 | CssmData ¶ms, uint32 &attrCount, Context::Attr * &attrs); | |
190 | virtual CSPContext *clone(Allocator &); // clone internal state | |
191 | virtual void setDigestAlgorithm(CSSM_ALGORITHMS digestAlg); | |
192 | ||
193 | virtual size_t inputSize(size_t outSize); // input for given output size | |
194 | virtual size_t outputSize(bool final = false, size_t inSize = 0); // output for given input size | |
195 | virtual void minimumProgress(size_t &in, size_t &out); // minimum progress chunks | |
196 | ||
197 | protected: | |
198 | // convenience forms of the above | |
199 | void update(const CssmData *in, uint32 inCount, Writer &writer); | |
200 | void final(CssmData &out, Allocator &alloc); | |
201 | void final(Writer &writer, Allocator &alloc); | |
202 | ||
203 | void update(const CssmData *in, uint32 inCount) | |
204 | { for (uint32 n = 0; n < inCount; n++) update(in[n]); } | |
205 | ||
206 | void checkOperation(CSSM_CONTEXT_TYPE type); | |
207 | void checkOperation(CSSM_CONTEXT_TYPE type, bool encode); | |
208 | ||
209 | CSSM_CONTEXT_TYPE mType; // CSSM context type | |
210 | bool mDirection; // operation direction (true if irrelevant) | |
211 | }; | |
212 | ||
213 | protected: | |
214 | virtual void setupContext(CSPContext * &ctx, const Context &context, bool encoding) = 0; | |
215 | ||
216 | virtual void getKeySize(const CssmKey &key, CSSM_KEY_SIZE &size); | |
217 | ||
218 | public: | |
219 | // an algorithm factory. This is an optional feature | |
220 | class AlgorithmFactory { | |
221 | public: | |
222 | virtual ~AlgorithmFactory(); | |
223 | ||
224 | // set ctx and return true if you can handle this | |
225 | virtual bool setup(CSPContext * &ctx, const Context &context) = 0; | |
226 | }; | |
227 | ||
228 | public: | |
229 | void EncryptData(CSSM_CC_HANDLE CCHandle, | |
230 | const Context &Context, | |
231 | const CssmData ClearBufs[], | |
232 | uint32 ClearBufCount, | |
233 | CssmData CipherBufs[], | |
234 | uint32 CipherBufCount, | |
235 | CSSM_SIZE &bytesEncrypted, | |
236 | CssmData &RemData, | |
237 | CSSM_PRIVILEGE Privilege); | |
238 | void EncryptDataInit(CSSM_CC_HANDLE CCHandle, | |
239 | const Context &Context, | |
240 | CSSM_PRIVILEGE Privilege); | |
241 | void EncryptDataUpdate(CSSM_CC_HANDLE CCHandle, | |
242 | const CssmData ClearBufs[], | |
243 | uint32 ClearBufCount, | |
244 | CssmData CipherBufs[], | |
245 | uint32 CipherBufCount, | |
246 | CSSM_SIZE &bytesEncrypted); | |
247 | void EncryptDataFinal(CSSM_CC_HANDLE CCHandle, | |
248 | CssmData &RemData); | |
249 | ||
250 | void DecryptData(CSSM_CC_HANDLE CCHandle, | |
251 | const Context &Context, | |
252 | const CssmData CipherBufs[], | |
253 | uint32 CipherBufCount, | |
254 | CssmData ClearBufs[], | |
255 | uint32 ClearBufCount, | |
256 | CSSM_SIZE &bytesDecrypted, | |
257 | CssmData &RemData, | |
258 | CSSM_PRIVILEGE Privilege); | |
259 | void DecryptDataInit(CSSM_CC_HANDLE CCHandle, | |
260 | const Context &Context, | |
261 | CSSM_PRIVILEGE Privilege); | |
262 | void DecryptDataUpdate(CSSM_CC_HANDLE CCHandle, | |
263 | const CssmData CipherBufs[], | |
264 | uint32 CipherBufCount, | |
265 | CssmData ClearBufs[], | |
266 | uint32 ClearBufCount, | |
267 | CSSM_SIZE &bytesDecrypted); | |
268 | void DecryptDataFinal(CSSM_CC_HANDLE CCHandle, | |
269 | CssmData &RemData); | |
270 | ||
271 | void QuerySize(CSSM_CC_HANDLE CCHandle, | |
272 | const Context &Context, | |
273 | CSSM_BOOL Encrypt, | |
274 | uint32 QuerySizeCount, | |
275 | QuerySizeData *DataBlock); | |
276 | ||
277 | void WrapKey(CSSM_CC_HANDLE CCHandle, | |
278 | const Context &Context, | |
279 | const AccessCredentials &AccessCred, | |
280 | const CssmKey &Key, | |
281 | const CssmData *DescriptiveData, | |
282 | CssmKey &WrappedKey, | |
283 | CSSM_PRIVILEGE Privilege); | |
284 | void UnwrapKey(CSSM_CC_HANDLE CCHandle, | |
285 | const Context &Context, | |
286 | const CssmKey *PublicKey, | |
287 | const CssmKey &WrappedKey, | |
288 | uint32 KeyUsage, | |
289 | uint32 KeyAttr, | |
290 | const CssmData *KeyLabel, | |
291 | const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, | |
292 | CssmKey &UnwrappedKey, | |
293 | CssmData &DescriptiveData, | |
294 | CSSM_PRIVILEGE Privilege); | |
295 | void DeriveKey(CSSM_CC_HANDLE CCHandle, | |
296 | const Context &Context, | |
297 | CssmData &Param, | |
298 | uint32 KeyUsage, | |
299 | uint32 KeyAttr, | |
300 | const CssmData *KeyLabel, | |
301 | const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, | |
302 | CssmKey &DerivedKey); | |
303 | ||
304 | void GenerateMac(CSSM_CC_HANDLE CCHandle, | |
305 | const Context &Context, | |
306 | const CssmData DataBufs[], | |
307 | uint32 DataBufCount, | |
308 | CssmData &Mac); | |
309 | void GenerateMacInit(CSSM_CC_HANDLE CCHandle, | |
310 | const Context &Context); | |
311 | void GenerateMacUpdate(CSSM_CC_HANDLE CCHandle, | |
312 | const CssmData DataBufs[], | |
313 | uint32 DataBufCount); | |
314 | void GenerateMacFinal(CSSM_CC_HANDLE CCHandle, | |
315 | CssmData &Mac); | |
316 | ||
317 | void VerifyMac(CSSM_CC_HANDLE CCHandle, | |
318 | const Context &Context, | |
319 | const CssmData DataBufs[], | |
320 | uint32 DataBufCount, | |
321 | const CssmData &Mac); | |
322 | virtual void VerifyMacInit(CSSM_CC_HANDLE CCHandle, | |
323 | const Context &Context); | |
324 | virtual void VerifyMacUpdate(CSSM_CC_HANDLE CCHandle, | |
325 | const CssmData DataBufs[], | |
326 | uint32 DataBufCount); | |
327 | virtual void VerifyMacFinal(CSSM_CC_HANDLE CCHandle, | |
328 | const CssmData &Mac); | |
329 | ||
330 | void SignData(CSSM_CC_HANDLE CCHandle, | |
331 | const Context &Context, | |
332 | const CssmData DataBufs[], | |
333 | uint32 DataBufCount, | |
334 | CSSM_ALGORITHMS DigestAlgorithm, | |
335 | CssmData &Signature); | |
336 | void SignDataInit(CSSM_CC_HANDLE CCHandle, | |
337 | const Context &Context); | |
338 | void SignDataUpdate(CSSM_CC_HANDLE CCHandle, | |
339 | const CssmData DataBufs[], | |
340 | uint32 DataBufCount); | |
341 | void SignDataFinal(CSSM_CC_HANDLE CCHandle, | |
342 | CssmData &Signature); | |
343 | ||
344 | void VerifyData(CSSM_CC_HANDLE CCHandle, | |
345 | const Context &Context, | |
346 | const CssmData DataBufs[], | |
347 | uint32 DataBufCount, | |
348 | CSSM_ALGORITHMS DigestAlgorithm, | |
349 | const CssmData &Signature); | |
350 | virtual void VerifyDataInit(CSSM_CC_HANDLE CCHandle, | |
351 | const Context &Context); | |
352 | virtual void VerifyDataUpdate(CSSM_CC_HANDLE CCHandle, | |
353 | const CssmData DataBufs[], | |
354 | uint32 DataBufCount); | |
355 | virtual void VerifyDataFinal(CSSM_CC_HANDLE CCHandle, | |
356 | const CssmData &Signature); | |
357 | ||
358 | void DigestData(CSSM_CC_HANDLE CCHandle, | |
359 | const Context &Context, | |
360 | const CssmData DataBufs[], | |
361 | uint32 DataBufCount, | |
362 | CssmData &Digest); | |
363 | void DigestDataInit(CSSM_CC_HANDLE CCHandle, | |
364 | const Context &Context); | |
365 | void DigestDataUpdate(CSSM_CC_HANDLE CCHandle, | |
366 | const CssmData DataBufs[], | |
367 | uint32 DataBufCount); | |
368 | void DigestDataFinal(CSSM_CC_HANDLE CCHandle, | |
369 | CssmData &Digest); | |
370 | void DigestDataClone(CSSM_CC_HANDLE CCHandle, | |
371 | CSSM_CC_HANDLE ClonedCCHandle); | |
372 | ||
373 | void GenerateKey(CSSM_CC_HANDLE CCHandle, | |
374 | const Context &Context, | |
375 | uint32 KeyUsage, | |
376 | uint32 KeyAttr, | |
377 | const CssmData *KeyLabel, | |
378 | const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, | |
379 | CssmKey &Key, | |
380 | CSSM_PRIVILEGE Privilege); | |
381 | void GenerateKeyPair(CSSM_CC_HANDLE CCHandle, | |
382 | const Context &Context, | |
383 | uint32 PublicKeyUsage, | |
384 | uint32 PublicKeyAttr, | |
385 | const CssmData *PublicKeyLabel, | |
386 | CssmKey &PublicKey, | |
387 | uint32 PrivateKeyUsage, | |
388 | uint32 PrivateKeyAttr, | |
389 | const CssmData *PrivateKeyLabel, | |
390 | const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, | |
391 | CssmKey &PrivateKey, | |
392 | CSSM_PRIVILEGE Privilege); | |
393 | ||
394 | void ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey, | |
395 | CssmKey &PrivateKey); | |
396 | void QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle, | |
397 | const Context *Context, | |
398 | const CssmKey *Key, | |
399 | CSSM_KEY_SIZE &KeySize); | |
400 | ||
401 | void FreeKey(const AccessCredentials *AccessCred, | |
402 | CssmKey &KeyPtr, | |
403 | CSSM_BOOL Delete); | |
404 | ||
405 | void GenerateRandom(CSSM_CC_HANDLE CCHandle, | |
406 | const Context &Context, | |
407 | CssmData &RandomNumber); | |
408 | void GenerateAlgorithmParams(CSSM_CC_HANDLE CCHandle, | |
409 | const Context &Context, | |
410 | uint32 ParamBits, | |
411 | CssmData &Param, | |
412 | uint32 &NumberOfUpdatedAttibutes, | |
413 | CSSM_CONTEXT_ATTRIBUTE_PTR &UpdatedAttributes); | |
414 | ||
415 | void Login(const AccessCredentials &AccessCred, | |
416 | const CssmData *LoginName, | |
417 | const void *Reserved); | |
418 | void Logout(); | |
419 | void VerifyDevice(const CssmData &DeviceCert); | |
420 | void GetOperationalStatistics(CSPOperationalStatistics &Statistics); | |
421 | ||
422 | void RetrieveCounter(CssmData &Counter); | |
423 | void RetrieveUniqueId(CssmData &UniqueID); | |
424 | void GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm, CssmData &TimeData); | |
425 | ||
426 | void GetKeyOwner(const CssmKey &Key, | |
427 | CSSM_ACL_OWNER_PROTOTYPE &Owner); | |
428 | void ChangeKeyOwner(const AccessCredentials &AccessCred, | |
429 | const CssmKey &Key, | |
430 | const CSSM_ACL_OWNER_PROTOTYPE &NewOwner); | |
431 | void GetKeyAcl(const CssmKey &Key, | |
432 | const CSSM_STRING *SelectionTag, | |
433 | uint32 &NumberOfAclInfos, | |
434 | CSSM_ACL_ENTRY_INFO_PTR &AclInfos); | |
435 | void ChangeKeyAcl(const AccessCredentials &AccessCred, | |
436 | const CSSM_ACL_EDIT &AclEdit, | |
437 | const CssmKey &Key); | |
438 | ||
439 | void GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE &Owner); | |
440 | void ChangeLoginOwner(const AccessCredentials &AccessCred, | |
441 | const CSSM_ACL_OWNER_PROTOTYPE &NewOwner); | |
442 | void GetLoginAcl(const CSSM_STRING *SelectionTag, | |
443 | uint32 &NumberOfAclInfos, | |
444 | CSSM_ACL_ENTRY_INFO_PTR &AclInfos); | |
445 | void ChangeLoginAcl(const AccessCredentials &AccessCred, | |
446 | const CSSM_ACL_EDIT &AclEdit); | |
447 | ||
448 | void PassThrough(CSSM_CC_HANDLE CCHandle, | |
449 | const Context &Context, | |
450 | uint32 PassThroughId, | |
451 | const void *InData, | |
452 | void **OutData); | |
453 | }; | |
454 | ||
455 | ||
456 | // | |
457 | // Classes for dealing with reference keys. | |
458 | // | |
459 | ||
460 | // Forward declaration. | |
461 | class KeyPool; | |
462 | ||
463 | // | |
464 | // A ReferencedKey -- The private (to the CSP) part of a Reference Key. | |
465 | // | |
466 | class ReferencedKey | |
467 | { | |
468 | friend class KeyPool; // So it can call deactivate() | |
469 | public: | |
470 | // What we use to reference a ReferencedKey. | |
471 | typedef CSSM_INTPTR KeyReference; | |
472 | ReferencedKey(KeyPool &session); // Calls KeyPool::add() | |
473 | virtual ~ReferencedKey(); // Calls KeyPool::erase() | |
474 | ||
475 | KeyReference keyReference(); | |
476 | bool isActive() { return mKeyPool != NULL; } | |
477 | ||
478 | template <class SubPool> | |
479 | SubPool &keyPool() { assert(mKeyPool); return safer_cast<SubPool &>(*mKeyPool); } | |
480 | public: | |
481 | // Making, retrieving and freeing CSSM_KEYBLOB_REF_FORMAT_INTEGER CSSM_KEY type reference keys | |
482 | // NOTE: that none of these functions affect mKeyMap. | |
483 | static void makeReferenceKey(Allocator &allocator, KeyReference keyReference, CSSM_KEY &ioKey); | |
484 | static KeyReference keyReference(const CSSM_KEY &key); | |
485 | static KeyReference freeReferenceKey(Allocator &allocator, CSSM_KEY &ioKey); | |
486 | ||
487 | private: | |
488 | void deactivate() { mKeyPool = NULL; } | |
489 | ||
490 | // Will be NULL iff this key is not active | |
491 | KeyPool *mKeyPool; | |
492 | }; | |
493 | ||
494 | ||
495 | // | |
496 | // KeyPool -- a mixin class to manage a pool of ReferencedKeys | |
497 | // | |
498 | class KeyPool | |
499 | { | |
500 | public: | |
501 | friend class ReferencedKey; // So it can call add() and erase() | |
502 | public: | |
503 | KeyPool(); | |
504 | virtual ~KeyPool(); | |
505 | ||
506 | // Type safe ReferencedKey subclass lookup | |
507 | template <class Subclass> | |
508 | Subclass &find(const CSSM_KEY &key) const; | |
509 | ||
510 | // Free the ioKey, erase keyReference from mKeyMap, and delete the ReferencedKey | |
511 | void freeKey(Allocator &allocator, CSSM_KEY &key); | |
512 | ||
513 | protected: | |
514 | // Called by the constructor of ReferencedKey -- add referencedKey to mKeyMap | |
515 | void add(ReferencedKey &referencedKey); | |
516 | ||
517 | ReferencedKey &findKey(const CSSM_KEY &key) const; | |
518 | ReferencedKey &findKeyReference(ReferencedKey::KeyReference keyReference) const; | |
519 | ||
520 | // Called by the destructor of ReferencedKey -- erase keyReference from mKeyMap | |
521 | void erase(ReferencedKey &referencedKey); | |
522 | ||
523 | // Erase keyReference from mKeyMap, and return it (for deletion) | |
524 | ReferencedKey &erase(ReferencedKey::KeyReference keyReference); | |
525 | ||
526 | protected: | |
527 | typedef map<ReferencedKey::KeyReference, ReferencedKey *> KeyMap; | |
528 | KeyMap mKeyMap; | |
529 | mutable Mutex mKeyMapLock; | |
530 | }; | |
531 | ||
532 | // Implementation of type safe ReferencedKey subclass lookup. | |
533 | template <class Subclass> | |
534 | Subclass & | |
535 | KeyPool::find(const CSSM_KEY &key) const | |
536 | { | |
537 | Subclass *sub; | |
538 | if (!(sub = dynamic_cast<Subclass *>(&findKey(key)))) | |
539 | CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE); | |
540 | return *sub; | |
541 | } | |
542 | ||
543 | } // end namespace Security | |
544 | ||
545 | #endif //_H_CSPSESSION |