]> git.saurik.com Git - apple/security.git/blob - Keychain/KCCursor.cpp
Security-28.tar.gz
[apple/security.git] / Keychain / KCCursor.cpp
1 /*
2 * Copyright (c) 2000-2001 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
19 //
20 // KCCursor.cpp
21 //
22
23 #include "KCCursor.h"
24
25 #include "Item.h"
26 #include "Schema.h"
27 #include "cssmdatetime.h"
28 #include "Globals.h"
29 #include "StorageManager.h"
30 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
31
32 using namespace KeychainCore;
33 using namespace CssmClient;
34 using namespace CSSMDateTimeUtils;
35
36 //
37 // KCCursorImpl
38 //
39 KCCursorImpl::KCCursorImpl(const DbCursor &dbCursor, SecItemClass itemClass, const SecKeychainAttributeList *attrList)
40 : mDbCursor(dbCursor)
41 {
42 if (!attrList) // No additional selectionPredicates: we are done
43 return;
44
45
46 mDbCursor->recordType(Schema::recordTypeFor(itemClass));
47
48 mDbCursor->conjunctive(CSSM_DB_AND);
49 const SecKeychainAttribute *end=&attrList->attr[attrList->count];
50 // Add all the attrs in attrs list to the cursor.
51 for (const SecKeychainAttribute *attr=attrList->attr; attr != end; ++attr)
52 {
53 const CssmDbAttributeInfo &info = Schema::attributeInfo(attr->tag);
54 void *buf = attr->data;
55 UInt32 length = attr->length;
56 uint8 timeString[16];
57
58 // XXX This code is duplicated in NewItemImpl::setAttribute()
59 // Convert a 4 or 8 byte TIME_DATE to a CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
60 // style attribute value.
61 if (info.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
62 {
63 if (length == sizeof(UInt32))
64 {
65 MacSecondsToTimeString(*reinterpret_cast<const UInt32 *>(buf),
66 16, &timeString);
67 buf = &timeString;
68 length = 16;
69 }
70 else if (length == sizeof(SInt64))
71 {
72 MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64 *>(buf),
73 16, &timeString);
74 buf = &timeString;
75 length = 16;
76 }
77 }
78 mDbCursor->add(CSSM_DB_EQUAL,info, CssmData(buf,length));
79 }
80 }
81
82 KCCursorImpl::KCCursorImpl(const DbCursor &dbCursor, const SecKeychainAttributeList *attrList)
83 : mDbCursor(dbCursor)
84 {
85 if (!attrList) // No additional selectionPredicates: we are done
86 return;
87
88 mDbCursor->conjunctive(CSSM_DB_AND);
89 bool foundClassAttribute=false;
90 const SecKeychainAttribute *end=&attrList->attr[attrList->count];
91 // Add all the attrs in attrs list to the cursor.
92 for (const SecKeychainAttribute *attr=attrList->attr; attr != end; ++attr)
93 {
94 if (attr->tag!=kSecClassItemAttr) // a regular attribute
95 {
96 const CssmDbAttributeInfo &info = Schema::attributeInfo(attr->tag);
97 void *buf = attr->data;
98 UInt32 length = attr->length;
99 uint8 timeString[16];
100
101 // XXX This code is duplicated in NewItemImpl::setAttribute()
102 // Convert a 4 or 8 byte TIME_DATE to a CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
103 // style attribute value.
104 if (info.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
105 {
106 if (length == sizeof(UInt32))
107 {
108 MacSecondsToTimeString(*reinterpret_cast<const UInt32 *>(buf),
109 16, &timeString);
110 buf = &timeString;
111 length = 16;
112 }
113 else if (length == sizeof(SInt64))
114 {
115 MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64 *>(buf),
116 16, &timeString);
117 buf = &timeString;
118 length = 16;
119 }
120 }
121 mDbCursor->add(CSSM_DB_EQUAL,info, CssmData(buf,length));
122
123 continue;
124 }
125
126 // the class attribute
127 if (foundClassAttribute || attr->length != sizeof(SecItemClass))
128 MacOSError::throwMe(paramErr); // We have 2 different 'clas' attributes
129
130 mDbCursor->recordType(Schema
131 ::recordTypeFor(*reinterpret_cast<SecItemClass *>(attr->data)));
132 foundClassAttribute=true;
133 }
134 }
135
136 KCCursorImpl::~KCCursorImpl()
137 {
138 }
139
140 bool
141 KCCursorImpl::next(Item &item)
142 {
143 DbAttributes dbAttributes;
144 DbUniqueRecord uniqueId;
145 if (!mDbCursor)
146 MacOSError::throwMe(errSecInvalidSearchRef);
147
148 for (;;)
149 {
150 if (!mDbCursor->next(&dbAttributes, NULL, uniqueId))
151 {
152 // Forget my resources.
153 mDbCursor = DbCursor();
154 return false;
155 }
156
157 // Skip records that we don't have a matching itemClass for,
158 // since we can't do anything with them.
159 if (Schema::itemClassFor(dbAttributes.recordType()))
160 break;
161 }
162
163 Keychain keychain = globals().storageManager.keychain(uniqueId->database()->dlDbIdentifier());
164 // Go though Keychain since item might already exist.
165 item = keychain->item(dbAttributes.recordType(), uniqueId);
166 return true;
167 }