]> git.saurik.com Git - apple/security.git/blob - Keychain/SecKeychainItem.cpp
Security-179.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 <Security/Keychains.h>
21 #include <Security/KeyItem.h>
22 #include <Security/Item.h>
23
24 #include "SecBridge.h"
25 #include "KCExceptions.h"
26 #include "Access.h"
27
28
29 //
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.
34 //
35 RefPointer<AclBearer> aclBearer(CFTypeRef itemRef)
36 {
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())
42 return &*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())
46 return &*key;
47 } else if (id == gTypes().KeychainImpl.typeID) {
48 // keychain (this yields the database ACL)
49 //@@@ not hooked up yet
50 }
51 // Guess not. Bummer
52 MacOSError::throwMe(errSecNoAccessForItem);
53 }
54
55
56 CFTypeID
57 SecKeychainItemGetTypeID(void)
58 {
59 BEGIN_SECAPI
60
61 secdebug("kcitem", "SecKeychainItemGetTypeID()");
62 return gTypes().ItemImpl.typeID;
63
64 END_SECAPI1(_kCFRuntimeNotATypeID)
65 }
66
67
68 OSStatus
69 SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList,
70 UInt32 length, const void *data, SecKeychainRef keychainRef,
71 SecAccessRef initialAccess, SecKeychainItemRef *itemRef)
72 {
73 BEGIN_SECAPI
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);
78 if (initialAccess)
79 item->setAccess(Access::required(initialAccess));
80
81 Keychain keychain = nil;
82 try
83 {
84 keychain = Keychain::optional(keychainRef);
85 if ( !keychain->exists() )
86 {
87 MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time.
88 }
89 }
90 catch(...)
91 {
92 keychain = globals().storageManager.defaultKeychainUI(item);
93 }
94
95 keychain->add(item);
96 if (itemRef)
97 *itemRef = item->handle();
98 END_SECAPI
99 }
100
101
102 OSStatus
103 SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
104 {
105 BEGIN_SECAPI
106 secdebug("kcitem", "SecKeychainItemModifyContent(%p, %p, %lu, %p)", itemRef, attrList, length, data);
107 Item item = ItemImpl::required(itemRef);
108 item->modifyContent(attrList, length, data);
109 END_SECAPI
110 }
111
112
113 OSStatus
114 SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
115 {
116 BEGIN_SECAPI
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);
121 END_SECAPI
122 }
123
124
125 OSStatus
126 SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data)
127 {
128 BEGIN_SECAPI
129 secdebug("kcitem", "SecKeychainItemFreeContent(%p, %p)", attrList, data);
130 ItemImpl::freeContent(attrList, data);
131 END_SECAPI
132 }
133
134
135 OSStatus
136 SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
137 {
138 BEGIN_SECAPI
139 secdebug("kcitem", "SecKeychainItemModifyAttributesAndData(%p, %p, %lu, %p)", itemRef, attrList, length, data);
140 Item item = ItemImpl::required(itemRef);
141 item->modifyAttributesAndData(attrList, length, data);
142 END_SECAPI
143 }
144
145
146 OSStatus
147 SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData)
148 {
149 BEGIN_SECAPI
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);
153 END_SECAPI
154 }
155
156
157 OSStatus
158 SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList, void *data)
159 {
160 BEGIN_SECAPI
161 secdebug("kcitem", "SecKeychainItemFreeAttributesAndData(%p, %p)", attrList, data);
162 ItemImpl::freeAttributesAndData(attrList, data);
163 END_SECAPI
164 }
165
166
167 OSStatus
168 SecKeychainItemDelete(SecKeychainItemRef itemRef)
169 {
170 BEGIN_SECAPI
171 secdebug("kcitem", "SecKeychainItemFreeAttributesAndData(%p)", itemRef);
172 Item item = ItemImpl::required( itemRef );
173 Keychain keychain = item->keychain();
174 KCThrowIf_( !keychain, errSecInvalidItemRef );
175
176 keychain->deleteItem( item ); // item must be persistant.
177 END_SECAPI
178 }
179
180
181 OSStatus
182 SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychainRef)
183 {
184 BEGIN_SECAPI
185 secdebug("kcitem", "SecKeychainItemCopyKeychain(%p, %p)", itemRef, keychainRef);
186 Required(keychainRef) = ItemImpl::required(itemRef)->keychain()->handle();
187 END_SECAPI
188 }
189
190
191 OSStatus
192 SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainRef destKeychainRef,
193 SecAccessRef initialAccess, SecKeychainItemRef *itemCopy)
194 {
195 BEGIN_SECAPI
196 secdebug("kcitem", "SecKeychainItemCreateCopy(%p, %p, %p, %p)",
197 itemRef, destKeychainRef, initialAccess, itemCopy);
198
199 Item copy = ItemImpl::required(itemRef)->copyTo(Keychain::optional(destKeychainRef), Access::optional(initialAccess));
200 if (itemCopy)
201 *itemCopy = copy->handle();
202 END_SECAPI
203 }
204
205
206 OSStatus
207 SecKeychainItemGetUniqueRecordID(SecKeychainItemRef itemRef, const CSSM_DB_UNIQUE_RECORD **uniqueRecordID)
208 {
209 BEGIN_SECAPI
210 secdebug("kcitem", "SecKeychainItemGetUniqueRecordID(%p, %p)", itemRef, uniqueRecordID);
211 Required(uniqueRecordID) = ItemImpl::required(itemRef)->dbUniqueRecord();
212 END_SECAPI
213 }
214
215
216 OSStatus
217 SecKeychainItemGetDLDBHandle(SecKeychainItemRef itemRef, CSSM_DL_DB_HANDLE* dldbHandle)
218 {
219 BEGIN_SECAPI
220 secdebug("kcitem", "SecKeychainItemGetDLDBHandle(%p, %p)", itemRef, dldbHandle);
221 *dldbHandle = ItemImpl::required(itemRef)->keychain()->database()->handle();
222 END_SECAPI
223 }
224
225
226 OSStatus SecAccessCreateFromObject(CFTypeRef sourceRef,
227 SecAccessRef *accessRef)
228 {
229 BEGIN_SECAPI
230 secdebug("kcitem", "SecAccessCreateFromObject(%p, %p)", sourceRef, accessRef);
231 Required(accessRef); // preflight
232 SecPointer<Access> access = new Access(*aclBearer(sourceRef));
233 *accessRef = access->handle();
234 END_SECAPI
235 }
236
237
238 /*!
239 */
240 OSStatus SecAccessModifyObject(SecAccessRef accessRef, CFTypeRef sourceRef)
241 {
242 BEGIN_SECAPI
243 secdebug("kcitem", "SecAccessModifyObject(%p, %p)", accessRef, sourceRef);
244 Access::required(accessRef)->setAccess(*aclBearer(sourceRef), true);
245 END_SECAPI
246 }
247
248 OSStatus
249 SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef* accessRef)
250 {
251 BEGIN_SECAPI
252
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();
257
258 END_SECAPI
259 }
260
261
262 OSStatus
263 SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef accessRef)
264 {
265 BEGIN_SECAPI
266
267 secdebug("kcitem", "SecKeychainItemSetAccess(%p, %p)", itemRef, accessRef);
268 Access::required(accessRef)->setAccess(*aclBearer(reinterpret_cast<CFTypeRef>(itemRef)), true);
269
270 END_SECAPI
271 }