X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_csp/lib/AppleCSP.cpp diff --git a/libsecurity_apple_csp/lib/AppleCSP.cpp b/libsecurity_apple_csp/lib/AppleCSP.cpp deleted file mode 100644 index 7fd55f16..00000000 --- a/libsecurity_apple_csp/lib/AppleCSP.cpp +++ /dev/null @@ -1,661 +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. - */ - - -// -// AppleCSP.cpp - top-level plugin and session implementation -// -#include "AppleCSP.h" -#include "AppleCSPSession.h" -#include "AppleCSPUtils.h" -#include -#include "cspdebugging.h" -#include -#include -#ifdef BSAFE_CSP_ENABLE -#include "bsafecsp.h" -#include "bsafecspi.h" -#endif -#ifdef CRYPTKIT_CSP_ENABLE -#include "cryptkitcsp.h" -#include "FEEKeys.h" -#endif -#include -#ifdef ASC_CSP_ENABLE -#include "ascFactory.h" -#endif -#include -#include -#include -#include - -#include "YarrowConnection.h" - -// -// Make and break the plugin object -// -AppleCSPPlugin::AppleCSPPlugin() : - normAllocator(Allocator::standard(Allocator::normal)), - privAllocator(Allocator::standard(Allocator::sensitive)), - #ifdef BSAFE_CSP_ENABLE - bSafe4Factory(new BSafeFactory(&normAllocator, &privAllocator)), - #endif - #ifdef CRYPTKIT_CSP_ENABLE - cryptKitFactory(new CryptKitFactory(&normAllocator, &privAllocator)), - #endif - miscAlgFactory(new MiscAlgFactory(&normAllocator, &privAllocator)), - #ifdef ASC_CSP_ENABLE - ascAlgFactory(new AscAlgFactory(&normAllocator, &privAllocator)), - #endif - rsaDsaAlgFactory(new RSA_DSA_Factory(&normAllocator, &privAllocator)), - dhAlgFactory(new DH_Factory(&normAllocator, &privAllocator)) -{ - // misc. once-per-address-space cruft... -} - -AppleCSPPlugin::~AppleCSPPlugin() -{ - #ifdef BSAFE_CSP_ENABLE - delete bSafe4Factory; - #endif - #ifdef CRYPTKIT_CSP_ENABLE - delete cryptKitFactory; - #endif - delete miscAlgFactory; - #ifdef ASC_CSP_ENABLE - delete ascAlgFactory; - #endif - delete rsaDsaAlgFactory; - delete dhAlgFactory; -} - - -// -// Create a new plugin session, our way -// -PluginSession *AppleCSPPlugin::makeSession( - CSSM_MODULE_HANDLE handle, - const CSSM_VERSION &version, - uint32 subserviceId, - CSSM_SERVICE_TYPE subserviceType, - CSSM_ATTACH_FLAGS attachFlags, - const CSSM_UPCALLS &upcalls) -{ - switch (subserviceType) { - case CSSM_SERVICE_CSP: - return new AppleCSPSession(handle, - *this, - version, - subserviceId, - subserviceType, - attachFlags, - upcalls); - default: - CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK); - return 0; // placebo - } -} - - -// -// Session constructor -// -AppleCSPSession::AppleCSPSession( - CSSM_MODULE_HANDLE handle, - AppleCSPPlugin &plug, - const CSSM_VERSION &version, - uint32 subserviceId, - CSSM_SERVICE_TYPE subserviceType, - CSSM_ATTACH_FLAGS attachFlags, - const CSSM_UPCALLS &upcalls) - : CSPFullPluginSession(handle, - plug, - version, - subserviceId, - subserviceType, - attachFlags, - upcalls), - #ifdef BSAFE_CSP_ENABLE - bSafe4Factory(*(dynamic_cast(plug.bSafe4Factory))), - #endif - #ifdef CRYPTKIT_CSP_ENABLE - cryptKitFactory(*(dynamic_cast(plug.cryptKitFactory))), - #endif - miscAlgFactory(*(dynamic_cast(plug.miscAlgFactory))), - #ifdef ASC_CSP_ENABLE - ascAlgFactory(*(dynamic_cast(plug.ascAlgFactory))), - #endif - rsaDsaAlgFactory(*(dynamic_cast(plug.rsaDsaAlgFactory))), - dhAlgFactory(*(dynamic_cast(plug.dhAlgFactory))), - normAllocator(*this), - privAllocator(plug.privAlloc()) -{ - // anything? -} - -AppleCSPSession::~AppleCSPSession() -{ - // anything? -} - -// -// Called at (CSSM) context create time. This is ignored; we do a full -// context setup later, at setupContext time. -// -CSPFullPluginSession::CSPContext * -AppleCSPSession::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 AppleCSPSession::setupContext( - CSPContext * &cspCtx, - const Context &context, - bool encoding) -{ - /* - * Note we leave the decision as to whether it's OK to - * reuse a context to the individual factories. - */ - #ifdef BSAFE_CSP_ENABLE - /* Give BSAFE the firsrt shot if it's present */ - if (bSafe4Factory.setup(*this, cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - #endif - if (rsaDsaAlgFactory.setup(*this, cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - if (miscAlgFactory.setup(*this, cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - if (dhAlgFactory.setup(*this, cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - #ifdef CRYPTKIT_CSP_ENABLE - if (cryptKitFactory.setup(*this, cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - #endif - #ifdef ASC_CSP_ENABLE - if (ascAlgFactory.setup(*this, cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - #endif - if(setup(cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - dprintf0("AppleCSPSession::setupContext: invalid algorithm\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); -} - -/* - * Used for generating crypto contexts at this level. - * Analogous to AlgorithmFactory.setup(). - */ -bool AppleCSPSession::setup( - CSPFullPluginSession::CSPContext * &cspCtx, - const Context &context) -{ - if (cspCtx) { - return false; // not ours or already set - } - - switch(context.type()) { - case CSSM_ALGCLASS_RANDOMGEN: - switch (context.algorithm()) { - case CSSM_ALGID_APPLE_YARROW: - cspCtx = new YarrowContext(*this); - return true; - /* other random algs here */ - default: - return false; - } - /* other contexts here */ - default: - return false; - } - /* NOT REACHED */ - return false; - -} - -// -// Context for CSSM_ALGID_APPLE_YARROW. -// -YarrowContext::YarrowContext(AppleCSPSession &session) - : AppleCSPContext(session) -{ - // nothing for now -} - -YarrowContext::~YarrowContext() -{ - // nothing for now -} - -// -// Only job here is to snag the length and process the optional seed argument -// -void YarrowContext::init( - const Context &context, - bool encoding) -{ - /* stash requested length for use later in outputSize() */ - outSize = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, - CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE); - - /* optional seed */ - CssmCryptoData *cseed = context.get(CSSM_ATTRIBUTE_SEED); - if(cseed == NULL) { - /* we're done */ - return; - } - CssmData seed = (*cseed)(); - if((seed.Length == 0) || - (seed.Data == NULL)) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SEED); - } - session().addEntropy((size_t)seed.Length, seed.Data); -} - -void YarrowContext::final( - CssmData &out) -{ - session().getRandomBytes((size_t)out.Length, out.Data); -} - -/*** - *** Binary Key support. - ***/ - -// Given a CSSM_DATA, extract its KeyRef. -static KeyRef CssmDataToKeyRef( - const CSSM_DATA &data) -{ - if(data.Length != sizeof(KeyRef)) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE); - } - - uint8 *cp = data.Data + sizeof(KeyRef) - 1; - KeyRef keyRef = 0; - for(unsigned dex=0; dex sizeof(keyRef)) { - /* don't leave old raw key material lying around */ - memset(data.Data + sizeof(keyRef), 0, data.Length - sizeof(keyRef)); - } - else if(data.Length < sizeof(keyRef)) { - /* not enough space for even a keyRef, force realloc */ - allocator.free(data.Data); - data.Data = NULL; - data.Length = 0; - } - setUpData(data, sizeof(keyRef), allocator); - - uint8 *cp = data.Data; - for(unsigned i=0; i>= 8; - } -} - -// Look up a BinaryKey by its KeyRef. Returns NULL if not -// found. refKeyMapLock held on entry and exit. -BinaryKey *AppleCSPSession::lookupKeyRef( - KeyRef keyRef) -{ - const BinaryKey *binKey; - - // use safe version, don't create new entry if this key - // isn't there - keyMap::iterator it = refKeyMap.find(keyRef); - if(it == refKeyMap.end()) { - return NULL; - } - binKey = it->second; - assert(binKey == reinterpret_cast(keyRef)); - assert(binKey->mKeyRef == keyRef); - return const_cast(binKey); -} - -// add a BinaryKey to our refKeyMap. Sets up cssmKey -// as appropriate. -void AppleCSPSession::addRefKey( - BinaryKey &binKey, - CssmKey &cssmKey) -{ - // for now, KeyRef is just the address of the BinaryKey - KeyRef keyRef = reinterpret_cast(&binKey); - - binKey.mKeyRef = keyRef; - binKey.mKeyHeader = CssmKey::Header::overlay(cssmKey.KeyHeader); - { - StLock _(refKeyMapLock); - assert(lookupKeyRef(keyRef) == NULL); - refKeyMap[keyRef] = &binKey; - } - cssmKey.KeyHeader.BlobType = CSSM_KEYBLOB_REFERENCE; - cssmKey.KeyHeader.Format = CSSM_KEYBLOB_REF_FORMAT_INTEGER; - keyRefToCssmData(keyRef, cssmKey.KeyData, normAllocator); - secdebug("freeKey", "CSP addRefKey key %p keyData %p keyRef %p", - &cssmKey, cssmKey.KeyData.Data, &binKey); -} - -// Given a CssmKey in reference form, obtain the associated -// BinaryKey. Throws CSSMERR_CSP_INVALID_KEY_REFERENCE if -// key not found in session key map. -BinaryKey & AppleCSPSession::lookupRefKey( - const CssmKey &cssmKey) -{ - KeyRef keyRef; - BinaryKey *binKey; - - keyRef = CssmDataToKeyRef(cssmKey.KeyData); - { - StLock _(refKeyMapLock); - binKey = lookupKeyRef(keyRef); - } - if(binKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE); - } - assert(Guid::overlay(binKey->mKeyHeader.CspId) == plugin.myGuid()); - - /* - * Verify sensitive fields have not changed between when the BinaryKey was - * created/stored and when the caller passed in the ref key. - * Some fields were changed by addRefKey, so make a local copy.... - */ - CSSM_KEYHEADER localHdr = cssmKey.KeyHeader; - 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); - } - return (*binKey); -} - -// CSPFullPluginSession declares & implements this. -// Note that we ignore the delete argument; since we don't -// store anything, freeing is the same as deleting. -void AppleCSPSession::FreeKey( - const AccessCredentials *AccessCred, - CssmKey &KeyPtr, - CSSM_BOOL Delete) -{ - - if((KeyPtr.blobType() == CSSM_KEYBLOB_REFERENCE) && - (KeyPtr.cspGuid() == plugin.myGuid())) { - // it's a ref key we generated - delete associated BinaryKey - KeyRef keyRef = CssmDataToKeyRef(KeyPtr.KeyData); - { - StLock _(refKeyMapLock); - BinaryKey *binKey = lookupKeyRef(keyRef); - if(binKey != NULL) { - secdebug("freeKey", "CSP FreeKey key %p keyData %p binKey %p", - &KeyPtr, KeyPtr.KeyData.Data, binKey); - try { - refKeyMap.erase(keyRef); - delete binKey; - } - catch (...) { - errorLog0("Error deleting/erasing known " - "ref key\n"); - } - } - else { - secdebug("freeKey", "CSP freeKey unknown key"); - } - } - } - CSPFullPluginSession::FreeKey(AccessCred, KeyPtr, Delete); -} - -/* Passthrough, used for key digest */ -void AppleCSPSession::PassThrough( - CSSM_CC_HANDLE CCHandle, - const Context &Context, - uint32 PassThroughId, - const void *InData, - void **OutData) -{ - *OutData = NULL; - - /* validate context */ - if(Context.type() != CSSM_ALGCLASS_NONE) { - CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT); - } - - switch(PassThroughId) { - case CSSM_APPLECSP_KEYDIGEST: - { - CssmKey &key = Context.get( - CSSM_ATTRIBUTE_KEY, - CSSMERR_CSP_MISSING_ATTR_KEY); - - /* validate key as best we can */ - switch(key.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - case CSSM_KEYCLASS_PRIVATE_KEY: - case CSSM_KEYCLASS_SESSION_KEY: - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - - /* - * Ref key: obtain binary, ask it for blob - * Raw key: get info provider, ask it for the blob. This - * allows for an optimized path which avoids - * converting to a BinaryKey. - */ - CssmData blobToHash; - switch(key.blobType()) { - case CSSM_KEYBLOB_RAW: - { - CSPKeyInfoProvider *provider = infoProvider(key); - bool converted = - provider->getHashableBlob(privAllocator, blobToHash); - if(converted) { - /* took optimized case; proceed */ - delete provider; - break; - } - - /* convert to BinaryKey and ask it to do the work */ - BinaryKey *binKey; - CSSM_KEYATTR_FLAGS flags = 0; // not used - provider->CssmKeyToBinary(NULL, // no paramKey - flags, - &binKey); - binKey->mKeyHeader = - CssmKey::Header::overlay(key.KeyHeader); - CSSM_KEYBLOB_FORMAT rawFormat; - rawFormat = CSSM_KEYBLOB_RAW_FORMAT_DIGEST; - CSSM_KEYATTR_FLAGS attrFlags = 0; - binKey->generateKeyBlob(privAllocator, - blobToHash, - rawFormat, - *this, - NULL, - attrFlags); - delete binKey; - delete provider; - break; - } - case CSSM_KEYBLOB_REFERENCE: - { - BinaryKey &binKey = lookupRefKey(key); - CSSM_KEYBLOB_FORMAT rawFormat; - rawFormat = CSSM_KEYBLOB_RAW_FORMAT_DIGEST; - CSSM_KEYATTR_FLAGS attrFlags = 0; - binKey.generateKeyBlob(privAllocator, - blobToHash, - rawFormat, - *this, - NULL, - attrFlags); - } - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - - /* obtain sha1 hash of blobToHash */ - - CSSM_DATA_PTR outHash = NULL; - try { - outHash = - (CSSM_DATA_PTR)normAllocator.malloc(sizeof(CSSM_DATA)); - outHash->Data = - (uint8 *)normAllocator.malloc(SHA1_DIGEST_SIZE); - outHash->Length = SHA1_DIGEST_SIZE; - } - catch(...) { - freeCssmData(blobToHash, privAllocator); - throw; - } - cspGenSha1Hash(blobToHash.data(), blobToHash.length(), - outHash->Data); - freeCssmData(blobToHash, privAllocator); - *OutData = outHash; - return; - } - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_PASSTHROUGH_ID); - } - /* NOT REACHED */ -} - -/* - * CSPSession version of QueryKeySizeInBits. - */ -void AppleCSPSession::getKeySize(const CssmKey &key, - CSSM_KEY_SIZE &size) -{ - CSPKeyInfoProvider *provider = infoProvider(key); - try { - provider->QueryKeySizeInBits(size); - } - catch(...) { - /* don't leak this on error */ - delete provider; - throw; - } - delete provider; -} - -void AppleCSPSession::getRandomBytes(size_t length, uint8 *cp) -{ - try { - cspGetRandomBytes(cp, (unsigned)length); - } - catch(...) { - errorLog0("CSP: YarrowClient failure\n"); - } -} - -void AppleCSPSession::addEntropy(size_t length, const uint8 *cp) -{ - try { - cspAddEntropy(cp, (unsigned)length); - } - catch(...) { - #if CSP_ALLOW_FEE_RNG - return; - #else - throw; - #endif - } -} - -/*** - *** CSPKeyInfoProvider support. - ***/ - -/* - * Find a CSPKeyInfoProvider subclass for the specified key. - */ -CSPKeyInfoProvider *AppleCSPSession::infoProvider( - const CssmKey &key) -{ - CSPKeyInfoProvider *provider = NULL; - - #ifdef BSAFE_CSP_ENABLE - /* Give BSAFE first shot, if it's here */ - provider = BSafe::BSafeKeyInfoProvider::provider(key, *this); - if(provider != NULL) { - return provider; - } - #endif - - provider = RSAKeyInfoProvider::provider(key, *this); - if(provider != NULL) { - return provider; - } - - provider = SymmetricKeyInfoProvider::provider(key, *this); - if(provider != NULL) { - return provider; - } - - #ifdef CRYPTKIT_CSP_ENABLE - provider = CryptKit::FEEKeyInfoProvider::provider(key, *this); - if(provider != NULL) { - return provider; - } - #endif - - provider = DSAKeyInfoProvider::provider(key, *this); - if(provider != NULL) { - return provider; - } - - provider = DHKeyInfoProvider::provider(key, *this); - if(provider != NULL) { - return provider; - } - - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); -} -