#include <security_cdsa_plugin/CSPsession.h>
#include <security_cdsa_plugin/cssmplugin.h>
#include <security_utilities/memutils.h>
#include <security_cdsa_utilities/cssmdates.h>
using LowLevelMemoryUtilities::increment;
CSPFullPluginSession::Writer::Writer(CssmData *v, uint32 n, CssmData *rem)
: vec(v), firstVec(v), lastVec(v + n - 1), remData(rem)
{
if (vec == NULL || n == 0)
CssmError::throwMe(CSSMERR_CSP_INVALID_OUTPUT_VECTOR); useData(vec);
written = 0;
}
void CSPFullPluginSession::Writer::allocate(size_t needed, Allocator &alloc)
{
if (!needed)
return; else if (vec == firstVec && !*vec) { *vec = makeBuffer(needed, alloc);
lastVec = vec; useData(vec);
} else {
size_t size = currentSize;
for (CssmData *v = vec + 1; v <= lastVec; v++)
size += v->length();
if (size >= needed)
return; if (remData) {
if (!*remData) { *remData = makeBuffer(needed - size, alloc);
return; }
if (size + remData->length() >= needed)
return; }
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
}
void CSPFullPluginSession::Writer::nextBlock(void * &ptr, size_t &size)
{
ptr = currentBuffer;
size = currentSize;
}
void CSPFullPluginSession::Writer::use(size_t used)
{
assert(used <= currentSize);
written += used;
if (used < currentSize) {
currentBuffer = increment(currentBuffer, used);
currentSize -= used;
} else {
if (vec < lastVec) {
useData(vec++); } else if (vec == lastVec && remData) {
useData(remData); vec++; #if !defined(NDEBUG) && 0
} else if (vec == lastVec) {
vec++;
} else if (vec > lastVec) {
assert(false); #endif
} else {
currentBuffer = NULL; currentSize = 0;
}
}
}
void CSPFullPluginSession::Writer::put(void *addr, size_t size)
{
while (size > 0) {
void *p; size_t sz;
nextBlock(p, sz);
if (size < sz)
sz = size; memcpy(p, addr, sz);
use(sz);
addr = increment(addr, sz);
size -= sz;
}
}
size_t CSPFullPluginSession::Writer::close()
{
return written;
}
void CSPFullPluginSession::setKey(CssmKey &key,
const Context &context, CSSM_KEYCLASS keyClass,
CSSM_KEYATTR_FLAGS attrs, CSSM_KEYUSE use)
{
memset(&key.KeyHeader, 0, sizeof(key.KeyHeader));
key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
key.KeyHeader.CspId = plugin.myGuid();
key.KeyHeader.AlgorithmId = context.algorithm();
key.KeyHeader.KeyClass = keyClass;
key.KeyHeader.KeyUsage = use;
key.KeyHeader.KeyAttr = attrs;
CssmDate *theDate = context.get<CssmDate>(CSSM_ATTRIBUTE_START_DATE);
if(theDate) {
key.KeyHeader.StartDate = *theDate;
}
theDate = context.get<CssmDate>(CSSM_ATTRIBUTE_END_DATE);
if(theDate) {
key.KeyHeader.EndDate = *theDate;
}
key.KeyHeader.WrapAlgorithmId = CSSM_ALGID_NONE;
key = CssmData();
}