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 // SSCSPSession.cpp - Security Server CSP session.
22 #include "SSCSPSession.h"
24 #include "CSPDLPlugin.h"
25 #include "SSDatabase.h"
26 #include "SSDLSession.h"
32 using namespace SecurityServer
;
35 // SSCSPSession -- Security Server CSP session
37 SSCSPSession::SSCSPSession(CSSM_MODULE_HANDLE handle
,
39 const CSSM_VERSION
&version
,
41 CSSM_SERVICE_TYPE subserviceType
,
42 CSSM_ATTACH_FLAGS attachFlags
,
43 const CSSM_UPCALLS
&upcalls
,
44 SSCSPDLSession
&ssCSPDLSession
)
45 : CSPFullPluginSession(handle
, plug
, version
, subserviceId
, subserviceType
,
46 attachFlags
, upcalls
),
47 mSSCSPDLSession(ssCSPDLSession
),
48 mSSFactory(plug
.mSSFactory
)
53 // Called at (CSSM) context create time. This is ignored; we do a full
54 // context setup later, at setupContext time.
56 CSPFullPluginSession::CSPContext
*
57 SSCSPSession::contextCreate(CSSM_CC_HANDLE handle
, const Context
&context
)
64 // Called by CSPFullPluginSession when an op is actually commencing.
65 // Context can safely assumed to be fully formed and stable for the
66 // duration of the op; thus we wait until now to set up our
67 // CSPContext as appropriate to the op.
70 SSCSPSession::setupContext(CSPContext
* &cspCtx
,
71 const Context
&context
,
74 // note we skip this if this CSPContext is being reused
78 if (mSSFactory
.setup(*this, cspCtx
, context
, encoding
))
82 if (mBSafe4Factory
.setup(*this, cspCtx
, context
))
85 if (mCryptKitFactory
.setup(*this, cspCtx
, context
))
89 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM
);
98 SSCSPSession::getDatabase(const Context
&context
)
100 CSSM_DL_DB_HANDLE
*aDLDbHandle
= context
.get
<CSSM_DL_DB_HANDLE
>(CSSM_ATTRIBUTE_DL_DB_HANDLE
);
104 return findSession
<SSDLSession
>(aDLDbHandle
->DLHandle
).findDbHandle(aDLDbHandle
->DBHandle
);
109 // Reference Key management
112 SSCSPSession::makeReferenceKey(KeyHandle inKeyHandle
, CssmKey
&ioKey
, SSDatabase
&inSSDatabase
,
113 uint32 inKeyAttr
, const CssmData
*inKeyLabel
)
115 return mSSCSPDLSession
.makeReferenceKey(*this, inKeyHandle
, ioKey
, inSSDatabase
, inKeyAttr
, inKeyLabel
);
119 SSCSPSession::lookupKey(const CssmKey
&inKey
)
121 return mSSCSPDLSession
.lookupKey(inKey
);
126 // Key creating and handeling members
129 SSCSPSession::WrapKey(CSSM_CC_HANDLE CCHandle
,
130 const Context
&context
,
131 const AccessCredentials
&AccessCred
,
133 const CssmData
*DescriptiveData
,
135 CSSM_PRIVILEGE Privilege
)
137 // @@@ Deal with permanent keys
138 const CssmKey
*keyInContext
=
139 context
.get
<const CssmKey
>(CSSM_ATTRIBUTE_KEY
);
141 KeyHandle contextKeyHandle
= (keyInContext
142 ? lookupKey(*keyInContext
).keyHandle()
144 clientSession().wrapKey(context
, contextKeyHandle
,
145 lookupKey(Key
).keyHandle(), &AccessCred
,
146 DescriptiveData
, WrappedKey
, *this);
150 SSCSPSession::UnwrapKey(CSSM_CC_HANDLE CCHandle
,
151 const Context
&context
,
152 const CssmKey
*PublicKey
,
153 const CssmWrappedKey
&WrappedKey
,
156 const CssmData
*KeyLabel
,
157 const CSSM_RESOURCE_CONTROL_CONTEXT
*CredAndAclEntry
,
158 CssmKey
&UnwrappedKey
,
159 CssmData
&DescriptiveData
,
160 CSSM_PRIVILEGE Privilege
)
162 SSDatabase database
= getDatabase(context
);
163 const AccessCredentials
*cred
= NULL
;
164 const AclEntryInput
*owner
= NULL
;
167 cred
= AccessCredentials::overlay(CredAndAclEntry
->AccessCred
);
168 owner
= &AclEntryInput::overlay(CredAndAclEntry
->InitialAclEntry
);
171 KeyHandle publicKey
= noKey
;
174 if (PublicKey
->blobType() == CSSM_KEYBLOB_RAW
)
176 // @@@ We need to unwrap the publicKey into the SecurityServer
178 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
181 publicKey
= lookupKey(*PublicKey
).keyHandle();
184 // @@@ Deal with permanent keys
185 const CssmKey
*keyInContext
=
186 context
.get
<const CssmKey
>(CSSM_ATTRIBUTE_KEY
);
188 KeyHandle contextKeyHandle
=
189 keyInContext
? lookupKey(*keyInContext
).keyHandle() : noKey
;
191 KeyHandle unwrappedKeyHandle
;
192 clientSession().unwrapKey(database
.dbHandle(), context
, contextKeyHandle
,
193 publicKey
, WrappedKey
, KeyUsage
, KeyAttr
,
194 cred
, owner
, DescriptiveData
, unwrappedKeyHandle
,
195 UnwrappedKey
.header(), *this);
196 makeReferenceKey(unwrappedKeyHandle
, UnwrappedKey
, database
, KeyAttr
,
201 SSCSPSession::DeriveKey(CSSM_CC_HANDLE ccHandle
,
202 const Context
&context
,
206 const CssmData
*keyLabel
,
207 const CSSM_RESOURCE_CONTROL_CONTEXT
*credAndAclEntry
,
214 SSCSPSession::GenerateKey(CSSM_CC_HANDLE ccHandle
,
215 const Context
&context
,
218 const CssmData
*keyLabel
,
219 const CSSM_RESOURCE_CONTROL_CONTEXT
*credAndAclEntry
,
221 CSSM_PRIVILEGE privilege
)
223 SSDatabase database
= getDatabase(context
);
224 const AccessCredentials
*cred
= NULL
;
225 const AclEntryInput
*owner
= NULL
;
228 cred
= AccessCredentials::overlay(credAndAclEntry
->AccessCred
);
229 owner
= &AclEntryInput::overlay(credAndAclEntry
->InitialAclEntry
);
233 clientSession().generateKey(database
.dbHandle(), context
, keyUsage
,
234 keyAttr
, cred
, owner
, keyHandle
, key
.header());
235 makeReferenceKey(keyHandle
, key
, database
, keyAttr
, keyLabel
);
239 SSCSPSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle
,
240 const Context
&context
,
241 uint32 publicKeyUsage
,
242 uint32 publicKeyAttr
,
243 const CssmData
*publicKeyLabel
,
245 uint32 privateKeyUsage
,
246 uint32 privateKeyAttr
,
247 const CssmData
*privateKeyLabel
,
248 const CSSM_RESOURCE_CONTROL_CONTEXT
*credAndAclEntry
,
250 CSSM_PRIVILEGE privilege
)
252 SSDatabase database
= getDatabase(context
);
253 const AccessCredentials
*cred
= NULL
;
254 const AclEntryInput
*owner
= NULL
;
257 cred
= AccessCredentials::overlay(credAndAclEntry
->AccessCred
);
258 owner
= &AclEntryInput::overlay(credAndAclEntry
->InitialAclEntry
);
261 KeyHandle pubKeyHandle
, privKeyHandle
;
262 clientSession().generateKey(database
.dbHandle(), context
,
263 publicKeyUsage
, publicKeyAttr
,
264 privateKeyUsage
, privateKeyAttr
,
266 pubKeyHandle
, publicKey
.header(),
267 privKeyHandle
, privateKey
.header());
268 makeReferenceKey(privKeyHandle
, privateKey
, database
, privateKeyAttr
,
270 // @@@ What if this throws, we need to free privateKey.
271 makeReferenceKey(pubKeyHandle
, publicKey
, database
, publicKeyAttr
,
276 SSCSPSession::ObtainPrivateKeyFromPublicKey(const CssmKey
&PublicKey
,
283 SSCSPSession::QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle
,
284 const Context
&Context
,
286 CSSM_KEY_SIZE
&KeySize
)
292 SSCSPSession::FreeKey(const AccessCredentials
*accessCred
,
293 CssmKey
&ioKey
, CSSM_BOOL deleteKey
)
295 if (ioKey
.blobType() == CSSM_KEYBLOB_REFERENCE
)
297 // @@@ Note that this means that detaching a session should free
298 // all keys ascociated with it or else...
302 // @@@ There are thread safety issues when deleting a key that is
303 // in use by another thread, but the answer to that is: Don't do
306 // Find the key in the map. Tell tell the key to free itself
307 // (when the auto_ptr deletes the key it removes itself from the map).
308 auto_ptr
<SSKey
> ssKey(&mSSCSPDLSession
.find
<SSKey
>(ioKey
));
309 ssKey
->free(accessCred
, ioKey
, deleteKey
);
313 CSPFullPluginSession::FreeKey(accessCred
, ioKey
, deleteKey
);
322 SSCSPSession::GenerateRandom(CSSM_CC_HANDLE ccHandle
,
323 const Context
&context
,
324 CssmData
&randomNumber
)
326 checkOperation(context
.type(), CSSM_ALGCLASS_RANDOMGEN
);
327 // if (context.algorithm() != @@@) CssmError::throwMe(ALGORITHM_NOT_SUPPORTED);
328 uint32 needed
= context
.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE
, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE
);
330 // @@@ What about the seed?
331 if (randomNumber
.length())
333 if (randomNumber
.length() < needed
)
334 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
335 randomNumber
.Length
= needed
;
336 clientSession().generateRandom(randomNumber
);
340 randomNumber
.Data
= alloc
<uint8
>(needed
);
343 randomNumber
.Length
= needed
;
344 clientSession().generateRandom(randomNumber
);
348 free(randomNumber
.Data
);
349 randomNumber
.Data
= NULL
;
356 // Login/Logout and token operational maintainance. These mean little
357 // without support by the actual implementation, but we can help...
358 // @@@ Should this be in CSP[non-Full]PluginSession?
361 SSCSPSession::Login(const AccessCredentials
&AccessCred
,
362 const CssmData
*LoginName
,
363 const void *Reserved
)
365 // @@@ Do a login to the securityServer making keys persistant until it
371 SSCSPSession::Logout()
377 SSCSPSession::VerifyDevice(const CssmData
&DeviceCert
)
379 CssmError::throwMe(CSSMERR_CSP_DEVICE_VERIFY_FAILED
);
383 SSCSPSession::GetOperationalStatistics(CSPOperationalStatistics
&statistics
)
390 // Utterly miscellaneous, rarely used, strange functions
393 SSCSPSession::RetrieveCounter(CssmData
&Counter
)
399 SSCSPSession::RetrieveUniqueId(CssmData
&UniqueID
)
405 SSCSPSession::GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm
, CssmData
&TimeData
)
412 // ACL retrieval and change operations
415 SSCSPSession::GetKeyOwner(const CssmKey
&Key
,
416 CSSM_ACL_OWNER_PROTOTYPE
&Owner
)
418 lookupKey(Key
).getOwner(Owner
, *this);
422 SSCSPSession::ChangeKeyOwner(const AccessCredentials
&AccessCred
,
424 const CSSM_ACL_OWNER_PROTOTYPE
&NewOwner
)
426 lookupKey(Key
).changeOwner(AccessCred
,
427 AclOwnerPrototype::overlay(NewOwner
));
431 SSCSPSession::GetKeyAcl(const CssmKey
&Key
,
432 const CSSM_STRING
*SelectionTag
,
433 uint32
&NumberOfAclInfos
,
434 CSSM_ACL_ENTRY_INFO_PTR
&AclInfos
)
436 lookupKey(Key
).getAcl(reinterpret_cast<const char *>(SelectionTag
),
438 reinterpret_cast<AclEntryInfo
*&>(AclInfos
), *this);
442 SSCSPSession::ChangeKeyAcl(const AccessCredentials
&AccessCred
,
443 const CSSM_ACL_EDIT
&AclEdit
,
446 lookupKey(Key
).changeAcl(AccessCred
, AclEdit::overlay(AclEdit
));
450 SSCSPSession::GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE
&Owner
)
456 SSCSPSession::ChangeLoginOwner(const AccessCredentials
&AccessCred
,
457 const CSSM_ACL_OWNER_PROTOTYPE
&NewOwner
)
463 SSCSPSession::GetLoginAcl(const CSSM_STRING
*SelectionTag
,
464 uint32
&NumberOfAclInfos
,
465 CSSM_ACL_ENTRY_INFO_PTR
&AclInfos
)
471 SSCSPSession::ChangeLoginAcl(const AccessCredentials
&AccessCred
,
472 const CSSM_ACL_EDIT
&AclEdit
)
480 // Passthroughs (by default, unimplemented)
483 SSCSPSession::PassThrough(CSSM_CC_HANDLE CCHandle
,
484 const Context
&Context
,
485 uint32 PassThroughId
,