2  * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved. 
   4  * The contents of this file constitute Original Code as defined in and are 
   5  * subject to the Apple Public Source License Version 1.2 (the 'License'). 
   6  * You may not use this file except in compliance with the License. Please obtain 
   7  * a copy of the License at http://www.apple.com/publicsource and read it before 
  10  * This Original Code and all software distributed under the License are 
  11  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 
  12  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 
  13  * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
  14  * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 
  15  * specific language governing rights and limitations under the License. 
  18 #include <Security/SecKeychainItem.h> 
  20 #include <Security/Keychains.h> 
  21 #include <Security/KeyItem.h> 
  22 #include <Security/Item.h> 
  24 #include "SecBridge.h" 
  25 #include "KCExceptions.h" 
  30 // Given a polymorphic Sec type object, return 
  31 // its AclBearer component. 
  32 // Note: Login ACLs are not hooked into this layer; 
  33 // modules or attachments have no Sec* layer representation. 
  35 RefPointer
<AclBearer
> aclBearer(CFTypeRef itemRef
) 
  37         // well, exactly what kind of something are you? 
  38         CFTypeID id 
= CFGetTypeID(itemRef
); 
  39         if (id 
== gTypes().ItemImpl
.typeID
) { 
  40                 // keychain item. If it's in a protected group, return the group key 
  41                 if (SSGroup group 
= ItemImpl::required(SecKeychainItemRef(itemRef
))->group()) 
  43         } else if (id 
== gTypes().KeyItem
.typeID
) { 
  44                 // key item, return the key itself. 
  45                 if (CssmClient::Key key 
= KeyItem::required(SecKeyRef(itemRef
))->key()) 
  47         } else if (id 
== gTypes().KeychainImpl
.typeID
) { 
  48                 // keychain (this yields the database ACL) 
  49                 //@@@ not hooked up yet 
  52         MacOSError::throwMe(errSecNoAccessForItem
); 
  57 SecKeychainItemGetTypeID(void) 
  61         secdebug("kcitem", "SecKeychainItemGetTypeID()"); 
  62         return gTypes().ItemImpl
.typeID
; 
  64         END_SECAPI1(_kCFRuntimeNotATypeID
) 
  69 SecKeychainItemCreateFromContent(SecItemClass itemClass
, SecKeychainAttributeList 
*attrList
, 
  70                 UInt32 length
, const void *data
, SecKeychainRef keychainRef
, 
  71                 SecAccessRef initialAccess
, SecKeychainItemRef 
*itemRef
) 
  74                 secdebug("kcitem", "SecKeychainItemCreateFromContent(%lu, %p, %lu, %p, %p, %p)", 
  75                         itemClass
, attrList
, length
, data
, keychainRef
, initialAccess
); 
  76                 KCThrowParamErrIf_(length
!=0 && data
==NULL
); 
  77         Item 
item(itemClass
, attrList
, length
, data
); 
  79                         item
->setAccess(Access::required(initialAccess
)); 
  81         Keychain keychain 
= nil
; 
  84             keychain 
= Keychain::optional(keychainRef
); 
  85             if ( !keychain
->exists() ) 
  87                 MacOSError::throwMe(errSecNoSuchKeychain
);      // Might be deleted or not available at this time. 
  92             keychain 
= globals().storageManager
.defaultKeychainUI(item
); 
  97                 *itemRef 
= item
->handle(); 
 103 SecKeychainItemModifyContent(SecKeychainItemRef itemRef
, const SecKeychainAttributeList 
*attrList
, UInt32 length
, const void *data
) 
 106                 secdebug("kcitem", "SecKeychainItemModifyContent(%p, %p, %lu, %p)", itemRef
, attrList
, length
, data
); 
 107                 Item item 
= ItemImpl::required(itemRef
); 
 108                 item
->modifyContent(attrList
, length
, data
); 
 114 SecKeychainItemCopyContent(SecKeychainItemRef itemRef
, SecItemClass 
*itemClass
, SecKeychainAttributeList 
*attrList
, UInt32 
*length
, void **outData
) 
 117                 secdebug("kcitem", "SecKeychainItemCopyContent(%p, %p, %p, %p, %p)", 
 118                         itemRef
, itemClass
, attrList
, length
, outData
); 
 119                 Item item 
= ItemImpl::required(itemRef
); 
 120                 item
->getContent(itemClass
, attrList
, length
, outData
); 
 126 SecKeychainItemFreeContent(SecKeychainAttributeList 
*attrList
, void *data
) 
 129                 secdebug("kcitem", "SecKeychainItemFreeContent(%p, %p)", attrList
, data
); 
 130                 ItemImpl::freeContent(attrList
, data
); 
 136 SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef
, const SecKeychainAttributeList 
*attrList
, UInt32 length
, const void *data
) 
 139                 secdebug("kcitem", "SecKeychainItemModifyAttributesAndData(%p, %p, %lu, %p)", itemRef
, attrList
, length
, data
); 
 140                 Item item 
