2 * Copyright (c) 2000-2004,2011-2016 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <Security/SecKeychainSearch.h>
25 #include <Security/SecKeychainSearchPriv.h>
26 #include <Security/SecCertificatePriv.h>
27 #include <security_keychain/KCCursor.h>
28 #include <security_keychain/Certificate.h>
29 #include <security_keychain/Item.h>
30 #include <security_cdsa_utilities/Schema.h>
33 #include "SecBridge.h"
36 SecKeychainSearchGetTypeID(void)
40 return gTypes().KCCursorImpl
.typeID
;
42 END_SECAPI1(_kCFRuntimeNotATypeID
)
47 SecKeychainSearchCreateFromAttributes(CFTypeRef keychainOrArray
, SecItemClass itemClass
, const SecKeychainAttributeList
*attrList
, SecKeychainSearchRef
*searchRef
)
53 StorageManager::KeychainList keychains
;
54 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
55 KCCursor
cursor(keychains
, itemClass
, attrList
);
56 *searchRef
= cursor
->handle();
63 SecKeychainSearchCreateFromAttributesExtended(CFTypeRef keychainOrArray
, SecItemClass itemClass
, const SecKeychainAttributeList
*attrList
, CSSM_DB_CONJUNCTIVE dbConjunctive
, CSSM_DB_OPERATOR dbOperator
, SecKeychainSearchRef
*searchRef
)
67 Required(searchRef
); // Make sure that searchRef is an invalid SearchRef
69 StorageManager::KeychainList keychains
;
70 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
71 KCCursor
cursor(keychains
, itemClass
, attrList
, dbConjunctive
, dbOperator
);
73 *searchRef
= cursor
->handle();
81 SecKeychainSearchCopyNext(SecKeychainSearchRef searchRef
, SecKeychainItemRef
*itemRef
)
85 RequiredParam(itemRef
);
87 KCCursorImpl
*itemCursor
= KCCursorImpl::required(searchRef
);
88 if (!itemCursor
->next(item
))
89 return errSecItemNotFound
;
91 *itemRef
=item
->handle();
94 bool itemChecked
= false;
96 /* see if we should convert outgoing item to a unified SecCertificateRef */
97 SecItemClass tmpItemClass
= Schema::itemClassFor(item
->recordType());
98 if (tmpItemClass
== kSecCertificateItemClass
) {
99 SecPointer
<Certificate
> certificate(static_cast<Certificate
*>(&*item
));
100 CssmData certData
= certificate
->data();
101 CFDataRef data
= NULL
;
102 if (certData
.Data
&& certData
.Length
) {
103 data
= CFDataCreate(NULL
, certData
.Data
, certData
.Length
);
106 /* zero-length or otherwise bad cert data; skip to next item */
111 if (!itemCursor
->next(item
))
112 return errSecItemNotFound
;
113 *itemRef
=item
->handle();
116 SecKeychainItemRef tmpRef
= *itemRef
;
117 *itemRef
= (SecKeychainItemRef
) SecCertificateCreateWithKeychainItem(NULL
, data
, tmpRef
);
122 if (NULL
== *itemRef
) {
123 /* unable to create unified certificate item; skip to next item */
124 if (!itemCursor
->next(item
))
125 return errSecItemNotFound
;
126 *itemRef
=item
->handle();
134 } while (!itemChecked
);
136 if (NULL
== *itemRef
) {
137 /* never permit a NULL item reference to be returned without an error result */
138 return errSecItemNotFound
;