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 "SecBridge.h"
21 #include "KCExceptions.h"
26 // Given a polymorphic Sec type object, return
27 // its AclBearer component.
28 // Note: Login ACLs are not hooked into this layer;
29 // modules or attachments have no Sec* layer representation.
31 RefPointer
<AclBearer
> aclBearer(CFTypeRef itemRef
)
33 // well, exactly what kind of something are you?
34 CFTypeID id
= CFGetTypeID(itemRef
);
35 if (id
== gTypes().item
.typeId
) {
36 // keychain item. If it's in a protected group, return the group key
37 if (SSGroup group
= gTypes().item
.required(SecKeychainItemRef(itemRef
))->group())
39 } else if (id
== gTypes().keyItem
.typeId
) {
41 //@@@ not hooked up yet
42 } else if (id
== gTypes().keychain
.typeId
) {
43 // keychain (this yields the database ACL)
44 //@@@ not hooked up yet
47 MacOSError::throwMe(errSecNoAccessForItem
);
52 SecKeychainItemGetTypeID(void)
56 return gTypes().item
.typeId
;
58 END_SECAPI1(_kCFRuntimeNotATypeID
)
63 SecKeychainItemCreateFromContent(SecItemClass itemClass
, SecKeychainAttributeList
*attrList
,
64 UInt32 length
, const void *data
, SecKeychainRef keychainRef
,
65 SecAccessRef initialAccess
, SecKeychainItemRef
*itemRef
)
68 KCThrowParamErrIf_(length
!=0 && data
==NULL
);
69 Item
item(itemClass
, attrList
, length
, data
);
71 item
->setAccess(gTypes().access
.required(initialAccess
));
72 Keychain::optional(keychainRef
)->add(item
);
74 *itemRef
= gTypes().item
.handle(*item
);
80 SecKeychainItemModifyContent(SecKeychainItemRef itemRef
, const SecKeychainAttributeList
*attrList
, UInt32 length
, const void *data
)
83 Item item
= gTypes().item
.required(itemRef
);
84 item
->modifyContent(attrList
, length
, data
);
90 SecKeychainItemCopyContent(SecKeychainItemRef itemRef
, SecItemClass
*itemClass
, SecKeychainAttributeList
*attrList
, UInt32
*length
, void **outData
)
93 Item item
= gTypes().item
.required(itemRef
);
94 item
->getContent(itemClass
, attrList
, length
, outData
);
100 SecKeychainItemFreeContent(SecKeychainAttributeList
*attrList
, void *data
)
103 ItemImpl::freeContent(attrList
, data
);
109 SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef
, const SecKeychainAttributeList
*attrList
, UInt32 length
, const void *data
)
112 Item item
= gTypes().item
.required(itemRef
);
113 item
->modifyAttributesAndData(attrList
, length
, data
);
119 SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef
, SecKeychainAttributeInfo
*info
, SecItemClass
*itemClass
, SecKeychainAttributeList
**attrList
, UInt32
*length
, void **outData
)
122 Item item
= gTypes().item
.required(itemRef
);
123 item
->getAttributesAndData(info
, itemClass
, attrList
, length
, outData
);
129 SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList
*attrList
, void *data
)
132 ItemImpl::freeAttributesAndData(attrList
, data
);
138 SecKeychainItemDelete(SecKeychainItemRef itemRef
)
141 Item item
= gTypes().item
.required( itemRef
);
142 Keychain keychain
= item
->keychain();
143 KCThrowIf_( !keychain
, errSecInvalidItemRef
);
145 keychain
->deleteItem( item
); // item must be persistant.
151 SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef
, SecKeychainRef
* keychainRef
)
154 Required(keychainRef
) = gTypes().keychain
.handle(*gTypes().item
.required(itemRef
)->keychain());
160 SecKeychainItemCreateCopy(SecKeychainItemRef itemRef
, SecKeychainRef destKeychainRef
,
161 SecAccessRef initialAccess
, SecKeychainItemRef
*itemCopy
)
164 Item copy
= gTypes().item
.required(itemRef
)->copyTo(Keychain::optional(destKeychainRef
));
166 *itemCopy
= gTypes().item
.handle(*copy
);
172 SecKeychainItemGetUniqueRecordID(SecKeychainItemRef keyItemRef
, CSSM_DB_UNIQUE_RECORD
* uniqueRecordID
)
175 uniqueRecordID
= gTypes().item
.required(keyItemRef
)->dbUniqueRecord();
181 SecKeychainItemGetDLDBHandle(SecKeychainItemRef itemRef
, CSSM_DL_DB_HANDLE
* dldbHandle
)
184 *dldbHandle
= gTypes().item
.required(itemRef
)->keychain()->database()->handle();
189 OSStatus
SecAccessCreateFromObject(CFTypeRef sourceRef
,
190 SecAccessRef
*accessRef
)
193 Required(accessRef
); // preflight
194 RefPointer
<Access
> access
= new Access(*aclBearer(sourceRef
));
195 *accessRef
= gTypes().access
.handle(*access
);
202 OSStatus
SecAccessModifyObject(SecAccessRef accessRef
, CFTypeRef sourceRef
)
205 gTypes().access
.required(accessRef
)->setAccess(*aclBearer(sourceRef
), true);
210 SecKeychainItemCopyAccess(SecKeychainItemRef itemRef
, SecAccessRef
* accessRef
)
214 Required(accessRef
); // preflight
215 RefPointer
<Access
> access
= new Access(*aclBearer(reinterpret_cast<CFTypeRef
>(itemRef
)));
216 *accessRef
= gTypes().access
.handle(*access
);
223 SecKeychainItemSetAccess(SecKeychainItemRef itemRef
, SecAccessRef accessRef
)
227 gTypes().access
.required(accessRef
)->setAccess(*aclBearer(reinterpret_cast<CFTypeRef
>(itemRef
)), true);