= ItemImpl::required(itemRef
); 
 141                 item
->modifyAttributesAndData(attrList
, length
, data
); 
 147 SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef
, SecKeychainAttributeInfo 
*info
, SecItemClass 
*itemClass
, SecKeychainAttributeList 
**attrList
, UInt32 
*length
, void **outData
) 
 150                 secdebug("kcitem", "SecKeychainItemCopyAttributesAndData(%p, %p, %p, %p, %p, %p)", itemRef
, info
, itemClass
, attrList
, length
, outData
); 
 151                 Item item 
= ItemImpl::required(itemRef
); 
 152                 item
->getAttributesAndData(info
, itemClass
, attrList
, length
, outData
); 
 158 SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList 
*attrList
, void *data
) 
 161                 secdebug("kcitem", "SecKeychainItemFreeAttributesAndData(%p, %p)", attrList
, data
); 
 162                 ItemImpl::freeAttributesAndData(attrList
, data
); 
 168 SecKeychainItemDelete(SecKeychainItemRef itemRef
) 
 171                 secdebug("kcitem", "SecKeychainItemFreeAttributesAndData(%p)", itemRef
); 
 172                 Item item 
= ItemImpl::required( itemRef 
); 
 173                 Keychain keychain 
= item
->keychain(); 
 174                 KCThrowIf_( !keychain
, errSecInvalidItemRef 
); 
 176         keychain
->deleteItem( item 
); // item must be persistant. 
 182 SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef
, SecKeychainRef
* keychainRef
) 
 185                 secdebug("kcitem", "SecKeychainItemCopyKeychain(%p, %p)", itemRef
, keychainRef
); 
 186                 Required(keychainRef
) = ItemImpl::required(itemRef
)->keychain()->handle(); 
 192 SecKeychainItemCreateCopy(SecKeychainItemRef itemRef
, SecKeychainRef destKeychainRef
, 
 193         SecAccessRef initialAccess
, SecKeychainItemRef 
*itemCopy
) 
 196                 secdebug("kcitem", "SecKeychainItemCreateCopy(%p, %p, %p, %p)", 
 197                         itemRef
, destKeychainRef
, initialAccess
, itemCopy
); 
 199                 Item copy 
= ItemImpl::required(itemRef
)->copyTo(Keychain::optional(destKeychainRef
), Access::optional(initialAccess
)); 
 201                         *itemCopy 
= copy
->handle(); 
 207 SecKeychainItemGetUniqueRecordID(SecKeychainItemRef itemRef
, const CSSM_DB_UNIQUE_RECORD 
**uniqueRecordID
) 
 210                 secdebug("kcitem", "SecKeychainItemGetUniqueRecordID(%p, %p)", itemRef
, uniqueRecordID
); 
 211         Required(uniqueRecordID
) = ItemImpl::required(itemRef
)->dbUniqueRecord(); 
 217 SecKeychainItemGetDLDBHandle(SecKeychainItemRef itemRef
, CSSM_DL_DB_HANDLE
* dldbHandle
) 
 220                 secdebug("kcitem", "SecKeychainItemGetDLDBHandle(%p, %p)", itemRef
, dldbHandle
); 
 221         *dldbHandle 
= ItemImpl::required(itemRef
)->keychain()->database()->handle(); 
 226 OSStatus 
SecAccessCreateFromObject(CFTypeRef sourceRef
, 
 227         SecAccessRef 
*accessRef
) 
 230         secdebug("kcitem", "SecAccessCreateFromObject(%p, %p)", sourceRef
, accessRef
); 
 231         Required(accessRef
);    // preflight 
 232         SecPointer
<Access
> access 
= new Access(*aclBearer(sourceRef
)); 
 233         *accessRef 
= access
->handle(); 
 240 OSStatus 
SecAccessModifyObject(SecAccessRef accessRef
, CFTypeRef sourceRef
) 
 243         secdebug("kcitem", "SecAccessModifyObject(%p, %p)", accessRef
, sourceRef
); 
 244         Access::required(accessRef
)->setAccess(*aclBearer(sourceRef
), true); 
 249 SecKeychainItemCopyAccess(SecKeychainItemRef itemRef
, SecAccessRef
* accessRef
) 
 253         secdebug("kcitem", "SecKeychainItemCopyAccess(%p, %p)", itemRef
, accessRef
); 
 254         Required(accessRef
);    // preflight 
 255         SecPointer
<Access
> access 
= new Access(*aclBearer(reinterpret_cast<CFTypeRef
>(itemRef
))); 
 256         *accessRef 
= access
->handle(); 
 263 SecKeychainItemSetAccess(SecKeychainItemRef itemRef
, SecAccessRef accessRef
) 
 267         secdebug("kcitem", "SecKeychainItemSetAccess(%p, %p)", itemRef
, accessRef
); 
 268         Access::required(accessRef
)->setAccess(*aclBearer(reinterpret_cast<CFTypeRef
>(itemRef
)), true);