X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_cspdl/lib/SSCSPSession.cpp?ds=inline diff --git a/libsecurity_apple_cspdl/lib/SSCSPSession.cpp b/libsecurity_apple_cspdl/lib/SSCSPSession.cpp deleted file mode 100644 index 994ef203..00000000 --- a/libsecurity_apple_cspdl/lib/SSCSPSession.cpp +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (c) 2000-2001 Apple Computer, 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. - */ - - -// -// SSCSPSession.cpp - Security Server CSP session. -// -#include "SSCSPSession.h" - -#include "CSPDLPlugin.h" -#include "SSDatabase.h" -#include "SSDLSession.h" -#include "SSKey.h" -#include -#include - -using namespace std; -using namespace SecurityServer; - -// -// SSCSPSession -- Security Server CSP session -// -SSCSPSession::SSCSPSession(CSSM_MODULE_HANDLE handle, - CSPDLPlugin &plug, - const CSSM_VERSION &version, - uint32 subserviceId, - CSSM_SERVICE_TYPE subserviceType, - CSSM_ATTACH_FLAGS attachFlags, - const CSSM_UPCALLS &upcalls, - SSCSPDLSession &ssCSPDLSession, - CssmClient::CSP &rawCsp) -: CSPFullPluginSession(handle, plug, version, subserviceId, subserviceType, - attachFlags, upcalls), - mSSCSPDLSession(ssCSPDLSession), - mSSFactory(plug.mSSFactory), - mRawCsp(rawCsp), - mClientSession(Allocator::standard(), *this) -{ - mClientSession.registerForAclEdits(SSCSPDLSession::didChangeKeyAclCallback, &mSSCSPDLSession); -} - -// -// Called at (CSSM) context create time. This is ignored; we do a full -// context setup later, at setupContext time. -// -CSPFullPluginSession::CSPContext * -SSCSPSession::contextCreate(CSSM_CC_HANDLE handle, const Context &context) -{ - return NULL; -} - - -// -// Called by CSPFullPluginSession when an op is actually commencing. -// Context can safely assumed to be fully formed and stable for the -// duration of the op; thus we wait until now to set up our -// CSPContext as appropriate to the op. -// -void -SSCSPSession::setupContext(CSPContext * &cspCtx, - const Context &context, - bool encoding) -{ - // note we skip this if this CSPContext is being reused - if (cspCtx == NULL) - { - - if (mSSFactory.setup(*this, cspCtx, context, encoding)) - return; - -#if 0 - if (mBSafe4Factory.setup(*this, cspCtx, context)) - return; - - if (mCryptKitFactory.setup(*this, cspCtx, context)) - return; -#endif - - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); - } -} - - -// -// DL interaction -// -SSDatabase -SSCSPSession::getDatabase(const Context &context) -{ - return getDatabase(context.get(CSSM_ATTRIBUTE_DL_DB_HANDLE)); -} - -SSDatabase -SSCSPSession::getDatabase(CSSM_DL_DB_HANDLE *aDLDbHandle) -{ - if (aDLDbHandle) - return findSession(aDLDbHandle->DLHandle).findDbHandle(aDLDbHandle->DBHandle); - else - return SSDatabase(); -} - - -// -// Reference Key management -// -void -SSCSPSession::makeReferenceKey(KeyHandle inKeyHandle, CssmKey &ioKey, SSDatabase &inSSDatabase, - uint32 inKeyAttr, const CssmData *inKeyLabel) -{ - return mSSCSPDLSession.makeReferenceKey(*this, inKeyHandle, ioKey, inSSDatabase, inKeyAttr, inKeyLabel); -} - -SSKey & -SSCSPSession::lookupKey(const CssmKey &inKey) -{ - return mSSCSPDLSession.lookupKey(inKey); -} - - -// -// Key creating and handeling members -// -void -SSCSPSession::WrapKey(CSSM_CC_HANDLE CCHandle, - const Context &context, - const AccessCredentials &AccessCred, - const CssmKey &Key, - const CssmData *DescriptiveData, - CssmKey &WrappedKey, - CSSM_PRIVILEGE Privilege) -{ - // @@@ Deal with permanent keys - const CssmKey *keyInContext = - context.get(CSSM_ATTRIBUTE_KEY); - - KeyHandle contextKeyHandle = (keyInContext - ? lookupKey(*keyInContext).keyHandle() - : noKey); - clientSession().wrapKey(context, contextKeyHandle, - lookupKey(Key).keyHandle(), &AccessCred, - DescriptiveData, WrappedKey, *this); -} - -void -SSCSPSession::UnwrapKey(CSSM_CC_HANDLE CCHandle, - const Context &context, - const CssmKey *PublicKey, - const CssmWrappedKey &WrappedKey, - uint32 KeyUsage, - uint32 KeyAttr, - const CssmData *KeyLabel, - const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, - CssmKey &UnwrappedKey, - CssmData &DescriptiveData, - CSSM_PRIVILEGE Privilege) -{ - SSDatabase database = getDatabase(context); - validateKeyAttr(KeyAttr); - const AccessCredentials *cred = NULL; - const AclEntryInput *owner = NULL; - if (CredAndAclEntry) - { - cred = AccessCredentials::overlay(CredAndAclEntry->AccessCred); - owner = &AclEntryInput::overlay(CredAndAclEntry->InitialAclEntry); - } - - KeyHandle publicKey = noKey; - if (PublicKey) - { - if (PublicKey->blobType() == CSSM_KEYBLOB_RAW) - { - // @@@ We need to unwrap the publicKey into the SecurityServer - // before continuing - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - else - publicKey = lookupKey(*PublicKey).keyHandle(); - } - - // @@@ Deal with permanent keys - const CssmKey *keyInContext = - context.get(CSSM_ATTRIBUTE_KEY); - - KeyHandle contextKeyHandle = - keyInContext ? lookupKey(*keyInContext).keyHandle() : noKey; - - KeyHandle unwrappedKeyHandle; - clientSession().unwrapKey(database.dbHandle(), context, contextKeyHandle, - publicKey, WrappedKey, KeyUsage, KeyAttr, - cred, owner, DescriptiveData, unwrappedKeyHandle, - UnwrappedKey.header(), *this); - makeReferenceKey(unwrappedKeyHandle, UnwrappedKey, database, KeyAttr, - KeyLabel); -} - -void -SSCSPSession::DeriveKey(CSSM_CC_HANDLE ccHandle, - const Context &context, - CssmData ¶m, - uint32 keyUsage, - uint32 keyAttr, - const CssmData *keyLabel, - const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry, - CssmKey &derivedKey) -{ - SSDatabase database = getDatabase(context); - validateKeyAttr(keyAttr); - const AccessCredentials *cred = NULL; - const AclEntryInput *owner = NULL; - if (credAndAclEntry) - { - cred = AccessCredentials::overlay(credAndAclEntry->AccessCred); - owner = &AclEntryInput::overlay(credAndAclEntry->InitialAclEntry); - } - - /* optional BaseKey */ - const CssmKey *keyInContext = - context.get(CSSM_ATTRIBUTE_KEY); - KeyHandle contextKeyHandle = - keyInContext ? lookupKey(*keyInContext).keyHandle() : noKey; - KeyHandle keyHandle; - switch(context.algorithm()) { - case CSSM_ALGID_KEYCHAIN_KEY: - { - // special interpretation: take DLDBHandle -> DbHandle from params - clientSession().extractMasterKey(database.dbHandle(), context, - getDatabase(param.interpretedAs(CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE)).dbHandle(), - keyUsage, keyAttr, cred, owner, keyHandle, derivedKey.header()); - } - break; - default: - clientSession().deriveKey(database.dbHandle(), context, contextKeyHandle, keyUsage, - keyAttr, param, cred, owner, keyHandle, derivedKey.header()); - break; - } - makeReferenceKey(keyHandle, derivedKey, database, keyAttr, keyLabel); -} - -void -SSCSPSession::GenerateKey(CSSM_CC_HANDLE ccHandle, - const Context &context, - uint32 keyUsage, - uint32 keyAttr, - const CssmData *keyLabel, - const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry, - CssmKey &key, - CSSM_PRIVILEGE privilege) -{ - SSDatabase database = getDatabase(context); - validateKeyAttr(keyAttr); - const AccessCredentials *cred = NULL; - const AclEntryInput *owner = NULL; - if (credAndAclEntry) - { - cred = AccessCredentials::overlay(credAndAclEntry->AccessCred); - owner = &AclEntryInput::overlay(credAndAclEntry->InitialAclEntry); - } - - KeyHandle keyHandle; - clientSession().generateKey(database.dbHandle(), context, keyUsage, - keyAttr, cred, owner, keyHandle, key.header()); - makeReferenceKey(keyHandle, key, database, keyAttr, keyLabel); -} - -void -SSCSPSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle, - const Context &context, - uint32 publicKeyUsage, - uint32 publicKeyAttr, - const CssmData *publicKeyLabel, - CssmKey &publicKey, - uint32 privateKeyUsage, - uint32 privateKeyAttr, - const CssmData *privateKeyLabel, - const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry, - CssmKey &privateKey, - CSSM_PRIVILEGE privilege) -{ - SSDatabase database = getDatabase(context); - validateKeyAttr(publicKeyAttr); - validateKeyAttr(privateKeyAttr); - const AccessCredentials *cred = NULL; - const AclEntryInput *owner = NULL; - if (credAndAclEntry) - { - cred = AccessCredentials::overlay(credAndAclEntry->AccessCred); - owner = &AclEntryInput::overlay(credAndAclEntry->InitialAclEntry); - } - - /* - * Public keys must be extractable in the clear - that's the Apple - * policy. The raw CSP is unable to enforce the extractable - * bit since it always sees that as true (it's managed and forced - * true by the SecurityServer). So... - */ - if(!(publicKeyAttr & CSSM_KEYATTR_EXTRACTABLE)) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK); - } - KeyHandle pubKeyHandle, privKeyHandle; - clientSession().generateKey(database.dbHandle(), context, - publicKeyUsage, publicKeyAttr, - privateKeyUsage, privateKeyAttr, - cred, owner, - pubKeyHandle, publicKey.header(), - privKeyHandle, privateKey.header()); - makeReferenceKey(privKeyHandle, privateKey, database, privateKeyAttr, - privateKeyLabel); - // @@@ What if this throws, we need to free privateKey. - makeReferenceKey(pubKeyHandle, publicKey, database, publicKeyAttr, - publicKeyLabel); -} - -void -SSCSPSession::ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey, - CssmKey &PrivateKey) -{ - unimplemented(); -} - -void -SSCSPSession::QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle, - const Context *Context, - const CssmKey *Key, - CSSM_KEY_SIZE &KeySize) -{ - unimplemented(); -} - -void -SSCSPSession::FreeKey(const AccessCredentials *accessCred, - CssmKey &ioKey, CSSM_BOOL deleteKey) -{ - if (ioKey.blobType() == CSSM_KEYBLOB_REFERENCE) - { - // @@@ Note that this means that detaching a session should free - // all keys ascociated with it or else... - // -- or else what? - // exactly! - - // @@@ There are thread safety issues when deleting a key that is - // in use by another thread, but the answer to that is: Don't do - // that! - - // Find the key in the map. Tell tell the key to free itself - // (when the auto_ptr deletes the key it removes itself from the map). - secdebug("freeKey", "CSPDL FreeKey"); - auto_ptr ssKey(&mSSCSPDLSession.find(ioKey)); - ssKey->free(accessCred, ioKey, deleteKey); - } - else - { - CSPFullPluginSession::FreeKey(accessCred, ioKey, deleteKey); - } -} - - -// -// Generation stuff. -// -void -SSCSPSession::GenerateRandom(CSSM_CC_HANDLE ccHandle, - const Context &context, - CssmData &randomNumber) -{ - checkOperation(context.type(), CSSM_ALGCLASS_RANDOMGEN); - // if (context.algorithm() != @@@) CssmError::throwMe(ALGORITHM_NOT_SUPPORTED); - uint32 needed = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE); - - // @@@ What about the seed? - if (randomNumber.length()) - { - if (randomNumber.length() < needed) - CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); - clientSession().generateRandom(context, randomNumber); - } - else - { - randomNumber.Data = alloc(needed); - try - { - clientSession().generateRandom(context, randomNumber); - } - catch(...) - { - free(randomNumber.Data); - randomNumber.Data = NULL; - throw; - } - } -} - -// -// Login/Logout and token operational maintainance. These mean little -// without support by the actual implementation, but we can help... -// @@@ Should this be in CSP[non-Full]PluginSession? -// -void -SSCSPSession::Login(const AccessCredentials &AccessCred, - const CssmData *LoginName, - const void *Reserved) -{ - // @@@ Do a login to the securityServer making keys persistant until it - // goes away - unimplemented(); -} - -void -SSCSPSession::Logout() -{ - unimplemented(); -} - -void -SSCSPSession::VerifyDevice(const CssmData &DeviceCert) -{ - CssmError::throwMe(CSSMERR_CSP_DEVICE_VERIFY_FAILED); -} - -void -SSCSPSession::GetOperationalStatistics(CSPOperationalStatistics &statistics) -{ - unimplemented(); -} - - -// -// Utterly miscellaneous, rarely used, strange functions -// -void -SSCSPSession::RetrieveCounter(CssmData &Counter) -{ - unimplemented(); -} - -void -SSCSPSession::RetrieveUniqueId(CssmData &UniqueID) -{ - unimplemented(); -} - -void -SSCSPSession::GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm, CssmData &TimeData) -{ - unimplemented(); -} - - -// -// ACL retrieval and change operations -// -void -SSCSPSession::GetKeyOwner(const CssmKey &Key, - CSSM_ACL_OWNER_PROTOTYPE &Owner) -{ - lookupKey(Key).getOwner(Owner, *this); -} - -void -SSCSPSession::ChangeKeyOwner(const AccessCredentials &AccessCred, - const CssmKey &Key, - const CSSM_ACL_OWNER_PROTOTYPE &NewOwner) -{ - lookupKey(Key).changeOwner(AccessCred, - AclOwnerPrototype::overlay(NewOwner)); -} - -void -SSCSPSession::GetKeyAcl(const CssmKey &Key, - const CSSM_STRING *SelectionTag, - uint32 &NumberOfAclInfos, - CSSM_ACL_ENTRY_INFO_PTR &AclInfos) -{ - lookupKey(Key).getAcl(reinterpret_cast(SelectionTag), - NumberOfAclInfos, - reinterpret_cast(AclInfos), *this); -} - -void -SSCSPSession::ChangeKeyAcl(const AccessCredentials &AccessCred, - const CSSM_ACL_EDIT &AclEdit, - const CssmKey &Key) -{ - lookupKey(Key).changeAcl(AccessCred, AclEdit::overlay(AclEdit)); -} - -void -SSCSPSession::GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE &Owner) -{ - unimplemented(); -} - -void -SSCSPSession::ChangeLoginOwner(const AccessCredentials &AccessCred, - const CSSM_ACL_OWNER_PROTOTYPE &NewOwner) -{ - unimplemented(); -} - -void -SSCSPSession::GetLoginAcl(const CSSM_STRING *SelectionTag, - uint32 &NumberOfAclInfos, - CSSM_ACL_ENTRY_INFO_PTR &AclInfos) -{ - unimplemented(); -} - -void -SSCSPSession::ChangeLoginAcl(const AccessCredentials &AccessCred, - const CSSM_ACL_EDIT &AclEdit) -{ - unimplemented(); -} - - - -// -// Passthroughs -// -void -SSCSPSession::PassThrough(CSSM_CC_HANDLE CCHandle, - const Context &context, - uint32 passThroughId, - const void *inData, - void **outData) -{ - checkOperation(context.type(), CSSM_ALGCLASS_NONE); - switch (passThroughId) { - case CSSM_APPLESCPDL_CSP_GET_KEYHANDLE: - { - // inData unused, must be NULL - if (inData) - CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER); - - // outData required, must be pointer-to-pointer-to-KeyHandle - KeyHandle &result = Required(reinterpret_cast(outData)); - - // we'll take the key from the context - const CssmKey &key = - context.get(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY); - - // all ready - result = lookupKey(key).keyHandle(); - break; - } - case CSSM_APPLECSP_KEYDIGEST: - { - // inData unused, must be NULL - if (inData) - CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER); - - // outData required - Required(outData); - - // take the key from the context, convert to KeyHandle - const CssmKey &key = - context.get(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY); - KeyHandle keyHandle = lookupKey(key).keyHandle(); - - // allocate digest holder on app's behalf - CSSM_DATA *digest = alloc(sizeof(CSSM_DATA)); - digest->Data = NULL; - digest->Length = 0; - - // go - try { - clientSession().getKeyDigest(keyHandle, CssmData::overlay(*digest)); - } - catch(...) { - free(digest); - throw; - } - *outData = digest; - break; - } - - default: - CssmError::throwMe(CSSM_ERRCODE_INVALID_PASSTHROUGH_ID); - } -} - -/* Validate requested key attr flags for newly generated keys */ -void SSCSPSession::validateKeyAttr(uint32 reqKeyAttr) -{ - if(reqKeyAttr & (CSSM_KEYATTR_RETURN_DATA)) { - /* CSPDL only supports reference keys */ - CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK); - } - if(reqKeyAttr & (CSSM_KEYATTR_ALWAYS_SENSITIVE | - CSSM_KEYATTR_NEVER_EXTRACTABLE)) { - /* invalid for any CSP */ - CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK); - } - /* There may be more, but we'll leave it to SS and CSP to decide */ -}