#ifndef _H_CSSMWALKERS
#define _H_CSSMWALKERS
#include <security_cdsa_utilities/walkers.h>
#include <security_cdsa_utilities/cssmdata.h>
#include <security_cdsa_utilities/cssmpods.h>
#include <security_cdsa_utilities/cssmkey.h>
namespace Security {
namespace DataWalkers {
template <class Action, class Record, class Element>
void enumerateArray(Action &operate, Record &record, Element *& (Record::*pointer)())
{
if (record.size()) {
Element *&root = (record.*pointer)();
operate.blob(root, record.size() * sizeof(Element));
for (uint32 ix = 0; ix < record.size(); ++ix)
walk(operate, record[ix]);
}
}
template <class Action>
void walk(Action &operate, CssmData &data)
{
operate(data);
operate.blob(data.Data, data.Length);
}
template <class Action>
CssmData *walk(Action &operate, CssmData * &data)
{
operate(data);
operate.blob(data->Data, data->Length);
return data;
}
template <class Action>
void walk(Action &operate, CSSM_DATA &data)
{ walk(operate, CssmData::overlay(data)); }
template <class Action>
CSSM_DATA *walk(Action &operate, CSSM_DATA * &data)
{ return walk(operate, CssmData::overlayVar(data)); }
template <class Action>
char *walk(Action &operate, char * &s)
{
if (s)
operate(s, operate.needsSize ? (strlen(s) + 1) : 0);
return s;
}
template <class Action>
CssmKey *walk(Action &operate, CssmKey * &key)
{
operate(key);
walk(operate, key->keyData());
return key;
}
template <class Action>
CSSM_KEY *walk(Action &operate, CSSM_KEY * &data)
{ return walk(operate, CssmKey::overlayVar(data)); }
template <class Action>
CssmCryptoData *walk(Action &operate, CssmCryptoData * &data)
{
operate(data);
walk(operate, data->param());
return data;
}
template <class Action>
CSSM_CRYPTO_DATA *walk(Action &operate, CSSM_CRYPTO_DATA * &data)
{ return walk(operate, CssmCryptoData::overlayVar(data)); }
template <class Action>
void walk(Action &operate, CSSM_PKCS5_PBKDF2_PARAMS &data)
{
operate(data);
walk(operate, data.Passphrase);
}
template <class Action>
CSSM_DATE_PTR walk(Action &operate, CSSM_DATE_PTR &date)
{
operate(date);
return date;
}
template <class Action>
CSSM_RANGE_PTR walk(Action &operate, CSSM_RANGE_PTR &range)
{
operate(range);
return range;
}
template <class Action>
CSSM_VERSION_PTR walk(Action &operate, CSSM_VERSION_PTR &version)
{
operate(version);
return version;
}
template <class Action>
CSSM_DL_DB_HANDLE_PTR walk(Action &operate, CSSM_DL_DB_HANDLE_PTR &dlDbHandle)
{
operate(dlDbHandle);
return dlDbHandle;
}
template <class Action>
CssmSubserviceUid *walk(Action &operate, CssmSubserviceUid * &ssUid)
{
operate(ssUid);
return ssUid;
}
class CssmDeriveData {
public:
CssmDeriveData(const CssmData &dat, CSSM_ALGORITHMS alg)
: baseData(dat), algorithm(alg) { }
CssmData baseData;
CSSM_ALGORITHMS algorithm;
template <class Action>
void enumerate(Action &operate)
{
walk(operate, baseData);
switch (algorithm) {
case CSSM_ALGID_PKCS5_PBKDF2:
#if BUG_3762664
walk(operate, *baseData.interpretedAs<CSSM_PKCS5_PBKDF2_PARAMS>
(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS));
#else
if (baseData.length() != sizeof(CSSM_PKCS5_PBKDF2_PARAMS))
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS);
walk(operate, *(CSSM_PKCS5_PBKDF2_PARAMS *)baseData.data());
#endif
break;
default:
break;
}
}
};
template <class Action>
void walk(Action &operate, CssmDeriveData &data)
{
operate(data);
data.enumerate(operate);
}
template <class Action>
CssmDeriveData *walk(Action &operate, CssmDeriveData * &data)
{
operate(data);
if (data)
data->enumerate(operate);
return data;
}
} }
#endif //_H_CSSMWALKERS