]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_apple_csp/lib/AppleCSP.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / 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 (file)
index 7fd55f1..0000000
+++ /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 <stdio.h> 
-#include "cspdebugging.h" 
-#include <security_cdsa_plugin/CSPsession.h>
-#include <security_utilities/alloc.h>
-#ifdef BSAFE_CSP_ENABLE
-#include "bsafecsp.h"
-#include "bsafecspi.h"
-#endif
-#ifdef CRYPTKIT_CSP_ENABLE
-#include "cryptkitcsp.h"
-#include "FEEKeys.h"
-#endif
-#include <miscAlgFactory.h> 
-#ifdef ASC_CSP_ENABLE
-#include "ascFactory.h"
-#endif
-#include <RSA_DSA_csp.h>
-#include <RSA_DSA_keys.h>
-#include <DH_csp.h>
-#include <DH_keys.h>
-
-#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<BSafeFactory *>(plug.bSafe4Factory))), 
-               #endif
-               #ifdef  CRYPTKIT_CSP_ENABLE
-               cryptKitFactory(*(dynamic_cast<CryptKitFactory *>(plug.cryptKitFactory))),
-               #endif
-               miscAlgFactory(*(dynamic_cast<MiscAlgFactory *>(plug.miscAlgFactory))),
-               #ifdef  ASC_CSP_ENABLE
-               ascAlgFactory(*(dynamic_cast<AscAlgFactory *>(plug.ascAlgFactory))),
-               #endif
-               rsaDsaAlgFactory(*(dynamic_cast<RSA_DSA_Factory *>(plug.rsaDsaAlgFactory))),
-               dhAlgFactory(*(dynamic_cast<DH_Factory *>(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<CssmCryptoData>(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); dex++) {
-               keyRef <<= 8;
-               keyRef |= *cp--;
-       }
-       return keyRef;
-}
-
-// Place a KeyRef into a CSSM_DATA, mallocing if necessary.
-static void keyRefToCssmData(
-       KeyRef                  keyRef,
-       CSSM_DATA               &data,
-       Allocator       &allocator)
-{
-       if(data.Length > 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<sizeof(keyRef); i++) {
-               *cp++ = keyRef & 0xff;
-               keyRef >>= 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<const BinaryKey *>(keyRef));
-       assert(binKey->mKeyRef == keyRef);
-       return const_cast<BinaryKey *>(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<KeyRef>(&binKey);
-       
-       binKey.mKeyRef = keyRef;
-       binKey.mKeyHeader = CssmKey::Header::overlay(cssmKey.KeyHeader);
-       {
-               StLock<Mutex> _(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<Mutex> _(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<Mutex> _(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<CssmKey>(
-                               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);
-}
-