X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/OSX/libsecurity_apple_cspdl/lib/SSCSPDLSession.cpp diff --git a/OSX/libsecurity_apple_cspdl/lib/SSCSPDLSession.cpp b/OSX/libsecurity_apple_cspdl/lib/SSCSPDLSession.cpp new file mode 100644 index 00000000..3c6b24e4 --- /dev/null +++ b/OSX/libsecurity_apple_cspdl/lib/SSCSPDLSession.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2000-2001,2008,2011-2012 Apple Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + + +// +// SSCSPDLSession.cpp - Security Server CSP/DL session. +// +#include "SSCSPDLSession.h" + +#include "CSPDLPlugin.h" +#include "SSKey.h" + + +#ifndef SECURITYSERVER_ACL_EDITS + +#include +#include +#include +#include + +// +// ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer +// +class ClientSessionKey: public CssmClient::AclBearer +{ +public: + ClientSessionKey(SecurityServer::ClientSession &clientSession, SecurityServer::KeyHandle keyHandle); + ~ClientSessionKey(); + + // Acl manipulation + virtual void getAcl(AutoAclEntryInfoList &aclInfos, + const char *selectionTag = NULL) const; + virtual void changeAcl(const CSSM_ACL_EDIT &aclEdit, + const CSSM_ACCESS_CREDENTIALS *cred = NULL); + + // Acl owner manipulation + virtual void getOwner(AutoAclOwnerPrototype &owner) const; + virtual void changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner, + const CSSM_ACCESS_CREDENTIALS *cred = NULL); + + +private: + SecurityServer::ClientSession &mClientSession; + SecurityServer::KeyHandle mKeyHandle; +}; + +#endif //!SECURITYSERVER_ACL_EDITS + + +using namespace SecurityServer; + +// +// SSCSPDLSession -- Security Server CSP session +// +SSCSPDLSession::SSCSPDLSession() +{ +} + + +// +// Reference Key management +// +void +SSCSPDLSession::makeReferenceKey(SSCSPSession &session, KeyHandle inKeyHandle, + CssmKey &outKey, SSDatabase &inSSDatabase, + uint32 inKeyAttr, const CssmData *inKeyLabel) +{ + new SSKey(session, inKeyHandle, outKey, inSSDatabase, inKeyAttr, + inKeyLabel); +} + +SSKey & +SSCSPDLSession::lookupKey(const CssmKey &inKey) +{ + /* for now we only allow ref keys */ + if(inKey.blobType() != CSSM_KEYBLOB_REFERENCE) { + CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); + } + + /* fetch key (this is just mapping the value in inKey.KeyData to an SSKey) */ + SSKey &theKey = find(inKey); + + #ifdef someday + /* + * Make sure caller hasn't changed any crucial header fields. + * Some fields were changed by makeReferenceKey, so make a local copy.... + */ + CSSM_KEYHEADER localHdr = cssmKey.KeyHeader; + get binKey-like thing from SSKey, maybe SSKey should keep a copy of + hdr...but that's' not supersecure....; + + localHdr.BlobType = binKey->mKeyHeader.BlobType; + localHdr.Format = binKey->mKeyHeader.Format; + if(memcmp(&localHdr, &binKey->mKeyHeader, sizeof(CSSM_KEYHEADER))) { + CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE); + } + #endif + return theKey; +} + +// Notification we receive when the acl on a key has changed. We should write it back to disk if it's persistent. +void +SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession &clientSession, + KeyHandle keyHandle, CSSM_ACL_AUTHORIZATION_TAG tag) +{ + SSKey *theKey = NULL; + + { + // Lookup the SSKey for the KeyHandle + StLock _(mKeyMapLock); + KeyMap::const_iterator it; + KeyMap::const_iterator end = mKeyMap.end(); + for (it = mKeyMap.begin(); it != end; ++it) + { + SSKey *aKey = dynamic_cast(it->second); + if (aKey->optionalKeyHandle() == keyHandle) + { + // Write the key to disk if it's persistent. + theKey = aKey; + break; + } + } + } + + if (theKey) + { + theKey->didChangeAcl(); + } + else + { + // @@@ 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. + secdebug("keyacl", "SSCSPDLSession::didChangeKeyAcl() keyHandle: %lu not found in map", (unsigned long)keyHandle); + CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE); + } +} + +void +SSCSPDLSession::didChangeKeyAclCallback(void *context, SecurityServer::ClientSession &clientSession, + SecurityServer::KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag) +{ + reinterpret_cast(context)->didChangeKeyAcl(clientSession, key, tag); +} + +#ifndef SECURITYSERVER_ACL_EDITS +// +// ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer +// +ClientSessionKey::ClientSessionKey(ClientSession &clientSession, SecurityServer::KeyHandle keyHandle) : + mClientSession(clientSession), + mKeyHandle(keyHandle) +{ +} + +ClientSessionKey::~ClientSessionKey() +{ +} + +void +ClientSessionKey::getAcl(AutoAclEntryInfoList &aclInfos, + const char *selectionTag) const +{ + secdebug("keyacl", "ClientSessionKey::getAcl() keyHandle: %u", mKeyHandle); + aclInfos.allocator(mClientSession.returnAllocator); + mClientSession.getKeyAcl(mKeyHandle, selectionTag, + *static_cast(aclInfos), + *reinterpret_cast(static_cast(aclInfos))); +} + +void +ClientSessionKey::changeAcl(const CSSM_ACL_EDIT &aclEdit, + const CSSM_ACCESS_CREDENTIALS *cred) +{ + secdebug("keyacl", "ClientSessionKey::changeAcl() keyHandle: %u", mKeyHandle); + mClientSession.changeKeyAcl(mKeyHandle, AccessCredentials::overlay(*cred), AclEdit::overlay(aclEdit)); +} + +void +ClientSessionKey::getOwner(AutoAclOwnerPrototype &owner) const +{ + secdebug("keyacl", "ClientSessionKey::getOwner() keyHandle: %u", mKeyHandle); + owner.allocator(mClientSession.returnAllocator); + mClientSession.getKeyOwner(mKeyHandle, + *reinterpret_cast(static_cast(owner))); +} + +void +ClientSessionKey::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner, + const CSSM_ACCESS_CREDENTIALS *cred) +{ + secdebug("keyacl", "ClientSessionKey::changeOwner() keyHandle: %u", mKeyHandle); + mClientSession.changeKeyOwner(mKeyHandle, AccessCredentials::overlay(*cred), AclOwnerPrototype::overlay(newOwner)); +} + +#endif // !SECURITYSERVER_ACL_EDITS