]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/cssmdb.cpp
Security-54.1.3.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / cssmdb.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 // cssmdb.cpp
20 //
21 //
22
23 #ifdef __MWERKS__
24 #define _CPP_UTILITIES
25 #endif
26
27 #include <Security/cssmdb.h>
28
29 #if 0
30 // XXX Obsolete
31 CSSM_RETURN AddFooToIntelList( void** theIntelListToAddItTo, unsigned long* theNumberOfThingsAlreadyInTheList, const void* theThingToAdd, size_t theSizeOfTheThingToAdd)
32 { // this is to make adding things to Intel LISTs (also called Arrays by the rest of us) easy! We do it everywhere! Join the fun!
33 CSSM_RETURN result = CSSM_OK;
34 void* theReallocatedBuffer = NULL;
35 if( *theIntelListToAddItTo == NULL )
36 {
37
38 *theIntelListToAddItTo = malloc(theSizeOfTheThingToAdd);
39 if(!*theIntelListToAddItTo)
40 {
41 result = CSSMERR_CSSM_MEMORY_ERROR;
42 }
43 }
44 else
45 {
46 theReallocatedBuffer = realloc((void*)*theIntelListToAddItTo, (*theNumberOfThingsAlreadyInTheList+1) * (theSizeOfTheThingToAdd) );
47 if(!theReallocatedBuffer)
48 {
49 result = CSSMERR_CSSM_MEMORY_ERROR;
50 }
51 else
52 {
53 *theIntelListToAddItTo = theReallocatedBuffer;
54 }
55 }
56
57 if(result == CSSM_OK )
58 {
59 memcpy( (void*)((char*)*theIntelListToAddItTo+(theSizeOfTheThingToAdd * (*theNumberOfThingsAlreadyInTheList))), theThingToAdd, theSizeOfTheThingToAdd);
60 (*theNumberOfThingsAlreadyInTheList)++;
61 }
62
63 return result;
64 }
65 #endif
66
67 //
68 // CssmDbAttributeInfo
69 //
70 bool
71 CssmDbAttributeInfo::operator <(const CssmDbAttributeInfo& other) const
72 {
73 if (nameFormat() < other.nameFormat()) return true;
74 if (other.nameFormat() < nameFormat()) return false;
75 // nameFormat's are equal.
76 switch (nameFormat())
77 {
78 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
79 {
80 int res = strcmp(static_cast<const char *>(*this), static_cast<const char *>(other));
81 if (res < 0) return true;
82 if (res > 0) return false;
83 break;
84 }
85 case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
86 if (static_cast<const CssmOid &>(*this) < static_cast<const CssmOid &>(other)) return true;
87 if (static_cast<const CssmOid &>(other) < static_cast<const CssmOid &>(*this)) return false;
88 break;
89 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
90 if (static_cast<uint32>(*this) < static_cast<uint32>(other)) return true;
91 if (static_cast<uint32>(other) < static_cast<uint32>(*this)) return false;
92 break;
93 default:
94 CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
95 }
96
97 return format() < other.format();
98 }
99
100 bool
101 CssmDbAttributeInfo::operator ==(const CssmDbAttributeInfo& other) const
102 {
103 if (nameFormat() != other.nameFormat()) return false;
104 if (format() != other.format()) return false;
105 switch (nameFormat())
106 {
107 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
108 return !strcmp(static_cast<const char *>(*this), static_cast<const char *>(other));
109 case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
110 return static_cast<const CssmOid &>(*this) == static_cast<const CssmOid &>(other);
111 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
112 return static_cast<uint32>(*this) == static_cast<uint32>(other);
113 default:
114 CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
115 }
116 }
117
118 //
119 // CssmDbAttributeData
120 //
121 void
122 CssmDbAttributeData::deleteValues(CssmAllocator &inAllocator)
123 {
124 // Loop over all values and delete each one.
125 if (Value)
126 {
127 for (uint32 anIndex = 0; anIndex < NumberOfValues; anIndex++)
128 {
129 if (Value[anIndex].Data)
130 {
131 inAllocator.free(Value[anIndex].Data);
132 }
133
134 Value[anIndex].Length = 0;
135 }
136
137 inAllocator.free(Value);
138 Value = NULL;
139 }
140
141 NumberOfValues = 0;
142 }
143
144 bool
145 CssmDbAttributeData::operator <(const CssmDbAttributeData &other) const
146 {
147 if (info() < other.info()) return true;
148 if (other.info() < info()) return false;
149
150 uint32 minSize = min(size(), other.size());
151 for (uint32 ix = 0; ix < minSize; ++ix)
152 {
153 if (at<const CssmData &>(ix) < other.at<const CssmData &>(ix))
154 return true;
155 if (other.at<const CssmData &>(ix) < at<const CssmData &>(ix))
156 return false;
157 }
158
159 return size() < other.size();
160 }
161
162 void
163 CssmDbAttributeData::add(const CssmDbAttributeData &src, CssmAllocator &inAllocator)
164 {
165 // Add all the values from another attribute into this attribute.
166
167 Value = reinterpret_cast<CSSM_DATA *>(inAllocator.realloc(Value,
168 sizeof(*Value) * (NumberOfValues + src.NumberOfValues)));
169
170 for (uint32 srcIndex = 0; srcIndex < src.NumberOfValues; srcIndex++) {
171 uint32 destIndex = NumberOfValues + srcIndex;
172
173 Value[destIndex].Length = 0;
174 Value[destIndex].Data = inAllocator.alloc<uint8>(src.Value[srcIndex].Length);
175 Value[destIndex].Length = src.Value[srcIndex].Length;
176 memcpy(Value[destIndex].Data, src.Value[srcIndex].Data, src.Value[srcIndex].Length);
177 }
178
179 NumberOfValues += src.NumberOfValues;
180 }
181
182 bool
183 CssmDbAttributeData::deleteValue(const CssmData &src, CssmAllocator &inAllocator)
184 {
185 // Delete a single value from this attribute, if it is present.
186
187 for (uint32 i = 0; i < NumberOfValues; i++)
188 if (CssmData::overlay(Value[i]) == src)
189 {
190 inAllocator.free(Value[i].Data);
191 Value[i].Length = 0;
192
193 NumberOfValues--;
194 Value[i].Data = Value[NumberOfValues].Data;
195 Value[i].Length = Value[NumberOfValues].Length;
196
197 return true;
198 }
199
200 return false;
201 }
202
203 // Delete those values found in src from this object, if they are present.
204 // Warning: This is O(N^2) worst case; if this becomes a performance bottleneck
205 // then it will need to be changed.
206
207 void
208 CssmDbAttributeData::deleteValues(const CssmDbAttributeData &src, CssmAllocator &inAllocator)
209 {
210 for (uint32 i = 0; i < src.NumberOfValues; i++)
211 deleteValue(CssmData::overlay(src.Value[i]), inAllocator);
212 }
213
214 //
215 // CssmDbRecordAttributeData
216 //
217 CssmDbAttributeData *
218 CssmDbRecordAttributeData::find(const CSSM_DB_ATTRIBUTE_INFO &inInfo)
219 {
220 const CssmDbAttributeInfo &anInfo = CssmDbAttributeInfo::overlay(inInfo);
221 for (uint32 ix = 0; ix < size(); ++ix)
222 {
223 if (at(ix).info() == anInfo)
224 return &at(ix);
225 }
226
227 return NULL;
228 }
229
230 bool
231 CssmDbRecordAttributeData::operator <(const CssmDbRecordAttributeData &other) const
232 {
233 if (recordType() < other.recordType()) return true;
234 if (other.recordType() < recordType()) return false;
235 if (semanticInformation() < other.semanticInformation()) return true;
236 if (other.semanticInformation() < semanticInformation()) return false;
237
238 uint32 minSize = min(size(), other.size());
239 for (uint32 ix = 0; ix < minSize; ++ix)
240 {
241 if (at(ix) < other.at(ix))
242 return true;
243 if (other.at(ix) < at(ix))
244 return false;
245 }
246
247 return size() < other.size();
248 }
249
250
251 //
252 // CssmAutoDbRecordAttributeData
253 //
254 CssmAutoDbRecordAttributeData::~CssmAutoDbRecordAttributeData()
255 {
256 clear();
257 }
258
259 void
260 CssmAutoDbRecordAttributeData::clear()
261 {
262 deleteValues();
263 ArrayBuilder<CssmDbAttributeData>::clear();
264 }
265
266
267
268 static bool CompareAttributeInfos (const CSSM_DB_ATTRIBUTE_INFO &a, const CSSM_DB_ATTRIBUTE_INFO &b)
269 {
270 // check the format of the names
271 if (a.AttributeNameFormat != b.AttributeNameFormat)
272 {
273 return false;
274 }
275
276 switch (a.AttributeNameFormat)
277 {
278 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
279 {
280 return strcmp (a.Label.AttributeName, b.Label.AttributeName) == 0;
281 }
282
283 case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
284 {
285 if (a.Label.AttributeOID.Length != b.Label.AttributeOID.Length)
286 {
287 return false;
288 }
289
290 return memcmp (a.Label.AttributeOID.Data, b.Label.AttributeOID.Data, a.Label.AttributeOID.Length) == 0;
291 }
292
293
294 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
295 {
296 return a.Label.AttributeID == b.Label.AttributeID;
297 }
298 }
299
300 return true; // just to keep the compiler from complaining
301 }
302
303
304
305 CssmDbAttributeData* CssmAutoDbRecordAttributeData::findAttribute (const CSSM_DB_ATTRIBUTE_INFO &info)
306 {
307 // walk through the data, looking for an attribute of the same type
308 int i;
309 for (i = 0; i < size (); ++i)
310 {
311 CssmDbAttributeData& d = at (i);
312 CSSM_DB_ATTRIBUTE_INFO &inInfo = d.info ();
313
314 if (CompareAttributeInfos (info, inInfo))
315 {
316 return &d;
317 }
318 }
319
320 // found nothing?
321 return NULL;
322 }
323
324
325
326 CssmDbAttributeData& CssmAutoDbRecordAttributeData::getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO &info)
327 {
328 // Either find an existing reference to an attribute in the list, or make a new one.
329 CssmDbAttributeData *anAttr = findAttribute (info);
330 if (anAttr) // was this already in the list?
331 {
332 // clean it up
333 anAttr->deleteValues (mValueAllocator);
334 }
335 else
336 {
337 // make a new one
338 anAttr = &add();
339 }
340
341 return *anAttr;
342 }
343
344
345
346 CssmDbAttributeData &
347 CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO &info)
348 {
349 CssmDbAttributeData& anAttr = getAttributeReference (info);
350 anAttr.info(info);
351 return anAttr;
352 }
353
354 CssmDbAttributeData &
355 CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value)
356 {
357 CssmDbAttributeData &anAttr = getAttributeReference (info);
358 anAttr.set(info, value, mValueAllocator);
359 return anAttr;
360 }
361
362 //
363 // CssmAutoQuery
364 //
365 CssmAutoQuery::CssmAutoQuery(const CSSM_QUERY &query, CssmAllocator &allocator)
366 : ArrayBuilder<CssmSelectionPredicate>(static_cast<CssmSelectionPredicate *>(SelectionPredicate),
367 NumSelectionPredicates,
368 query.NumSelectionPredicates, allocator)
369 {
370 RecordType = query.RecordType;
371 Conjunctive = query.Conjunctive;
372 QueryLimits = query.QueryLimits;
373 QueryFlags = query.QueryFlags;
374 for (uint32 ix = 0; ix < query.NumSelectionPredicates; ++ix)
375 add().set(query.SelectionPredicate[ix], allocator);
376 }
377
378 CssmAutoQuery::~CssmAutoQuery()
379 {
380 clear();
381 }
382
383 void
384 CssmAutoQuery::clear()
385 {
386 deleteValues();
387 ArrayBuilder<CssmSelectionPredicate>::clear();
388 }
389
390 CssmSelectionPredicate &
391 CssmAutoQuery::add(CSSM_DB_OPERATOR dbOperator, const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value)
392 {
393 CssmSelectionPredicate &predicate = add();
394 predicate.dbOperator(dbOperator);
395 predicate.set(info, value, allocator());
396 return predicate;
397 }