]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_cdsa_plugin/lib/CSPsession.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_cdsa_plugin / lib / CSPsession.cpp
diff --git a/libsecurity_cdsa_plugin/lib/CSPsession.cpp b/libsecurity_cdsa_plugin/lib/CSPsession.cpp
deleted file mode 100644 (file)
index d3eb960..0000000
+++ /dev/null
@@ -1,1156 +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.
- */
-
-
-//
-// CSPsession - Plugin framework for CSP plugin modules
-//
-#include <security_cdsa_plugin/CSPsession.h>
-#include <security_cdsa_plugin/cssmplugin.h>
-#include <security_cdsa_utilities/cssmbridge.h>
-
-
-typedef CSPFullPluginSession::CSPContext CSPContext;
-
-
-//
-// PluginContext construction
-//
-CSPPluginSession::PluginContext::~PluginContext()
-{ /* virtual */ }
-
-CSPFullPluginSession::AlgorithmFactory::~AlgorithmFactory()
-{ /* virtual */ }
-
-
-//
-// Internal utilities
-//
-CssmData CSPFullPluginSession::makeBuffer(size_t size, Allocator &alloc)
-{
-       return CssmData(alloc.malloc(size), size);
-}
-
-inline size_t CSPFullPluginSession::totalBufferSize(const CssmData *data, uint32 count)
-{
-       size_t size = 0;
-       for (uint32 n = 0; n < count; n++)
-               size += data[n].length();
-       return size;
-}
-
-
-//
-// Notify a context that its underlying CSSM context has (well, may have) changed.
-// The default reaction is to ask the frame to delete the context and start over.
-//
-bool CSPPluginSession::PluginContext::changed(const Context &context)
-{
-    return false;      // delete me, please
-}
-
-
-//
-// The Session's init() function calls your setupContext() method to prepare
-// it for action, then calls the context's init() method.
-//
-CSPContext *CSPFullPluginSession::init(CSSM_CC_HANDLE ccHandle,
-                                                                       CSSM_CONTEXT_TYPE type,
-                                                                       const Context &context, bool encoding)
-{
-    CSPContext *ctx = getContext<CSPContext>(ccHandle);
-    checkOperation(context.type(), type);
-
-    // ask the implementation to set up an internal context
-    setupContext(ctx, context, encoding);
-    assert(ctx != NULL);       // must have context now (@@@ throw INTERNAL_ERROR instead?)
-    ctx->mType = context.type();
-    ctx->mDirection = encoding;
-    setContext(ccHandle, ctx);
-
-    // initialize the context and return it
-    ctx->init(context, encoding);
-    return ctx;
-}
-
-
-//
-// Retrieve a context for a staged operation in progress.
-//
-CSPContext *CSPFullPluginSession::getStagedContext(CSSM_CC_HANDLE ccHandle,
-       CSSM_CONTEXT_TYPE type, bool encoding)
-{
-       CSPContext *ctx = getContext<CSPContext>(ccHandle);
-       if (ctx == NULL)
-               CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);        //@@@ better diagnostic?
-       checkOperation(ctx->type(), type);
-       if (ctx->encoding() != encoding)
-               CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
-       return ctx;
-}
-
-
-//
-// The Session's checkState() function is called for subsequent staged operations
-// (update/final) to verify that the user didn't screw up the sequencing.
-//
-void CSPFullPluginSession::checkOperation(CSSM_CONTEXT_TYPE ctxType, CSSM_CONTEXT_TYPE opType)
-{
-    switch (opType) {
-        case CSSM_ALGCLASS_NONE:       // no check
-            return;
-        case CSSM_ALGCLASS_CRYPT:      // symmetric or asymmetric encryption
-            if (ctxType == CSSM_ALGCLASS_SYMMETRIC ||
-                ctxType == CSSM_ALGCLASS_ASYMMETRIC)
-                return;
-        default:                                       // plain match
-            if (ctxType == opType)
-                return;
-    }
-    CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
-}
-
-
-//
-// The default implementations of the primary context operations throw internal
-// errors. You must implement any of these that are actually called by the
-// operations involved. The others, of course, can be left alone.
-//
-void CSPContext::init(const Context &context, bool encoding)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-void CSPContext::update(const CssmData &data)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-void CSPContext::update(void *inp, size_t &inSize, void *outp, size_t &outSize)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-void CSPContext::final(CssmData &out)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-void CSPContext::final(const CssmData &in)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-void CSPContext::generate(const Context &, CssmKey &pubKey, CssmKey &privKey)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-void CSPContext::generate(const Context &, uint32, CssmData &params,
-                                                uint32 &attrCount, Context::Attr * &attrs)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-size_t CSPContext::inputSize(size_t outSize)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-size_t CSPContext::outputSize(bool final, size_t inSize)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-void CSPContext::minimumProgress(size_t &in, size_t &out)
-{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
-
-CSPFullPluginSession::CSPContext *CSPContext::clone(Allocator &)
-{ CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); }
-
-void CSPContext::setDigestAlgorithm(CSSM_ALGORITHMS digestAlg)
-{ CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); }
-
-void CSPContext::update(const CssmData *in,
-                                               uint32 inCount, Writer &writer)
-{
-    const CssmData *lastIn = in + inCount;
-    CssmData current;
-    for (;;) {
-        if (current.length() == 0) {
-            if (in == lastIn)
-                return;                // all done
-            current = *in++;
-                       continue; // Just in case next block is zero length too.
-        }
-        // match up current input and output buffers
-        void *outP; size_t outSize;
-        writer.nextBlock(outP, outSize);
-        size_t inSize = inputSize(outSize);
-        if (inSize > current.length())
-            inSize = current.length(); // cap to remaining input buffer
-        if (inSize > 0) {
-            // we can stuff into the current output buffer - do it
-            update(current.data(), inSize, outP, outSize);
-            current.use(inSize);
-            writer.use(outSize);
-        } else {
-            // We have remaining output buffer space, but not enough
-            // for the algorithm to make progress with it. We must proceed with
-            // a bounce buffer and split it manually into this and the next buffer(s).
-            size_t minOutput;
-            minimumProgress(inSize, minOutput);
-            assert(minOutput > outSize);               // PluginContext consistency (not fatal)
-            char splitBuffer[128];
-            assert(minOutput <= sizeof(splitBuffer)); // @@@ static buffer for now
-            outSize = sizeof(splitBuffer);
-            if (current.length() < inSize)
-                inSize = current.length();     // cap to data remaining in input buffer
-            update(current.data(), inSize, splitBuffer, outSize);
-            assert(inSize > 0);                                // progress made
-            writer.put(splitBuffer, outSize);  // stuff into buffer, the hard way
-            current.use(inSize);
-        }
-    }
-}
-
-void CSPContext::final(CssmData &out, Allocator &alloc)
-{
-    size_t needed = outputSize(true, 0);
-    if (out) {
-        if (out.length() < needed)
-            CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
-    } else {
-        out = makeBuffer(needed, alloc);
-    }
-    final(out);
-}
-
-void CSPContext::final(Writer &writer, Allocator &alloc)
-{
-    if (size_t needed = outputSize(true, 0)) {
-        // need to generate additional output
-        writer.allocate(needed, alloc);                // belt + suspender
-    
-        void *addr; size_t size;
-        writer.nextBlock(addr, size);          // next single block available
-        if (needed <= size) {                          // rest fits into one block
-            CssmData chunk(addr, size);
-            final(chunk);
-            writer.use(chunk.length());
-        } else {                                                       // need to split it up
-            char splitBuffer[128];
-            assert(needed <= sizeof(splitBuffer));
-            CssmData chunk(splitBuffer, sizeof(splitBuffer));
-            final(chunk);
-            writer.put(chunk.data(), chunk.length());
-        }
-    }
-}
-
-
-//
-// Default context response functions
-//
-CSPPluginSession::PluginContext *
-CSPPluginSession::contextCreate(CSSM_CC_HANDLE, const Context &)
-{
-       return NULL;    // request no local context
-}
-
-void CSPPluginSession::contextUpdate(CSSM_CC_HANDLE ccHandle,
-                                     const Context &context, PluginContext * &ctx)
-{
-    // call update notifier in context object
-    if (ctx && !ctx->changed(context)) {
-        // context requested that it be removed
-        delete ctx;
-        ctx = NULL;
-    }
-}
-
-void CSPPluginSession::contextDelete(CSSM_CC_HANDLE, const Context &, PluginContext *)
-{
-    // do nothing (you can't prohibit deletion here)
-}
-
-
-//
-// Default event notification handler.
-// This default handler calls the virtual context* methods to dispose of context actions.
-//
-void CSPPluginSession::EventNotify(CSSM_CONTEXT_EVENT event,
-                                   CSSM_CC_HANDLE ccHandle, const Context &context)
-{
-    switch (event) {
-        case CSSM_CONTEXT_EVENT_CREATE:
-            if (PluginContext *ctx = contextCreate(ccHandle, context)) {
-                               StLock<Mutex> _(contextMapLock);
-                assert(contextMap[ccHandle] == NULL);  // check context re-creation
-                contextMap[ccHandle] = ctx;
-            }
-            break;
-        case CSSM_CONTEXT_EVENT_UPDATE:
-            // note that the handler can change the map entry (even to NULL, if desired)
-                       {
-                               StLock<Mutex> _(contextMapLock);
-                               contextUpdate(ccHandle, context, contextMap[ccHandle]);
-                       }
-            break;
-        case CSSM_CONTEXT_EVENT_DELETE:
-                       {
-                               StLock<Mutex> _(contextMapLock);
-                               if (PluginContext *ctx = contextMap[ccHandle]) {
-                                       contextDelete(ccHandle, context, ctx);
-                                       delete ctx;
-                               }
-                               contextMap.erase(ccHandle);
-                       }
-                       break;
-        default:
-            CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);   // unexpected event code
-    }
-}
-
-
-//
-// Defaults for methods you *should* implement.
-// If you don't, they'll throw UNIMPLEMENTED.
-//
-void CSPFullPluginSession::getKeySize(const CssmKey &key, CSSM_KEY_SIZE &size)
-{ unimplemented(); }
-
-//
-// Encryption and decryption
-//
-void CSPFullPluginSession::EncryptData(CSSM_CC_HANDLE ccHandle,
-                                       const Context &context,
-                                       const CssmData clearBufs[],
-                                       uint32 clearBufCount,
-                                       CssmData cipherBufs[],
-                                       uint32 cipherBufCount,
-                                       CSSM_SIZE &bytesEncrypted,
-                                       CssmData &remData,
-                                       CSSM_PRIVILEGE privilege)
-{
-    Writer writer(cipherBufs, cipherBufCount, &remData);
-    CSPContext *ctx = init(ccHandle, CSSM_ALGCLASS_CRYPT, context, true);
-    size_t outNeeded = ctx->outputSize(true, totalBufferSize(clearBufs, clearBufCount));
-    writer.allocate(outNeeded, *this);
-    ctx->update(clearBufs, clearBufCount, writer);
-    ctx->final(writer, *this);
-    bytesEncrypted = writer.close();
-}
-
-void CSPFullPluginSession::EncryptDataInit(CSSM_CC_HANDLE ccHandle,
-                             const Context &context,
-                             CSSM_PRIVILEGE Privilege)
-{
-    init(ccHandle, CSSM_ALGCLASS_CRYPT, context, true);
-}
-
-void CSPFullPluginSession::EncryptDataUpdate(CSSM_CC_HANDLE ccHandle,
-                                         const CssmData clearBufs[],
-                                         uint32 clearBufCount,
-                                         CssmData cipherBufs[],
-                                         uint32 cipherBufCount,
-                                         CSSM_SIZE &bytesEncrypted)
-{
-    CSPContext *alg = getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, true);
-    Writer writer(cipherBufs, cipherBufCount);
-    size_t outNeeded = alg->outputSize(false, totalBufferSize(clearBufs, clearBufCount));
-    writer.allocate(outNeeded, *this);
-    alg->update(clearBufs, clearBufCount, writer);
-    bytesEncrypted = writer.close();
-}
-
-void CSPFullPluginSession::EncryptDataFinal(CSSM_CC_HANDLE ccHandle,
-                              CssmData &remData)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, true)->final(remData, *this);
-}
-
-
-void CSPFullPluginSession::DecryptData(CSSM_CC_HANDLE ccHandle,
-                                   const Context &context,
-                                   const CssmData cipherBufs[],
-                                   uint32 cipherBufCount,
-                                   CssmData clearBufs[],
-                                   uint32 clearBufCount,
-                                   CSSM_SIZE &bytesDecrypted,
-                                   CssmData &remData,
-                                   CSSM_PRIVILEGE privilege)
-{
-    Writer writer(clearBufs, clearBufCount, &remData);
-    CSPContext *ctx = init(ccHandle, CSSM_ALGCLASS_CRYPT, context, false);
-    size_t outNeeded = ctx->outputSize(true, totalBufferSize(cipherBufs, cipherBufCount));
-    writer.allocate(outNeeded, *this);
-    ctx->update(cipherBufs, cipherBufCount, writer);
-    ctx->final(writer, *this);
-    bytesDecrypted = writer.close();
-}
-
-void CSPFullPluginSession::DecryptDataInit(CSSM_CC_HANDLE ccHandle,
-                             const Context &context,
-                             CSSM_PRIVILEGE Privilege)
-{
-    init(ccHandle, CSSM_ALGCLASS_CRYPT, context, false);
-}
-
-void CSPFullPluginSession::DecryptDataUpdate(CSSM_CC_HANDLE ccHandle,
-                               const CssmData cipherBufs[],
-                               uint32 cipherBufCount,
-                               CssmData clearBufs[],
-                               uint32 clearBufCount,
-                               CSSM_SIZE &bytesDecrypted)
-{
-    CSPContext *ctx = getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, false);
-    Writer writer(clearBufs, clearBufCount);
-    size_t outNeeded = ctx->outputSize(false, totalBufferSize(cipherBufs, cipherBufCount));
-    writer.allocate(outNeeded, *this);
-    ctx->update(cipherBufs, cipherBufCount, writer);
-    bytesDecrypted = writer.close();
-}
-
-void CSPFullPluginSession::DecryptDataFinal(CSSM_CC_HANDLE ccHandle,
-                                      CssmData &remData)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, false)->final(remData, *this);
-}
-               
-void CSPFullPluginSession::QuerySize(CSSM_CC_HANDLE ccHandle,
-                                                                        const Context &context,
-                                                                        CSSM_BOOL encrypt,
-                                                                        uint32 querySizeCount,
-                                                                        QuerySizeData *dataBlock)
-{
-       if (querySizeCount == 0)
-               return; // nothing ventured, nothing gained
-       CSPContext *ctx = getContext<CSPContext>(ccHandle);     // existing context?
-       if (ctx == NULL)        // force internal context creation (as best we can)
-               ctx = init(ccHandle, context.type(), context, encrypt);
-       // If QuerySizeCount > 1, we assume this inquires about a staged
-       // operation, and the LAST item gets the 'final' treatment.
-       //@@@ Intel revised algspec says "use the staged flag" -- TBD
-       for (uint32 n = 0; n < querySizeCount; n++) {
-               // the outputSize() call might throw CSSMERR_CSP_QUERY_SIZE_UNKNOWN
-               dataBlock[n].SizeOutputBlock =
-                       (uint32)ctx->outputSize(n == querySizeCount-1, dataBlock[n].inputSize());
-       }
-       //@@@ if we forced a context creation, should we discard it now?
-}
-
-
-//
-// Key wrapping and unwrapping.
-//
-void CSPFullPluginSession::WrapKey(CSSM_CC_HANDLE CCHandle,
-                                                               const Context &Context,
-                                                               const AccessCredentials &AccessCred,
-                                                               const CssmKey &Key,
-                                                               const CssmData *DescriptiveData,
-                                                               CssmKey &WrappedKey,
-                                                               CSSM_PRIVILEGE Privilege)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::UnwrapKey(CSSM_CC_HANDLE CCHandle,
-                                                               const Context &Context,
-                                                               const CssmKey *PublicKey,
-                                                               const CssmKey &WrappedKey,
-                                                               uint32 KeyUsage,
-                                                               uint32 KeyAttr,
-                                                               const CssmData *KeyLabel,
-                                                               const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
-                                                               CssmKey &UnwrappedKey,
-                                                               CssmData &DescriptiveData,
-                                                               CSSM_PRIVILEGE Privilege)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::DeriveKey(CSSM_CC_HANDLE CCHandle,
-                                                       const Context &Context,
-                                                       CssmData &Param,
-                                                       uint32 KeyUsage,
-                                                       uint32 KeyAttr,
-                                                       const CssmData *KeyLabel,
-                                                       const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
-                                                       CssmKey &DerivedKey)
-{
-       unimplemented();
-}
-
-
-//
-// Message Authentication Codes.
-// Almost like signatures (signatures with symmetric keys), though the
-// underlying implementation may be somewhat different.
-//
-void CSPFullPluginSession::GenerateMac(CSSM_CC_HANDLE ccHandle,
-                                   const Context &context,
-                                   const CssmData dataBufs[],
-                                   uint32 dataBufCount,
-                                   CssmData &mac)
-{
-    GenerateMacInit(ccHandle, context);
-    GenerateMacUpdate(ccHandle, dataBufs, dataBufCount);
-    GenerateMacFinal(ccHandle, mac);
-}
-
-void CSPFullPluginSession::GenerateMacInit(CSSM_CC_HANDLE ccHandle,
-                                           const Context &context)
-{
-    init(ccHandle, CSSM_ALGCLASS_MAC, context, true);
-}
-
-void CSPFullPluginSession::GenerateMacUpdate(CSSM_CC_HANDLE ccHandle,
-                                             const CssmData dataBufs[],
-                                             uint32 dataBufCount)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, true)->update(dataBufs, dataBufCount);
-}
-
-void CSPFullPluginSession::GenerateMacFinal(CSSM_CC_HANDLE ccHandle,
-                                            CssmData &mac)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, true)->final(mac, *this);
-}
-
-void CSPFullPluginSession::VerifyMac(CSSM_CC_HANDLE ccHandle,
-                                     const Context &context,
-                                     const CssmData dataBufs[],
-                                     uint32 dataBufCount,
-                                     const CssmData &mac)
-{
-    VerifyMacInit(ccHandle, context);
-    VerifyMacUpdate(ccHandle, dataBufs, dataBufCount);
-    VerifyMacFinal(ccHandle, mac);
-}
-
-void CSPFullPluginSession::VerifyMacInit(CSSM_CC_HANDLE ccHandle,
-                                         const Context &context)
-{
-    init(ccHandle, CSSM_ALGCLASS_MAC, context, false);
-}
-
-void CSPFullPluginSession::VerifyMacUpdate(CSSM_CC_HANDLE ccHandle,
-                                           const CssmData dataBufs[],
-                                           uint32 dataBufCount)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, false)->update(dataBufs, dataBufCount);
-}
-
-void CSPFullPluginSession::VerifyMacFinal(CSSM_CC_HANDLE ccHandle,
-                                          const CssmData &mac)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, false)->final(mac);
-}
-
-
-//
-// Signatures
-//
-void CSPFullPluginSession::SignData(CSSM_CC_HANDLE ccHandle,
-                                const Context &context,
-                                const CssmData dataBufs[],
-                                uint32 dataBufCount,
-                                CSSM_ALGORITHMS digestAlgorithm,
-                                CssmData &Signature)
-{
-       SignDataInit(ccHandle, context);
-       if(digestAlgorithm != CSSM_ALGID_NONE) {
-               getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, 
-                       true)->setDigestAlgorithm(digestAlgorithm);
-       }
-       SignDataUpdate(ccHandle, dataBufs, dataBufCount);
-       SignDataFinal(ccHandle, Signature);
-}
-
-void CSPFullPluginSession::SignDataInit(CSSM_CC_HANDLE ccHandle,
-                                    const Context &context)
-{
-    init(ccHandle, CSSM_ALGCLASS_SIGNATURE, context, true);
-}
-
-void CSPFullPluginSession::SignDataUpdate(CSSM_CC_HANDLE ccHandle,
-                    const CssmData dataBufs[],
-                    uint32 dataBufCount)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, true)->update(dataBufs, dataBufCount);
-}
-
-void CSPFullPluginSession::SignDataFinal(CSSM_CC_HANDLE ccHandle,
-                           CssmData &signature)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, true)->final(signature, *this);
-}
-
-
-void CSPFullPluginSession::VerifyData(CSSM_CC_HANDLE ccHandle,
-                                  const Context &context,
-                                  const CssmData dataBufs[],
-                                  uint32 dataBufCount,
-                                  CSSM_ALGORITHMS digestAlgorithm,
-                                  const CssmData &Signature)
-{
-       VerifyDataInit(ccHandle, context);
-       if(digestAlgorithm != CSSM_ALGID_NONE) {
-               getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, 
-                       false)->setDigestAlgorithm(digestAlgorithm);
-       }
-       VerifyDataUpdate(ccHandle, dataBufs, dataBufCount);
-       VerifyDataFinal(ccHandle, Signature);
-}
-
-void CSPFullPluginSession::VerifyDataInit(CSSM_CC_HANDLE ccHandle, const Context &context)
-{
-    init(ccHandle, CSSM_ALGCLASS_SIGNATURE, context, false);
-}
-
-void CSPFullPluginSession::VerifyDataUpdate(CSSM_CC_HANDLE ccHandle,
-                                        const CssmData dataBufs[],
-                                        uint32 dataBufCount)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, false)->update(dataBufs, dataBufCount);
-}
-
-void CSPFullPluginSession::VerifyDataFinal(CSSM_CC_HANDLE ccHandle,
-                     const CssmData &signature)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, false)->final(signature);
-}
-
-
-//
-// Digesting
-//
-void CSPFullPluginSession::DigestData(CSSM_CC_HANDLE ccHandle,
-               const Context &context,
-               const CssmData dataBufs[],
-               uint32 DataBufCount,
-               CssmData &Digest)
-{
-    DigestDataInit(ccHandle, context);
-    DigestDataUpdate(ccHandle, dataBufs, DataBufCount);
-    DigestDataFinal(ccHandle, Digest);
-}
-
-void CSPFullPluginSession::DigestDataInit(CSSM_CC_HANDLE ccHandle, const Context &context)
-{
-    init(ccHandle, CSSM_ALGCLASS_DIGEST, context);
-}
-
-void CSPFullPluginSession::DigestDataUpdate(CSSM_CC_HANDLE ccHandle,
-                              const CssmData dataBufs[],
-                              uint32 dataBufCount)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_DIGEST)->update(dataBufs, dataBufCount);
-}
-
-void CSPFullPluginSession::DigestDataFinal(CSSM_CC_HANDLE ccHandle,
-                                           CssmData &digest)
-{
-    getStagedContext(ccHandle, CSSM_ALGCLASS_DIGEST)->final(digest, *this);
-}
-
-void CSPFullPluginSession::DigestDataClone(CSSM_CC_HANDLE ccHandle,
-                                           CSSM_CC_HANDLE clonedCCHandle)
-{
-    CSPContext *cloned = getStagedContext(ccHandle, CSSM_ALGCLASS_DIGEST)->clone(*this);
-    cloned->mDirection = true;
-    cloned->mType = CSSM_ALGCLASS_DIGEST;
-    setContext(clonedCCHandle, cloned);
-}
-
-
-//
-// Key generation, Derivation, and inquiry
-//
-void CSPFullPluginSession::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)
-{
-    CSPContext *alg = init(ccHandle, CSSM_ALGCLASS_KEYGEN, context);
-    setKey(key, context, CSSM_KEYCLASS_SESSION_KEY, keyAttr, keyUsage);
-    CssmKey blank;             // dummy 2nd key (not used)
-    alg->generate(context, key, blank);
-}
-
-class ContextMinder
-{
-private:
-       CSSM_CC_HANDLE mHandle;
-
-public:
-       ContextMinder(CSSM_CC_HANDLE ccHandle) : mHandle(ccHandle) {}
-       ~ContextMinder() {CSSM_DeleteContext(mHandle);}
-};
-
-
-
-void CSPFullPluginSession::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)
-{
-    CSPContext *alg = init(ccHandle, CSSM_ALGCLASS_KEYGEN, context);
-    
-    setKey(publicKey, context, CSSM_KEYCLASS_PUBLIC_KEY, publicKeyAttr, publicKeyUsage);
-    setKey(privateKey, context, CSSM_KEYCLASS_PRIVATE_KEY, privateKeyAttr, privateKeyUsage);
-    alg->generate(context, publicKey, privateKey);
-       
-    //@@@ handle labels
-    //@@@ handle reference keys
-
-       bool encryptPublic = publicKeyUsage & CSSM_KEYUSE_ENCRYPT;
-       bool encryptPrivate = privateKeyUsage & CSSM_KEYUSE_ENCRYPT;
-
-       if (!(encryptPublic || encryptPrivate))
-       {
-               return ;
-       }
-       
-       // time to do the FIPS required test!
-       CSSM_CSP_HANDLE moduleHandle = handle();
-       CSSM_CC_HANDLE encryptHandle;
-       CSSM_ACCESS_CREDENTIALS nullCreds;
-       memset(&nullCreds, 0, sizeof(nullCreds));
-
-       CSSM_KEY_PTR encryptingKey, decryptingKey;
-       if (encryptPublic)
-       {
-               encryptingKey = &publicKey;
-               decryptingKey = &privateKey;
-       }
-       else
-       {
-               encryptingKey = &privateKey;
-               decryptingKey = &publicKey;
-       }
-       
-       // make data to be encrypted
-       unsigned bytesInKey = encryptingKey->KeyHeader.LogicalKeySizeInBits / 8;
-       u_int8_t buffer[bytesInKey];
-       unsigned i;
-       
-       for (i = 0; i < bytesInKey; ++i)
-       {
-               buffer[i] = i;
-       }
-       
-       CSSM_DATA clearBuf = {bytesInKey, buffer};
-       CSSM_DATA cipherBuf; // have the CSP allocate the resulting memory
-       CSSM_SIZE bytesEncrypted;
-       CSSM_DATA remData = {0, NULL};
-       CSSM_DATA decryptedBuf = {bytesInKey, buffer};
-       
-       CSSM_RETURN result = CSSM_CSP_CreateAsymmetricContext(moduleHandle, encryptingKey->KeyHeader.AlgorithmId,  &nullCreds, encryptingKey, CSSM_PADDING_NONE, &encryptHandle);
-       if (result != CSSM_OK)
-       {
-               CssmError::throwMe(result);
-       }
-       
-       ContextMinder encryptMinder(encryptHandle); // auto throw away if we error out
-       
-       CSSM_QUERY_SIZE_DATA qsData;
-       qsData.SizeInputBlock = bytesInKey;
-       result = CSSM_QuerySize(encryptHandle, CSSM_TRUE, 1, &qsData);
-       if (result == CSSMERR_CSP_INVALID_ALGORITHM)
-       {
-               return;
-       }
-       
-       uint8 cipherBuffer[qsData.SizeOutputBlock];
-       cipherBuf.Length = qsData.SizeOutputBlock;
-       cipherBuf.Data = cipherBuffer;
-
-       // do the encryption
-       result = CSSM_EncryptData(encryptHandle, &clearBuf, 1, &cipherBuf, 1, &bytesEncrypted, &remData);
-       if (result != CSSM_OK)
-       {
-               CssmError::throwMe(result);
-       }
-       
-       // check the result
-       if (memcmp(cipherBuf.Data, clearBuf.Data, clearBuf.Length) == 0)
-       {
-               // we have a match, that's not good news...
-               abort();
-       }
-       
-       // clean up
-       if (remData.Data != NULL)
-       {
-               free(remData.Data);
-       }
-       
-       // make a context to perform the decryption
-       CSSM_CC_HANDLE decryptHandle;
-       result = CSSM_CSP_CreateAsymmetricContext(moduleHandle, encryptingKey->KeyHeader.AlgorithmId, &nullCreds, decryptingKey, CSSM_PADDING_NONE, &decryptHandle);
-       ContextMinder decryptMinder(decryptHandle);
-
-       if (result != CSSM_OK)
-       {
-               CssmError::throwMe(result);
-       }
-       
-       result = CSSM_DecryptData(decryptHandle, &cipherBuf, 1, &decryptedBuf, 1, &bytesEncrypted, &remData);
-       if (result != CSSM_OK)
-       {
-               CssmError::throwMe(result);
-       }
-       
-       // check the results
-       for (i = 0; i < bytesInKey; ++i)
-       {
-               if (decryptedBuf.Data[i] != (i & 0xFF))
-               {
-                       // bad news
-                       abort();
-               }
-       }
-       
-       if (remData.Data != NULL)
-       {
-               free(remData.Data);
-       }
-}
-
-void CSPFullPluginSession::ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
-                                                                                                                CssmKey &PrivateKey)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::QueryKeySizeInBits(CSSM_CC_HANDLE ccHandle,
-                                               const Context *context,
-                                               const CssmKey *key,
-                                               CSSM_KEY_SIZE &keySize)
-{
-       if (context) {
-               getKeySize(context->get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY),
-                       keySize);
-       } else {
-               getKeySize(CssmKey::required(key), keySize);
-       }
-}
-
-
-//
-// Free a key object.
-//
-void CSPFullPluginSession::FreeKey(const AccessCredentials *AccessCred,
-                                                                  CssmKey &key,
-                                                                  CSSM_BOOL Delete)
-{
-       free(key.data());
-}
-
-
-//
-// Random number and parameter generation
-//
-void CSPFullPluginSession::GenerateRandom(CSSM_CC_HANDLE ccHandle,
-                                          const Context &context,
-                                          CssmData &randomNumber)
-{
-    init(ccHandle, CSSM_ALGCLASS_RANDOMGEN, context)->final(randomNumber, *this);
-}
-
-void CSPFullPluginSession::GenerateAlgorithmParams(CSSM_CC_HANDLE ccHandle,
-                                    const Context &context,
-                                    uint32 paramBits,
-                                    CssmData &param,
-                                    uint32 &attrCount,
-                                    CSSM_CONTEXT_ATTRIBUTE_PTR &attrs)
-{
-    Context::Attr *attrList;
-    init(ccHandle, CSSM_ALGCLASS_NONE, context)->generate(context, paramBits,
-                                                          param, attrCount, attrList);
-    attrs = attrList;
-}
-
-
-//
-// 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 CSPFullPluginSession::Login(const AccessCredentials &AccessCred,
-                       const CssmData *LoginName,
-                       const void *Reserved)
-{
-       if (Reserved != NULL)
-               CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
-               
-       // default implementation refuses to log in
-       //@@@ should hand it to implementation virtual defaulting to this
-       CssmError::throwMe(CSSMERR_CSP_INVALID_LOGIN_NAME);
-}
-
-void CSPFullPluginSession::Logout()
-{
-       if (!loggedIn(false))
-               CssmError::throwMe(CSSMERR_CSP_NOT_LOGGED_IN);
-}
-
-void CSPFullPluginSession::VerifyDevice(const CssmData &DeviceCert)
-{
-       CssmError::throwMe(CSSMERR_CSP_DEVICE_VERIFY_FAILED);
-}
-
-void CSPFullPluginSession::GetOperationalStatistics(CSPOperationalStatistics &statistics)
-{
-       memset(&statistics, 0, sizeof(statistics));
-       statistics.UserAuthenticated = loggedIn();
-       //@@@ collect device flags - capability matrix setup?
-       //@@@ collect token limitation parameters (static) - capability matrix setup?
-       //@@@ collect token statistics (dynamic) - dynamic accounting call-downs?
-}
-
-
-//
-// Utterly miscellaneous, rarely used, strange functions
-//
-void CSPFullPluginSession::RetrieveCounter(CssmData &Counter)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::RetrieveUniqueId(CssmData &UniqueID)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm, CssmData &TimeData)
-{
-       unimplemented();
-}
-
-
-//
-// ACL retrieval and change operations
-//
-void CSPFullPluginSession::GetKeyOwner(const CssmKey &Key,
-               CSSM_ACL_OWNER_PROTOTYPE &Owner)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::ChangeKeyOwner(const AccessCredentials &AccessCred,
-               const CssmKey &Key,
-               const CSSM_ACL_OWNER_PROTOTYPE &NewOwner)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::GetKeyAcl(const CssmKey &Key,
-               const CSSM_STRING *SelectionTag,
-               uint32 &NumberOfAclInfos,
-               CSSM_ACL_ENTRY_INFO_PTR &AclInfos)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::ChangeKeyAcl(const AccessCredentials &AccessCred,
-               const CSSM_ACL_EDIT &AclEdit,
-               const CssmKey &Key)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE &Owner)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::ChangeLoginOwner(const AccessCredentials &AccessCred,
-               const CSSM_ACL_OWNER_PROTOTYPE &NewOwner)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::GetLoginAcl(const CSSM_STRING *SelectionTag,
-               uint32 &NumberOfAclInfos,
-               CSSM_ACL_ENTRY_INFO_PTR &AclInfos)
-{
-       unimplemented();
-}
-
-void CSPFullPluginSession::ChangeLoginAcl(const AccessCredentials &AccessCred,
-               const CSSM_ACL_EDIT &AclEdit)
-{
-       unimplemented();
-}
-
-
-
-//
-// Passthroughs (by default, unimplemented)
-//
-void CSPFullPluginSession::PassThrough(CSSM_CC_HANDLE CCHandle,
-                                                                               const Context &Context,
-                                                                               uint32 PassThroughId,
-                                                                               const void *InData,
-                                                                               void **OutData)
-{
-       unimplemented();
-}
-
-
-//
-// KeyPool -- ReferencedKey management functionality
-//
-KeyPool::KeyPool()
-{
-}
-
-KeyPool::~KeyPool()
-{
-       StLock<Mutex> _(mKeyMapLock);
-       // Delete every ReferencedKey in the pool, but be careful to deactivate them first
-       // to keep them from calling erase (which would cause deadlock since we already hold mKeyMapLock).
-       KeyMap::iterator end = mKeyMap.end();
-       for (KeyMap::iterator it = mKeyMap.begin(); it != end; ++it)
-       {
-               try
-               {
-                       it->second->deactivate();
-               }
-               catch(...) {}
-               delete it->second;
-       }
-       mKeyMap.clear();
-}
-
-void
-KeyPool::add(ReferencedKey &referencedKey)
-{
-       StLock<Mutex> _(mKeyMapLock);
-       bool inserted;
-    inserted = mKeyMap.insert(KeyMap::value_type(referencedKey.keyReference(), &referencedKey)).second;
-       // Since add is only called from the constructor of ReferencedKey we should
-       // never add a key that is already in mKeyMap
-       assert(inserted);
-}
-
-ReferencedKey &
-KeyPool::findKey(const CSSM_KEY &key) const
-{
-       return findKeyReference(ReferencedKey::keyReference(key));
-}
-
-ReferencedKey &
-KeyPool::findKeyReference(ReferencedKey::KeyReference keyReference) const
-{
-       StLock<Mutex> _(mKeyMapLock);
-       KeyMap::const_iterator it = mKeyMap.find(keyReference);
-       if (it == mKeyMap.end())
-               CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
-
-       return *it->second;
-}
-
-void
-KeyPool::erase(ReferencedKey &referencedKey)
-{
-       erase(referencedKey.keyReference());
-}
-
-ReferencedKey &
-KeyPool::erase(ReferencedKey::KeyReference keyReference)
-{
-       StLock<Mutex> _(mKeyMapLock);
-       KeyMap::iterator it = mKeyMap.find(keyReference);
-       if (it == mKeyMap.end())
-               CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
-
-       ReferencedKey &referencedKey = *it->second;
-       mKeyMap.erase(it);
-       return referencedKey;
-}
-
-// Erase keyReference from mKeyMap, free the ioKey, and delete the ReferencedKey
-void
-KeyPool::freeKey(Allocator &allocator, CSSM_KEY &ioKey)
-{
-       delete &erase(ReferencedKey::freeReferenceKey(allocator, ioKey));
-}
-
-//
-// ReferencedKey class
-//
-ReferencedKey::ReferencedKey(KeyPool &keyPool) : mKeyPool(&keyPool)
-{
-       mKeyPool->add(*this);
-}
-
-ReferencedKey::~ReferencedKey()
-{
-       if (isActive())
-               mKeyPool->erase(*this);
-}
-
-ReferencedKey::KeyReference
-ReferencedKey::keyReference()
-{
-       // @@@ Possibly check isActive() and return an invalid reference if it is not set.
-       return reinterpret_cast<ReferencedKey::KeyReference>(this);
-}
-
-//
-// Making, retrieving and freeing Key references of CssmKeys
-//
-void
-ReferencedKey::makeReferenceKey(Allocator &allocator, KeyReference keyReference, CSSM_KEY &key)
-{
-       key.KeyHeader.BlobType = CSSM_KEYBLOB_REFERENCE;
-       key.KeyHeader.Format = CSSM_KEYBLOB_REF_FORMAT_INTEGER;
-       key.KeyData.Length = sizeof(KeyReference);
-       key.KeyData.Data = allocator.alloc<uint8>(sizeof(KeyReference));
-       uint8 *cp = key.KeyData.Data;
-       for (int i = sizeof(KeyReference); --i >= 0;)
-       {
-               cp[i] = keyReference & 0xff;
-               keyReference = keyReference >> 8;
-       }
-}
-
-ReferencedKey::KeyReference
-ReferencedKey::keyReference(const CSSM_KEY &key)
-{
-       if (key.KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE
-               || key.KeyHeader.Format != CSSM_KEYBLOB_REF_FORMAT_INTEGER
-               || key.KeyData.Length != sizeof(KeyReference)
-               || key.KeyData.Data == NULL)
-               CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
-
-       const uint8 *cp = key.KeyData.Data;
-       KeyReference keyReference = 0;
-       for (uint32 i = 0; i < sizeof(KeyReference); ++i)
-               keyReference = (keyReference << 8) + cp[i];
-
-       return keyReference;
-}
-
-ReferencedKey::KeyReference
-ReferencedKey::freeReferenceKey(Allocator &allocator, CSSM_KEY &key)
-{
-       KeyReference aKeyReference = keyReference(key);
-       allocator.free(key.KeyData.Data);
-       key.KeyData.Data = NULL;
-       key.KeyData.Length = 0;
-       return aKeyReference;
-}