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