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);