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 // SSCSPDLSession.cpp - Security Server CSP/DL session.
22 #include "SSCSPDLSession.h"
24 #include "CSPDLPlugin.h"
28 #ifndef SECURITYSERVER_ACL_EDITS
30 #include <Security/aclclient.h>
31 #include <Security/Access.h>
32 #include <Security/TrustedApplication.h>
35 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
37 class ClientSessionKey
: public CssmClient::AclBearer
40 ClientSessionKey(SecurityServer::ClientSession
&clientSession
, SecurityServer::KeyHandle keyHandle
);
44 virtual void getAcl(AutoAclEntryInfoList
&aclInfos
,
45 const char *selectionTag
= NULL
) const;
46 virtual void changeAcl(const CSSM_ACL_EDIT
&aclEdit
,
47 const CSSM_ACCESS_CREDENTIALS
*cred
= NULL
);
49 // Acl owner manipulation
50 virtual void getOwner(AutoAclOwnerPrototype
&owner
) const;
51 virtual void changeOwner(const CSSM_ACL_OWNER_PROTOTYPE
&newOwner
,
52 const CSSM_ACCESS_CREDENTIALS
*cred
= NULL
);
56 SecurityServer::ClientSession
&mClientSession
;
57 SecurityServer::KeyHandle mKeyHandle
;
60 #endif //!SECURITYSERVER_ACL_EDITS
63 using namespace SecurityServer
;
66 // SSCSPDLSession -- Security Server CSP session
68 SSCSPDLSession::SSCSPDLSession()
74 // Reference Key management
77 SSCSPDLSession::makeReferenceKey(SSCSPSession
&session
, KeyHandle inKeyHandle
,
78 CssmKey
&outKey
, SSDatabase
&inSSDatabase
,
79 uint32 inKeyAttr
, const CssmData
*inKeyLabel
)
81 new SSKey(session
, inKeyHandle
, outKey
, inSSDatabase
, inKeyAttr
,
86 SSCSPDLSession::lookupKey(const CssmKey
&inKey
)
88 /* for now we only allow ref keys */
89 if(inKey
.blobType() != CSSM_KEYBLOB_REFERENCE
) {
90 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
93 /* fetch key (this is just mapping the value in inKey.KeyData to an SSKey) */
94 SSKey
&theKey
= find
<SSKey
>(inKey
);
98 * Make sure caller hasn't changed any crucial header fields.
99 * Some fields were changed by makeReferenceKey, so make a local copy....
101 CSSM_KEYHEADER localHdr
= cssmKey
.KeyHeader
;
102 get binKey
-like thing from SSKey
, maybe SSKey should keep a copy of
103 hdr
...but that
's' not supersecure
....;
105 localHdr
.BlobType
= binKey
->mKeyHeader
.BlobType
;
106 localHdr
.Format
= binKey
->mKeyHeader
.Format
;
107 if(memcmp(&localHdr
, &binKey
->mKeyHeader
, sizeof(CSSM_KEYHEADER
))) {
108 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
);
114 // Notification we receive when the acl on a key has changed. We should write it back to disk if it's persistant.
116 SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession
&clientSession
,
117 KeyHandle keyHandle
, CSSM_ACL_AUTHORIZATION_TAG tag
)
119 #ifndef SECURITYSERVER_ACL_EDITS
121 // The user checked to don't ask again checkbox in the rogue app alert. Let's edit the ACL for this key and add the calling application (ourself) to it.
122 secdebug("keyacl", "SSCSPDLSession::didChangeKeyAcl(keyHandle: %lu tag: %lu)", keyHandle
, tag
);
123 ClientSessionKey
csKey(clientSession
, keyHandle
); // the underlying key
124 KeychainCore::SecPointer
<KeychainCore::Access
> access
= new KeychainCore::Access(csKey
); // extract access rights
125 KeychainCore::SecPointer
<KeychainCore::TrustedApplication
> thisApp
= new KeychainCore::TrustedApplication
;
126 access
->addApplicationToRight(tag
, thisApp
.get()); // add this app
127 access
->setAccess(csKey
, true); // commit
129 #endif // !SECURITYSERVER_ACL_EDITS
131 SSKey
*theKey
= NULL
;
134 // Lookup the SSKey for the KeyHandle
135 StLock
<Mutex
> _(mKeyMapLock
);
136 KeyMap::const_iterator it
;
137 KeyMap::const_iterator end
= mKeyMap
.end();
138 for (it
= mKeyMap
.begin(); it
!= end
; ++it
)
140 SSKey
*aKey
= dynamic_cast<SSKey
*>(it
->second
);
141 if (aKey
->optionalKeyHandle() == keyHandle
)
143 // Write the key to disk if it's persistant.
152 theKey
->didChangeAcl();
156 // @@@ 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.
157 secdebug("keyacl", "SSCSPDLSession::didChangeKeyAcl() keyHandle: %lu not found in map", keyHandle
);
158 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
);
163 SSCSPDLSession::didChangeKeyAclCallback(void *context
, SecurityServer::ClientSession
&clientSession
,
164 SecurityServer::KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
)
166 reinterpret_cast<SSCSPDLSession
*>(context
)->didChangeKeyAcl(clientSession
, key
, tag
);
169 #ifndef SECURITYSERVER_ACL_EDITS
171 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
173 ClientSessionKey::ClientSessionKey(ClientSession
&clientSession
, SecurityServer::KeyHandle keyHandle
) :
174 mClientSession(clientSession
),
175 mKeyHandle(keyHandle
)
179 ClientSessionKey::~ClientSessionKey()
184 ClientSessionKey::getAcl(AutoAclEntryInfoList
&aclInfos
,
185 const char *selectionTag
) const
187 secdebug("keyacl", "ClientSessionKey::getAcl() keyHandle: %lu", mKeyHandle
);
188 aclInfos
.allocator(mClientSession
.returnAllocator
);
189 mClientSession
.getKeyAcl(mKeyHandle
, selectionTag
,
190 *static_cast<uint32
*>(aclInfos
),
191 *reinterpret_cast<AclEntryInfo
**>(static_cast<CSSM_ACL_ENTRY_INFO_PTR
*>(aclInfos
)));
195 ClientSessionKey::changeAcl(const CSSM_ACL_EDIT
&aclEdit
,
196 const CSSM_ACCESS_CREDENTIALS
*cred
)
198 secdebug("keyacl", "ClientSessionKey::changeAcl() keyHandle: %lu", mKeyHandle
);
199 mClientSession
.changeKeyAcl(mKeyHandle
, AccessCredentials::overlay(*cred
), AclEdit::overlay(aclEdit
));
203 ClientSessionKey::getOwner(AutoAclOwnerPrototype
&owner
) const
205 secdebug("keyacl", "ClientSessionKey::getOwner() keyHandle: %lu", mKeyHandle
);
206 owner
.allocator(mClientSession
.returnAllocator
);
207 mClientSession
.getKeyOwner(mKeyHandle
,
208 *reinterpret_cast<AclOwnerPrototype
*>(static_cast<CSSM_ACL_OWNER_PROTOTYPE
*>(owner
)));
212 ClientSessionKey::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE
&newOwner
,
213 const CSSM_ACCESS_CREDENTIALS
*cred
)
215 secdebug("keyacl", "ClientSessionKey::changeOwner() keyHandle: %lu", mKeyHandle
);
216 mClientSession
.changeKeyOwner(mKeyHandle
, AccessCredentials::overlay(*cred
), AclOwnerPrototype::overlay(newOwner
));
219 #endif // !SECURITYSERVER_ACL_EDITS