#include <Security/TrustItem.h>
#include <Security/Schema.h>
#include <Security/SecCFTypes.h>
namespace Security {
namespace KeychainCore {
UserTrustItem::UserTrustItem(Certificate *cert, Policy *policy, const TrustData &trustData) :
ItemImpl(CSSM_DL_DB_RECORD_USER_TRUST,
reinterpret_cast<SecKeychainAttributeList *>(NULL),
UInt32(sizeof(trustData)),
reinterpret_cast<const void *>(&trustData)),
mCertificate(cert), mPolicy(policy)
{
debug("usertrust", "create %p (%p,%p) = %d", this, cert, policy, trustData.trust);
}
UserTrustItem::~UserTrustItem()
{
debug("usertrust", "destroy %p", this);
}
UserTrustItem::TrustData UserTrustItem::trust()
{
CssmDataContainer data;
getData(data);
if (data.length() != sizeof(TrustData))
MacOSError::throwMe(errSecInvalidTrustSetting);
return *data.interpretedAs<TrustData>();
}
PrimaryKey UserTrustItem::add(Keychain &keychain)
{
if (mKeychain)
MacOSError::throwMe(errSecDuplicateItem);
populateAttributes();
CSSM_DB_RECORDTYPE recordType = mDbAttributes->recordType();
Db db(keychain->database());
try
{
mUniqueId = db->insert(recordType, mDbAttributes.get(), mData.get());
debug("usertrust", "%p inserted", this);
}
catch (const CssmError &e)
{
if (e.cssmError() != CSSMERR_DL_INVALID_RECORDTYPE)
throw;
debug("usertrust", "adding schema relation for user trusts");
db->createRelation(CSSM_DL_DB_RECORD_USER_TRUST, "CSSM_DL_DB_RECORD_USER_TRUST",
Schema::UserTrustSchemaAttributeCount,
Schema::UserTrustSchemaAttributeList,
Schema::UserTrustSchemaIndexCount,
Schema::UserTrustSchemaIndexList);
mUniqueId = db->insert(recordType, mDbAttributes.get(), mData.get());
debug("usertrust", "%p inserted now", this);
}
mPrimaryKey = keychain->makePrimaryKey(recordType, mUniqueId);
mKeychain = keychain;
return mPrimaryKey;
}
void UserTrustItem::populateAttributes()
{
const CssmData &certData = mCertificate->data();
const CssmOid &policyOid = mPolicy->oid();
mDbAttributes->add(Schema::attributeInfo(kSecTrustCertAttr), certData);
mDbAttributes->add(Schema::attributeInfo(kSecTrustPolicyAttr), policyOid);
}
} }