]> git.saurik.com Git - apple/security.git/blob - Keychain/SecKeychainItem.cpp
Security-54.tar.gz
[apple/security.git] / Keychain / SecKeychainItem.cpp
1 /*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18 #include <Security/SecKeychainItem.h>
19
20 #include "SecBridge.h"
21 #include "KCExceptions.h"
22 #include "Access.h"
23
24
25 //
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.
30 //
31 RefPointer<AclBearer> aclBearer(CFTypeRef itemRef)
32 {
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())
38 return &*group;
39 } else if (id == gTypes().keyItem.typeId) {
40 // key item
41 //@@@ not hooked up yet
42 } else if (id == gTypes().keychain.typeId) {
43 // keychain (this yields the database ACL)
44 //@@@ not hooked up yet
45 }
46 // Guess not. Bummer
47 MacOSError::throwMe(errSecNoAccessForItem);
48 }
49
50
51 CFTypeID
52 SecKeychainItemGetTypeID(void)
53 {
54 BEGIN_SECAPI
55
56 return gTypes().item.typeId;
57
58 END_SECAPI1(_kCFRuntimeNotATypeID)
59 }
60
61
62 OSStatus
63 SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList,
64 UInt32 length, const void *data, SecKeychainRef keychainRef,
65 SecAccessRef initialAccess, SecKeychainItemRef *itemRef)
66 {
67 BEGIN_SECAPI
68 KCThrowParamErrIf_(length!=0 && data==NULL);
69 Item item(itemClass, attrList, length, data);
70 if (initialAccess)
71 item->setAccess(gTypes().access.required(initialAccess));
72 Keychain::optional(keychainRef)->add(item);
73 if (itemRef)
74 *itemRef = gTypes().item.handle(*item);
75 END_SECAPI
76 }
77
78
79 OSStatus
80 SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
81 {
82 BEGIN_SECAPI
83 Item item = gTypes().item.required(itemRef);
84 item->modifyContent(attrList, length, data);
85 END_SECAPI
86 }
87
88
89 OSStatus
90 SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
91 {
92 BEGIN_SECAPI
93 Item item = gTypes().item.required(itemRef);
94 item->getContent(itemClass, attrList, length, outData);
95 END_SECAPI
96 }
97
98
99 OSStatus
100 SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data)
101 {
102 BEGIN_SECAPI
103 ItemImpl::freeContent(attrList, data);
104 END_SECAPI
105 }
106
107
108 OSStatus
109 SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
110 {
111 BEGIN_SECAPI
112 Item item = gTypes().item.required(itemRef);
113 item->modifyAttributesAndData(attrList, length, data);
114 END_SECAPI
115 }
116
117
118 OSStatus
119 SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData)
120 {
121 BEGIN_SECAPI
122 Item item = gTypes().item.required(itemRef);
123 item->getAttributesAndData(info, itemClass, attrList, length, outData);
124 END_SECAPI
125 }
126
127
128 OSStatus
129 SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList, void *data)
130 {
131 BEGIN_SECAPI
132 ItemImpl::freeAttributesAndData(attrList, data);
133 END_SECAPI
134 }
135
136
137 OSStatus
138 SecKeychainItemDelete(SecKeychainItemRef itemRef)
139 {
140 BEGIN_SECAPI
141 Item item = gTypes().item.required( itemRef );
142 Keychain keychain = item->keychain();
143 KCThrowIf_( !keychain, errSecInvalidItemRef );
144
145 keychain->deleteItem( item ); // item must be persistant.
146 END_SECAPI
147 }
148
149
150 OSStatus
151 SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychainRef)
152 {
153 BEGIN_SECAPI
154 Required(keychainRef) = gTypes().keychain.handle(*gTypes().item.required(itemRef)->keychain());
155 END_SECAPI
156 }
157
158
159 OSStatus
160 SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainRef destKeychainRef,
161 SecAccessRef initialAccess, SecKeychainItemRef *itemCopy)
162 {
163 BEGIN_SECAPI
164 Item copy = gTypes().item.required(itemRef)->copyTo(Keychain::optional(destKeychainRef));
165 if (itemCopy)
166 *itemCopy = gTypes().item.handle(*copy);
167 END_SECAPI
168 }
169
170
171 OSStatus
172 SecKeychainItemGetUniqueRecordID(SecKeychainItemRef keyItemRef, CSSM_DB_UNIQUE_RECORD* uniqueRecordID)
173 {
174 BEGIN_SECAPI
175 uniqueRecordID = gTypes().item.required(keyItemRef)->dbUniqueRecord();
176 END_SECAPI
177 }
178
179
180 OSStatus
181 SecKeychainItemGetDLDBHandle(SecKeychainItemRef itemRef, CSSM_DL_DB_HANDLE* dldbHandle)
182 {
183 BEGIN_SECAPI
184 *dldbHandle = gTypes().item.required(itemRef)->keychain()->database()->handle();
185 END_SECAPI
186 }
187
188
189 OSStatus SecAccessCreateFromObject(CFTypeRef sourceRef,
190 SecAccessRef *accessRef)
191 {
192 BEGIN_SECAPI
193 Required(accessRef); // preflight
194 RefPointer<Access> access = new Access(*aclBearer(sourceRef));
195 *accessRef = gTypes().access.handle(*access);
196 END_SECAPI
197 }
198
199
200 /*!
201 */
202 OSStatus SecAccessModifyObject(SecAccessRef accessRef, CFTypeRef sourceRef)
203 {
204 BEGIN_SECAPI
205 gTypes().access.required(accessRef)->setAccess(*aclBearer(sourceRef), true);
206 END_SECAPI
207 }
208
209 OSStatus
210 SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef* accessRef)
211 {
212 BEGIN_SECAPI
213
214 Required(accessRef); // preflight
215 RefPointer<Access> access = new Access(*aclBearer(reinterpret_cast<CFTypeRef>(itemRef)));
216 *accessRef = gTypes().access.handle(*access);
217
218 END_SECAPI
219 }
220
221
222 OSStatus
223 SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef accessRef)
224 {
225 BEGIN_SECAPI
226
227 gTypes().access.required(accessRef)->setAccess(*aclBearer(reinterpret_cast<CFTypeRef>(itemRef)), true);
228
229 END_SECAPI
230 }