]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_plugin/lib/CSPsession.h
Security-59306.101.1.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_plugin / lib / CSPsession.h
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 &params, 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