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