#include <security_cdsa_utilities/context.h>
Context::Context(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS algorithmId)
{
clearPod();
ContextType = type;
AlgorithmType = algorithmId;
}
void Context::deleteAttribute(CSSM_ATTRIBUTE_TYPE type)
{
for (uint32 n = 0; n < attributesInUse(); n++)
if (ContextAttributes[n].AttributeType == type) {
ContextAttributes[n].AttributeType = CSSM_ATTRIBUTE_NONE;
ContextAttributes[n].AttributeLength = 0;
return;
}
CssmError::throwMe(CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT);
}
size_t Context::copyAttributes(CSSM_CONTEXT_ATTRIBUTE * &attrs, uint32 &count,
Allocator &alloc) const
{
Context::Builder builder(alloc);
for (unsigned n = 0; n < attributesInUse(); n++)
builder.setup(ContextAttributes[n]);
size_t size = builder.make();
for (unsigned n = 0; n < attributesInUse(); n++)
builder.put(ContextAttributes[n]);
builder.done(attrs, count);
return size;
}
Context::Attr *Context::find(CSSM_ATTRIBUTE_TYPE theType,
const CSSM_CONTEXT_ATTRIBUTE *attrs, unsigned int count)
{
for (unsigned n = 0; n < count; n++)
if (attrs[n].AttributeType == theType)
return (Attr *)&attrs[n];
return NULL;
}
void Context::postIPC(void *base, CSSM_CONTEXT_ATTRIBUTE *ipcAttributes)
{
ReconstituteWalker relocator(LowLevelMemoryUtilities::difference(ipcAttributes, base));
ContextAttributes = ipcAttributes; for (uint32 n = 0; n < attributesInUse(); n++)
walk(relocator, (*this)[n]);
}
size_t Context::Builder::make()
{
size_t vectorSize =
LowLevelMemoryUtilities::alignUp(slotCount * sizeof(CSSM_CONTEXT_ATTRIBUTE));
size_t totalSize = vectorSize + sizer;
attributes = reinterpret_cast<Attr *>(allocator.malloc(totalSize));
copier = LowLevelMemoryUtilities::increment(attributes, vectorSize);
slot = 0;
return totalSize;
}
void Context::Builder::done(CSSM_CONTEXT_ATTRIBUTE * &attributes, uint32 &count)
{
assert(slot == slotCount); attributes = this->attributes;
count = slotCount;
this->attributes = NULL; }
#if defined(DEBUGDUMP)
static void dumpData(CSSM_DATA *data)
{
if (data == NULL)
Debug::dump("[NULL]");
else
Debug::dump("[%p,%ld]@%p", data->Data, data->Length, data);
}
void Context::Attr::dump() const
{
Debug::dump(" Attr{type=%x, size=%d, value=", int(AttributeType), int(AttributeLength));
switch (AttributeType & CSSM_ATTRIBUTE_TYPE_MASK) {
case CSSM_ATTRIBUTE_DATA_UINT32:
Debug::dump("%ld", long(Attribute.Uint32)); break;
case CSSM_ATTRIBUTE_DATA_STRING:
Debug::dump("%s@%p", Attribute.String, Attribute.String); break;
case CSSM_ATTRIBUTE_DATA_CSSM_DATA:
dumpData(Attribute.Data);
break;
case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA:
dumpData(&Attribute.CryptoData->Param);
break;
default:
Debug::dump("%p", Attribute.String); break; };
Debug::dump("}\n");
}
void Context::dump(const char *title, const CSSM_CONTEXT_ATTRIBUTE *attrs) const
{
if (attrs == NULL)
attrs = ContextAttributes;
Debug::dump("Context %s{type=%d, alg=%d, CSP=%u, %d attributes@%p:\n",
title ? title : "",
int(ContextType), int(AlgorithmType), (unsigned int)CSPHandle,
int(NumberOfAttributes), attrs);
for (unsigned int n = 0; n < NumberOfAttributes; n++)
Attr::overlay(attrs[n]).dump();
Debug::dump("} // end Context\n");
}
#endif //DEBUGDUMP