#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>
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;
class TransitLock {
public:
Attachment &attachment;
TransitLock(Attachment &att) : attachment(att)
{
attachment.module.safeLock();
}
~TransitLock()
{
attachment.module.safeUnlock();
attachment.exit();
}
};
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, 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_RETURN CSSMAPI
CSSM_GetContext (CSSM_CC_HANDLE CCHandle,
CSSM_CONTEXT_PTR *ContextP)
{
BEGIN_API
HandleContext &context = HandleObject::find<HandleContext>(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)
}
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);
HandleContext &context = HandleObject::find<HandleContext>(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); context.ContextAttributes = oldAttributes; context.NumberOfAttributes = oldCount; context.ContextType = oldType; context.AlgorithmType = oldAlgorithm; CssmError::throwMe(err); }
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);
context.validateChange(CSSM_CONTEXT_EVENT_DELETE);
context.destroy(&context, context.attachment);
END_API(CSSM)
}
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); 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
HandleContext &context = HandleObject::find<HandleContext>(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; Required(ContextAttributes); HandleContext &context = HandleObject::find<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
for (uint32 n = 0; n < NumberOfAttributes; n++)
context.deleteAttribute(ContextAttributes[n].AttributeType);
END_API(CSSM)
}
CSSM_RETURN CSSMAPI
CSSM_DigestDataClone (CSSM_CC_HANDLE ccHandle,
CSSM_CC_HANDLE *newCCHandle)
{
BEGIN_API
HandleContext &context = HandleObject::findAndLock<HandleContext>(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)
{
BEGIN_API
Required(keySize);
Context *context;
CSPAttachment *attachment;
if (ccHandle == (CSSM_CC_HANDLE) HandleObject::invalidHandle) {
attachment = &enterAttachment<CSPAttachment>(CSPHandle);
context = NULL;
} else {
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
HandleContext &context = enterContext(CCHandle);
StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit> _(context.attachment, true);
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);
}
if (count)
context.mergeAttributes(attributes, count);
END_API(CSSM)
}
#include <derived_src/transition.gen>