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>
32 #include <os/activity.h>
34 #include "SecBridge.h"
37 SecKeychainSearchGetTypeID(void)
41 return gTypes().KCCursorImpl
.typeID
;
43 END_SECAPI1(_kCFRuntimeNotATypeID
)
48 SecKeychainSearchCreateFromAttributes(CFTypeRef keychainOrArray
, SecItemClass itemClass
, const SecKeychainAttributeList
*attrList
, SecKeychainSearchRef
*searchRef
)
51 os_activity_t activity
= os_activity_create("SecKeychainSearchCreateFromAttributes", OS_ACTIVITY_CURRENT
, OS_ACTIVITY_FLAG_IF_NONE_PRESENT
);
52 os_activity_scope(activity
);
57 StorageManager::KeychainList keychains
;
58 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
59 KCCursor
cursor(keychains
, itemClass
, attrList
);
60 *searchRef
= cursor
->handle();
67 SecKeychainSearchCreateFromAttributesExtended(CFTypeRef keychainOrArray
, SecItemClass itemClass
, const SecKeychainAttributeList
*attrList
, CSSM_DB_CONJUNCTIVE dbConjunctive
, CSSM_DB_OPERATOR dbOperator
, SecKeychainSearchRef
*searchRef
)
70 os_activity_t activity
= os_activity_create("SecKeychainSearchCreateFromAttributesExtended", OS_ACTIVITY_CURRENT
, OS_ACTIVITY_FLAG_IF_NONE_PRESENT
);
71 os_activity_scope(activity
);
74 Required(searchRef
); // Make sure that searchRef is an invalid SearchRef
76 StorageManager::KeychainList keychains
;
77 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
78 KCCursor
cursor(keychains
, itemClass
, attrList
, dbConjunctive
, dbOperator
);
80 *searchRef
= cursor
->handle();
88 SecKeychainSearchCopyNext(SecKeychainSearchRef searchRef
, SecKeychainItemRef
*itemRef
)
91 os_activity_t activity
= os_activity_create("SecKeychainSearchCopyNext", OS_ACTIVITY_CURRENT
, OS_ACTIVITY_FLAG_IF_NONE_PRESENT
);
92 os_activity_scope(activity
);
95 RequiredParam(itemRef
);
97 KCCursorImpl
*itemCursor
= KCCursorImpl::required(searchRef
);
98 if (!itemCursor
->next(item
))
99 return errSecItemNotFound
;
101 *itemRef
=item
->handle();
103 bool itemChecked
= false;
105 /* see if we should convert outgoing item to a unified SecCertificateRef */
106 SecItemClass tmpItemClass
= Schema::itemClassFor(item
->recordType());
107 if (tmpItemClass
== kSecCertificateItemClass
) {
108 SecPointer
<Certificate
> certificate(static_cast<Certificate
*>(&*item
));
109 CssmData certData
= certificate
->data();
110 CFDataRef data
= NULL
;
111 if (certData
.Data
&& certData
.Length
) {
112 data
= CFDataCreate(NULL
, certData
.Data
, certData
.Length
);
115 /* zero-length or otherwise bad cert data; skip to next item */
120 if (!itemCursor
->next(item
))
121 return errSecItemNotFound
;
122 *itemRef
=item
->handle();
125 SecKeychainItemRef tmpRef
= *itemRef
;
126 *itemRef
= (SecKeychainItemRef
) SecCertificateCreateWithKeychainItem(NULL
, data
, tmpRef
);
131 if (NULL
== *itemRef
) {
132 /* unable to create unified certificate item; skip to next item */
133 if (!itemCursor
->next(item
))
134 return errSecItemNotFound
;
135 *itemRef
=item
->handle();
143 } while (!itemChecked
);
145 if (NULL
== *itemRef
) {
146 /* never permit a NULL item reference to be returned without an error result */
147 return errSecItemNotFound
;