]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
fa7225c8 | 2 | * Copyright (c) 2000-2004,2011-2016 Apple Inc. All Rights Reserved. |
5c19dc3a | 3 | * |
b1ab9ed8 | 4 | * @APPLE_LICENSE_HEADER_START@ |
5c19dc3a | 5 | * |
b1ab9ed8 A |
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 | |
11 | * file. | |
5c19dc3a | 12 | * |
b1ab9ed8 A |
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. | |
5c19dc3a | 20 | * |
b1ab9ed8 A |
21 | * @APPLE_LICENSE_HEADER_END@ |
22 | */ | |
23 | ||
24 | #include <Security/SecKeychainSearch.h> | |
25 | #include <Security/SecKeychainSearchPriv.h> | |
5c19dc3a | 26 | #include <Security/SecCertificatePriv.h> |
b1ab9ed8 | 27 | #include <security_keychain/KCCursor.h> |
5c19dc3a | 28 | #include <security_keychain/Certificate.h> |
b1ab9ed8 | 29 | #include <security_keychain/Item.h> |
5c19dc3a A |
30 | #include <security_cdsa_utilities/Schema.h> |
31 | #include <syslog.h> | |
866f8763 | 32 | #include <os/activity.h> |
b1ab9ed8 A |
33 | |
34 | #include "SecBridge.h" | |
35 | ||
36 | CFTypeID | |
37 | SecKeychainSearchGetTypeID(void) | |
38 | { | |
39 | BEGIN_SECAPI | |
40 | ||
41 | return gTypes().KCCursorImpl.typeID; | |
42 | ||
43 | END_SECAPI1(_kCFRuntimeNotATypeID) | |
44 | } | |
45 | ||
46 | ||
47 | OSStatus | |
48 | SecKeychainSearchCreateFromAttributes(CFTypeRef keychainOrArray, SecItemClass itemClass, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef) | |
49 | { | |
50 | BEGIN_SECAPI | |
866f8763 A |
51 | os_activity_t activity = os_activity_create("SecKeychainSearchCreateFromAttributes", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT); |
52 | os_activity_scope(activity); | |
53 | os_release(activity); | |
b1ab9ed8 A |
54 | |
55 | Required(searchRef); | |
56 | ||
57 | StorageManager::KeychainList keychains; | |
58 | globals().storageManager.optionalSearchList(keychainOrArray, keychains); | |
59 | KCCursor cursor(keychains, itemClass, attrList); | |
60 | *searchRef = cursor->handle(); | |
61 | ||
62 | END_SECAPI | |
63 | } | |
64 | ||
65 | ||
66 | OSStatus | |
67 | SecKeychainSearchCreateFromAttributesExtended(CFTypeRef keychainOrArray, SecItemClass itemClass, const SecKeychainAttributeList *attrList, CSSM_DB_CONJUNCTIVE dbConjunctive, CSSM_DB_OPERATOR dbOperator, SecKeychainSearchRef *searchRef) | |
68 | { | |
69 | BEGIN_SECAPI | |
866f8763 A |
70 | os_activity_t activity = os_activity_create("SecKeychainSearchCreateFromAttributesExtended", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT); |
71 | os_activity_scope(activity); | |
72 | os_release(activity); | |
5c19dc3a | 73 | |
b1ab9ed8 | 74 | Required(searchRef); // Make sure that searchRef is an invalid SearchRef |
5c19dc3a | 75 | |
b1ab9ed8 A |
76 | StorageManager::KeychainList keychains; |
77 | globals().storageManager.optionalSearchList(keychainOrArray, keychains); | |
78 | KCCursor cursor(keychains, itemClass, attrList, dbConjunctive, dbOperator); | |
5c19dc3a | 79 | |
b1ab9ed8 | 80 | *searchRef = cursor->handle(); |
5c19dc3a | 81 | |
b1ab9ed8 A |
82 | END_SECAPI |
83 | } | |
84 | ||
85 | ||
86 | ||
87 | OSStatus | |
88 | SecKeychainSearchCopyNext(SecKeychainSearchRef searchRef, SecKeychainItemRef *itemRef) | |
89 | { | |
fa7225c8 | 90 | BEGIN_SECAPI |
866f8763 A |
91 | os_activity_t activity = os_activity_create("SecKeychainSearchCopyNext", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT); |
92 | os_activity_scope(activity); | |
93 | os_release(activity); | |
b1ab9ed8 A |
94 | |
95 | RequiredParam(itemRef); | |
96 | Item item; | |
5c19dc3a A |
97 | KCCursorImpl *itemCursor = KCCursorImpl::required(searchRef); |
98 | if (!itemCursor->next(item)) | |
b1ab9ed8 A |
99 | return errSecItemNotFound; |
100 | ||
101 | *itemRef=item->handle(); | |
102 | ||
5c19dc3a A |
103 | bool itemChecked = false; |
104 | do { | |
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); | |
113 | } | |
114 | if (!data) { | |
115 | /* zero-length or otherwise bad cert data; skip to next item */ | |
fa7225c8 A |
116 | if (*itemRef) { |
117 | CFRelease(*itemRef); | |
118 | *itemRef = NULL; | |
119 | } | |
5c19dc3a A |
120 | if (!itemCursor->next(item)) |
121 | return errSecItemNotFound; | |
122 | *itemRef=item->handle(); | |
123 | continue; | |
124 | } | |
125 | SecKeychainItemRef tmpRef = *itemRef; | |
126 | *itemRef = (SecKeychainItemRef) SecCertificateCreateWithKeychainItem(NULL, data, tmpRef); | |
127 | if (data) | |
128 | CFRelease(data); | |
129 | if (tmpRef) | |
130 | CFRelease(tmpRef); | |
fa7225c8 A |
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(); | |
136 | continue; | |
137 | } | |
5c19dc3a | 138 | itemChecked = true; |
fa7225c8 | 139 | } |
5c19dc3a A |
140 | else { |
141 | itemChecked = true; | |
142 | } | |
143 | } while (!itemChecked); | |
fa7225c8 A |
144 | |
145 | if (NULL == *itemRef) { | |
146 | /* never permit a NULL item reference to be returned without an error result */ | |
147 | return errSecItemNotFound; | |
148 | } | |
5c19dc3a | 149 | |
b1ab9ed8 A |
150 | END_SECAPI |
151 | } |