#include "sstransit.h"
#include <security_cdsa_client/cspclient.h>
#include <security_utilities/mach++.h>
namespace Security {
namespace SecurityServer {
using MachPlusPlus::check;
using MachPlusPlus::VMGuard;
DataOutput::~DataOutput()
{
VMGuard _(mData, mLength);
if (mData) if (mTarget) { if (mTarget->data()) { if (mTarget->length() < mLength)
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
mTarget->length(mLength); } else { *mTarget = CssmData(allocator.malloc(mLength), mLength);
}
memcpy(mTarget->data(), mData, mLength);
}
}
DatabaseAccessCredentials::DatabaseAccessCredentials(const AccessCredentials *creds, Allocator &alloc)
: Copier<AccessCredentials>(creds, alloc)
{
if (creds) {
for (uint32 n = 0; n < value()->samples().length(); n++) {
TypedList sample = value()->samples()[n];
sample.checkProper();
switch (sample.type()) {
case CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK:
sample.snip(); sample.checkProper();
if (sample.type() == CSSM_SAMPLE_TYPE_SYMMETRIC_KEY ||
sample.type() == CSSM_SAMPLE_TYPE_ASYMMETRIC_KEY) {
secdebug("SSclient", "key sample encountered");
if (sample.length() != 4
|| sample[1].type() != CSSM_LIST_ELEMENT_DATUM
|| sample[2].type() != CSSM_LIST_ELEMENT_DATUM
|| sample[3].type() != CSSM_LIST_ELEMENT_DATUM)
CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
mapKeySample(
sample[1].data(),
*sample[2].data().interpretedAs<CssmKey>(CSSM_ERRCODE_INVALID_SAMPLE_VALUE));
}
break;
case CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK:
sample.snip(); sample.checkProper();
if (sample.type() == CSSM_SAMPLE_TYPE_SYMMETRIC_KEY ||
sample.type() == CSSM_SAMPLE_TYPE_ASYMMETRIC_KEY) {
secdebug("SSclient", "key sample encountered");
if (sample.length() != 3
|| sample[1].type() != CSSM_LIST_ELEMENT_DATUM
|| sample[2].type() != CSSM_LIST_ELEMENT_DATUM)
CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
mapKeySample(
sample[1].data(),
*sample[2].data().interpretedAs<CssmKey>(CSSM_ERRCODE_INVALID_SAMPLE_VALUE));
}
break;
default:
break;
}
}
}
}
void DatabaseAccessCredentials::mapKeySample(CssmData &cspHandleData, CssmKey &key)
{
CSSM_CC_HANDLE ctx;
CSSM_CSP_HANDLE &cspHandle = *cspHandleData.interpretedAs<CSSM_CSP_HANDLE>(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
CssmError::check(CSSM_CSP_CreatePassThroughContext(cspHandle, &key, &ctx));
KeyHandle ssKey;
CSSM_RETURN passthroughError =
CSSM_CSP_PassThrough(ctx, CSSM_APPLESCPDL_CSP_GET_KEYHANDLE, NULL, (void **)&ssKey);
CSSM_DeleteContext(ctx); switch (passthroughError) {
case CSSM_OK: assert(sizeof(CSSM_CSP_HANDLE) >= sizeof(KeyHandle)); cspHandle = ssKey;
cspHandleData.length(sizeof(KeyHandle));
secdebug("SSclient", "key sample mapped to key 0x%x", ssKey);
return;
case CSSMERR_CSP_INVALID_PASSTHROUGH_ID:
return; default:
CssmError::throwMe(passthroughError); }
}
DataRetrieval::DataRetrieval(CssmDbRecordAttributeData *&attributes, Allocator &alloc)
: Copier<CssmDbRecordAttributeData>(attributes),
mAllocator(alloc), mAttributes(attributes), mAddr(NULL), mBase(NULL), mLength(0)
{
}
DataRetrieval::~DataRetrieval()
{
if (mAddr) {
relocate(mAddr, mBase);
assert(mAttributes->size() == mAddr->size());
mAttributes->recordType(mAddr->recordType());
mAttributes->semanticInformation(mAddr->semanticInformation());
for (uint32 n = 0; n < mAttributes->size(); n++)
mAttributes->at(n).copyValues(mAddr->at(n), mAllocator);
}
}
} }