+++ /dev/null
-/*
- * Copyright (c) 2000-2004,2011-2012,2014 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The 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.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-//
-// transition - transition layer for CSSM API/SPI calls.
-//
-// This file defines all functions that connect the CSSM API (CSSM_*)
-// to a plugin's SPI (CSSM_SPI_*) functions. The bulk of these functions
-// is automatically generated by the Perl script transition.pl (thanks, Larry!)
-// from the cssm*.h official header files, under control of the configuration
-// file transition.cfg. Those that need special magic are marked "custom" in
-// transition.cfg and are defined here.
-//
-// @@@ Reconsider CSP locking for context operations
-//
-#include "cssmint.h"
-#include "attachfactory.h"
-#include "manager.h"
-#include "cssmcontext.h"
-#include <Security/cssmcspi.h>
-#include <Security/cssmdli.h>
-#include <Security/cssmcli.h>
-#include <Security/cssmaci.h>
-#include <Security/cssmtpi.h>
-#include <Security/cssmkrapi.h>
-#include <Security/cssmkrspi.h>
-#include <security_cdsa_utilities/cssmbridge.h>
-
-
-//
-// Names for the standard Attachment types
-//
-typedef StandardAttachment<CSSM_SERVICE_CSP, CSSM_SPI_CSP_FUNCS> CSPAttachment;
-typedef StandardAttachment<CSSM_SERVICE_DL, CSSM_SPI_DL_FUNCS> DLAttachment;
-typedef StandardAttachment<CSSM_SERVICE_CL, CSSM_SPI_CL_FUNCS> CLAttachment;
-typedef StandardAttachment<CSSM_SERVICE_AC, CSSM_SPI_AC_FUNCS> ACAttachment;
-typedef StandardAttachment<CSSM_SERVICE_TP, CSSM_SPI_TP_FUNCS> TPAttachment;
-
-
-//
-// A conditional locking class for always-right(TM) lock management.
-//
-class TransitLock {
-public:
- Attachment &attachment;
-
- TransitLock(Attachment &att) : attachment(att)
- {
- attachment.module.safeLock();
- }
-
- ~TransitLock()
- {
- attachment.module.safeUnlock();
- attachment.exit();
- }
-};
-
-
-//
-// Context management functions
-//
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateSignatureContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- const CSSM_ACCESS_CREDENTIALS *AccessCred,
- const CSSM_KEY *Key,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.setup(AccessCred);
- maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
- maker.put(CSSM_ATTRIBUTE_KEY, Key);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_SIGNATURE, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateSymmetricContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- CSSM_ENCRYPT_MODE Mode,
- const CSSM_ACCESS_CREDENTIALS *AccessCred,
- const CSSM_KEY *Key,
- const CSSM_DATA *InitVector,
- CSSM_PADDING Padding,
- void *Reserved,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- if (Reserved != NULL)
- CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
- HandleContext::Maker maker(CSPHandle);
- maker.setup(Mode);
- maker.setup(AccessCred);
- maker.setup(Key);
- maker.setup(InitVector);
- maker.setup(Padding);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_MODE, Mode);
- maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
- maker.put(CSSM_ATTRIBUTE_KEY, Key);
- maker.put(CSSM_ATTRIBUTE_INIT_VECTOR, InitVector);
- maker.put(CSSM_ATTRIBUTE_PADDING, Padding);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_SYMMETRIC, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateDigestContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.make();
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_DIGEST, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateMacContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- const CSSM_KEY *Key,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_KEY, Key);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_MAC, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateRandomGenContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- const CSSM_CRYPTO_DATA *Seed,
- CSSM_SIZE Length,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.setup(Seed);
- maker.setup(Length, CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_SEED, Seed);
- maker.put(CSSM_ATTRIBUTE_OUTPUT_SIZE, (uint32_t)Length);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_RANDOMGEN, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateAsymmetricContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- const CSSM_ACCESS_CREDENTIALS *AccessCred,
- const CSSM_KEY *Key,
- CSSM_PADDING Padding,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.setup(AccessCred, CSSMERR_CSP_MISSING_ATTR_ACCESS_CREDENTIALS);
- maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
- maker.setup(Padding);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
- maker.put(CSSM_ATTRIBUTE_KEY, Key);
- maker.put(CSSM_ATTRIBUTE_PADDING, Padding);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_ASYMMETRIC, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateDeriveKeyContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- CSSM_KEY_TYPE DeriveKeyType,
- uint32 DeriveKeyLengthInBits,
- const CSSM_ACCESS_CREDENTIALS *AccessCred,
- const CSSM_KEY *BaseKey,
- uint32 IterationCount,
- const CSSM_DATA *Salt,
- const CSSM_CRYPTO_DATA *Seed,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.setup(DeriveKeyType, CSSMERR_CSP_INVALID_ATTR_KEY_TYPE);
- maker.setup(DeriveKeyLengthInBits, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH);
- maker.setup(AccessCred);
- maker.setup(BaseKey);
- maker.setup(IterationCount);
- maker.setup(Salt);
- maker.setup(Seed);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_KEY_TYPE, DeriveKeyType);
- maker.put(CSSM_ATTRIBUTE_KEY_LENGTH, DeriveKeyLengthInBits);
- maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
- maker.put(CSSM_ATTRIBUTE_KEY, BaseKey);
- maker.put(CSSM_ATTRIBUTE_ITERATION_COUNT, IterationCount);
- maker.put(CSSM_ATTRIBUTE_SALT, Salt);
- maker.put(CSSM_ATTRIBUTE_SEED, Seed);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_DERIVEKEY, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreateKeyGenContext (CSSM_CSP_HANDLE CSPHandle,
- CSSM_ALGORITHMS AlgorithmID,
- uint32 KeySizeInBits,
- const CSSM_CRYPTO_DATA *Seed,
- const CSSM_DATA *Salt,
- const CSSM_DATE *StartDate,
- const CSSM_DATE *EndDate,
- const CSSM_DATA *Params,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.setup(KeySizeInBits, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH);
- maker.setup(Seed);
- maker.setup(Salt);
- maker.setup(StartDate);
- maker.setup(EndDate);
- maker.setup(Params);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_KEY_LENGTH, KeySizeInBits);
- maker.put(CSSM_ATTRIBUTE_SEED, Seed);
- maker.put(CSSM_ATTRIBUTE_SALT, Salt);
- maker.put(CSSM_ATTRIBUTE_START_DATE, StartDate);
- maker.put(CSSM_ATTRIBUTE_END_DATE, EndDate);
- maker.put(CSSM_ATTRIBUTE_ALG_PARAMS, Params);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_KEYGEN, AlgorithmID);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_CSP_CreatePassThroughContext (CSSM_CSP_HANDLE CSPHandle,
- const CSSM_KEY *Key,
- CSSM_CC_HANDLE *NewContextHandle)
-{
- BEGIN_API
- HandleContext::Maker maker(CSPHandle);
- maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
- maker.make();
- maker.put(CSSM_ATTRIBUTE_KEY, Key);
- Required(NewContextHandle) = maker(CSSM_ALGCLASS_NONE, CSSM_ALGID_NONE);
- END_API(CSSM)
-}
-
-
-//
-// CSSM_GetContext makes a deep copy of a CSP context and hands it to the
-// caller. The result is NOT a HandleContext, but a bare Context that is
-// in no dictionaries etc. User must delete it by calling CSSM_FreeContext.
-//
-CSSM_RETURN CSSMAPI
-CSSM_GetContext (CSSM_CC_HANDLE CCHandle,
- CSSM_CONTEXT_PTR *ContextP)
-{
- BEGIN_API
-#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
- HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
- Context *newContext = new(context.attachment) Context(context.type(), context.algorithm());
- try {
- newContext->CSPHandle = context.attachment.handle();
- newContext->copyFrom(context, context.attachment);
- Required(ContextP) = newContext;
- } catch (...) {
- context.attachment.free(newContext);
- throw;
- }
- END_API(CSSM)
-}
-
-
-//
-// Since we allocated all the data in one fell heap, our FreeContext
-// function is disappointingly simple.
-//
-CSSM_RETURN CSSMAPI
-CSSM_FreeContext (CSSM_CONTEXT_PTR ContextP)
-{
- BEGIN_API
- Context *context = &Context::required(ContextP);
- context->destroy(context, HandleObject::find<CSPAttachment>(context->CSPHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE));
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_SetContext (CSSM_CC_HANDLE CCHandle,
- const CSSM_CONTEXT *ContextP)
-{
- BEGIN_API
- const Context &source = Context::required(ContextP);
-#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
- HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
-
- CSSM_CONTEXT_ATTRIBUTE *oldAttributes = context.ContextAttributes;
- uint32 oldCount = context.NumberOfAttributes;
- CSSM_CONTEXT_TYPE oldType = context.ContextType;
- CSSM_ALGORITHMS oldAlgorithm = context.AlgorithmType;
-
- context.copyFrom(source, context.attachment);
- context.ContextType = source.ContextType;
- context.AlgorithmType = source.AlgorithmType;
-
- if (CSSM_RETURN err = context.validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
- context.attachment.free(context.ContextAttributes); // free rejected attribute blob
- context.ContextAttributes = oldAttributes; // restore...
- context.NumberOfAttributes = oldCount; // ... old
- context.ContextType = oldType; // ... values
- context.AlgorithmType = oldAlgorithm; // ... in context
- CssmError::throwMe(err); // tell the caller it failed
- }
-
- context.attachment.free(oldAttributes);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_DeleteContext (CSSM_CC_HANDLE CCHandle)
-{
- BEGIN_API
- HandleContext &context = enterContext(CCHandle);
- StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit>
- _(context.attachment, true);
-
- // ignore error return from CSP event notify (can't decline deletion)
- context.validateChange(CSSM_CONTEXT_EVENT_DELETE);
-
- context.destroy(&context, context.attachment);
- END_API(CSSM)
-}
-
-
-//
-// The GetContextAttribute API is fatally flawed. The standard implies a deep
-// copy of the attribute value, but no release function exists. Instead, we
-// return a shallow copy (sharing structure) which you need not release, but
-// which becomes invalid when the source Context is destroyed.
-//
-CSSM_RETURN CSSMAPI
-CSSM_GetContextAttribute (const CSSM_CONTEXT *Context,
- uint32 AttributeType,
- CSSM_CONTEXT_ATTRIBUTE_PTR *ContextAttribute)
-{
- BEGIN_API
- CSSM_ATTRIBUTE_TYPE type = CSSM_ATTRIBUTE_TYPE(AttributeType); // CDSA defect
- Required(ContextAttribute) = Context::required(Context).find(type);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_UpdateContextAttributes (CSSM_CC_HANDLE CCHandle,
- uint32 NumberAttributes,
- const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes)
-{
- BEGIN_API
-#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
- HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
- context.mergeAttributes(ContextAttributes, NumberAttributes);
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_DeleteContextAttributes (CSSM_CC_HANDLE CCHandle,
- uint32 NumberOfAttributes,
- const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes)
-{
- BEGIN_API
- if (NumberOfAttributes == 0)
- return CSSM_OK; // I suppose
- Required(ContextAttributes); // preflight
-#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
- HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
- for (uint32 n = 0; n < NumberOfAttributes; n++)
- context.deleteAttribute(ContextAttributes[n].AttributeType);
- END_API(CSSM)
-}
-
-
-//
-// Miscellaneous odds and ends - these functions just need a wee bit of
-// manual massaging to fit.
-//
-CSSM_RETURN CSSMAPI
-CSSM_DigestDataClone (CSSM_CC_HANDLE ccHandle,
- CSSM_CC_HANDLE *newCCHandle)
-{
- BEGIN_API
-#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
- HandleContext &context = HandleObject::findAndLock<HandleContext>((CSSM_HANDLE)ccHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
- TransitLock _(context.attachment);
- HandleContext *newContext =
- new(context.attachment) HandleContext(context.attachment, context.type(), context.algorithm());
- try {
- newContext->CSPHandle = context.attachment.handle();
- newContext->copyFrom(context, context.attachment);
- context.attachment.downcalls.DigestDataClone(context.attachment.handle(), ccHandle, newContext->handle());
- Required(newCCHandle) = newContext->handle();
- } catch (...) {
- newContext->destroy(newContext, context.attachment);
- throw;
- }
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_QueryKeySizeInBits (CSSM_CSP_HANDLE CSPHandle,
- CSSM_CC_HANDLE ccHandle,
- const CSSM_KEY *key,
- CSSM_KEY_SIZE_PTR keySize)
-{
- //@@@ could afford not to lock attachment in have-CC case
- BEGIN_API
- Required(keySize);
- Context *context;
- CSPAttachment *attachment;
- if (ccHandle == (CSSM_CC_HANDLE) HandleObject::invalidHandle) {
- // key specified by CSPHandle and Key
- attachment = &enterAttachment<CSPAttachment>(CSPHandle);
- context = NULL;
- } else {
- // key specified by ccHandle
- HandleContext *ctx = &enterContext(ccHandle);
- try {
- attachment = &ctx->attachment;
- context = ctx;
- CSPHandle = context->CSPHandle;
- key = &context->get<CssmKey>(CSSM_ATTRIBUTE_KEY,
- CSSMERR_CSP_INVALID_KEY);
- } catch (...) {
- attachment->exit();
- throw;
- }
- }
- TransitLock _(*attachment);
- CSSM_RETURN result = attachment->downcalls.QueryKeySizeInBits(CSPHandle,
- ccHandle, context, key, keySize);
- return result;
- END_API(CSSM)
-}
-
-
-CSSM_RETURN CSSMAPI
-CSSM_GenerateAlgorithmParams (CSSM_CC_HANDLE CCHandle,
- uint32 ParamBits,
- CSSM_DATA_PTR Param)
-{
- BEGIN_API
- // this function has more subtle locking than usual. Pay attention:
-
- // (1) Resolve context and ensure attachment exit
- HandleContext &context = enterContext(CCHandle);
- StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit> _(context.attachment, true);
-
- // (2) Call CSP, acquiring module safe-lock for a moment (only)
- CSSM_CONTEXT_ATTRIBUTE_PTR attributes;
- uint32 count;
- {
- StLock<Module, &Module::safeLock, &Module::safeUnlock> _(context.attachment.module);
- if (CSSM_RETURN err =
- context.attachment.downcalls.GenerateAlgorithmParams(context.attachment.handle(),
- CCHandle, &context,
- ParamBits, Param,
- &count, &attributes))
- CssmError::throwMe(err);
- }
-
- // (3) Merge the attributes returned into the context, which will (again) acquire the module safe-lock internally
- if (count)
- context.mergeAttributes(attributes, count);
- // the memory at (attributes, count) belongs to the CSP; don't free it here
- END_API(CSSM)
-}
-
-
-//
-// Include the auto-generated functions
-//
-#include <derived_src/transition.gen>