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