2 * Copyright (c) 2000-2001,2008,2011-2012 Apple 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 // SSCSPDLSession.cpp - Security Server CSP/DL session.
22 #include "SSCSPDLSession.h"
24 #include "CSPDLPlugin.h"
28 #ifndef SECURITYSERVER_ACL_EDITS
30 #include <security_cdsa_client/aclclient.h>
31 #include <security_keychain/Access.h>
32 #include <security_keychain/TrustedApplication.h>
33 #include <security_utilities/seccfobject.h>
36 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
38 class ClientSessionKey
: public CssmClient::AclBearer
41 ClientSessionKey(SecurityServer::ClientSession
&clientSession
, SecurityServer::KeyHandle keyHandle
);
45 virtual void getAcl(AutoAclEntryInfoList
&aclInfos
,
46 const char *selectionTag
= NULL
) const;
47 virtual void changeAcl(const CSSM_ACL_EDIT
&aclEdit
,
48 const CSSM_ACCESS_CREDENTIALS
*cred
= NULL
);
50 // Acl owner manipulation
51 virtual void getOwner(AutoAclOwnerPrototype
&owner
) const;
52 virtual void changeOwner(const CSSM_ACL_OWNER_PROTOTYPE
&newOwner
,
53 const CSSM_ACCESS_CREDENTIALS
*cred
= NULL
);
57 SecurityServer::ClientSession
&mClientSession
;
58 SecurityServer::KeyHandle mKeyHandle
;
61 #endif //!SECURITYSERVER_ACL_EDITS
64 using namespace SecurityServer
;
67 // SSCSPDLSession -- Security Server CSP session
69 SSCSPDLSession::SSCSPDLSession()
75 // Reference Key management
78 SSCSPDLSession::makeReferenceKey(SSCSPSession
&session
, KeyHandle inKeyHandle
,
79 CssmKey
&outKey
, SSDatabase
&inSSDatabase
,
80 uint32 inKeyAttr
, const CssmData
*inKeyLabel
)
82 // The analyzer doesn't know what to do with the naked creation of an item
83 #ifndef __clang_analyzer__
84 SSKey
* sskey
= new SSKey(session
, inKeyHandle
, outKey
, inSSDatabase
, inKeyAttr
,
86 (void) sskey
; // Compiler thinks this variable isn't used, but we want the side effects of creation. Tell the compiler it's okay.
88 secinfo("SecAccessReference", "made a new reference sskey with handle %d [%ld]", sskey
->keyHandle(), sskey
->keyReference());
93 SSCSPDLSession::lookupKey(const CssmKey
&inKey
)
95 /* for now we only allow ref keys */
96 if(inKey
.blobType() != CSSM_KEYBLOB_REFERENCE
) {
97 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
100 /* fetch key (this is just mapping the value in inKey.KeyData to an SSKey) */
101 SSKey
&theKey
= find
<SSKey
>(inKey
);
103 secinfo("SecAccessReference", "looked up a sskey with handle %d [%ld]", theKey
.keyHandle(), theKey
.keyReference());
107 * Make sure caller hasn't changed any crucial header fields.
108 * Some fields were changed by makeReferenceKey, so make a local copy....
110 CSSM_KEYHEADER localHdr
= cssmKey
.KeyHeader
;
111 get binKey
-like thing from SSKey
, maybe SSKey should keep a copy of
112 hdr
...but that
's' not supersecure
....;
114 localHdr
.BlobType
= binKey
->mKeyHeader
.BlobType
;
115 localHdr
.Format
= binKey
->mKeyHeader
.Format
;
116 if(memcmp(&localHdr
, &binKey
->mKeyHeader
, sizeof(CSSM_KEYHEADER
))) {
117 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
);
123 // Notification we receive when the acl on a key has changed. We should write it back to disk if it's persistent.
125 SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession
&clientSession
,
126 KeyHandle keyHandle
, CSSM_ACL_AUTHORIZATION_TAG tag
)
128 StLock
<Mutex
> __(mKeyDeletionMutex
); // The key can't be deleted while we're poking at it, on pain of crashing
130 SSKey
*theKey
= NULL
;
133 // Lookup the SSKey for the KeyHandle
134 StLock
<Mutex
> _(mKeyMapLock
);
135 KeyMap::const_iterator it
;
136 KeyMap::const_iterator end
= mKeyMap
.end();
137 for (it
= mKeyMap
.begin(); it
!= end
; ++it
)
139 SSKey
*aKey
= dynamic_cast<SSKey
*>(it
->second
);
140 if (aKey
->optionalKeyHandle() == keyHandle
)
142 // Write the key to disk if it's persistent.
151 theKey
->didChangeAcl();
155 // @@@ Should we really throw here or just continue without updating the ACL? In reality this should never happen, so let's at least log it and throw.
156 secinfo("keyacl", "SSCSPDLSession::didChangeKeyAcl() keyHandle: %lu not found in map", (unsigned long)keyHandle
);
157 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
);
162 SSCSPDLSession::didChangeKeyAclCallback(void *context
, SecurityServer::ClientSession
&clientSession
,
163 SecurityServer::KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
)
165 reinterpret_cast<SSCSPDLSession
*>(context
)->didChangeKeyAcl(clientSession
, key
, tag
);
168 #ifndef SECURITYSERVER_ACL_EDITS
170 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
172 ClientSessionKey::ClientSessionKey(ClientSession
&clientSession
, SecurityServer::KeyHandle keyHandle
) :
173 mClientSession(clientSession
),
174 mKeyHandle(keyHandle
)
178 ClientSessionKey::~ClientSessionKey()
183 ClientSessionKey::getAcl(AutoAclEntryInfoList
&aclInfos
,
184 const char *selectionTag
) const
186 secinfo("keyacl", "ClientSessionKey::getAcl() keyHandle: %u", mKeyHandle
);
187 aclInfos
.allocator(mClientSession
.returnAllocator
);
188 mClientSession
.getKeyAcl(mKeyHandle
, selectionTag
,
189 *static_cast<uint32
*>(aclInfos
),
190 *reinterpret_cast<AclEntryInfo
**>(static_cast<CSSM_ACL_ENTRY_INFO_PTR
*>(aclInfos
)));
194 ClientSessionKey::changeAcl(const CSSM_ACL_EDIT
&aclEdit
,
195 const CSSM_ACCESS_CREDENTIALS
*cred
)
197 secinfo("keyacl", "ClientSessionKey::changeAcl() keyHandle: %u", mKeyHandle
);
198 mClientSession
.changeKeyAcl(mKeyHandle
, AccessCredentials::overlay(*cred
), AclEdit::overlay(aclEdit
));
202 ClientSessionKey::getOwner(AutoAclOwnerPrototype
&owner
) const
204 secinfo("keyacl", "ClientSessionKey::getOwner() keyHandle: %u", mKeyHandle
);
205 owner
.allocator(mClientSession
.returnAllocator
);
206 mClientSession
.getKeyOwner(mKeyHandle
,
207 *reinterpret_cast<AclOwnerPrototype
*>(static_cast<CSSM_ACL_OWNER_PROTOTYPE
*>(owner
)));
211 ClientSessionKey::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE
&newOwner
,
212 const CSSM_ACCESS_CREDENTIALS
*cred
)
214 secinfo("keyacl", "ClientSessionKey::changeOwner() keyHandle: %u", mKeyHandle
);
215 mClientSession
.changeKeyOwner(mKeyHandle
, AccessCredentials::overlay(*cred
), AclOwnerPrototype::overlay(newOwner
));
218 #endif // !SECURITYSERVER_ACL_EDITS