]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_cspdl/lib/SSCSPDLSession.cpp
Security-59306.80.4.tar.gz
[apple/security.git] / OSX / libsecurity_apple_cspdl / lib / SSCSPDLSession.cpp
1 /*
2 * Copyright (c) 2000-2001,2008,2011-2012 Apple 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_cdsa_client/aclclient.h>
31 #include <security_keychain/Access.h>
32 #include <security_keychain/TrustedApplication.h>
33 #include <security_utilities/seccfobject.h>
34
35 //
36 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
37 //
38 class ClientSessionKey: public CssmClient::AclBearer
39 {
40 public:
41 ClientSessionKey(SecurityServer::ClientSession &clientSession, SecurityServer::KeyHandle keyHandle);
42 ~ClientSessionKey();
43
44 // Acl manipulation
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);
49
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);
54
55
56 private:
57 SecurityServer::ClientSession &mClientSession;
58 SecurityServer::KeyHandle mKeyHandle;
59 };
60
61 #endif //!SECURITYSERVER_ACL_EDITS
62
63
64 using namespace SecurityServer;
65
66 //
67 // SSCSPDLSession -- Security Server CSP session
68 //
69 SSCSPDLSession::SSCSPDLSession()
70 {
71 }
72
73
74 //
75 // Reference Key management
76 //
77 void
78 SSCSPDLSession::makeReferenceKey(SSCSPSession &session, KeyHandle inKeyHandle,
79 CssmKey &outKey, SSDatabase &inSSDatabase,
80 uint32 inKeyAttr, const CssmData *inKeyLabel)
81 {
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,
85 inKeyLabel);
86 (void) sskey; // Compiler thinks this variable isn't used, but we want the side effects of creation. Tell the compiler it's okay.
87
88 secinfo("SecAccessReference", "made a new reference sskey with handle %d [%ld]", sskey->keyHandle(), sskey->keyReference());
89 #endif
90 }
91
92 SSKey &
93 SSCSPDLSession::lookupKey(const CssmKey &inKey)
94 {
95 /* for now we only allow ref keys */
96 if(inKey.blobType() != CSSM_KEYBLOB_REFERENCE) {
97 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
98 }
99
100 /* fetch key (this is just mapping the value in inKey.KeyData to an SSKey) */
101 SSKey &theKey = find<SSKey>(inKey);
102
103 secinfo("SecAccessReference", "looked up a sskey with handle %d [%ld]", theKey.keyHandle(), theKey.keyReference());
104
105 #ifdef someday
106 /*
107 * Make sure caller hasn't changed any crucial header fields.
108 * Some fields were changed by makeReferenceKey, so make a local copy....
109 */
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....;
113
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);
118 }
119 #endif
120 return theKey;
121 }
122
123 // Notification we receive when the acl on a key has changed. We should write it back to disk if it's persistent.
124 void
125 SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession &clientSession,
126 KeyHandle keyHandle, CSSM_ACL_AUTHORIZATION_TAG tag)
127 {
128 StLock<Mutex> __(mKeyDeletionMutex); // The key can't be deleted while we're poking at it, on pain of crashing
129
130 SSKey *theKey = NULL;
131
132 {
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)
138 {
139 SSKey *aKey = dynamic_cast<SSKey *>(it->second);
140 if (aKey->optionalKeyHandle() == keyHandle)
141 {
142 // Write the key to disk if it's persistent.
143 theKey = aKey;
144 break;
145 }
146 }
147 }
148
149 if (theKey)
150 {
151 theKey->didChangeAcl();
152 }
153 else
154 {
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);
158 }
159 }
160
161 void
162 SSCSPDLSession::didChangeKeyAclCallback(void *context, SecurityServer::ClientSession &clientSession,
163 SecurityServer::KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag)
164 {
165 reinterpret_cast<SSCSPDLSession *>(context)->didChangeKeyAcl(clientSession, key, tag);
166 }
167
168 #ifndef SECURITYSERVER_ACL_EDITS
169 //
170 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
171 //
172 ClientSessionKey::ClientSessionKey(ClientSession &clientSession, SecurityServer::KeyHandle keyHandle) :
173 mClientSession(clientSession),
174 mKeyHandle(keyHandle)
175 {
176 }
177
178 ClientSessionKey::~ClientSessionKey()
179 {
180 }
181
182 void
183 ClientSessionKey::getAcl(AutoAclEntryInfoList &aclInfos,
184 const char *selectionTag) const
185 {
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)));
191 }
192
193 void
194 ClientSessionKey::changeAcl(const CSSM_ACL_EDIT &aclEdit,
195 const CSSM_ACCESS_CREDENTIALS *cred)
196 {
197 secinfo("keyacl", "ClientSessionKey::changeAcl() keyHandle: %u", mKeyHandle);
198 mClientSession.changeKeyAcl(mKeyHandle, AccessCredentials::overlay(*cred), AclEdit::overlay(aclEdit));
199 }
200
201 void
202 ClientSessionKey::getOwner(AutoAclOwnerPrototype &owner) const
203 {
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)));
208 }
209
210 void
211 ClientSessionKey::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
212 const CSSM_ACCESS_CREDENTIALS *cred)
213 {
214 secinfo("keyacl", "ClientSessionKey::changeOwner() keyHandle: %u", mKeyHandle);
215 mClientSession.changeKeyOwner(mKeyHandle, AccessCredentials::overlay(*cred), AclOwnerPrototype::overlay(newOwner));
216 }
217
218 #endif // !SECURITYSERVER_ACL_EDITS