5 // Created by Mitch Adler on 11/16/12.
6 // Copyright (c) 2012-2013 Apple Inc. All rights reserved.
9 #include "SecuritydXPC.h"
10 #include <ipc/securityd_client.h>
11 #include <utilities/SecCFError.h>
12 #include <utilities/SecDb.h>
13 #include <utilities/SecCFWrappers.h>
14 #include <utilities/der_plist.h>
16 // TODO Shorten these string values to save ipc bandwidth.
17 const char *kSecXPCKeyOperation
= "operation";
18 const char *kSecXPCKeyResult
= "status";
19 const char *kSecXPCKeyError
= "error";
20 const char *kSecXPCKeyPeerInfos
= "peer-infos";
21 const char *kSecXPCKeyUserLabel
= "userlabel";
22 const char *kSecXPCKeyBackup
= "backup";
23 const char *kSecXPCKeyKeybag
= "keybag";
24 const char *kSecXPCKeyUserPassword
= "password";
25 const char *kSecXPCKeyQuery
= "query";
26 const char *kSecXPCKeyAttributesToUpdate
= "attributesToUpdate";
27 const char *kSecXPCKeyDomain
= "domain";
28 const char *kSecXPCKeyDigest
= "digest";
29 const char *kSecXPCKeyCertificate
= "cert";
30 const char *kSecXPCKeySettings
= "settings";
31 const char *kSecXPCKeyOTAFileDirectory
= "path";
32 const char *kSecXPCLimitInMinutes
= "limitMinutes";
35 // XPC Functions for both client and server.
39 CFStringRef
SOSCCGetOperationDescription(enum SecXPCOperation op
)
44 case sec_item_copy_matching_id
:
45 return CFSTR("copy_matching");
46 case sec_item_update_id
:
47 return CFSTR("update");
48 case sec_item_delete_id
:
49 return CFSTR("delete");
50 case sec_trust_store_contains_id
:
51 return CFSTR("trust_store_contains");
52 case sec_trust_store_set_trust_settings_id
:
53 return CFSTR("trust_store_set_trust_settings");
54 case sec_trust_store_remove_certificate_id
:
55 return CFSTR("trust_store_remove_certificate");
56 case sec_delete_all_id
:
57 return CFSTR("delete_all");
58 case sec_trust_evaluate_id
:
59 return CFSTR("trust_evaluate");
60 case sec_keychain_backup_id
:
61 return CFSTR("keychain_backup");
62 case sec_keychain_restore_id
:
63 return CFSTR("keychain_restore");
64 case sec_keychain_sync_update_id
:
65 return CFSTR("keychain_sync_update");
66 case sec_keychain_backup_syncable_id
:
67 return CFSTR("keychain_backup_syncable");
68 case sec_keychain_restore_syncable_id
:
69 return CFSTR("keychain_restore_syncable");
70 case sec_ota_pki_asset_version_id
:
71 return CFSTR("ota_pki_asset_version");
72 case kSecXPCOpTryUserCredentials
:
73 return CFSTR("TryUserCredentials");
74 case kSecXPCOpSetUserCredentials
:
75 return CFSTR("SetUserCredentials");
76 case kSecXPCOpCanAuthenticate
:
77 return CFSTR("CanAuthenticate");
78 case kSecXPCOpPurgeUserCredentials
:
79 return CFSTR("PurgeUserCredentials");
80 case kSecXPCOpDeviceInCircle
:
81 return CFSTR("DeviceInCircle");
82 case kSecXPCOpRequestToJoin
:
83 return CFSTR("RequestToJoin");
84 case kSecXPCOpResetToOffering
:
85 return CFSTR("ResetToOffering");
86 case kSecXPCOpResetToEmpty
:
87 return CFSTR("ResetToEmpty");
88 case kSecXPCOpRemoveThisDeviceFromCircle
:
89 return CFSTR("RemoveThisDevice");
90 case kSecXPCOpBailFromCircle
:
91 return CFSTR("BailFromCircle");
92 case kSecXPCOpAcceptApplicants
:
93 return CFSTR("AcceptApplicants");
94 case kSecXPCOpRejectApplicants
:
95 return CFSTR("RejectApplicants");
96 case kSecXPCOpCopyApplicantPeerInfo
:
97 return CFSTR("ApplicantPeerInfo");
98 case kSecXPCOpCopyPeerPeerInfo
:
99 return CFSTR("PeerPeerInfo");
100 case kSecXPCOpCopyConcurringPeerPeerInfo
:
101 return CFSTR("ConcurringPeerPeerInfo");
102 case kSecXPCOpOTAGetEscrowCertificates
:
103 return CFSTR("OTAGetEscrowCertificates");
104 case kSecXPCOpOTAPKIGetNewAsset
:
105 return CFSTR("sec_ota_pki_get_new_asset");
106 case kSecXPCOpProcessSyncWithAllPeers
:
107 return CFSTR("ProcessSyncWithAllPeers");
109 return CFSTR("Unknown xpc operation");
113 bool SecXPCDictionarySetPList(xpc_object_t message
, const char *key
, CFTypeRef object
, CFErrorRef
*error
)
116 return SecError(errSecParam
, error
, CFSTR("object for key %s is NULL"), key
);
118 size_t size
= der_sizeof_plist(object
, error
);
121 uint8_t *der
= malloc(size
);
122 uint8_t *der_end
= der
+ size
;
123 uint8_t *der_start
= der_encode_plist(object
, error
, der
, der_end
);
129 assert(der
== der_start
);
130 xpc_dictionary_set_data(message
, key
, der_start
, der_end
- der_start
);
135 bool SecXPCDictionarySetPListOptional(xpc_object_t message
, const char *key
, CFTypeRef object
, CFErrorRef
*error
) {
136 return !object
|| SecXPCDictionarySetPList(message
, key
, object
, error
);
139 bool SecXPCDictionarySetData(xpc_object_t message
, const char *key
, CFDataRef data
, CFErrorRef
*error
)
142 return SecError(errSecParam
, error
, CFSTR("data for key %s is NULL"), key
);
144 xpc_dictionary_set_data(message
, key
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
148 bool SecXPCDictionarySetString(xpc_object_t message
, const char *key
, CFStringRef string
, CFErrorRef
*error
)
151 return SecError(errSecParam
, error
, CFSTR("string for key %s is NULL"), key
);
153 __block
bool ok
= true;
154 CFStringPerformWithCString(string
, ^(const char *utf8Str
) {
156 xpc_dictionary_set_string(message
, key
, utf8Str
);
158 ok
= SecError(errSecParam
, error
, CFSTR("failed to convert string for key %s to utf8"), key
);
163 bool SecXPCDictionarySetDataOptional(xpc_object_t message
, const char *key
, CFDataRef data
, CFErrorRef
*error
) {
164 return !data
|| SecXPCDictionarySetData(message
, key
, data
, error
);
167 CFArrayRef
SecXPCDictionaryCopyArray(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
168 CFTypeRef array
= SecXPCDictionaryCopyPList(message
, key
, error
);
170 CFTypeID type_id
= CFGetTypeID(array
);
171 if (type_id
!= CFArrayGetTypeID()) {
172 CFStringRef description
= CFCopyTypeIDDescription(type_id
);
173 SecError(errSecParam
, error
, CFSTR("object for key %s not array but %@"), key
, description
);
174 CFReleaseNull(description
);
175 CFReleaseNull(array
);
178 return (CFArrayRef
)array
;
181 bool SecXPCDictionaryCopyArrayOptional(xpc_object_t message
, const char *key
, CFArrayRef
*parray
, CFErrorRef
*error
) {
182 if (!xpc_dictionary_get_value(message
, key
)) {
186 *parray
= SecXPCDictionaryCopyArray(message
, key
, error
);
190 CFDataRef
SecXPCDictionaryCopyData(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
191 CFDataRef data
= NULL
;
193 const uint8_t *bytes
= xpc_dictionary_get_data(message
, key
, &size
);
195 SecError(errSecParam
, error
, CFSTR("no data for key %s"), key
);
199 data
= CFDataCreate(kCFAllocatorDefault
, bytes
, size
);
201 SecError(errSecParam
, error
, CFSTR("failed to create data for key %s"), key
);
206 bool SecXPCDictionaryCopyDataOptional(xpc_object_t message
, const char *key
, CFDataRef
*pdata
, CFErrorRef
*error
) {
208 if (!xpc_dictionary_get_data(message
, key
, &size
)) {
212 *pdata
= SecXPCDictionaryCopyData(message
, key
, error
);
216 CFDictionaryRef
SecXPCDictionaryCopyDictionary(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
217 CFTypeRef dict
= SecXPCDictionaryCopyPList(message
, key
, error
);
219 CFTypeID type_id
= CFGetTypeID(dict
);
220 if (type_id
!= CFDictionaryGetTypeID()) {
221 CFStringRef description
= CFCopyTypeIDDescription(type_id
);
222 SecError(errSecParam
, error
, CFSTR("object for key %s not dictionary but %@"), key
, description
);
223 CFReleaseNull(description
);
227 return (CFDictionaryRef
)dict
;
230 bool SecXPCDictionaryCopyDictionaryOptional(xpc_object_t message
, const char *key
, CFDictionaryRef
*pdictionary
, CFErrorRef
*error
) {
231 if (!xpc_dictionary_get_value(message
, key
)) {
235 *pdictionary
= SecXPCDictionaryCopyDictionary(message
, key
, error
);
239 CFTypeRef
SecXPCDictionaryCopyPList(xpc_object_t message
, const char *key
, CFErrorRef
*error
)
241 CFTypeRef cfobject
= NULL
;
243 const uint8_t *der
= xpc_dictionary_get_data(message
, key
, &size
);
245 SecError(errSecParam
, error
, CFSTR("no object for key %s"), key
);
249 const uint8_t *der_end
= der
+ size
;
250 der
= der_decode_plist(kCFAllocatorDefault
, kCFPropertyListImmutable
,
251 &cfobject
, error
, der
, der_end
);
252 if (der
!= der_end
) {
253 SecError(errSecParam
, error
, CFSTR("trailing garbage after der decoded object for key %s"), key
);
254 CFReleaseNull(cfobject
);
259 bool SecXPCDictionaryCopyPListOptional(xpc_object_t message
, const char *key
, CFTypeRef
*pobject
, CFErrorRef
*error
) {
261 if (!xpc_dictionary_get_data(message
, key
, &size
)) {
265 *pobject
= SecXPCDictionaryCopyPList(message
, key
, error
);
269 CFStringRef
SecXPCDictionaryCopyString(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
270 const char *string
= xpc_dictionary_get_string(message
, key
);
272 CFStringRef result
= CFStringCreateWithCString(kCFAllocatorDefault
, string
, kCFStringEncodingUTF8
);
274 SecError(errSecAllocate
, error
, CFSTR("object for key %s failed to convert %s to CFString"), key
, string
);
278 SecError(errSecParam
, error
, CFSTR("object for key %s not string"), key
);