]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecuritydXPC.c
4f7cee722a070d11924bb87aa9cc119534ee3d99
[apple/security.git] / OSX / sec / Security / SecuritydXPC.c
1 /*
2 * Copyright (c) 2012-2014 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 #include <Security/SecuritydXPC.h>
26 #include <ipc/securityd_client.h>
27 #include <utilities/SecCFError.h>
28 #include <utilities/SecDb.h>
29 #include <utilities/SecCFWrappers.h>
30 #include <utilities/der_plist.h>
31
32 // TODO Shorten these string values to save ipc bandwidth.
33 const char *kSecXPCKeyOperation = "operation";
34 const char *kSecXPCKeyResult = "status";
35 const char *kSecXPCKeyError = "error";
36 const char *kSecXPCKeyClientToken = "client";
37 const char *kSecXPCKeyPeerInfos = "peer-infos";
38 const char *kSecXPCKeyUserLabel = "userlabel";
39 const char *kSecXPCKeyBackup = "backup";
40 const char *kSecXPCKeyKeybag = "keybag";
41 const char *kSecXPCKeyUserPassword = "password";
42 const char *kSecXPCKeyDSID = "dsid";
43 const char *kSecXPCKeyQuery = "query";
44 const char *kSecXPCKeyAttributesToUpdate = "attributesToUpdate";
45 const char *kSecXPCKeyDomain = "domain";
46 const char *kSecXPCKeyDigest = "digest";
47 const char *kSecXPCKeyCertificate = "cert";
48 const char *kSecXPCKeySettings = "settings";
49 const char *kSecXPCKeyOTAFileDirectory = "path";
50 const char *kSecXPCLimitInMinutes = "limitMinutes";
51 const char *kSecXPCPublicPeerId = "publicPeerId"; // Public peer id
52 const char *kSecXPCOTRSession = "otrsess"; // OTR session bytes
53 const char *kSecXPCData = "data"; // Data to process
54 const char *kSecXPCOTRReady = "otrrdy"; // OTR ready for messages
55 const char *kSecXPCKeyDeviceID = "deviceID";
56 const char *kSecXPCKeySendIDSMessage = "sendIDSMessageCommand";
57 const char *kSecXPCKeyIDSMessage = "idsMessage";
58 const char *kSecXPCKeyViewName = "viewname";
59 const char *kSecXPCKeyViewActionCode = "viewactioncode";
60 const char *kSecXPCKeyHSA2AutoAcceptInfo = "autoacceptinfo";
61 const char *kSecXPCKeyString = "cfstring";
62 const char *kSecXPCKeyNewPublicBackupKey = "newPublicBackupKey";
63 const char *kSecXPCKeyIncludeV0 = "includeV0";
64 const char *kSecXPCKeyReason = "reason";
65 const char *kSecXPCKeyEnabledViewsKey = "enabledViews";
66 const char *kSecXPCKeyDisabledViewsKey = "disabledViews";
67
68 //
69 // XPC Functions for both client and server.
70 //
71
72
73 CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op)
74 {
75 switch (op) {
76 case kSecXPCOpAccountSetToNew:
77 return CFSTR("AccountSetToNew");
78 case kSecXPCOpOTAGetEscrowCertificates:
79 return CFSTR("OTAGetEscrowCertificates");
80 case kSecXPCOpOTAPKIGetNewAsset:
81 return CFSTR("OTAPKIGetNewAsset");
82 case kSecXPCOpSetHSA2AutoAcceptInfo:
83 return CFSTR("SetHSA2AutoAcceptInfo");
84 case kSecXPCOpAcceptApplicants:
85 return CFSTR("AcceptApplicants");
86 case kSecXPCOpApplyToARing:
87 return CFSTR("ApplyToARing");
88 case kSecXPCOpBailFromCircle:
89 return CFSTR("BailFromCircle");
90 case kSecXPCOpCanAuthenticate:
91 return CFSTR("CanAuthenticate");
92 case kSecXPCOpCopyApplicantPeerInfo:
93 return CFSTR("CopyApplicantPeerInfo");
94 case kSecXPCOpCopyConcurringPeerPeerInfo:
95 return CFSTR("CopyConcurringPeerPeerInfo");
96 case kSecXPCOpCopyEngineState:
97 return CFSTR("CopyEngineState");
98 case kSecXPCOpCopyGenerationPeerInfo:
99 return CFSTR("CopyGenerationPeerInfo");
100 case kSecXPCOpCopyIncompatibilityInfo:
101 return CFSTR("CopyIncompatibilityInfo");
102 case kSecXPCOpCopyMyPeerInfo:
103 return CFSTR("CopyMyPeerInfo");
104 case kSecXPCOpCopyNotValidPeerPeerInfo:
105 return CFSTR("CopyNotValidPeerPeerInfo");
106 case kSecXPCOpCopyPeerPeerInfo:
107 return CFSTR("CopyPeerPeerInfo");
108 case kSecXPCOpCopyRetirementPeerInfo:
109 return CFSTR("CopyRetirementPeerInfo");
110 case kSecXPCOpCopyValidPeerPeerInfo:
111 return CFSTR("CopyValidPeerPeerInfo");
112 case kSecXPCOpDeviceInCircle:
113 return CFSTR("DeviceInCircle");
114 case kSecXPCOpEnableRing:
115 return CFSTR("EnableRing");
116 case kSecXPCOpGetAllTheRings:
117 return CFSTR("GetAllTheRings");
118 case kSecXPCOpGetLastDepartureReason:
119 return CFSTR("GetLastDepartureReason");
120 case kSecXPCOpHandleIDSMessage:
121 return CFSTR("HandleIDSMessage");
122 case kSecXPCOpIDSDeviceID:
123 return CFSTR("IDSDeviceID");
124 case kSecXPCOpLoggedOutOfAccount:
125 return CFSTR("LoggedOutOfAccount");
126 case kSecXPCOpPingTest:
127 return CFSTR("PingTest");
128 case kSecXPCOpProcessSyncWithAllPeers:
129 return CFSTR("ProcessSyncWithAllPeers");
130 case kSecXPCOpProcessUnlockNotification:
131 return CFSTR("ProcessUnlockNotification");
132 case kSecXPCOpPurgeUserCredentials:
133 return CFSTR("PurgeUserCredentials");
134 case kSecXPCOpRejectApplicants:
135 return CFSTR("RejectApplicants");
136 case kSecXPCOpRemoveThisDeviceFromCircle:
137 return CFSTR("RemoveThisDeviceFromCircle");
138 case kSecXPCOpRequestDeviceID:
139 return CFSTR("RequestDeviceID");
140 case kSecXPCOpRequestEnsureFreshParameters:
141 return CFSTR("RequestEnsureFreshParameters");
142 case kSecXPCOpRequestToJoin:
143 return CFSTR("RequestToJoin");
144 case kSecXPCOpRequestToJoinAfterRestore:
145 return CFSTR("RequestToJoinAfterRestore");
146 case kSecXPCOpResetToEmpty:
147 return CFSTR("ResetToEmpty");
148 case kSecXPCOpResetToOffering:
149 return CFSTR("ResetToOffering");
150 case kSecXPCOpRingStatus:
151 return CFSTR("RingStatus");
152 case kSecXPCOpRollKeys:
153 return CFSTR("RollKeys");
154 case kSecXPCOpSecurityProperty:
155 return CFSTR("SecurityProperty");
156 case kSecXPCOpSendIDSMessage:
157 return CFSTR("SendIDSMessage");
158 case kSecXPCOpSetBagForAllSlices:
159 return CFSTR("SetBagForAllSlices");
160 case kSecXPCOpSetDeviceID:
161 return CFSTR("SetDeviceID");
162 case kSecXPCOpSetLastDepartureReason:
163 return CFSTR("SetLastDepartureReason");
164 case kSecXPCOpSetNewPublicBackupKey:
165 return CFSTR("SetNewPublicBackupKey");
166 case kSecXPCOpSetUserCredentials:
167 return CFSTR("SetUserCredentials");
168 case kSecXPCOpSetUserCredentialsAndDSID:
169 return CFSTR("SetUserCredentialsAndDSID");
170 case kSecXPCOpTryUserCredentials:
171 return CFSTR("TryUserCredentials");
172 case kSecXPCOpValidateUserPublic:
173 return CFSTR("ValidateUserPublic");
174 case kSecXPCOpView:
175 return CFSTR("View");
176 case kSecXPCOpWithdrawlFromARing:
177 return CFSTR("WithdrawlFromARing");
178 case sec_add_shared_web_credential_id:
179 return CFSTR("add_shared_web_credential");
180 case sec_copy_shared_web_credential_id:
181 return CFSTR("copy_shared_web_credential");
182 case sec_delete_all_id:
183 return CFSTR("delete_all");
184 case sec_get_log_settings_id:
185 return CFSTR("get_log_settings");
186 case sec_item_add_id:
187 return CFSTR("add");
188 case sec_item_backup_copy_names_id:
189 return CFSTR("backup_copy_names");
190 case sec_item_backup_handoff_fd_id:
191 return CFSTR("backup_handoff_fd");
192 case sec_item_backup_restore_id:
193 return CFSTR("backup_restore");
194 case sec_item_backup_set_confirmed_manifest_id:
195 return CFSTR("backup_set_confirmed_manifest");
196 case sec_item_copy_matching_id:
197 return CFSTR("copy_matching");
198 case sec_item_delete_id:
199 return CFSTR("delete");
200 case sec_item_update_id:
201 return CFSTR("update");
202 case sec_keychain_backup_id:
203 return CFSTR("keychain_backup");
204 case sec_keychain_backup_syncable_id:
205 return CFSTR("keychain_backup_syncable");
206 case sec_keychain_restore_id:
207 return CFSTR("keychain_restore");
208 case sec_keychain_restore_syncable_id:
209 return CFSTR("keychain_restore_syncable");
210 case sec_keychain_sync_update_message_id:
211 return CFSTR("keychain_sync_update_message");
212 case sec_ota_pki_asset_version_id:
213 return CFSTR("ota_pki_asset_version");
214 case sec_otr_session_create_remote_id:
215 return CFSTR("otr_session_create_remote");
216 case sec_otr_session_process_packet_remote_id:
217 return CFSTR("otr_session_process_packet_remote");
218 case sec_set_circle_log_settings_id:
219 return CFSTR("set_circle_log_settings");
220 case sec_set_xpc_log_settings_id:
221 return CFSTR("set_xpc_log_settings");
222 case sec_trust_evaluate_id:
223 return CFSTR("trust_evaluate");
224 case sec_trust_store_contains_id:
225 return CFSTR("trust_store_contains");
226 case sec_trust_store_remove_certificate_id:
227 return CFSTR("trust_store_remove_certificate");
228 case sec_trust_store_set_trust_settings_id:
229 return CFSTR("trust_store_set_trust_settings");
230 case soscc_EnsurePeerRegistration_id:
231 return CFSTR("EnsurePeerRegistration");
232 default:
233 return CFSTR("Unknown xpc operation");
234 }
235 }
236
237 bool SecXPCDictionarySetPList(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error)
238 {
239 if (!object)
240 return SecError(errSecParam, error, CFSTR("object for key %s is NULL"), key);
241
242 size_t size = der_sizeof_plist(object, error);
243 if (!size)
244 return false;
245 uint8_t *der = malloc(size);
246 uint8_t *der_end = der + size;
247 uint8_t *der_start = der_encode_plist(object, error, der, der_end);
248 if (!der_start) {
249 free(der);
250 return false;
251 }
252
253 assert(der == der_start);
254 xpc_dictionary_set_data(message, key, der_start, der_end - der_start);
255 free(der);
256 return true;
257 }
258
259 bool SecXPCDictionarySetPListOptional(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error) {
260 return !object || SecXPCDictionarySetPList(message, key, object, error);
261 }
262
263 bool SecXPCDictionarySetData(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error)
264 {
265 if (!data)
266 return SecError(errSecParam, error, CFSTR("data for key %s is NULL"), key);
267
268 xpc_dictionary_set_data(message, key, CFDataGetBytePtr(data), CFDataGetLength(data));
269 return true;
270 }
271
272 bool SecXPCDictionarySetString(xpc_object_t message, const char *key, CFStringRef string, CFErrorRef *error)
273 {
274 if (!string)
275 return SecError(errSecParam, error, CFSTR("string for key %s is NULL"), key);
276
277 __block bool ok = true;
278 CFStringPerformWithCString(string, ^(const char *utf8Str) {
279 if (utf8Str)
280 xpc_dictionary_set_string(message, key, utf8Str);
281 else
282 ok = SecError(errSecParam, error, CFSTR("failed to convert string for key %s to utf8"), key);
283 });
284 return ok;
285 }
286
287 bool SecXPCDictionarySetStringOptional(xpc_object_t message, const char *key, CFStringRef string, CFErrorRef *error) {
288 return !string || SecXPCDictionarySetString(message, key, string, error);
289 }
290
291 bool SecXPCDictionarySetDataOptional(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error) {
292 return !data || SecXPCDictionarySetData(message, key, data, error);
293 }
294
295 bool SecXPCDictionarySetInt64(xpc_object_t message, const char *key, int64_t value, CFErrorRef *error) {
296 xpc_dictionary_set_int64(message, key, value);
297 return true;
298 }
299
300 bool SecXPCDictionarySetFileDescriptor(xpc_object_t message, const char *key, int fd, CFErrorRef *error) {
301 xpc_dictionary_set_fd(message, key, fd);
302 return true;
303 }
304
305 int SecXPCDictionaryDupFileDescriptor(xpc_object_t message, const char *key, CFErrorRef *error) {
306 int fd = xpc_dictionary_dup_fd(message, key);
307 if (fd < 0)
308 SecError(errSecParam, error, CFSTR("missing fd for key %s"), key);
309
310 return fd;
311 }
312
313 CFArrayRef SecXPCDictionaryCopyArray(xpc_object_t message, const char *key, CFErrorRef *error) {
314 CFTypeRef array = SecXPCDictionaryCopyPList(message, key, error);
315 if (array) {
316 CFTypeID type_id = CFGetTypeID(array);
317 if (type_id != CFArrayGetTypeID()) {
318 CFStringRef description = CFCopyTypeIDDescription(type_id);
319 SecError(errSecParam, error, CFSTR("object for key %s not array but %@"), key, description);
320 CFReleaseNull(description);
321 CFReleaseNull(array);
322 }
323 }
324 return (CFArrayRef)array;
325 }
326
327 bool SecXPCDictionaryCopyArrayOptional(xpc_object_t message, const char *key, CFArrayRef *parray, CFErrorRef *error) {
328 if (!xpc_dictionary_get_value(message, key)) {
329 *parray = NULL;
330 return true;
331 }
332 *parray = SecXPCDictionaryCopyArray(message, key, error);
333 return *parray;
334 }
335
336 CFDataRef SecXPCDictionaryCopyData(xpc_object_t message, const char *key, CFErrorRef *error) {
337 CFDataRef data = NULL;
338 size_t size = 0;
339 const uint8_t *bytes = xpc_dictionary_get_data(message, key, &size);
340 if (!bytes) {
341 SecError(errSecParam, error, CFSTR("no data for key %s"), key);
342 return NULL;
343 }
344
345 data = CFDataCreate(kCFAllocatorDefault, bytes, size);
346 if (!data)
347 SecError(errSecParam, error, CFSTR("failed to create data for key %s"), key);
348
349 return data;
350 }
351
352 bool SecXPCDictionaryCopyDataOptional(xpc_object_t message, const char *key, CFDataRef *pdata, CFErrorRef *error) {
353 size_t size = 0;
354 if (!xpc_dictionary_get_data(message, key, &size)) {
355 *pdata = NULL;
356 return true;
357 }
358 *pdata = SecXPCDictionaryCopyData(message, key, error);
359 return *pdata;
360 }
361
362 CFDictionaryRef SecXPCDictionaryCopyDictionary(xpc_object_t message, const char *key, CFErrorRef *error) {
363 CFTypeRef dict = SecXPCDictionaryCopyPList(message, key, error);
364 if (dict) {
365 CFTypeID type_id = CFGetTypeID(dict);
366 if (type_id != CFDictionaryGetTypeID()) {
367 CFStringRef description = CFCopyTypeIDDescription(type_id);
368 SecError(errSecParam, error, CFSTR("object for key %s not dictionary but %@"), key, description);
369 CFReleaseNull(description);
370 CFReleaseNull(dict);
371 }
372 }
373 return (CFDictionaryRef)dict;
374 }
375
376 bool SecXPCDictionaryCopyDictionaryOptional(xpc_object_t message, const char *key, CFDictionaryRef *pdictionary, CFErrorRef *error) {
377 if (!xpc_dictionary_get_value(message, key)) {
378 *pdictionary = NULL;
379 return true;
380 }
381 *pdictionary = SecXPCDictionaryCopyDictionary(message, key, error);
382 return *pdictionary;
383 }
384
385 CFTypeRef SecXPCDictionaryCopyPList(xpc_object_t message, const char *key, CFErrorRef *error)
386 {
387 CFTypeRef cfobject = NULL;
388 size_t size = 0;
389 const uint8_t *der = xpc_dictionary_get_data(message, key, &size);
390 if (!der) {
391 SecError(errSecParam, error, CFSTR("no object for key %s"), key);
392 return NULL;
393 }
394
395 const uint8_t *der_end = der + size;
396 der = der_decode_plist(kCFAllocatorDefault, kCFPropertyListImmutable,
397 &cfobject, error, der, der_end);
398 if (der != der_end) {
399 SecError(errSecParam, error, CFSTR("trailing garbage after der decoded object for key %s"), key);
400 CFReleaseNull(cfobject);
401 }
402 return cfobject;
403 }
404
405 bool SecXPCDictionaryCopyPListOptional(xpc_object_t message, const char *key, CFTypeRef *pobject, CFErrorRef *error) {
406 size_t size = 0;
407 if (!xpc_dictionary_get_data(message, key, &size)) {
408 *pobject = NULL;
409 return true;
410 }
411 *pobject = SecXPCDictionaryCopyPList(message, key, error);
412 return *pobject;
413 }
414
415 CFStringRef SecXPCDictionaryCopyString(xpc_object_t message, const char *key, CFErrorRef *error) {
416 const char *string = xpc_dictionary_get_string(message, key);
417 if (string) {
418 CFStringRef result = CFStringCreateWithCString(kCFAllocatorDefault, string, kCFStringEncodingUTF8);
419 if (!result) {
420 SecError(errSecAllocate, error, CFSTR("object for key %s failed to convert %s to CFString"), key, string);
421 }
422 return result;
423 } else {
424 SecError(errSecParam, error, CFSTR("object for key %s not string"), key);
425 return NULL;
426 }
427 }
428
429 bool SecXPCDictionaryCopyStringOptional(xpc_object_t message, const char *key, CFStringRef *pstring, CFErrorRef *error) {
430 if (!xpc_dictionary_get_value(message, key)) {
431 *pstring = NULL;
432 return true;
433 }
434 *pstring = SecXPCDictionaryCopyString(message, key, error);
435 return *pstring;
436 }