]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m
Security-58286.270.3.0.1.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSViews.m
1 /*
2 * Copyright (c) 2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * SOSViews.c - Implementation of views
26 */
27
28 #include <AssertMacros.h>
29 #include <TargetConditionals.h>
30
31 #include "SOSViews.h"
32 #include <utilities/SecCFWrappers.h>
33 #include <utilities/SecCFRelease.h>
34 #include <utilities/SecXPCError.h>
35
36 #include <utilities/SecCFError.h>
37 #include <utilities/der_set.h>
38 #include <Security/SecureObjectSync/SOSInternal.h>
39
40 #include <Security/SecureObjectSync/SOSPeerInfo.h>
41 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
42 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
43 #include <Security/SecureObjectSync/SOSCloudCircle.h>
44
45 #include <utilities/array_size.h>
46 #include <Security/SecureObjectSync/SOSAccount.h>
47 #include <Security/SecureObjectSync/SOSAccountPriv.h>
48
49 #define viewMemError CFSTR("Failed to get memory for views in PeerInfo")
50 #define viewUnknownError CFSTR("Unknown view(%@) (ViewResultCode=%d)")
51 #define viewInvalidError CFSTR("Peer is invalid for this view(%@) (ViewResultCode=%d)")
52
53 // Internal Views:
54 const CFStringRef kSOSViewKeychainV0_tomb = CFSTR("KeychainV0-tomb"); // iCloud Keychain backup for v0 peers (no tombstones)
55 const CFStringRef kSOSViewBackupBagV0_tomb = CFSTR("BackupBagV0-tomb"); // iCloud Keychain backup bag for v0 peers (no tombstones)
56 const CFStringRef kSOSViewWiFi_tomb = CFSTR("WiFi-tomb");
57 const CFStringRef kSOSViewAutofillPasswords_tomb = CFSTR("Passwords-tomb");
58 const CFStringRef kSOSViewSafariCreditCards_tomb = CFSTR("CreditCards-tomb");
59 const CFStringRef kSOSViewiCloudIdentity_tomb = CFSTR("iCloudIdentity-tomb");
60 const CFStringRef kSOSViewOtherSyncable_tomb = CFSTR("OtherSyncable-tomb");
61
62 // Views
63 const CFStringRef kSOSViewKeychainV0 = CFSTR("KeychainV0"); // iCloud Keychain syncing for v0 peers
64
65 #undef DOVIEWMACRO
66 #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULTSETTING, INITIALSYNCSETTING, ALWAYSONSETTING, BACKUPSETTING, V0SETTING) \
67 const CFStringRef k##SYSTEM##View##VIEWNAME = CFSTR(DEFSTRING);
68 #include "Security/SecureObjectSync/ViewList.list"
69
70 // View Hints
71 // Note that by definition, there cannot be a V0 view hint
72 // These will be deprecated for new constants found in SecItemPriv.h
73 const CFStringRef kSOSViewHintPCSMasterKey = CFSTR("PCS-MasterKey");
74 const CFStringRef kSOSViewHintPCSiCloudDrive = CFSTR("PCS-iCloudDrive");
75 const CFStringRef kSOSViewHintPCSPhotos = CFSTR("PCS-Photos");
76 const CFStringRef kSOSViewHintPCSCloudKit = CFSTR("PCS-CloudKit");
77 const CFStringRef kSOSViewHintPCSEscrow = CFSTR("PCS-Escrow");
78 const CFStringRef kSOSViewHintPCSFDE = CFSTR("PCS-FDE");
79 const CFStringRef kSOSViewHintPCSMailDrop = CFSTR("PCS-Maildrop");
80 const CFStringRef kSOSViewHintPCSiCloudBackup = CFSTR("PCS-Backup");
81 const CFStringRef kSOSViewHintPCSNotes = CFSTR("PCS-Notes");
82 const CFStringRef kSOSViewHintPCSiMessage = CFSTR("PCS-iMessage");
83 const CFStringRef kSOSViewHintPCSFeldspar = CFSTR("PCS-Feldspar");
84
85 const CFStringRef kSOSViewHintAppleTV = CFSTR("AppleTV");
86 const CFStringRef kSOSViewHintHomeKit = CFSTR("HomeKit");
87
88 CFMutableSetRef SOSViewCopyViewSet(ViewSetKind setKind) {
89 CFMutableSetRef result = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
90
91 // Only return views in the SOS system, unless they asked for kViewSetCKKS
92 #undef DOVIEWMACRO
93 #define __TYPE_MEMBER_ false
94 #define __TYPE_MEMBER_D true
95 #define __TYPE_MEMBER_I true
96 #define __TYPE_MEMBER_A true
97 #define __TYPE_MEMBER_V true
98 #define __TYPE_MEMBER_B true
99 #define __SYSTEM_SOS true
100 #define __SYSTEM_CKKS false
101
102 #define DOVIEWMACRO_SOS(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \
103 if(((setKind == kViewSetAll) || \
104 ((setKind == kViewSetDefault) && __TYPE_MEMBER_##DEFAULT) || \
105 ((setKind == kViewSetInitial) && __TYPE_MEMBER_##INITIAL) || \
106 ((setKind == kViewSetAlwaysOn) && __TYPE_MEMBER_##ALWAYSON) || \
107 ((setKind == kViewSetRequiredForBackup) && __TYPE_MEMBER_##BACKUP) || \
108 ((setKind == kViewSetV0) && __TYPE_MEMBER_##V0) )) { \
109 CFSetAddValue(result, k##SYSTEM##View##VIEWNAME); \
110 }
111
112 #define DOVIEWMACRO_CKKS(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \
113 if(setKind == kViewSetCKKS) { \
114 CFSetAddValue(result, k##SYSTEM##View##VIEWNAME); \
115 }
116
117 #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \
118 DOVIEWMACRO_##SYSTEM(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0)
119 #include "Security/SecureObjectSync/ViewList.list"
120
121 return result;
122 }
123
124 bool SOSViewInSOSSystem(CFStringRef view) {
125
126 if(CFEqualSafe(view, kSOSViewKeychainV0)) {
127 return true;
128 }
129
130 #undef DOVIEWMACRO
131 #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \
132 if(CFEqualSafe(view, k##SYSTEM##View##VIEWNAME)) { \
133 return __SYSTEM_##SYSTEM; \
134 }
135 #include "Security/SecureObjectSync/ViewList.list"
136
137 return false;
138 }
139
140 bool SOSViewHintInSOSSystem(CFStringRef viewHint) {
141 #undef DOVIEWMACRO
142 #define CHECK_VIEWHINT_(VIEWNAME, SYSTEM) \
143 if(CFEqualSafe(viewHint, kSecAttrViewHint##VIEWNAME)) { \
144 return __SYSTEM_##SYSTEM; \
145 }
146 #define CHECK_VIEWHINT_V(VIEWNAME, SYSTEM)
147
148 #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \
149 CHECK_VIEWHINT_##V0(VIEWNAME, SYSTEM)
150 #include "Security/SecureObjectSync/ViewList.list"
151
152 return false;
153 }
154
155 bool SOSViewHintInCKKSSystem(CFStringRef viewHint) {
156
157 #undef DOVIEWMACRO_SOS
158 #undef DOVIEWMACRO_CKKS
159 #undef DOVIEWMACRO
160
161 #define DOVIEWMACRO_SOS(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0)
162 #define DOVIEWMACRO_CKKS(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \
163 if(CFEqualSafe(viewHint, kSecAttrViewHint##VIEWNAME)) { \
164 return true; \
165 }
166 #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \
167 DOVIEWMACRO_##SYSTEM(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0)
168
169 #include "Security/SecureObjectSync/ViewList.list"
170
171 return false;
172 }
173
174
175 CFGiblisGetSingleton(CFSetRef, SOSViewsGetV0ViewSet, defaultViewSet, ^{
176 // Since peer->views must never be NULL, fill in with a default
177 const void *values[] = { kSOSViewKeychainV0 };
178 *defaultViewSet = CFSetCreate(kCFAllocatorDefault, values, array_size(values), &kCFTypeSetCallBacks);
179 });
180
181 CFGiblisGetSingleton(CFSetRef, SOSViewsGetV0SubviewSet, subViewSet, (^{
182 // Since peer->views must never be NULL, fill in with a default
183 *subViewSet = SOSViewCopyViewSet(kViewSetV0);
184 }));
185
186 CFGiblisGetSingleton(CFSetRef, SOSViewsGetV0BackupViewSet, defaultViewSet, ^{
187 const void *values[] = { kSOSViewKeychainV0_tomb };
188 *defaultViewSet = CFSetCreate(kCFAllocatorDefault, values, array_size(values), &kCFTypeSetCallBacks);
189 });
190
191 CFGiblisGetSingleton(CFSetRef, SOSViewsGetV0BackupBagViewSet, defaultViewSet, ^{
192 const void *values[] = { kSOSViewBackupBagV0_tomb };
193 *defaultViewSet = CFSetCreate(kCFAllocatorDefault, values, array_size(values), &kCFTypeSetCallBacks);
194 });
195
196
197 CFGiblisGetSingleton(CFSetRef, SOSViewsGetInitialSyncSubviewSet, subViewSet, (^{
198 *subViewSet = SOSViewCopyViewSet(kViewSetInitial);
199 }));
200
201
202 bool SOSViewsIsV0Subview(CFStringRef viewName) {
203 return CFSetContainsValue(SOSViewsGetV0SubviewSet(), viewName);
204 }
205
206 CFSetRef sTestViewSet = NULL;
207 void SOSViewsSetTestViewsSet(CFSetRef testViewNames) {
208 CFRetainAssign(sTestViewSet, testViewNames);
209 }
210
211 CFSetRef SOSViewsGetAllCurrent(void) {
212 static dispatch_once_t dot;
213 static CFMutableSetRef allViews = NULL;
214 dispatch_once(&dot, ^{
215 allViews = SOSViewCopyViewSet(kViewSetAll);
216
217 CFSetAddValue(allViews, kSOSViewKeychainV0);
218 if(sTestViewSet) CFSetUnion(allViews, sTestViewSet);
219 });
220 return allViews;
221 }
222
223 static CFDictionaryRef SOSViewsGetBitmasks(void) {
224 static dispatch_once_t once;
225 static CFMutableDictionaryRef masks = NULL;
226
227 dispatch_once(&once, ^{
228 CFSetRef views = SOSViewsGetAllCurrent();
229 CFMutableArrayRef viewArray = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
230 CFSetForEach(views, ^(const void *value) {
231 CFStringRef viewName = (CFStringRef) value;
232 CFArrayAppendValue(viewArray, viewName);
233 });
234 CFIndex viewCount = CFArrayGetCount(viewArray);
235 if(viewCount > 32) {
236 secnotice("views", "Too many views defined, can't make bitmask (%d)", (int) viewCount);
237 } else {
238 __block uint32_t maskValue = 1;
239 CFRange all = CFRangeMake(0, viewCount);
240 CFArraySortValues(viewArray, all, (CFComparatorFunction)CFStringCompare, NULL);
241 masks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, NULL);
242 CFArrayForEach(viewArray, ^(const void *value) {
243 CFDictionaryAddValue(masks, value, (const void *) (uintptr_t) maskValue);
244 maskValue <<= 1;
245 });
246 }
247 CFReleaseNull(viewArray);
248 });
249 return masks;
250 }
251
252 static uint64_t SOSViewBitmaskFromSet(CFSetRef views) {
253 __block uint64_t retval = 0;
254 CFDictionaryRef masks = SOSViewsGetBitmasks();
255 if(masks) {
256 CFSetForEach(views, ^(const void *viewName) {
257 uint64_t viewMask = (uint64_t) CFDictionaryGetValue(masks, viewName);
258 retval |= viewMask;
259 });
260 }
261 return retval;
262 }
263
264 uint64_t SOSPeerInfoViewBitMask(SOSPeerInfoRef pi) {
265 __block uint64_t retval = 0;
266 CFSetRef views = SOSPeerInfoCopyEnabledViews(pi);
267 if(views) {
268 retval = SOSViewBitmaskFromSet(views);
269 CFReleaseNull(views);
270 }
271 return retval;
272 }
273
274 CFSetRef SOSViewCreateSetFromBitmask(uint64_t bitmask) {
275 CFMutableSetRef retval = NULL;
276 CFDictionaryRef masks = SOSViewsGetBitmasks();
277 if(masks) {
278 retval = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
279 CFDictionaryForEach(masks, ^(const void *key, const void *value) {
280 CFStringRef viewName = (CFStringRef) key;
281 uint64_t viewMask = (uint64_t) value;
282 if(bitmask & viewMask) {
283 CFSetAddValue(retval, viewName);
284 }
285 });
286 }
287 return retval;
288 }
289
290 const char *SOSViewsXlateAction(SOSViewActionCode action) {
291 switch(action) {
292 case kSOSCCViewEnable: return "kSOSCCViewEnable";
293 case kSOSCCViewDisable: return "kSOSCCViewDisable";
294 case kSOSCCViewQuery: return "kSOSCCViewQuery";
295 default: return "unknownViewAction";
296 }
297 }
298
299
300 // Eventually this will want to know the gestalt or security properties...
301 void SOSViewsForEachDefaultEnabledViewName(void (^operation)(CFStringRef viewName)) {
302 CFMutableSetRef defaultViews = SOSViewCopyViewSet(kViewSetDefault);
303
304 CFSetForEach(defaultViews, ^(const void *value) {
305 CFStringRef name = asString(value, NULL);
306
307 if (name) {
308 operation(name);
309 }
310 });
311
312 CFReleaseNull(defaultViews);
313 }
314
315 static bool SOSViewsIsKnownView(CFStringRef viewname) {
316 CFSetRef allViews = SOSViewsGetAllCurrent();
317 if(CFSetContainsValue(allViews, viewname)) return true;
318 secnotice("views","Not a known view");
319 return false;
320 }
321
322 static bool SOSViewsRequireIsKnownView(CFStringRef viewname, CFErrorRef* error) {
323 return SOSViewsIsKnownView(viewname) || SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, viewUnknownError, viewname, kSOSCCNoSuchView);
324 }
325
326 bool SOSPeerInfoIsEnabledView(SOSPeerInfoRef pi, CFStringRef viewName) {
327 if (pi->version < kSOSPeerV2BaseVersion) {
328 return CFSetContainsValue(SOSViewsGetV0ViewSet(), viewName);
329 } else {
330 return SOSPeerInfoV2DictionaryHasSetContaining(pi, sViewsKey, viewName);
331 }
332 }
333
334 void SOSPeerInfoWithEnabledViewSet(SOSPeerInfoRef pi, void (^operation)(CFSetRef enabled)) {
335 if (pi->version < kSOSPeerV2BaseVersion) {
336 operation(SOSViewsGetV0ViewSet());
337 } else {
338 SOSPeerInfoV2DictionaryWithSet(pi, sViewsKey, operation);
339 }
340 }
341
342 CFMutableSetRef SOSPeerInfoCopyEnabledViews(SOSPeerInfoRef pi) {
343 if (pi->version < kSOSPeerV2BaseVersion) {
344 return CFSetCreateMutableCopy(kCFAllocatorDefault, CFSetGetCount(SOSViewsGetV0ViewSet()), SOSViewsGetV0ViewSet());
345 } else {
346 CFMutableSetRef views = SOSPeerInfoV2DictionaryCopySet(pi, sViewsKey);
347 if (!views) {
348 // This is unexpected: log and return an empty set to prevent <rdar://problem/21938868>
349 secerror("%@ v2 peer has no views", SOSPeerInfoGetPeerID(pi));
350 views = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
351 }
352 return views;
353 }
354 }
355
356 CFSetRef SOSPeerInfoGetPermittedViews(SOSPeerInfoRef pi) {
357 return SOSViewsGetAllCurrent();
358 }
359
360 static void SOSPeerInfoSetViews(SOSPeerInfoRef pi, CFSetRef newviews) {
361 if(!newviews) {
362 secnotice("views","Asked to swap to NULL views");
363 return;
364 }
365 SOSPeerInfoV2DictionarySetValue(pi, sViewsKey, newviews);
366 }
367
368 static bool SOSPeerInfoViewIsValid(SOSPeerInfoRef pi, CFStringRef viewname) {
369 return true;
370 }
371
372 SOSViewResultCode SOSViewsEnable(SOSPeerInfoRef pi, CFStringRef viewname, CFErrorRef *error) {
373 SOSViewResultCode retval = kSOSCCGeneralViewError;
374
375 CFMutableSetRef newviews = SOSPeerInfoCopyEnabledViews(pi);
376 require_action_quiet(newviews, fail,
377 SOSCreateError(kSOSErrorAllocationFailure, viewMemError, NULL, error));
378 require_action_quiet(SOSViewsRequireIsKnownView(viewname, error), fail,
379 retval = kSOSCCNoSuchView);
380 require_action_quiet(SOSPeerInfoViewIsValid(pi, viewname), fail,
381 SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, viewInvalidError, viewname, retval = kSOSCCViewNotQualified));
382 CFSetAddValue(newviews, viewname);
383 SOSPeerInfoSetViews(pi, newviews);
384 CFReleaseSafe(newviews);
385 return kSOSCCViewMember;
386
387 fail:
388 CFReleaseNull(newviews);
389 secnotice("views","Failed to enable view(%@): %@", viewname, error ? *error : NULL);
390 return retval;
391 }
392
393 bool SOSViewSetEnable(SOSPeerInfoRef pi, CFSetRef viewSet) {
394 __block bool addedView = false;
395 CFMutableSetRef newviews = SOSPeerInfoCopyEnabledViews(pi);
396 require_action_quiet(newviews, errOut, secnotice("views", "failed to copy enabled views"));
397
398 CFSetForEach(viewSet, ^(const void *value) {
399 CFStringRef viewName = (CFStringRef) value;
400 if(SOSViewsIsKnownView(viewName) && SOSPeerInfoViewIsValid(pi, viewName)) {
401 if (!CFSetContainsValue(newviews, viewName)) {
402 addedView = true;
403 CFSetAddValue(newviews, viewName);
404 }
405 } else {
406 secnotice("views", "couldn't add view %@", viewName);
407 }
408 });
409 require_quiet(addedView, errOut);
410
411 SOSPeerInfoSetViews(pi, newviews);
412
413 errOut:
414 CFReleaseNull(newviews);
415 return addedView;
416 }
417
418
419 SOSViewResultCode SOSViewsDisable(SOSPeerInfoRef pi, CFStringRef viewname, CFErrorRef *error) {
420 SOSViewResultCode retval = kSOSCCGeneralViewError;
421 CFMutableSetRef newviews = SOSPeerInfoCopyEnabledViews(pi);
422 require_action_quiet(newviews, fail,
423 SOSCreateError(kSOSErrorAllocationFailure, viewMemError, NULL, error));
424 require_action_quiet(SOSViewsRequireIsKnownView(viewname, error), fail, retval = kSOSCCNoSuchView);
425
426 CFSetRemoveValue(newviews, viewname);
427 SOSPeerInfoSetViews(pi, newviews);
428 CFReleaseSafe(newviews);
429 return kSOSCCViewNotMember;
430
431 fail:
432 CFReleaseNull(newviews);
433 secnotice("views","Failed to disable view(%@): %@", viewname, error ? *error : NULL);
434 return retval;
435 }
436
437
438 bool SOSViewSetDisable(SOSPeerInfoRef pi, CFSetRef viewSet) {
439 __block bool removed = false;
440 CFMutableSetRef newviews = SOSPeerInfoCopyEnabledViews(pi);
441 require_action_quiet(newviews, errOut, secnotice("views", "failed to copy enabled views"));
442
443 CFSetForEach(viewSet, ^(const void *value) {
444 CFStringRef viewName = (CFStringRef) value;
445 if(SOSViewsIsKnownView(viewName) && CFSetContainsValue(newviews, viewName)) {
446 removed = true;
447 CFSetRemoveValue(newviews, viewName);
448 } else {
449 secnotice("views", "couldn't delete view %@", viewName);
450 }
451 });
452
453 require_quiet(removed, errOut);
454
455 SOSPeerInfoSetViews(pi, newviews);
456
457 errOut:
458 CFReleaseNull(newviews);
459 return removed;
460 }
461
462
463 SOSViewResultCode SOSViewsQuery(SOSPeerInfoRef pi, CFStringRef viewname, CFErrorRef *error) {
464 SOSViewResultCode retval = kSOSCCNoSuchView;
465 CFSetRef views = NULL;
466 require_quiet(SOSViewsRequireIsKnownView(viewname, error), fail);
467
468 views = SOSPeerInfoCopyEnabledViews(pi);
469 if(!views){
470 retval = kSOSCCViewNotMember;
471 CFReleaseNull(views);
472 return retval;
473 }
474
475 // kSOSViewKeychainV0 is set if there is a V0 PeerInfo in the circle. It represents all of the subviews in
476 // SOSViewsGetV0SubviewSet() so we return kSOSCCViewMember for that case. kSOSViewKeychainV0 and the subviews
477 // are mutually exclusive.
478 else if(CFSetContainsValue(views, kSOSViewKeychainV0) && CFSetContainsValue(SOSViewsGetV0SubviewSet(), viewname)) {
479 retval = kSOSCCViewMember;
480 } else {
481 retval = (CFSetContainsValue(views, viewname)) ? kSOSCCViewMember: kSOSCCViewNotMember;
482 }
483
484 CFReleaseNull(views);
485 return retval;
486
487 fail:
488 secnotice("views","Failed to query view(%@): %@", viewname, error ? *error : NULL);
489 CFReleaseNull(views);
490 return retval;
491 }
492
493
494 /* Need XPC way to carry CFSets of views */
495
496
497
498 xpc_object_t CreateXPCObjectWithCFSetRef(CFSetRef setref, CFErrorRef *error) {
499 xpc_object_t result = NULL;
500 size_t data_size = 0;
501 uint8_t *data = NULL;
502 require_action_quiet(setref, errOut, SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedNull, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Unexpected Null Set to encode")));
503 require_quiet((data_size = der_sizeof_set(setref, error)) != 0, errOut);
504 require_quiet((data = (uint8_t *)malloc(data_size)) != NULL, errOut);
505
506 der_encode_set(setref, error, data, data + data_size);
507 result = xpc_data_create(data, data_size);
508 free(data);
509 errOut:
510 return result;
511 }
512