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