#include <Security/cspclient.h>
using namespace CssmClient;
CSPImpl::CSPImpl(const Guid &guid) : AttachmentImpl(guid, CSSM_SERVICE_CSP)
{
}
CSPImpl::CSPImpl(const Module &module) : AttachmentImpl(module, CSSM_SERVICE_CSP)
{
}
CSPImpl::~CSPImpl()
{
}
void CSPImpl::freeKey(CssmKey &key, const AccessCredentials *cred, bool permanent)
{
check(CSSM_FreeKey(handle(), cred, &key, permanent));
}
CssmClient::Context::Context(const CSP &csp, CSSM_ALGORITHMS alg)
: ObjectImpl(csp), mAlgorithm(alg), mStaged(false)
{
}
CssmClient::Context::~Context()
{
try
{
deactivate();
} catch(...) {}
}
void CssmClient::Context::init()
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CssmClient::Context::deactivate()
{
if (mActive)
{
mActive = false;
check(CSSM_DeleteContext(mHandle));
}
}
void CssmClient::Context::algorithm(CSSM_ALGORITHMS alg)
{
if (isActive())
abort(); mAlgorithm = alg;
}
uint32 CssmClient::Context::getOutputSize(uint32 inputSize, bool encrypt = true)
{
CSSM_QUERY_SIZE_DATA data;
data.SizeInputBlock = inputSize;
getOutputSize(data, 1, encrypt);
return data.SizeOutputBlock;
}
void CssmClient::Context::getOutputSize(CSSM_QUERY_SIZE_DATA &sizes, uint32 count, bool encrypt = true)
{
check(CSSM_QuerySize(handle(), encrypt, count, &sizes));
}
void CssmClient::Context::override(const Security::Context &ctx)
{
if (!isActive()) {
check(CSSM_CSP_CreateDigestContext(attachment()->handle(), CSSM_ALGID_NONE, &mHandle));
}
check(CSSM_SetContext(mHandle, &ctx));
mActive = true; }
void
PassThrough::operator() (uint32 passThroughId, const void *inData, void **outData)
{
check(CSSM_CSP_PassThrough(handle(), passThroughId, inData, outData));
}
void PassThrough::activate()
{
if (!mActive) {
check(CSSM_CSP_CreatePassThroughContext(attachment()->handle(), mKey, &mHandle));
mActive = true;
}
}
void Digest::activate()
{
if (!mActive) {
check(CSSM_CSP_CreateDigestContext(attachment()->handle(), mAlgorithm, &mHandle));
mActive = true;
}
}
void Digest::digest(const CssmData *data, uint32 count, CssmData &digest)
{
activate();
if (mStaged)
Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS);
check(CSSM_DigestData(handle(), data, count, &digest));
}
void Digest::digest(const CssmData *data, uint32 count)
{
activate();
if (!mStaged) {
check(CSSM_DigestDataInit(handle()));
mStaged = true;
}
check(CSSM_DigestDataUpdate(handle(), data, count));
}
void Digest::operator () (CssmData &digest)
{
if (!mStaged)
Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED);
check(CSSM_DigestDataFinal(handle(), &digest));
mStaged = false;
}
void Random::seed(const CssmCryptoData &seedData)
{
mSeed = &seedData;
set(CSSM_ATTRIBUTE_SEED, seedData);
}
void Random::size(uint32 sz)
{
mSize = sz;
set(CSSM_ATTRIBUTE_OUTPUT_SIZE, sz);
}
void Random::activate()
{
if (!mActive) {
check(CSSM_CSP_CreateRandomGenContext(attachment()->handle(), mAlgorithm,
mSeed, mSize, &mHandle));
mActive = true;
}
}
void Random::generate(CssmData &data, uint32 newSize)
{
if (newSize)
size(newSize);
activate();
assert(!mStaged); check(CSSM_GenerateRandom(handle(), &data));
}