]> git.saurik.com Git - apple/security.git/blob - AppleCSPDL/SSCSPDLSession.cpp
Security-164.1.tar.gz
[apple/security.git] / AppleCSPDL / SSCSPDLSession.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // SSCSPDLSession.cpp - Security Server CSP/DL session.
21 //
22 #include "SSCSPDLSession.h"
23
24 #include "CSPDLPlugin.h"
25 #include "SSKey.h"
26
27
28 #ifndef SECURITYSERVER_ACL_EDITS
29
30 #include <Security/aclclient.h>
31 #include <Security/Access.h>
32 #include <Security/TrustedApplication.h>
33
34 //
35 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
36 //
37 class ClientSessionKey: public CssmClient::AclBearer
38 {
39 public:
40 ClientSessionKey(SecurityServer::ClientSession &clientSession, SecurityServer::KeyHandle keyHandle);
41 ~ClientSessionKey();
42
43 // Acl manipulation
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);
48
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);
53
54
55 private:
56 SecurityServer::ClientSession &mClientSession;
57 SecurityServer::KeyHandle mKeyHandle;
58 };
59
60 #endif //!SECURITYSERVER_ACL_EDITS
61
62
63 using namespace SecurityServer;
64
65 //
66 // SSCSPDLSession -- Security Server CSP session
67 //
68 SSCSPDLSession::SSCSPDLSession()
69 {
70 }
71
72
73 //
74 // Reference Key management
75 //
76 void
77 SSCSPDLSession::makeReferenceKey(SSCSPSession &session, KeyHandle inKeyHandle,
78 CssmKey &outKey, SSDatabase &inSSDatabase,
79 uint32 inKeyAttr, const CssmData *inKeyLabel)
80 {
81 new SSKey(session, inKeyHandle, outKey, inSSDatabase, inKeyAttr,
82 inKeyLabel);
83 }
84
85 SSKey &
86 SSCSPDLSession::lookupKey(const CssmKey &inKey)
87 {
88 /* for now we only allow ref keys */
89 if(inKey.blobType() != CSSM_KEYBLOB_REFERENCE) {
90 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
91 }
92
93 /* fetch key (this is just mapping the value in inKey.KeyData to an SSKey) */
94 SSKey &theKey = find<SSKey>(inKey);
95
96 #ifdef someday
97 /*
98 * Make sure caller hasn't changed any crucial header fields.
99 * Some fields were changed by makeReferenceKey, so make a local copy....
100 */
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....;
104
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);
109 }
110 #endif
111 return theKey;
112 }
113
114 // Notification we receive when the acl on a key has changed. We should write it back to disk if it's persistant.
115 void
116 SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession &clientSession,
117 KeyHandle keyHandle, CSSM_ACL_AUTHORIZATION_TAG tag)
118 {
119 #ifndef SECURITYSERVER_ACL_EDITS
120 {
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
128 }
129 #endif // !SECURITYSERVER_ACL_EDITS
130
131 SSKey *theKey = NULL;
132
133 {
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)
139 {
140 SSKey *aKey = dynamic_cast<SSKey *>(it->second);
141 if (aKey->optionalKeyHandle() == keyHandle)
142 {
143 // Write the key to disk if it's persistant.
144 theKey = aKey;
145 break;
146 }
147 }
148 }
149
150 if (theKey)
151 {
152 theKey->didChangeAcl();
153 }
154 else
155 {
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);
159 }
160 }
161
162 void
163 SSCSPDLSession::didChangeKeyAclCallback(void *context, SecurityServer::ClientSession &clientSession,
164 SecurityServer::KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag)
165 {
166 reinterpret_cast<SSCSPDLSession *>(context)->didChangeKeyAcl(clientSession, key, tag);
167 }
168
169 #ifndef SECURITYSERVER_ACL_EDITS
170 //
171 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
172 //
173 ClientSessionKey::ClientSessionKey(ClientSession &clientSession, SecurityServer::KeyHandle keyHandle) :
174 mClientSession(clientSession),
175 mKeyHandle(keyHandle)
176 {
177 }
178
179 ClientSessionKey::~ClientSessionKey()
180 {
181 }
182
183 void
184 ClientSessionKey::getAcl(AutoAclEntryInfoList &aclInfos,
185 const char *selectionTag) const
186 {
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)));
192 }
193
194 void
195 ClientSessionKey::changeAcl(const CSSM_ACL_EDIT &aclEdit,
196 const CSSM_ACCESS_CREDENTIALS *cred)
197 {
198 secdebug("keyacl", "ClientSessionKey::changeAcl() keyHandle: %lu", mKeyHandle);
199 mClientSession.changeKeyAcl(mKeyHandle, AccessCredentials::overlay(*cred), AclEdit::overlay(aclEdit));
200 }
201
202 void
203 ClientSessionKey::getOwner(AutoAclOwnerPrototype &owner) const
204 {
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)));
209 }
210
211 void
212 ClientSessionKey::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
213 const CSSM_ACCESS_CREDENTIALS *cred)
214 {
215 secdebug("keyacl", "ClientSessionKey::changeOwner() keyHandle: %lu", mKeyHandle);
216 mClientSession.changeKeyOwner(mKeyHandle, AccessCredentials::overlay(*cred), AclOwnerPrototype::overlay(newOwner));
217 }
218
219 #endif // !SECURITYSERVER_ACL_EDITS