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