2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // CSPsession.h - Framework for CSP plugin modules
25 #include <Security/CSPabstractsession.h>
28 #if defined(_CPP_CSPSESSION)
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
42 class CSPPluginSession
: public PluginSession
, public CSPAbstractPluginSession
{
44 CSPPluginSession(CSSM_MODULE_HANDLE theHandle
,
46 const CSSM_VERSION
&version
,
48 CSSM_SERVICE_TYPE subserviceType
,
49 CSSM_ATTACH_FLAGS attachFlags
,
50 const CSSM_UPCALLS
&upcalls
)
51 : PluginSession(theHandle
, plug
, version
, subserviceId
, subserviceType
, attachFlags
, upcalls
) { }
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();
61 virtual bool changed(const Context
&context
);
62 virtual ~PluginContext();
66 bool loggedIn() const { return mLoggedIn
; }
67 bool loggedIn(bool li
) { bool old
= mLoggedIn
; mLoggedIn
= li
; return old
; }
69 template <class Ctx
> Ctx
*getContext(CSSM_CC_HANDLE handle
)
70 { StLock
<Mutex
> _(contextMapLock
); return safe_cast
<Ctx
*>(contextMap
[handle
]); }
72 void setContext(CSSM_CC_HANDLE handle
, PluginContext
*ctx
)
73 { StLock
<Mutex
> _(contextMapLock
); contextMap
[handle
] = ctx
; }
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
);
85 map
<CSSM_CC_HANDLE
, PluginContext
*> contextMap
;
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.
95 class CSPFullPluginSession
: public CSPPluginSession
{
97 class AlgorithmFactory
;
99 CSPFullPluginSession(CSSM_MODULE_HANDLE theHandle
,
101 const CSSM_VERSION
&version
,
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
) { }
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);
113 // verify proper state on continuation (update/final) calls
114 CSPContext
*getStagedContext(CSSM_CC_HANDLE ccHandle
,
115 CSSM_CONTEXT_TYPE type
, bool encoding
= true);
117 static const uint32 CSSM_ALGCLASS_CRYPT
= 1001; // internally added to CONTEXT_TYPE
120 // validate operation type against context class
121 void checkOperation(CSSM_CONTEXT_TYPE ctxType
, CSSM_CONTEXT_TYPE opType
);
125 // The Writer class encapsulates staged-output destinations with optional overflow
129 Writer(CssmData
*v
, uint32 n
, CssmData
*rem
= NULL
);
131 // can this buffer be extended?
132 bool isExtensible() const
133 { return !*vec
|| remData
&& !*remData
; }
135 // increase size if necessary (and possible)
136 void allocate(size_t needed
, CssmAllocator
&alloc
);
138 // straight-forward buffer writing
139 void put(void *addr
, size_t size
);
141 // locate-mode output (deliver buffer mode)
142 void nextBlock(void * &p
, size_t &sz
);
145 // wrap up and return total number of bytes written
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
154 void *currentBuffer
; // next free byte in vec
155 size_t currentSize
; // free bytes in vec
157 size_t written
; // bytes written
159 void useData(CssmData
*data
)
160 { currentBuffer
= data
->data(); currentSize
= data
->length(); }
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
);
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.
177 class CSPContext
: public PluginContext
{
178 friend class CSPFullPluginSession
;
180 CSSM_CONTEXT_TYPE
type() const { return mType
; }
181 bool encoding() const { return mDirection
; }
183 // init() is called for all algorithms
184 virtual void init(const Context
&context
, bool encoding
= true);
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
¶ms
, uint32
&attrCount
, Context::Attr
* &attrs
);
194 virtual CSPContext
*clone(CssmAllocator
&); // clone internal state
195 virtual void setDigestAlgorithm(CSSM_ALGORITHMS digestAlg
);
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
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
);
207 void update(const CssmData
*in
, uint32 inCount
)
208 { for (uint32 n
= 0; n
< inCount
; n
++) update(in
[n
]); }
210 void checkOperation(CSSM_CONTEXT_TYPE type
);
211 void checkOperation(CSSM_CONTEXT_TYPE type
, bool encode
);
213 CSSM_CONTEXT_TYPE mType
; // CSSM context type
214 bool mDirection
; // operation direction (true if irrelevant)
218 virtual void setupContext(CSPContext
* &ctx
, const Context
&context
, bool encoding
) = 0;
220 virtual void getKeySize(const CssmKey
&key
, CSSM_KEY_SIZE
&size
);
223 // an algorithm factory. This is an optional feature
224 class AlgorithmFactory
{
226 // set ctx and return true if you can handle this
227 virtual bool setup(CSPContext
* &ctx
, const Context
&context
) = 0;
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
,
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
,
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
,
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
,
273 void QuerySize(CSSM_CC_HANDLE CCHandle
,
274 const Context
&Context
,
276 uint32 QuerySizeCount
,
277 QuerySizeData
*DataBlock
);
279 void WrapKey(CSSM_CC_HANDLE CCHandle
,
280 const Context
&Context
,
281 const AccessCredentials
&AccessCred
,
283 const CssmData
*DescriptiveData
,
285 CSSM_PRIVILEGE Privilege
);
286 void UnwrapKey(CSSM_CC_HANDLE CCHandle
,
287 const Context
&Context
,
288 const CssmKey
*PublicKey
,
289 const CssmKey
&WrappedKey
,
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
,
302 const CssmData
*KeyLabel
,
303 const CSSM_RESOURCE_CONTROL_CONTEXT
*CredAndAclEntry
,
304 CssmKey
&DerivedKey
);
306 void GenerateMac(CSSM_CC_HANDLE CCHandle
,
307 const Context
&Context
,
308 const CssmData DataBufs
[],
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
,
319 void VerifyMac(CSSM_CC_HANDLE CCHandle
,
320 const Context
&Context
,
321 const CssmData DataBufs
[],
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
);
332 void SignData(CSSM_CC_HANDLE CCHandle
,
333 const Context
&Context
,
334 const CssmData DataBufs
[],
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
);
346 void VerifyData(CSSM_CC_HANDLE CCHandle
,
347 const Context
&Context
,
348 const CssmData DataBufs
[],
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
);
360 void DigestData(CSSM_CC_HANDLE CCHandle
,
361 const Context
&Context
,
362 const CssmData DataBufs
[],
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
,
372 void DigestDataClone(CSSM_CC_HANDLE CCHandle
,
373 CSSM_CC_HANDLE ClonedCCHandle
);
375 void GenerateKey(CSSM_CC_HANDLE CCHandle
,
376 const Context
&Context
,
379 const CssmData
*KeyLabel
,
380 const CSSM_RESOURCE_CONTROL_CONTEXT
*CredAndAclEntry
,
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
,
389 uint32 PrivateKeyUsage
,
390 uint32 PrivateKeyAttr
,
391 const CssmData
*PrivateKeyLabel
,
392 const CSSM_RESOURCE_CONTROL_CONTEXT
*CredAndAclEntry
,
394 CSSM_PRIVILEGE Privilege
);
396 void ObtainPrivateKeyFromPublicKey(const CssmKey
&PublicKey
,
397 CssmKey
&PrivateKey
);
398 void QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle
,
399 const Context
*Context
,
401 CSSM_KEY_SIZE
&KeySize
);
403 void FreeKey(const AccessCredentials
*AccessCred
,
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
,
414 uint32
&NumberOfUpdatedAttibutes
,
415 CSSM_CONTEXT_ATTRIBUTE_PTR
&UpdatedAttributes
);
417 void Login(const AccessCredentials
&AccessCred
,
418 const CssmData
*LoginName
,
419 const void *Reserved
);
421 void VerifyDevice(const CssmData
&DeviceCert
);
422 void GetOperationalStatistics(CSPOperationalStatistics
&Statistics
);
424 void RetrieveCounter(CssmData
&Counter
);
425 void RetrieveUniqueId(CssmData
&UniqueID
);
426 void GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm
, CssmData
&TimeData
);
428 void GetKeyOwner(const CssmKey
&Key
,
429 CSSM_ACL_OWNER_PROTOTYPE
&Owner
);
430 void ChangeKeyOwner(const AccessCredentials
&AccessCred
,
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
,
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
);
450 void PassThrough(CSSM_CC_HANDLE CCHandle
,
451 const Context
&Context
,
452 uint32 PassThroughId
,
459 // Classes for dealing with reference keys.
462 // Forward declaration.
466 // A ReferencedKey -- The private (to the CSP) part of a Reference Key.
470 friend class KeyPool
; // So it can call deactivate()
472 // What we use to reference a ReferencedKey.
473 typedef uint32 KeyReference
;
475 ReferencedKey(KeyPool
&session
); // Calls KeyPool::add()
476 virtual ~ReferencedKey(); // Calls KeyPool::erase()
478 KeyReference
keyReference();
479 bool isActive() { return mKeyPool
!= NULL
; }
481 template <class SubPool
>
482 SubPool
&keyPool() { assert(mKeyPool
); return safer_cast
<SubPool
&>(*mKeyPool
); }
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
);
491 void deactivate() { mKeyPool
= NULL
; }
493 // Will be NULL iff this key is not active
499 // KeyPool -- a mixin class to manage a pool of ReferencedKeys
504 friend class ReferencedKey
; // So it can call add() and erase()
509 // Type safe ReferencedKey subclass lookup
510 template <class Subclass
>
511 Subclass
&find(const CSSM_KEY
&key
) const;
513 // Free the ioKey, erase keyReference from mKeyMap, and delete the ReferencedKey
514 void freeKey(CssmAllocator
&allocator
, CSSM_KEY
&key
);
517 // Called by the constructor of ReferencedKey -- add referencedKey to mKeyMap
518 void add(ReferencedKey
&referencedKey
);
520 ReferencedKey
&findKey(const CSSM_KEY
&key
) const;
521 ReferencedKey
&findKeyReference(ReferencedKey::KeyReference keyReference
) const;
523 // Called by the destructor of ReferencedKey -- erase keyReference from mKeyMap
524 void erase(ReferencedKey
&referencedKey
);
526 // Erase keyReference from mKeyMap, and return it (for deletion)
527 ReferencedKey
&erase(ReferencedKey::KeyReference keyReference
);
530 typedef map
<ReferencedKey::KeyReference
, ReferencedKey
*> KeyMap
;
532 mutable Mutex mKeyMapLock
;
535 // Implementation of type safe ReferencedKey subclass lookup.
536 template <class Subclass
>
538 KeyPool::find(const CSSM_KEY
&key
) const
541 if (!(sub
= dynamic_cast<Subclass
*>(&findKey(key
))))
542 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
);
546 } // end namespace Security
548 #if defined(_CPP_CSPSESSION)
552 #endif //_H_CSPSESSION