SecKeychainItem.cpp [plain text]
#include <Security/SecKeychainItem.h>
#include <Security/SecKeychainItemPriv.h>
#include <security_keychain/Keychains.h>
#include <security_keychain/KeyItem.h>
#include <security_keychain/Item.h>
#include <security_keychain/KCCursor.h> // @@@ Remove this when SecKeychainItemFindFirst moves to SecKeychainSearch
#include "SecBridge.h"
#include "KCExceptions.h"
#include "Access.h"
RefPointer<AclBearer> aclBearer(CFTypeRef itemRef)
{
CFTypeID id = CFGetTypeID(itemRef);
if (id == gTypes().ItemImpl.typeID) {
if (SSGroup group = ItemImpl::required(SecKeychainItemRef(itemRef))->group())
return &*group;
} else if (id == gTypes().KeyItem.typeID) {
if (CssmClient::Key key = KeyItem::required(SecKeyRef(itemRef))->key())
return &*key;
} else if (id == gTypes().KeychainImpl.typeID) {
}
MacOSError::throwMe(errSecNoAccessForItem);
}
CFTypeID
SecKeychainItemGetTypeID(void)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemGetTypeID()");
return gTypes().ItemImpl.typeID;
END_SECAPI1(_kCFRuntimeNotATypeID)
}
OSStatus
SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList,
UInt32 length, const void *data, SecKeychainRef keychainRef,
SecAccessRef initialAccess, SecKeychainItemRef *itemRef)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemCreateFromContent(%lu, %p, %lu, %p, %p, %p)",
itemClass, attrList, length, data, keychainRef, initialAccess);
KCThrowParamErrIf_(length!=0 && data==NULL);
Item item(itemClass, attrList, length, data);
if (initialAccess)
item->setAccess(Access::required(initialAccess));
Keychain keychain = nil;
try
{
keychain = Keychain::optional(keychainRef);
if ( !keychain->exists() )
{
MacOSError::throwMe(errSecNoSuchKeychain); }
}
catch(...)
{
keychain = globals().storageManager.defaultKeychainUI(item);
}
keychain->add(item);
if (itemRef)
*itemRef = item->handle();
END_SECAPI
}
OSStatus
SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemModifyContent(%p, %p, %lu, %p)", itemRef, attrList, length, data);
Item item = ItemImpl::required(itemRef);
item->modifyContent(attrList, length, data);
END_SECAPI
}
OSStatus
SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemCopyContent(%p, %p, %p, %p, %p)",
itemRef, itemClass, attrList, length, outData);
Item item = ItemImpl::required(itemRef);
item->getContent(itemClass, attrList, length, outData);
END_SECAPI
}
OSStatus
SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemFreeContent(%p, %p)", attrList, data);
ItemImpl::freeContent(attrList, data);
END_SECAPI
}
OSStatus
SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemModifyAttributesAndData(%p, %p, %lu, %p)", itemRef, attrList, length, data);
Item item = ItemImpl::required(itemRef);
item->modifyAttributesAndData(attrList, length, data);
END_SECAPI
}
OSStatus
SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemCopyAttributesAndData(%p, %p, %p, %p, %p, %p)", itemRef, info, itemClass, attrList, length, outData);
Item item = ItemImpl::required(itemRef);
item->getAttributesAndData(info, itemClass, attrList, length, outData);
END_SECAPI
}
OSStatus
SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList, void *data)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemFreeAttributesAndData(%p, %p)", attrList, data);
ItemImpl::freeAttributesAndData(attrList, data);
END_SECAPI
}
OSStatus
SecKeychainItemDelete(SecKeychainItemRef itemRef)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemFreeAttributesAndData(%p)", itemRef);
Item item = ItemImpl::required( itemRef );
Keychain keychain = item->keychain();
KCThrowIf_( !keychain, errSecInvalidItemRef );
keychain->deleteItem( item ); END_SECAPI
}
OSStatus
SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychainRef)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemCopyKeychain(%p, %p)", itemRef, keychainRef);
Required(keychainRef) = ItemImpl::required(itemRef)->keychain()->handle();
END_SECAPI
}
OSStatus
SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainRef destKeychainRef,
SecAccessRef initialAccess, SecKeychainItemRef *itemCopy)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemCreateCopy(%p, %p, %p, %p)",
itemRef, destKeychainRef, initialAccess, itemCopy);
Item copy = ItemImpl::required(itemRef)->copyTo(Keychain::optional(destKeychainRef), Access::optional(initialAccess));
if (itemCopy)
*itemCopy = copy->handle();
END_SECAPI
}
OSStatus
SecKeychainItemGetUniqueRecordID(SecKeychainItemRef itemRef, const CSSM_DB_UNIQUE_RECORD **uniqueRecordID)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemGetUniqueRecordID(%p, %p)", itemRef, uniqueRecordID);
Required(uniqueRecordID) = ItemImpl::required(itemRef)->dbUniqueRecord();
END_SECAPI
}
OSStatus
SecKeychainItemGetDLDBHandle(SecKeychainItemRef itemRef, CSSM_DL_DB_HANDLE* dldbHandle)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemGetDLDBHandle(%p, %p)", itemRef, dldbHandle);
*dldbHandle = ItemImpl::required(itemRef)->keychain()->database()->handle();
END_SECAPI
}
OSStatus SecAccessCreateFromObject(CFTypeRef sourceRef,
SecAccessRef *accessRef)
{
BEGIN_SECAPI
secdebug("kcitem", "SecAccessCreateFromObject(%p, %p)", sourceRef, accessRef);
Required(accessRef); SecPointer<Access> access = new Access(*aclBearer(sourceRef));
*accessRef = access->handle();
END_SECAPI
}
OSStatus SecAccessModifyObject(SecAccessRef accessRef, CFTypeRef sourceRef)
{
BEGIN_SECAPI
secdebug("kcitem", "SecAccessModifyObject(%p, %p)", accessRef, sourceRef);
Access::required(accessRef)->setAccess(*aclBearer(sourceRef), true);
END_SECAPI
}
OSStatus
SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef* accessRef)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemCopyAccess(%p, %p)", itemRef, accessRef);
Required(accessRef); SecPointer<Access> access = new Access(*aclBearer(reinterpret_cast<CFTypeRef>(itemRef)));
*accessRef = access->handle();
END_SECAPI
}
OSStatus
SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef accessRef)
{
BEGIN_SECAPI
secdebug("kcitem", "SecKeychainItemSetAccess(%p, %p)", itemRef, accessRef);
Access::required(accessRef)->setAccess(*aclBearer(reinterpret_cast<CFTypeRef>(itemRef)), true);
END_SECAPI
}
OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data)
{
BEGIN_SECAPI
ItemImpl::required(itemRef)->setData(length, data);
END_SECAPI
}
OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, void* data, UInt32* actualLength)
{
BEGIN_SECAPI
if (!((data && maxLength) || actualLength))
MacOSError::throwMe(paramErr);
CssmDataContainer aData;
ItemImpl::required(itemRef)->getData(aData);
if (actualLength)
*actualLength = aData.length();
if (data)
{
if (aData.length() > maxLength)
MacOSError::throwMe(errKCBufferTooSmall);
memcpy(data, aData.data(), aData.length());
}
END_SECAPI
}
OSStatus SecKeychainItemUpdate(SecKeychainItemRef itemRef)
{
BEGIN_SECAPI
ItemImpl::required(itemRef)->update();
END_SECAPI
}
OSStatus SecKeychainItemAddNoUI(SecKeychainRef keychainRef, SecKeychainItemRef itemRef)
{
BEGIN_SECAPI
Item item = ItemImpl::required(itemRef);
Keychain::optional(keychainRef)->add(item);
END_SECAPI
}
OSStatus SecKeychainItemAdd(SecKeychainItemRef itemRef)
{
BEGIN_SECAPI
Item item = ItemImpl::required(itemRef);
Keychain defaultKeychain = globals().storageManager.defaultKeychainUI(item);
defaultKeychain->add(item);
END_SECAPI
}
OSStatus SecKeychainItemCreateNew(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, SecKeychainItemRef* itemRef)
{
BEGIN_SECAPI
RequiredParam(itemRef) = Item(itemClass, itemCreator, length, data)->handle();
END_SECAPI
}
OSStatus SecKeychainItemGetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute, UInt32* actualLength)
{
BEGIN_SECAPI
ItemImpl::required(itemRef)->getAttribute(RequiredParam(attribute), actualLength);
END_SECAPI
}
OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute)
{
BEGIN_SECAPI
ItemImpl::required(itemRef)->setAttribute(RequiredParam(attribute));
END_SECAPI
}
OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef, SecKeychainItemRef *itemRef)
{
BEGIN_SECAPI
KCCursor cursor;
if (keychainRef)
cursor = KeychainImpl::required(keychainRef)->createCursor(attrList);
else
cursor = globals().storageManager.createCursor(attrList);
Item item;
if (!cursor->next(item))
return errKCItemNotFound;
*itemRef=item->handle();
if (searchRef)
*searchRef=cursor->handle();
END_SECAPI
}