2 * Copyright (c) 2007-2015 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/SecureObjectSync/SOSPeerInfoDER.h>
25 #include <Security/SecureObjectSync/SOSCloudCircle.h>
26 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
27 #include <Security/SecureObjectSync/SOSInternal.h>
28 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
29 #include <Security/SecBasePriv.h>
30 #include <Security/SecCertificatePriv.h>
31 #include <Security/SecEntitlements.h>
32 #include <Security/SecInternal.h>
33 #include <Security/SecItemPriv.h> /* For SecItemDeleteAll */
34 #include <Security/SecPolicyInternal.h>
35 #include <Security/SecTask.h>
36 #include <Security/SecuritydXPC.h>
37 #include <securityd/OTATrustUtilities.h>
38 #include <securityd/SOSCloudCircleServer.h>
39 #include <securityd/SecItemBackupServer.h>
40 #include <securityd/SecItemServer.h>
41 #include <securityd/SecLogSettingsServer.h>
42 #include <securityd/SecOTRRemote.h>
43 #include <securityd/SecTrustServer.h>
44 #include <securityd/SecTrustStoreServer.h>
45 #include <securityd/iCloudTrace.h>
46 #include <securityd/spi.h>
47 #include <utilities/SecCFError.h>
48 #include <utilities/SecCFWrappers.h>
49 #include <utilities/SecDb.h>
50 #include <utilities/SecIOFormat.h>
51 #include <utilities/SecXPCError.h>
52 #include <utilities/debugging.h>
54 #include <AssertMacros.h>
55 #include <CoreFoundation/CFXPCBridge.h>
56 #include <CoreFoundation/CoreFoundation.h>
58 #include <bsm/libbsm.h>
59 #include <ipc/securityd_client.h>
60 #include <libkern/OSAtomic.h>
61 #include <mach/mach.h>
62 #include <mach/message.h>
64 #include <sys/queue.h>
65 #include <sys/sysctl.h>
67 #include <xpc/private.h>
70 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
71 #include <Security/SecTaskPriv.h>
74 static CFStringRef
SecTaskCopyStringForEntitlement(SecTaskRef task
,
75 CFStringRef entitlement
)
77 CFStringRef value
= (CFStringRef
)SecTaskCopyValueForEntitlement(task
,
79 if (value
&& CFGetTypeID(value
) != CFStringGetTypeID()) {
87 static CFArrayRef
SecTaskCopyArrayOfStringsForEntitlement(SecTaskRef task
,
88 CFStringRef entitlement
)
90 CFArrayRef value
= (CFArrayRef
)SecTaskCopyValueForEntitlement(task
,
93 if (CFGetTypeID(value
) == CFArrayGetTypeID()) {
94 CFIndex ix
, count
= CFArrayGetCount(value
);
95 for (ix
= 0; ix
< count
; ++ix
) {
96 CFStringRef string
= (CFStringRef
)CFArrayGetValueAtIndex(value
, ix
);
97 if (CFGetTypeID(string
) != CFStringGetTypeID()) {
112 static CFStringRef
SecTaskCopyApplicationIdentifier(SecTaskRef task
) {
113 return SecTaskCopyStringForEntitlement(task
,
114 kSecEntitlementApplicationIdentifier
);
117 static CFArrayRef
SecTaskCopySharedWebCredentialDomains(SecTaskRef task
) {
118 return SecTaskCopyArrayOfStringsForEntitlement(task
,
119 kSecEntitlementAssociatedDomains
);
122 static CFArrayRef
SecTaskCopyAccessGroups(SecTaskRef task
) {
123 CFMutableArrayRef groups
= NULL
;
124 CFArrayRef keychainAccessGroups
= SecTaskCopyArrayOfStringsForEntitlement(task
,
125 kSecEntitlementKeychainAccessGroups
);
126 CFArrayRef appleSecurityApplicationGroups
= SecTaskCopyArrayOfStringsForEntitlement(task
,
127 kSecEntitlementAppleSecurityApplicationGroups
);
128 CFStringRef appID
= SecTaskCopyApplicationIdentifier(task
);
129 CFIndex kagLen
= keychainAccessGroups
? CFArrayGetCount(keychainAccessGroups
) : 0;
130 CFIndex asagLen
= appleSecurityApplicationGroups
? CFArrayGetCount(appleSecurityApplicationGroups
) : 0;
131 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
132 if ((appID
|| asagLen
) && !SecTaskEntitlementsValidated(task
)) {
133 CFReleaseNull(appID
);
137 CFIndex len
= kagLen
+ asagLen
+ (appID
? 1 : 0);
139 groups
= CFArrayCreateMutable(kCFAllocatorDefault
, len
, &kCFTypeArrayCallBacks
);
141 CFArrayAppendArray(groups
, keychainAccessGroups
, CFRangeMake(0, kagLen
));
143 CFArrayAppendValue(groups
, appID
);
145 CFArrayAppendArray(groups
, appleSecurityApplicationGroups
, CFRangeMake(0, asagLen
));
146 #if TARGET_IPHONE_SIMULATOR
148 secwarning("No keychain access group specified whilst running in simulator, falling back to default set");
149 groups
= (CFMutableArrayRef
)CFRetainSafe(SecAccessGroupsGetCurrent());
153 CFReleaseSafe(appID
);
154 CFReleaseSafe(keychainAccessGroups
);
155 CFReleaseSafe(appleSecurityApplicationGroups
);
159 static bool SecTaskGetBooleanValueForEntitlement(SecTaskRef task
,
160 CFStringRef entitlement
) {
161 CFStringRef canModify
= (CFStringRef
)SecTaskCopyValueForEntitlement(task
,
165 CFTypeID canModifyType
= CFGetTypeID(canModify
);
166 bool ok
= (CFBooleanGetTypeID() == canModifyType
) && CFBooleanGetValue((CFBooleanRef
)canModify
);
167 CFRelease(canModify
);
171 static void with_label_and_password(xpc_object_t message
, void (^action
)(CFStringRef label
, CFDataRef password
)) {
172 const char *label_utf8
= xpc_dictionary_get_string(message
, kSecXPCKeyUserLabel
);
174 if (label_utf8
) { // Anything we would do here requires a user label
175 size_t password_length
= 0;
176 const void *password_data
= xpc_dictionary_get_data(message
, kSecXPCKeyUserPassword
, &password_length
);
178 CFDataRef user_password
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, password_data
, password_length
, kCFAllocatorNull
);
179 CFStringRef user_label
= CFStringCreateWithCString(kCFAllocatorDefault
, label_utf8
, kCFStringEncodingUTF8
);
181 action(user_label
, user_password
);
183 CFReleaseNull(user_password
);
184 CFReleaseNull(user_label
);
188 static void with_label_and_password_and_dsid(xpc_object_t message
, void (^action
)(CFStringRef label
, CFDataRef password
, CFStringRef dsid
)) {
189 const char *label_utf8
= xpc_dictionary_get_string(message
, kSecXPCKeyUserLabel
);
191 if (label_utf8
) { // Anything we would do here requires a user label
192 size_t password_length
= 0;
193 const void *password_data
= xpc_dictionary_get_data(message
, kSecXPCKeyUserPassword
, &password_length
);
194 const char *xdsid
= xpc_dictionary_get_string(message
, kSecXPCKeyDSID
);
196 CFDataRef user_password
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, password_data
, password_length
, kCFAllocatorNull
);
197 CFStringRef user_label
= CFStringCreateWithCString(kCFAllocatorDefault
, label_utf8
, kCFStringEncodingUTF8
);
198 CFStringRef dsid
= CFStringCreateWithCString(kCFAllocatorDefault
, xdsid
, kCFStringEncodingUTF8
);
200 action(user_label
, user_password
, dsid
);
203 CFReleaseNull(user_password
);
204 CFReleaseNull(user_label
);
208 static void with_label_and_number(xpc_object_t message
, void (^action
)(CFStringRef label
, uint64_t number
)) {
209 const char *label_utf8
= xpc_dictionary_get_string(message
, kSecXPCKeyViewName
);
210 const int64_t number
= xpc_dictionary_get_int64(message
, kSecXPCKeyViewActionCode
);
211 secnotice("views", "Action Code Raw is %d", (int) number
);
212 CFStringRef user_label
= CFStringCreateWithCString(kCFAllocatorDefault
, label_utf8
, kCFStringEncodingUTF8
);
214 action(user_label
, number
);
215 CFReleaseNull(user_label
);
218 static bool SecXPCDictionarySetChainOptional(xpc_object_t message
, const char *key
, SecCertificatePathRef path
, CFErrorRef
*error
) {
221 xpc_object_t xpc_chain
= SecCertificatePathCopyXPCArray(path
, error
);
225 xpc_dictionary_set_value(message
, key
, xpc_chain
);
226 xpc_release(xpc_chain
);
230 static SecCertificateRef
SecXPCDictionaryCopyCertificate(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
232 const void *bytes
= xpc_dictionary_get_data(message
, key
, &length
);
234 SecCertificateRef certificate
= SecCertificateCreateWithBytes(kCFAllocatorDefault
, bytes
, length
);
237 SecError(errSecDecode
, error
, CFSTR("object for key %s failed to create certificate from data"), key
);
239 SecError(errSecParam
, error
, CFSTR("object for key %s missing"), key
);
244 static bool SecXPCDictionaryCopyCertificates(xpc_object_t message
, const char *key
, CFArrayRef
*certificates
, CFErrorRef
*error
) {
245 xpc_object_t xpc_certificates
= xpc_dictionary_get_value(message
, key
);
246 if (!xpc_certificates
)
247 return SecError(errSecAllocate
, error
, CFSTR("no certs for key %s"), key
);
248 *certificates
= SecCertificateXPCArrayCopyArray(xpc_certificates
, error
);
249 return *certificates
;
252 static bool SecXPCDictionaryCopyCertificatesOptional(xpc_object_t message
, const char *key
, CFArrayRef
*certificates
, CFErrorRef
*error
) {
253 xpc_object_t xpc_certificates
= xpc_dictionary_get_value(message
, key
);
254 if (!xpc_certificates
) {
255 *certificates
= NULL
;
258 *certificates
= SecCertificateXPCArrayCopyArray(xpc_certificates
, error
);
259 return *certificates
;
262 static bool SecXPCDictionaryCopyPoliciesOptional(xpc_object_t message
, const char *key
, CFArrayRef
*policies
, CFErrorRef
*error
) {
263 xpc_object_t xpc_policies
= xpc_dictionary_get_value(message
, key
);
269 *policies
= SecPolicyXPCArrayCopyArray(xpc_policies
, error
);
270 return *policies
!= NULL
;
273 static SecTrustStoreRef
SecXPCDictionaryGetTrustStore(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
274 SecTrustStoreRef ts
= NULL
;
275 CFStringRef domain
= SecXPCDictionaryCopyString(message
, key
, error
);
277 ts
= SecTrustStoreForDomainName(domain
, error
);
283 static bool SecXPCDictionaryGetDouble(xpc_object_t message
, const char *key
, double *pvalue
, CFErrorRef
*error
) {
284 *pvalue
= xpc_dictionary_get_double(message
, key
);
285 if (*pvalue
== NAN
) {
286 return SecError(errSecParam
, error
, CFSTR("object for key %s bad double"), key
);
291 static CFDataRef
CFDataCreateWithXPCArrayAtIndex(xpc_object_t xpc_data_array
, size_t index
, CFErrorRef
*error
) {
292 CFDataRef data
= NULL
;
294 const uint8_t *bytes
= xpc_array_get_data(xpc_data_array
, index
, &length
);
296 data
= CFDataCreate(kCFAllocatorDefault
, bytes
, length
);
299 SecError(errSecParam
, error
, CFSTR("data_array[%zu] failed to decode"), index
);
304 static CFArrayRef
CFDataXPCArrayCopyArray(xpc_object_t xpc_data_array
, CFErrorRef
*error
) {
305 CFMutableArrayRef data_array
= NULL
;
306 require_action_quiet(xpc_get_type(xpc_data_array
) == XPC_TYPE_ARRAY
, exit
,
307 SecError(errSecParam
, error
, CFSTR("data_array xpc value is not an array")));
308 size_t count
= xpc_array_get_count(xpc_data_array
);
309 require_action_quiet(data_array
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
310 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
313 for (ix
= 0; ix
< count
; ++ix
) {
314 CFDataRef data
= CFDataCreateWithXPCArrayAtIndex(xpc_data_array
, ix
, error
);
316 CFRelease(data_array
);
319 CFArraySetValueAtIndex(data_array
, ix
, data
);
327 static bool SecXPCDictionaryCopyCFDataArrayOptional(xpc_object_t message
, const char *key
, CFArrayRef
*data_array
, CFErrorRef
*error
) {
328 xpc_object_t xpc_data_array
= xpc_dictionary_get_value(message
, key
);
329 if (!xpc_data_array
) {
334 *data_array
= CFDataXPCArrayCopyArray(xpc_data_array
, error
);
335 return *data_array
!= NULL
;
338 static CFSetRef
SecXPCSetCreateFromXPCDictionaryElement(xpc_object_t event
, const char *key
) {
339 CFErrorRef error
= NULL
;
340 xpc_object_t object
= xpc_dictionary_get_value(event
, key
);
341 CFSetRef retval
= NULL
;
342 if(object
) retval
= CreateCFSetRefFromXPCObject(object
, &error
);
343 CFReleaseNull(error
);
348 static void securityd_xpc_dictionary_handler(const xpc_connection_t connection
, xpc_object_t event
) {
349 xpc_type_t type
= xpc_get_type(event
);
350 __block CFErrorRef error
= NULL
;
351 xpc_object_t xpcError
= NULL
;
352 xpc_object_t replyMessage
= NULL
;
353 SecTaskRef clientTask
= NULL
;
354 CFDataRef clientAuditToken
= NULL
;
355 CFArrayRef accessGroups
= NULL
;
356 CFArrayRef domains
= NULL
;
358 secdebug("serverxpc", "entering");
359 if (type
== XPC_TYPE_DICTIONARY
) {
360 // TODO: Find out what we're dispatching.
361 replyMessage
= xpc_dictionary_create_reply(event
);
363 uint64_t operation
= xpc_dictionary_get_uint64(event
, kSecXPCKeyOperation
);
366 audit_token_t auditToken
= {};
367 xpc_connection_get_audit_token(connection
, &auditToken
);
369 clientTask
= SecTaskCreateWithAuditToken(kCFAllocatorDefault
, auditToken
);
370 clientAuditToken
= CFDataCreate(kCFAllocatorDefault
, (const UInt8
*)&auditToken
, sizeof(auditToken
));
371 accessGroups
= SecTaskCopyAccessGroups(clientTask
);
372 if (operation
== sec_add_shared_web_credential_id
|| operation
== sec_copy_shared_web_credential_id
) {
373 domains
= SecTaskCopySharedWebCredentialDomains(clientTask
);
376 // TODO: change back to secdebug
377 secinfo("serverxpc", "XPC [%@] operation: %@ (%" PRIu64
")", clientTask
, SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), operation
);
380 // Ensure that we remain dirty for a minimum of two seconds to avoid jetsam loops.
381 // Refer to rdar://problem/18615626&18616300 for more details.
382 int64_t minimumDirtyInterval
= (int64_t) (2 * NSEC_PER_SEC
);
383 xpc_transaction_begin();
384 dispatch_after(dispatch_time(DISPATCH_TIME_NOW
, minimumDirtyInterval
), dispatch_get_main_queue(), ^{
385 xpc_transaction_end();
389 // operations before kSecXPCOpTryUserCredentials don't need this entitlement.
390 hasEntitlement
= (operation
< kSecXPCOpTryUserCredentials
) ||
391 (clientTask
&& SecTaskGetBooleanValueForEntitlement(clientTask
, kSecEntitlementKeychainCloudCircle
));
393 // Per <rdar://problem/13315020> Disable the entitlement check for "keychain-cloud-circle"
394 // we disable entitlement enforcement. However, we still log so we know who needs the entitlement
396 if (!hasEntitlement
) {
397 CFErrorRef entitlementError
= NULL
;
398 SecError(errSecMissingEntitlement
, &entitlementError
, CFSTR("%@: %@ lacks entitlement %@"), SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), clientTask
, kSecEntitlementKeychainCloudCircle
);
399 secnotice("serverxpc", "MissingEntitlement: %@", entitlementError
);
400 CFReleaseSafe(entitlementError
);
406 case sec_item_add_id
:
408 CFDictionaryRef query
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyQuery
, &error
);
410 CFTypeRef result
= NULL
;
411 if (_SecItemAdd(query
, accessGroups
, &result
, &error
) && result
) {
412 SecXPCDictionarySetPList(replyMessage
, kSecXPCKeyResult
, result
, &error
);
419 case sec_item_copy_matching_id
:
421 CFDictionaryRef query
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyQuery
, &error
);
423 CFTypeRef result
= NULL
;
424 if (_SecItemCopyMatching(query
, accessGroups
, &result
, &error
) && result
) {
425 SecXPCDictionarySetPList(replyMessage
, kSecXPCKeyResult
, result
, &error
);
432 case sec_item_update_id
:
434 CFDictionaryRef query
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyQuery
, &error
);
436 CFDictionaryRef attributesToUpdate
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyAttributesToUpdate
, &error
);
437 if (attributesToUpdate
) {
438 bool result
= _SecItemUpdate(query
, attributesToUpdate
, accessGroups
, &error
);
439 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
440 CFRelease(attributesToUpdate
);
446 case sec_item_delete_id
:
448 CFDictionaryRef query
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyQuery
, &error
);
450 bool result
= _SecItemDelete(query
, accessGroups
, &error
);
451 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
456 case sec_trust_store_contains_id
:
458 SecTrustStoreRef ts
= SecXPCDictionaryGetTrustStore(event
, kSecXPCKeyDomain
, &error
);
460 CFDataRef digest
= SecXPCDictionaryCopyData(event
, kSecXPCKeyDigest
, &error
);
463 if (SecTrustStoreContainsCertificateWithDigest(ts
, digest
, &contains
, &error
))
464 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, contains
);
470 case sec_trust_store_set_trust_settings_id
:
472 if (SecTaskGetBooleanValueForEntitlement(clientTask
, kSecEntitlementModifyAnchorCertificates
)) {
473 SecTrustStoreRef ts
= SecXPCDictionaryGetTrustStore(event
, kSecXPCKeyDomain
, &error
);
475 SecCertificateRef certificate
= SecXPCDictionaryCopyCertificate(event
, kSecXPCKeyCertificate
, &error
);
477 CFTypeRef trustSettingsDictOrArray
= NULL
;
478 if (SecXPCDictionaryCopyPListOptional(event
, kSecXPCKeySettings
, &trustSettingsDictOrArray
, &error
)) {
479 bool result
= _SecTrustStoreSetTrustSettings(ts
, certificate
, trustSettingsDictOrArray
, &error
);
480 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
481 CFReleaseSafe(trustSettingsDictOrArray
);
483 CFRelease(certificate
);
487 SecError(errSecMissingEntitlement
, &error
, CFSTR("%@: %@ lacks entitlement %@"), SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), clientTask
, kSecEntitlementModifyAnchorCertificates
);
491 case sec_trust_store_remove_certificate_id
:
493 if (SecTaskGetBooleanValueForEntitlement(clientTask
, kSecEntitlementModifyAnchorCertificates
)) {
494 SecTrustStoreRef ts
= SecXPCDictionaryGetTrustStore(event
, kSecXPCKeyDomain
, &error
);
496 CFDataRef digest
= SecXPCDictionaryCopyData(event
, kSecXPCKeyDigest
, &error
);
498 bool result
= SecTrustStoreRemoveCertificateWithDigest(ts
, digest
, &error
);
499 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
504 SecError(errSecMissingEntitlement
, &error
, CFSTR("%@: %@ lacks entitlement %@"), SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), clientTask
, kSecEntitlementModifyAnchorCertificates
);
508 case sec_delete_all_id
:
509 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, _SecItemDeleteAll(&error
));
511 case sec_trust_evaluate_id
:
513 CFArrayRef certificates
= NULL
, anchors
= NULL
, policies
= NULL
, responses
= NULL
, scts
= NULL
, trustedLogs
= NULL
;
514 bool anchorsOnly
= xpc_dictionary_get_bool(event
, kSecTrustAnchorsOnlyKey
);
516 if (SecXPCDictionaryCopyCertificates(event
, kSecTrustCertificatesKey
, &certificates
, &error
) &&
517 SecXPCDictionaryCopyCertificatesOptional(event
, kSecTrustAnchorsKey
, &anchors
, &error
) &&
518 SecXPCDictionaryCopyPoliciesOptional(event
, kSecTrustPoliciesKey
, &policies
, &error
) &&
519 SecXPCDictionaryCopyCFDataArrayOptional(event
, kSecTrustResponsesKey
, &responses
, &error
) &&
520 SecXPCDictionaryCopyCFDataArrayOptional(event
, kSecTrustSCTsKey
, &scts
, &error
) &&
521 SecXPCDictionaryCopyArrayOptional(event
, kSecTrustTrustedLogsKey
, &trustedLogs
, &error
) &&
522 SecXPCDictionaryGetDouble(event
, kSecTrustVerifyDateKey
, &verifyTime
, &error
)) {
523 // If we have no error yet, capture connection and reply in block and properly retain them.
524 xpc_retain(connection
);
525 CFRetainSafe(clientTask
);
526 CFRetainSafe(clientAuditToken
);
528 // Clear replyMessage so we don't send a synchronous reply.
529 xpc_object_t asyncReply
= replyMessage
;
532 SecTrustServerEvaluateBlock(clientAuditToken
,
533 certificates
, anchors
, anchorsOnly
, policies
, responses
, scts
, trustedLogs
, verifyTime
, accessGroups
,
534 ^(SecTrustResultType tr
, CFArrayRef details
, CFDictionaryRef info
, SecCertificatePathRef chain
, CFErrorRef replyError
) {
535 // Send back reply now
537 CFRetain(replyError
);
539 xpc_dictionary_set_int64(asyncReply
, kSecTrustResultKey
, tr
);
540 SecXPCDictionarySetPListOptional(asyncReply
, kSecTrustDetailsKey
, details
, &replyError
) &&
541 SecXPCDictionarySetPListOptional(asyncReply
, kSecTrustInfoKey
, info
, &replyError
) &&
542 SecXPCDictionarySetChainOptional(asyncReply
, kSecTrustChainKey
, chain
, &replyError
);
545 secdebug("ipc", "%@ %@ %@", clientTask
, SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), replyError
);
546 xpc_object_t xpcReplyError
= SecCreateXPCObjectWithCFError(replyError
);
548 xpc_dictionary_set_value(asyncReply
, kSecXPCKeyError
, xpcReplyError
);
549 xpc_release(xpcReplyError
);
551 CFRelease(replyError
);
553 secdebug("ipc", "%@ %@ reponding %@", clientTask
, SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), asyncReply
);
556 xpc_connection_send_message(connection
, asyncReply
);
557 xpc_release(asyncReply
);
558 xpc_release(connection
);
559 CFReleaseSafe(clientTask
);
560 CFReleaseSafe(clientAuditToken
);
563 CFReleaseSafe(policies
);
564 CFReleaseSafe(anchors
);
565 CFReleaseSafe(certificates
);
566 CFReleaseSafe(responses
);
568 CFReleaseSafe(trustedLogs
);
571 case sec_keychain_backup_id
:
573 CFDataRef keybag
= NULL
, passcode
= NULL
;
574 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCKeyKeybag
, &keybag
, &error
)) {
575 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCKeyUserPassword
, &passcode
, &error
)) {
576 CFDataRef backup
= _SecServerKeychainBackup(keybag
, passcode
, &error
);
578 SecXPCDictionarySetData(replyMessage
, kSecXPCKeyResult
, backup
, &error
);
581 CFReleaseSafe(passcode
);
583 CFReleaseSafe(keybag
);
587 case sec_keychain_restore_id
:
589 CFDataRef backup
= SecXPCDictionaryCopyData(event
, kSecXPCKeyBackup
, &error
);
591 CFDataRef keybag
= SecXPCDictionaryCopyData(event
, kSecXPCKeyKeybag
, &error
);
593 CFDataRef passcode
= NULL
;
594 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCKeyUserPassword
, &passcode
, &error
)) {
595 bool result
= _SecServerKeychainRestore(backup
, keybag
, passcode
, &error
);
596 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
597 CFReleaseSafe(passcode
);
605 case sec_keychain_sync_update_message_id
:
607 CFDictionaryRef updates
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyQuery
, &error
);
609 CFArrayRef result
= _SecServerKeychainSyncUpdateMessage(updates
, &error
);
610 SecXPCDictionarySetPList(replyMessage
, kSecXPCKeyResult
, result
, &error
);
611 CFReleaseNull(result
);
613 CFReleaseNull(updates
);
616 case sec_keychain_backup_syncable_id
:
618 CFDictionaryRef oldbackup
= NULL
;
619 if (SecXPCDictionaryCopyDictionaryOptional(event
, kSecXPCKeyBackup
, &oldbackup
, &error
)) {
620 CFDataRef keybag
= SecXPCDictionaryCopyData(event
, kSecXPCKeyKeybag
, &error
);
622 CFDataRef passcode
= NULL
;
623 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCKeyUserPassword
, &passcode
, &error
)) {
624 CFDictionaryRef newbackup
= _SecServerBackupSyncable(oldbackup
, keybag
, passcode
, &error
);
626 SecXPCDictionarySetPList(replyMessage
, kSecXPCKeyResult
, newbackup
, &error
);
627 CFRelease(newbackup
);
629 CFReleaseSafe(passcode
);
633 CFReleaseSafe(oldbackup
);
637 case sec_keychain_restore_syncable_id
:
639 CFDictionaryRef backup
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyBackup
, &error
);
641 CFDataRef keybag
= SecXPCDictionaryCopyData(event
, kSecXPCKeyKeybag
, &error
);
643 CFDataRef passcode
= NULL
;
644 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCKeyUserPassword
, &passcode
, &error
)) {
645 bool result
= _SecServerRestoreSyncable(backup
, keybag
, passcode
, &error
);
646 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
647 CFReleaseSafe(passcode
);
655 case sec_item_backup_copy_names_id
:
657 CFArrayRef names
= SecServerItemBackupCopyNames(&error
);
658 SecXPCDictionarySetPListOptional(replyMessage
, kSecXPCKeyResult
, names
, &error
);
659 CFReleaseSafe(names
);
662 case sec_item_backup_handoff_fd_id
:
664 CFStringRef backupName
= SecXPCDictionaryCopyString(event
, kSecXPCKeyBackup
, &error
);
667 fd
= SecServerItemBackupHandoffFD(backupName
, &error
);
668 CFRelease(backupName
);
670 SecXPCDictionarySetFileDescriptor(replyMessage
, kSecXPCKeyResult
, fd
, &error
);
675 case sec_item_backup_set_confirmed_manifest_id
:
677 CFDataRef keybagDigest
= NULL
;
678 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCKeyKeybag
, &keybagDigest
, &error
)) {
679 CFDataRef manifest
= NULL
;
680 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCData
, &manifest
, &error
)) {
681 CFStringRef backupName
= SecXPCDictionaryCopyString(event
, kSecXPCKeyBackup
, &error
);
683 bool result
= SecServerItemBackupSetConfirmedManifest(backupName
, keybagDigest
, manifest
, &error
);
684 CFRelease(backupName
);
685 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
687 CFReleaseSafe(manifest
);
689 CFRelease(keybagDigest
);
693 case sec_item_backup_restore_id
:
696 CFStringRef backupName
= SecXPCDictionaryCopyString(event
, kSecXPCKeyBackup
, &error
);
698 CFStringRef peerID
= NULL
;
699 if (SecXPCDictionaryCopyStringOptional(event
, kSecXPCKeyDigest
, &peerID
, &error
)) {
700 CFDataRef keybag
= SecXPCDictionaryCopyData(event
, kSecXPCKeyKeybag
, &error
);
702 CFDataRef secret
= SecXPCDictionaryCopyData(event
, kSecXPCKeyUserPassword
, &error
);
704 CFDataRef backup
= SecXPCDictionaryCopyData(event
, kSecXPCData
, &error
);
706 result
= SecServerItemBackupRestore(backupName
, peerID
, keybag
, secret
, backup
, &error
);
713 CFReleaseSafe(peerID
);
715 CFRelease(backupName
);
717 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
720 case sec_ota_pki_asset_version_id
:
722 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
723 SecOTAPKIGetCurrentAssetVersion(&error
));
726 case sec_add_shared_web_credential_id
:
728 CFDictionaryRef query
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyQuery
, &error
);
730 CFTypeRef result
= NULL
;
731 CFStringRef appID
= (clientTask
) ? SecTaskCopyApplicationIdentifier(clientTask
) : NULL
;
732 if (_SecAddSharedWebCredential(query
, &auditToken
, appID
, domains
, &result
, &error
) && result
) {
733 SecXPCDictionarySetPList(replyMessage
, kSecXPCKeyResult
, result
, &error
);
736 CFReleaseSafe(appID
);
741 case sec_copy_shared_web_credential_id
:
743 CFDictionaryRef query
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyQuery
, &error
);
745 CFTypeRef result
= NULL
;
746 CFStringRef appID
= (clientTask
) ? SecTaskCopyApplicationIdentifier(clientTask
) : NULL
;
747 if (_SecCopySharedWebCredential(query
, &auditToken
, appID
, domains
, &result
, &error
) && result
) {
748 SecXPCDictionarySetPList(replyMessage
, kSecXPCKeyResult
, result
, &error
);
751 CFReleaseSafe(appID
);
756 case sec_get_log_settings_id
:
758 CFPropertyListRef currentList
= SecCopyLogSettings_Server(&error
);
760 SecXPCDictionarySetPList(replyMessage
, kSecXPCKeyResult
, currentList
, &error
);
762 CFReleaseSafe(currentList
);
765 case sec_set_xpc_log_settings_id
:
767 CFPropertyListRef newSettings
= SecXPCDictionaryCopyPList(event
, kSecXPCKeyQuery
, &error
);
769 SecSetXPCLogSettings_Server(newSettings
, &error
);
771 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, true);
772 CFReleaseNull(newSettings
);
775 case sec_set_circle_log_settings_id
:
777 CFPropertyListRef newSettings
= SecXPCDictionaryCopyPList(event
, kSecXPCKeyQuery
, &error
);
779 SecSetCircleLogSettings_Server(newSettings
, &error
);
781 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, true);
782 CFReleaseNull(newSettings
);
785 case sec_otr_session_create_remote_id
:
787 CFDataRef publicPeerId
= NULL
;
788 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCPublicPeerId
, &publicPeerId
, &error
)) {
789 CFDataRef otrSession
= _SecOTRSessionCreateRemote(publicPeerId
, &error
);
791 SecXPCDictionarySetData(replyMessage
, kSecXPCKeyResult
, otrSession
, &error
);
792 CFRelease(otrSession
);
794 CFReleaseSafe(publicPeerId
);
798 case sec_otr_session_process_packet_remote_id
:
800 CFDataRef sessionData
= NULL
, inputPacket
= NULL
, outputSessionData
= NULL
, outputPacket
= NULL
;
801 bool readyForMessages
= false;
802 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCOTRSession
, &sessionData
, &error
)) {
803 if (SecXPCDictionaryCopyDataOptional(event
, kSecXPCData
, &inputPacket
, &error
)) {
804 bool result
= _SecOTRSessionProcessPacketRemote(sessionData
, inputPacket
, &outputSessionData
, &outputPacket
, &readyForMessages
, &error
);
806 SecXPCDictionarySetData(replyMessage
, kSecXPCOTRSession
, outputSessionData
, &error
);
807 SecXPCDictionarySetData(replyMessage
, kSecXPCData
, outputPacket
, &error
);
808 xpc_dictionary_set_bool(replyMessage
, kSecXPCOTRReady
, readyForMessages
);
809 CFRelease(outputSessionData
);
810 CFRelease(outputPacket
);
812 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, result
);
814 CFReleaseSafe(inputPacket
);
816 CFReleaseSafe(sessionData
);
820 case kSecXPCOpTryUserCredentials
:
821 with_label_and_password(event
, ^(CFStringRef label
, CFDataRef password
) {
822 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
823 SOSCCTryUserCredentials_Server(label
, password
, &error
));
826 case kSecXPCOpSetUserCredentials
:
827 with_label_and_password(event
, ^(CFStringRef label
, CFDataRef password
) {
828 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
829 SOSCCSetUserCredentials_Server(label
, password
, &error
));
832 case kSecXPCOpSetUserCredentialsAndDSID
:
833 with_label_and_password_and_dsid(event
, ^(CFStringRef label
, CFDataRef password
, CFStringRef dsid
) {
834 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
835 SOSCCSetUserCredentialsAndDSID_Server(label
, password
, dsid
, &error
));
839 with_label_and_number(event
, ^(CFStringRef view
, uint64_t actionCode
) {
840 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
841 SOSCCView_Server(view
, (SOSViewActionCode
)actionCode
, &error
));
844 case kSecXPCOpViewSet
:
846 CFSetRef enabledViews
= SecXPCSetCreateFromXPCDictionaryElement(event
, kSecXPCKeyEnabledViewsKey
);
847 CFSetRef disabledViews
= SecXPCSetCreateFromXPCDictionaryElement(event
, kSecXPCKeyDisabledViewsKey
);
848 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCViewSet_Server(enabledViews
, disabledViews
));
849 CFReleaseNull(enabledViews
);
850 CFReleaseNull(disabledViews
);
853 case kSecXPCOpSecurityProperty
:
854 with_label_and_number(event
, ^(CFStringRef property
, uint64_t actionCode
) {
855 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
856 SOSCCSecurityProperty_Server(property
, (SOSSecurityPropertyActionCode
)actionCode
, &error
));
859 case kSecXPCOpCanAuthenticate
:
860 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
861 SOSCCCanAuthenticate_Server(&error
));
863 case kSecXPCOpPurgeUserCredentials
:
864 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
865 SOSCCPurgeUserCredentials_Server(&error
));
867 case kSecXPCOpDeviceInCircle
:
868 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
869 SOSCCThisDeviceIsInCircle_Server(&error
));
871 case kSecXPCOpRequestToJoin
:
872 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
873 SOSCCRequestToJoinCircle_Server(&error
));
875 case kSecXPCOpRequestToJoinAfterRestore
:
876 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
877 SOSCCRequestToJoinCircleAfterRestore_Server(&error
));
879 case kSecXPCOpRequestEnsureFreshParameters
:
880 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
881 SOSCCRequestEnsureFreshParameters_Server(&error
));
883 case kSecXPCOpGetAllTheRings
:
885 CFStringRef ringDescriptions
= SOSCCGetAllTheRings_Server(&error
);
886 xpc_object_t xpc_dictionary
= _CFXPCCreateXPCObjectFromCFObject(ringDescriptions
);
887 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_dictionary
);
888 xpc_release(xpc_dictionary
);
891 case kSecXPCOpApplyToARing
:
893 CFStringRef ringName
= SecXPCDictionaryCopyString(event
, kSecXPCKeyString
, &error
);
894 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCApplyToARing_Server(ringName
, &error
));
895 CFReleaseNull(ringName
);
898 case kSecXPCOpWithdrawlFromARing
:
900 CFStringRef ringName
= SecXPCDictionaryCopyString(event
, kSecXPCKeyString
, &error
);
901 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCWithdrawlFromARing_Server(ringName
, &error
));
902 CFReleaseNull(ringName
);
905 case kSecXPCOpRingStatus
:
907 CFStringRef ringName
= SecXPCDictionaryCopyString(event
, kSecXPCKeyString
, &error
);
908 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCRingStatus_Server(ringName
, &error
));
909 CFReleaseNull(ringName
);
912 case kSecXPCOpEnableRing
:
914 CFStringRef ringName
= SecXPCDictionaryCopyString(event
, kSecXPCKeyString
, &error
);
915 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCEnableRing_Server(ringName
, &error
));
916 CFReleaseNull(ringName
);
919 case kSecXPCOpRequestDeviceID
:
921 CFStringRef deviceID
= SOSCCRequestDeviceID_Server(&error
);
923 SecXPCDictionarySetString(replyMessage
, kSecXPCKeyResult
, deviceID
, &error
);
927 case kSecXPCOpSetDeviceID
:
929 CFStringRef IDS
= SecXPCDictionaryCopyString(event
, kSecXPCKeyDeviceID
, &error
);
930 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCSetDeviceID_Server(IDS
, &error
));
934 case kSecXPCOpHandleIDSMessage
:
936 CFDictionaryRef IDS
= SecXPCDictionaryCopyDictionary(event
, kSecXPCKeyIDSMessage
, &error
);
937 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
, SOSCCHandleIDSMessage_Server(IDS
, &error
));
942 case kSecXPCOpSendIDSMessage
:
944 CFStringRef message
= SecXPCDictionaryCopyString(event
, kSecXPCKeySendIDSMessage
, &error
);
945 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCIDSServiceRegistrationTest_Server(message
, &error
));
946 CFReleaseNull(message
);
949 case kSecXPCOpPingTest
:
951 CFStringRef message
= SecXPCDictionaryCopyString(event
, kSecXPCKeySendIDSMessage
, &error
);
952 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCIDSPingTest_Server(message
, &error
));
953 CFReleaseNull(message
);
956 case kSecXPCOpIDSDeviceID
:
958 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCIDSDeviceIDIsAvailableTest_Server(&error
));
961 case kSecXPCOpAccountSetToNew
:
962 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, SOSCCAccountSetToNew_Server(&error
));
964 case kSecXPCOpResetToOffering
:
965 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
966 SOSCCResetToOffering_Server(&error
));
968 case kSecXPCOpResetToEmpty
:
969 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
970 SOSCCResetToEmpty_Server(&error
));
972 case kSecXPCOpRemoveThisDeviceFromCircle
:
973 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
974 SOSCCRemoveThisDeviceFromCircle_Server(&error
));
976 case kSecXPCOpLoggedOutOfAccount
:
977 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
978 SOSCCLoggedOutOfAccount_Server(&error
));
980 case kSecXPCOpBailFromCircle
:
982 uint64_t limit_in_seconds
= xpc_dictionary_get_uint64(event
, kSecXPCLimitInMinutes
);
983 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
984 SOSCCBailFromCircle_Server(limit_in_seconds
, &error
));
987 case kSecXPCOpAcceptApplicants
:
989 xpc_object_t xapplicants
= xpc_dictionary_get_value(event
, kSecXPCKeyPeerInfos
);
990 CFArrayRef applicants
= CreateArrayOfPeerInfoWithXPCObject(xapplicants
, &error
); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
991 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
992 (applicants
&& SOSCCAcceptApplicants_Server(applicants
, &error
)));
993 CFReleaseSafe(applicants
);
996 case kSecXPCOpRejectApplicants
:
998 xpc_object_t xapplicants
= xpc_dictionary_get_value(event
, kSecXPCKeyPeerInfos
);
999 CFArrayRef applicants
= CreateArrayOfPeerInfoWithXPCObject(xapplicants
, &error
); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
1000 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
1001 (applicants
&& SOSCCRejectApplicants_Server(applicants
, &error
)));
1002 CFReleaseSafe(applicants
);
1005 case kSecXPCOpSetNewPublicBackupKey
:
1007 CFDataRef publicBackupKey
= SecXPCDictionaryCopyData(event
, kSecXPCKeyNewPublicBackupKey
, &error
);
1008 SOSPeerInfoRef peerInfo
= SOSCCSetNewPublicBackupKey_Server(publicBackupKey
, &error
);
1009 CFDataRef peerInfoData
= peerInfo
? SOSPeerInfoCopyEncodedData(peerInfo
, kCFAllocatorDefault
, &error
) : NULL
;
1010 CFReleaseNull(peerInfo
);
1012 xpc_object_t xpc_object
= _CFXPCCreateXPCObjectFromCFObject(peerInfoData
);
1013 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_object
);
1014 xpc_release(xpc_object
);
1016 CFReleaseNull(peerInfoData
);
1017 CFReleaseSafe(publicBackupKey
);
1021 case kSecXPCOpSetBagForAllSlices
:
1023 CFDataRef backupSlice
= SecXPCDictionaryCopyData(event
, kSecXPCKeyKeybag
, &error
);
1024 bool includeV0
= xpc_dictionary_get_bool(event
, kSecXPCKeyIncludeV0
);
1025 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, backupSlice
&& SOSCCRegisterSingleRecoverySecret_Server(backupSlice
, includeV0
, &error
));
1026 CFReleaseSafe(backupSlice
);
1029 case kSecXPCOpCopyApplicantPeerInfo
:
1031 CFArrayRef array
= SOSCCCopyApplicantPeerInfo_Server(&error
);
1033 xpc_object_t xpc_array
= CreateXPCObjectWithArrayOfPeerInfo(array
, &error
);
1034 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1035 xpc_release(xpc_array
);
1037 CFReleaseNull(array
);
1040 case kSecXPCOpCopyValidPeerPeerInfo
:
1042 CFArrayRef array
= SOSCCCopyValidPeerPeerInfo_Server(&error
);
1044 xpc_object_t xpc_array
= CreateXPCObjectWithArrayOfPeerInfo(array
, &error
);
1045 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1046 xpc_release(xpc_array
);
1048 CFReleaseNull(array
);
1051 case kSecXPCOpValidateUserPublic
:
1053 bool trusted
= SOSCCValidateUserPublic_Server(&error
);
1054 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
, trusted
);
1057 case kSecXPCOpCopyNotValidPeerPeerInfo
:
1059 CFArrayRef array
= SOSCCCopyNotValidPeerPeerInfo_Server(&error
);
1061 xpc_object_t xpc_array
= CreateXPCObjectWithArrayOfPeerInfo(array
, &error
);
1062 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1063 xpc_release(xpc_array
);
1065 CFReleaseNull(array
);
1068 case kSecXPCOpCopyGenerationPeerInfo
:
1070 CFArrayRef array
= SOSCCCopyGenerationPeerInfo_Server(&error
);
1072 xpc_object_t xpc_array
= _CFXPCCreateXPCObjectFromCFObject(array
);
1073 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1074 xpc_release(xpc_array
);
1076 CFReleaseNull(array
);
1079 case kSecXPCOpCopyRetirementPeerInfo
:
1081 CFArrayRef array
= SOSCCCopyRetirementPeerInfo_Server(&error
);
1083 xpc_object_t xpc_array
= CreateXPCObjectWithArrayOfPeerInfo(array
, &error
);
1084 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1085 xpc_release(xpc_array
);
1087 CFReleaseNull(array
);
1090 case kSecXPCOpCopyEngineState
:
1092 CFArrayRef array
= SOSCCCopyEngineState_Server(&error
);
1094 xpc_object_t xpc_array
= _CFXPCCreateXPCObjectFromCFObject(array
);
1095 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1096 xpc_release(xpc_array
);
1098 CFReleaseNull(array
);
1101 case kSecXPCOpCopyPeerPeerInfo
:
1103 CFArrayRef array
= SOSCCCopyPeerPeerInfo_Server(&error
);
1105 xpc_object_t xpc_array
= CreateXPCObjectWithArrayOfPeerInfo(array
, &error
);
1106 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1107 xpc_release(xpc_array
);
1109 CFReleaseNull(array
);
1112 case kSecXPCOpCopyConcurringPeerPeerInfo
:
1114 CFArrayRef array
= SOSCCCopyConcurringPeerPeerInfo_Server(&error
);
1116 xpc_object_t xpc_array
= CreateXPCObjectWithArrayOfPeerInfo(array
, &error
);
1117 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1118 xpc_release(xpc_array
);
1120 CFReleaseNull(array
);
1123 case kSecXPCOpCopyMyPeerInfo
:
1125 SOSPeerInfoRef peerInfo
= SOSCCCopyMyPeerInfo_Server(&error
);
1126 CFDataRef peerInfoData
= peerInfo
? SOSPeerInfoCopyEncodedData(peerInfo
, kCFAllocatorDefault
, &error
) : NULL
;
1127 CFReleaseNull(peerInfo
);
1129 xpc_object_t xpc_object
= _CFXPCCreateXPCObjectFromCFObject(peerInfoData
);
1130 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_object
);
1131 xpc_release(xpc_object
);
1133 CFReleaseNull(peerInfoData
);
1136 case kSecXPCOpGetLastDepartureReason
:
1137 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
1138 SOSCCGetLastDepartureReason_Server(&error
));
1140 case kSecXPCOpSetLastDepartureReason
:
1142 int32_t reason
= (int32_t) xpc_dictionary_get_int64(event
, kSecXPCKeyReason
);
1143 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
1144 SOSCCSetLastDepartureReason_Server(reason
, &error
));
1147 case kSecXPCOpProcessSyncWithAllPeers
:
1148 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
1149 SOSCCProcessSyncWithAllPeers_Server(&error
));
1151 case soscc_EnsurePeerRegistration_id
:
1152 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
1153 SOSCCProcessEnsurePeerRegistration_Server(&error
));
1155 case kSecXPCOpCopyIncompatibilityInfo
: {
1156 CFStringRef iis
= SOSCCCopyIncompatibilityInfo_Server(&error
);
1157 SecXPCDictionarySetString(replyMessage
, kSecXPCKeyResult
, iis
, &error
);
1161 case kSecXPCOpOTAGetEscrowCertificates
:
1163 uint32_t escrowRootType
= (uint32_t)xpc_dictionary_get_uint64(event
, "escrowType");
1164 CFArrayRef array
= SecOTAPKICopyCurrentEscrowCertificates(escrowRootType
, &error
);
1166 xpc_object_t xpc_array
= _CFXPCCreateXPCObjectFromCFObject(array
);
1167 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1168 xpc_release(xpc_array
);
1170 CFReleaseNull(array
);
1173 case kSecXPCOpOTAPKIGetNewAsset
:
1174 xpc_dictionary_set_int64(replyMessage
, kSecXPCKeyResult
,
1175 SecOTAPKISignalNewAsset(&error
));
1177 case kSecXPCOpRollKeys
:
1179 bool force
= xpc_dictionary_get_bool(event
, "force");
1180 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
1181 _SecServerRollKeys(force
, &error
));
1184 case kSecXPCOpSetHSA2AutoAcceptInfo
:
1186 CFDataRef cfbytes
= NULL
;
1187 const uint8_t *bytes
= NULL
;
1190 bytes
= xpc_dictionary_get_data(event
,
1191 kSecXPCKeyHSA2AutoAcceptInfo
, &len
);
1193 SOSCreateError(kSOSErrorBadKey
,
1194 CFSTR("missing autoaccept info"), NULL
, &error
);
1198 cfbytes
= CFDataCreate(NULL
, bytes
, len
);
1200 SOSCreateError(kSOSErrorAllocationFailure
,
1201 CFSTR("could not allocate autoaccept info"),
1206 xpc_dictionary_set_bool(replyMessage
,
1208 SOSCCSetHSA2AutoAcceptInfo_Server(cfbytes
, &error
));
1212 case kSecXPCOpWaitForInitialSync
:
1213 xpc_dictionary_set_bool(replyMessage
, kSecXPCKeyResult
,
1214 SOSCCWaitForInitialSync_Server(&error
));
1217 case kSecXPCOpCopyYetToSyncViews
:
1219 CFArrayRef array
= SOSCCCopyYetToSyncViewsList_Server(&error
);
1221 xpc_object_t xpc_array
= _CFXPCCreateXPCObjectFromCFObject(array
);
1222 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyResult
, xpc_array
);
1223 xpc_release(xpc_array
);
1225 CFReleaseNull(array
);
1238 if(SecErrorGetOSStatus(error
) == errSecItemNotFound
|| isSOSErrorCoded(error
, kSOSErrorPublicKeyAbsent
))
1239 secdebug("ipc", "%@ %@ %@", clientTask
, SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), error
);
1240 else if (SecErrorGetOSStatus(error
) == errSecAuthNeeded
)
1241 secwarning("Authentication is needed %@ %@ %@", clientTask
, SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), error
);
1243 secerror("%@ %@ %@", clientTask
, SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), error
);
1245 xpcError
= SecCreateXPCObjectWithCFError(error
);
1247 xpc_dictionary_set_value(replyMessage
, kSecXPCKeyError
, xpcError
);
1249 } else if (replyMessage
) {
1250 secdebug("ipc", "%@ %@ responding %@", clientTask
, SOSCCGetOperationDescription((enum SecXPCOperation
)operation
), replyMessage
);
1253 SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType
, sSecXPCErrorDomain
, NULL
, &error
, 0, CFSTR("Messages expect to be xpc dictionary, got: %@"), event
);
1254 secerror("%@: returning error: %@", clientTask
, error
);
1255 xpcError
= SecCreateXPCObjectWithCFError(error
);
1256 replyMessage
= xpc_create_reply_with_format(event
, "{%string: %value}", kSecXPCKeyError
, xpcError
);
1260 xpc_connection_send_message(connection
, replyMessage
);
1261 xpc_release(replyMessage
);
1264 xpc_release(xpcError
);
1265 CFReleaseSafe(error
);
1266 CFReleaseSafe(accessGroups
);
1267 CFReleaseSafe(domains
);
1268 CFReleaseSafe(clientTask
);
1269 CFReleaseSafe(clientAuditToken
);
1272 static void securityd_xpc_init(const char *service_name
)
1274 secdebug("serverxpc", "start");
1275 xpc_connection_t listener
= xpc_connection_create_mach_service(service_name
, NULL
, XPC_CONNECTION_MACH_SERVICE_LISTENER
);
1277 seccritical("security failed to register xpc listener for %s, exiting", service_name
);
1281 xpc_connection_set_event_handler(listener
, ^(xpc_object_t connection
) {
1282 if (xpc_get_type(connection
) == XPC_TYPE_CONNECTION
) {
1283 xpc_connection_set_event_handler(connection
, ^(xpc_object_t event
) {
1284 if (xpc_get_type(event
) == XPC_TYPE_DICTIONARY
) {
1285 xpc_retain(connection
);
1287 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), ^{
1288 securityd_xpc_dictionary_handler(connection
, event
);
1290 xpc_release(connection
);
1294 xpc_connection_resume(connection
);
1297 xpc_connection_resume(listener
);
1302 int main(int argc
, char *argv
[])
1304 char *wait4debugger
= getenv("WAIT4DEBUGGER");
1305 if (wait4debugger
&& !strcasecmp("YES", wait4debugger
)) {
1306 seccritical("SIGSTOPing self, awaiting debugger");
1307 kill(getpid(), SIGSTOP
);
1308 asl_log(NULL
, NULL
, ASL_LEVEL_CRIT
,
1309 "Again, for good luck (or bad debuggers)");
1310 kill(getpid(), SIGSTOP
);
1313 const char *serviceName
= kSecuritydXPCServiceName
;
1315 serviceName
= kTrustdXPCServiceName
;
1316 if (argc
> 1 && (!strcmp(argv
[1], "--agent"))) {
1317 serviceName
= kTrustdAgentXPCServiceName
;
1320 securityd_init_server();
1321 securityd_xpc_init(serviceName
);
1328 /* vi:set ts=4 sw=4 et: */