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
{
98 class AlgorithmFactory
;
100 CSPFullPluginSession(CSSM_MODULE_HANDLE theHandle
,
102 const CSSM_VERSION
&version
,
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
) { }
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);
114 // verify proper state on continuation (update/final) calls
115 CSPContext
*getStagedContext(CSSM_CC_HANDLE ccHandle
,
116 CSSM_CONTEXT_TYPE type
, bool encoding
= true);
118 static const uint32 CSSM_ALGCLASS_CRYPT
= 1001; // internally added to CONTEXT_TYPE
121 // validate operation type against context class
122 void checkOperation(CSSM_CONTEXT_TYPE ctxType
, CSSM_CONTEXT_TYPE opType
);
126 // The Writer class encapsulates staged-output destinations with optional overflow
130 Writer(CssmData
*v
, uint32 n
, CssmData
*rem
= NULL
);
132 // can this buffer be extended?
133 bool isExtensible() const
134 { return !*vec
|| remData
&& !*remData
; }
136 // increase size if necessary (and possible)
137 void allocate(size_t needed
, CssmAllocator
&alloc
);
139 // straight-forward buffer writing
140 void put(void *addr
, size_t size
);
142 // locate-mode output (deliver buffer mode)
143 void nextBlock(void * &p
, size_t &sz
);
146 // wrap up and return total number of bytes written
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
155 void *currentBuffer
; // next free byte in vec
156 size_t currentSize
; // free bytes in vec
158 size_t written
; // bytes written
160 void useData(CssmData
*data
)
161 { currentBuffer
= data
->data(); currentSize
= data
->length(); }
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
);
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.
178 class CSPContext
: public PluginContext
{
179 friend class CSPFullPluginSession
;
181 CSSM_CONTEXT_TYPE
type() const { return mType
; }
182 bool encoding() const { return mDirection
; }
184 // init() is called for all algorithms
185 virtual void init(const Context
&context
, bool encoding
= true);
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
¶ms
, uint32
&attrCount
, Context::Attr
* &attrs
);
195 virtual CSPContext
*clone(CssmAllocator
&); // clone internal state
196 virtual void setDigestAlgorithm(CSSM_ALGORITHMS digestAlg
);
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
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
);
208 void update(const CssmData
*in
, uint32 inCount
)
209 { for (uint32 n
= 0; n
< inCount
; n
++) update(in
[n
]); }
211 void checkOperation(CSSM_CONTEXT_TYPE type
);
212 void checkOperation(CSSM_CONTEXT_TYPE type
, bool encode
);
214 CSSM_CONTEXT_TYPE mType
; // CSSM context type
215 bool mDirection
; // operation direction (true if irrelevant)
219 virtual void setupContext(CSPContext
* &ctx
, const Context
&context
, bool encoding
) = 0;
221 virtual void getKeySize(const CssmKey
&key
, CSSM_KEY_SIZE
&size
);
224 // an algorithm factory. This is an optional feature
225 class AlgorithmFactory
{
227 // set ctx and return true if you can handle this
228 virtual bool setup(CSPContext
* &ctx
, const Context
&context
) = 0;
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
,
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
,
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
,
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
,
274 void QuerySize(CSSM_CC_HANDLE CCHandle
,
275 const Context
&Context
,
277 uint32 QuerySizeCount
,
278 QuerySizeData
*DataBlock
);
280 void WrapKey(CSSM_CC_HANDLE CCHandle
,
281 const Context
&Context
,
282 const AccessCredentials
&AccessCred
,
284 const CssmData
*DescriptiveData
,
286 CSSM_PRIVILEGE Privilege
);
287 void UnwrapKey(CSSM_CC_HANDLE CCHandle
,
288 const Context
&Context
,
289 const CssmKey
*PublicKey
,
290 const CssmKey
&WrappedKey
,
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
,
303 const CssmData
*KeyLabel
,
304 const CSSM_RESOURCE_CONTROL_CONTEXT
*CredAndAclEntry
,
305 CssmKey
&DerivedKey
);
307 void GenerateMac(CSSM_CC_HANDLE CCHandle
,
308 const Context
&Context
,
309 const CssmData DataBufs
[],
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
,
320 void VerifyMac(CSSM_CC_HANDLE CCHandle
,
321 const Context
&Context
,
322 const CssmData DataBufs
[],
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
);
333 void SignData(CSSM_CC_HANDLE CCHandle
,
334 const Context
&Context
,
335 const CssmData DataBufs
[],
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
);
347 void VerifyData(CSSM_CC_HANDLE CCHandle
,
348 const Context
&Context
,
349 const CssmData DataBufs
[],
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
);
361 void DigestData(CSSM_CC_HANDLE CCHandle
,
362 const Context
&Context
,
363 const CssmData DataBufs
[],
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
,
373 void DigestDataClone(CSSM_CC_HANDLE CCHandle
,
374 CSSM_CC_HANDLE ClonedCCHandle
);
376 void GenerateKey(CSSM_CC_HANDLE CCHandle
,
377 const Context
&Context
,
380 const CssmData
*KeyLabel
,
381 const CSSM_RESOURCE_CONTROL_CONTEXT
*CredAndAclEntry
,
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
,
390 uint32 PrivateKeyUsage
,
391 uint32 PrivateKeyAttr
,
392 const CssmData
*PrivateKeyLabel
,
393 const CSSM_RESOURCE_CONTROL_CONTEXT
*CredAndAclEntry
,
395 CSSM_PRIVILEGE Privilege
);
397 void ObtainPrivateKeyFromPublicKey(const CssmKey
&PublicKey
,
398 CssmKey
&PrivateKey
);
399 void QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle
,
400 const Context
*Context
,
402 CSSM_KEY_SIZE
&KeySize
);
404 void FreeKey(const AccessCredentials
*AccessCred
,
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
,
415 uint32
&NumberOfUpdatedAttibutes
,
416 CSSM_CONTEXT_ATTRIBUTE_PTR
&UpdatedAttributes
);
418 void Login(const AccessCredentials
&AccessCred
,
419 const CssmData
*LoginName
,
420 const void *Reserved
);
422 void VerifyDevice(const CssmData
&DeviceCert
);
423 void GetOperationalStatistics(CSPOperationalStatistics
&Statistics
);
425 void RetrieveCounter(CssmData
&Counter
);
426 void RetrieveUniqueId(CssmData
&UniqueID
);
427 void GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm
, CssmData
&TimeData
);
429 void GetKeyOwner(const CssmKey
&Key
,
430 CSSM_ACL_OWNER_PROTOTYPE
&Owner
);
431 void ChangeKeyOwner(const AccessCredentials
&AccessCred
,
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
,
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
);
451 void PassThrough(CSSM_CC_HANDLE CCHandle
,
452 const Context
&Context
,
453 uint32 PassThroughId
,
460 // Classes for dealing with reference keys.
463 // Forward declaration.
467 // A ReferencedKey -- The private (to the CSP) part of a Reference Key.
471 friend class KeyPool
; // So it can call deactivate()
473 // What we use to reference a ReferencedKey.
474 typedef uint32 KeyReference
;
476 ReferencedKey(KeyPool
&session
); // Calls KeyPool::add()
477 virtual ~ReferencedKey(); // Calls KeyPool::erase()
479 KeyReference
keyReference();
480 bool isActive() { return mKeyPool
!= NULL
; }
482 template <class SubPool
>
483 SubPool
&keyPool() { assert(mKeyPool
); return safer_cast
<SubPool
&>(*mKeyPool
); }
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
);
492 void deactivate() { mKeyPool
= NULL
; }
494 // Will be NULL iff this key is not active
500 // KeyPool -- a mixin class to manage a pool of ReferencedKeys
505 friend class ReferencedKey
; // So it can call add() and erase()
510 // Type safe ReferencedKey subclass lookup
511 template <class Subclass
>
512 Subclass
&find(const CSSM_KEY
&key
) const;
514 // Free the ioKey, erase keyReference from mKeyMap, and delete the ReferencedKey
515 void freeKey(CssmAllocator
&allocator
, CSSM_KEY
&key
);
518 // Called by the constructor of ReferencedKey -- add referencedKey to mKeyMap
519 void add(ReferencedKey
&referencedKey
);
521 ReferencedKey
&findKey(const CSSM_KEY
&key
) const;
522 ReferencedKey
&findKeyReference(ReferencedKey::KeyReference keyReference
) const;
524 // Called by the destructor of ReferencedKey -- erase keyReference from mKeyMap
525 void erase(ReferencedKey
&referencedKey
);
527 // Erase keyReference from mKeyMap, and return it (for deletion)
528 ReferencedKey
&erase(ReferencedKey::KeyReference keyReference
);
531 typedef map
<ReferencedKey::KeyReference
, ReferencedKey
*> KeyMap
;
533 mutable Mutex mKeyMapLock
;
536 // Implementation of type safe ReferencedKey subclass lookup.
537 template <class Subclass
>
539 KeyPool::find(const CSSM_KEY
&key
) const
542 if (!(sub
= dynamic_cast<Subclass
*>(&findKey(key
))))
543 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
);
547 } // end namespace Security
549 #if defined(_CPP_CSPSESSION)
553 #endif //_H_CSPSESSION