2 * Copyright (c) 2000-2001 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.
27 #include "cssmdatetime.h"
29 #include "StorageManager.h"
30 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
31 #include <Security/SecKeychainAPIPriv.h>
33 using namespace KeychainCore
;
34 using namespace CssmClient
;
35 using namespace CSSMDateTimeUtils
;
40 KCCursorImpl::KCCursorImpl(const StorageManager::KeychainList
&searchList
, SecItemClass itemClass
, const SecKeychainAttributeList
*attrList
) :
41 mSearchList(searchList
),
42 mCurrent(mSearchList
.begin())
44 recordType(Schema::recordTypeFor(itemClass
));
46 if (!attrList
) // No additional selectionPredicates: we are done
49 conjunctive(CSSM_DB_AND
);
50 const SecKeychainAttribute
*end
=&attrList
->attr
[attrList
->count
];
51 // Add all the attrs in attrs list to the cursor.
52 for (const SecKeychainAttribute
*attr
=attrList
->attr
; attr
!= end
; ++attr
)
54 const CssmDbAttributeInfo
&info
= Schema::attributeInfo(attr
->tag
);
55 void *buf
= attr
->data
;
56 UInt32 length
= attr
->length
;
59 // XXX This code is duplicated in NewItemImpl::setAttribute()
60 // Convert a 4 or 8 byte TIME_DATE to a CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
61 // style attribute value.
62 if (info
.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
)
64 if (length
== sizeof(UInt32
))
66 MacSecondsToTimeString(*reinterpret_cast<const UInt32
*>(buf
),
71 else if (length
== sizeof(SInt64
))
73 MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64
*>(buf
),
79 add(CSSM_DB_EQUAL
,info
, CssmData(buf
,length
));
83 KCCursorImpl::KCCursorImpl(const StorageManager::KeychainList
&searchList
, const SecKeychainAttributeList
*attrList
) :
84 mSearchList(searchList
),
85 mCurrent(mSearchList
.begin())
87 if (!attrList
) // No additional selectionPredicates: we are done
90 conjunctive(CSSM_DB_AND
);
91 bool foundClassAttribute
=false;
92 const SecKeychainAttribute
*end
=&attrList
->attr
[attrList
->count
];
93 // Add all the attrs in attrs list to the cursor.
94 for (const SecKeychainAttribute
*attr
=attrList
->attr
; attr
!= end
; ++attr
)
96 if (attr
->tag
!=kSecClassItemAttr
) // a regular attribute
98 const CssmDbAttributeInfo
&info
= Schema::attributeInfo(attr
->tag
);
99 void *buf
= attr
->data
;
100 UInt32 length
= attr
->length
;
101 uint8 timeString
[16];
103 // XXX This code is duplicated in NewItemImpl::setAttribute()
104 // Convert a 4 or 8 byte TIME_DATE to a CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
105 // style attribute value.
106 if (info
.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
)
108 if (length
== sizeof(UInt32
))
110 MacSecondsToTimeString(*reinterpret_cast<const UInt32
*>(buf
),
115 else if (length
== sizeof(SInt64
))
117 MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64
*>(buf
),
123 add(CSSM_DB_EQUAL
,info
, CssmData(buf
,length
));
128 // the class attribute
129 if (foundClassAttribute
|| attr
->length
!= sizeof(SecItemClass
))
130 MacOSError::throwMe(paramErr
); // We have 2 different 'clas' attributes
132 recordType(Schema::recordTypeFor(*reinterpret_cast<SecItemClass
*>(attr
->data
)));
133 foundClassAttribute
=true;
137 KCCursorImpl::~KCCursorImpl()
142 KCCursorImpl::next(Item
&item
)
144 DbAttributes dbAttributes
;
145 DbUniqueRecord uniqueId
;
151 if (mCurrent
== mSearchList
.end())
153 // No more keychains to search so we are done.
157 mDbCursor
= DbCursor((*mCurrent
)->database(), *this);
163 gotRecord
= mDbCursor
->next(&dbAttributes
, NULL
, uniqueId
);
165 catch(const CssmCommonError
&err
)
167 OSStatus status
= err
.osStatus();
168 if (status
!= CSSMERR_DL_DATASTORE_DOESNOT_EXIST
169 && status
!= CSSMERR_DL_INVALID_RECORDTYPE
)
175 // If we did not get a record from the current keychain or the current
176 // keychain did not exist skip to the next keychain in the list.
180 mDbCursor
= DbCursor();
184 // If doing a search for all records skip the db blob added by the
185 // CSP/DL and skip symmetric key items.
186 // @@@ This is wrong since we should only skip symmetric keys that are
187 // group keys and not user generated symmetric keys.
188 if (mDbCursor
->recordType() == CSSM_DL_DB_RECORD_ANY
&&
189 (dbAttributes
.recordType() == 0x80008000
190 || dbAttributes
.recordType() == CSSM_DL_DB_RECORD_SYMMETRIC_KEY
))
196 // Go though Keychain since item might already exist.
197 item
= (*mCurrent
)->item(dbAttributes
.recordType(), uniqueId
);