#include <security_keychain/Identity.h>
#include <security_cdsa_utilities/KeySchema.h>
#include <security_keychain/KCCursor.h>
#include <string.h>
using namespace KeychainCore;
Identity::Identity(const SecPointer<KeyItem> &privateKey,
const SecPointer<Certificate> &certificate) :
mPrivateKey(privateKey),
mCertificate(certificate)
{
}
Identity::Identity(const StorageManager::KeychainList &keychains, const SecPointer<Certificate> &certificate) :
mCertificate(certificate)
{
KCCursor keyCursor(keychains, CSSM_DL_DB_RECORD_PRIVATE_KEY, NULL);
keyCursor->add(CSSM_DB_EQUAL, KeySchema::Label, certificate->publicKeyHash());
Item key;
if (!keyCursor->next(key))
MacOSError::throwMe(errSecItemNotFound);
SecPointer<KeyItem> keyItem(static_cast<KeyItem *>(&*key));
mPrivateKey = keyItem;
}
Identity::~Identity() throw()
{
}
SecPointer<KeyItem>
Identity::privateKey() const
{
return mPrivateKey;
}
SecPointer<Certificate>
Identity::certificate() const
{
return mCertificate;
}
bool
Identity::operator < (const Identity &other) const
{
return (mCertificate < other.mCertificate);
}
bool
Identity::operator == (const Identity &other) const
{
return (mCertificate == other.mCertificate && mPrivateKey == other.mPrivateKey);
}
bool Identity::equal(SecCFObject &other)
{
CFHashCode this_hash = hash();
CFHashCode other_hash = other.hash();
return (this_hash == other_hash);
}
CFHashCode Identity::hash()
{
CFHashCode result = SecCFObject::hash();
struct keyAndCertHash
{
CFHashCode keyHash;
CFHashCode certHash;
};
struct keyAndCertHash hashes;
memset(&hashes, 0, sizeof(struct keyAndCertHash));
KeyItem* pKeyItem = mPrivateKey.get();
if (NULL != pKeyItem)
{
hashes.keyHash = pKeyItem->hash();
}
Certificate* pCert = mCertificate.get();
if (NULL != pCert)
{
hashes.certHash = pCert->hash();
}
if (hashes.keyHash != 0 || hashes.certHash != 0)
{
CFDataRef temp_data = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)&hashes, sizeof(struct keyAndCertHash), kCFAllocatorNull);
if (NULL != temp_data)
{
result = CFHash(temp_data);
CFRelease(temp_data);
}
}
return result;
}