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         SSKey
* sskey 
= new SSKey(session
, inKeyHandle
, outKey
, inSSDatabase
, inKeyAttr
, 
  84     (void) sskey
; // Compiler thinks this variable isn't used, but we want the side effects of creation. Tell the compiler it's okay. 
  86     secinfo("SecAccessReference", "made a new reference sskey with handle %d [%ld]", sskey
->keyHandle(), sskey
->keyReference()); 
  90 SSCSPDLSession::lookupKey(const CssmKey 
&inKey
) 
  92         /* for now we only allow ref keys */ 
  93         if(inKey
.blobType() != CSSM_KEYBLOB_REFERENCE
) { 
  94                 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
); 
  97         /* fetch key (this is just mapping the value in inKey.KeyData to an SSKey) */ 
  98         SSKey 
&theKey 
= find
<SSKey
>(inKey
); 
 100     secinfo("SecAccessReference", "looked up a sskey with handle %d [%ld]", theKey
.keyHandle(), theKey
.keyReference()); 
 104          * Make sure caller hasn't changed any crucial header fields. 
 105          * Some fields were changed by makeReferenceKey, so make a local copy.... 
 107         CSSM_KEYHEADER localHdr 
= cssmKey
.KeyHeader
; 
 108         get binKey
-like thing from SSKey
, maybe SSKey should keep a copy of 
 
 109         hdr
...but that
's' not supersecure
....; 
 111         localHdr
.BlobType 
= binKey
->mKeyHeader
.BlobType
; 
 112         localHdr
.Format 
= binKey
->mKeyHeader
.Format
; 
 113         if(memcmp(&localHdr
, &binKey
->mKeyHeader
, sizeof(CSSM_KEYHEADER
))) { 
 114                 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
); 
 120 // Notification we receive when the acl on a key has changed.  We should write it back to disk if it's persistent. 
 122 SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession 
&clientSession
, 
 123         KeyHandle keyHandle
, CSSM_ACL_AUTHORIZATION_TAG tag
) 
 125         SSKey 
*theKey 
= NULL
; 
 128                 // Lookup the SSKey for the KeyHandle 
 129                 StLock
<Mutex
> _(mKeyMapLock
); 
 130                 KeyMap::const_iterator it
; 
 131                 KeyMap::const_iterator end 
= mKeyMap
.end(); 
 132                 for (it 
= mKeyMap
.begin(); it 
!= end
; ++it
) 
 134                         SSKey 
*aKey 
= dynamic_cast<SSKey 
*>(it
->second
); 
 135                         if (aKey
->optionalKeyHandle() == keyHandle
) 
 137                                 // Write the key to disk if it's persistent. 
 146                 theKey
->didChangeAcl(); 
 150                 // @@@ 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. 
 151                 secinfo("keyacl", "SSCSPDLSession::didChangeKeyAcl() keyHandle: %lu not found in map", (unsigned long)keyHandle
); 
 152                 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE
); 
 157 SSCSPDLSession::didChangeKeyAclCallback(void *context
, SecurityServer::ClientSession 
&clientSession
, 
 158         SecurityServer::KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
) 
 160         reinterpret_cast<SSCSPDLSession 
*>(context
)->didChangeKeyAcl(clientSession
, key
, tag
); 
 163 #ifndef SECURITYSERVER_ACL_EDITS 
 165 // ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer 
 167 ClientSessionKey::ClientSessionKey(ClientSession 
&clientSession
, SecurityServer::KeyHandle keyHandle
) : 
 168         mClientSession(clientSession
), 
 169         mKeyHandle(keyHandle
) 
 173 ClientSessionKey::~ClientSessionKey() 
 178 ClientSessionKey::getAcl(AutoAclEntryInfoList 
&aclInfos
, 
 179         const char *selectionTag
) const 
 181         secinfo("keyacl", "ClientSessionKey::getAcl() keyHandle: %u", mKeyHandle
); 
 182         aclInfos
.allocator(mClientSession
.returnAllocator
); 
 183         mClientSession
.getKeyAcl(mKeyHandle
, selectionTag
, 
 184                 *static_cast<uint32 
*>(aclInfos
), 
 185                 *reinterpret_cast<AclEntryInfo 
**>(static_cast<CSSM_ACL_ENTRY_INFO_PTR 
*>(aclInfos
))); 
 189 ClientSessionKey::changeAcl(const CSSM_ACL_EDIT 
&aclEdit
, 
 190         const CSSM_ACCESS_CREDENTIALS 
*cred
) 
 192         secinfo("keyacl", "ClientSessionKey::changeAcl() keyHandle: %u", mKeyHandle
); 
 193         mClientSession
.changeKeyAcl(mKeyHandle
, AccessCredentials::overlay(*cred
), AclEdit::overlay(aclEdit
)); 
 197 ClientSessionKey::getOwner(AutoAclOwnerPrototype 
&owner
) const 
 199         secinfo("keyacl", "ClientSessionKey::getOwner() keyHandle: %u", mKeyHandle
); 
 200         owner
.allocator(mClientSession
.returnAllocator
); 
 201         mClientSession
.getKeyOwner(mKeyHandle
, 
 202                 *reinterpret_cast<AclOwnerPrototype 
*>(static_cast<CSSM_ACL_OWNER_PROTOTYPE 
*>(owner
))); 
 206 ClientSessionKey::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE 
&newOwner
, 
 207         const CSSM_ACCESS_CREDENTIALS 
*cred
) 
 209         secinfo("keyacl", "ClientSessionKey::changeOwner() keyHandle: %u", mKeyHandle
); 
 210         mClientSession
.changeKeyOwner(mKeyHandle
, AccessCredentials::overlay(*cred
), AclOwnerPrototype::overlay(newOwner
)); 
 213 #endif // !SECURITYSERVER_ACL_EDITS