]> git.saurik.com Git - apple/security.git/blob - Security/sec/Security/SecuritydXPC.c
Security-57031.20.26.tar.gz
[apple/security.git] / Security / 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 *kSecXPCKeyQuery = "query";
43 const char *kSecXPCKeyAttributesToUpdate = "attributesToUpdate";
44 const char *kSecXPCKeyDomain = "domain";
45 const char *kSecXPCKeyDigest = "digest";
46 const char *kSecXPCKeyCertificate = "cert";
47 const char *kSecXPCKeySettings = "settings";
48 const char *kSecXPCKeyOTAFileDirectory = "path";
49 const char *kSecXPCLimitInMinutes = "limitMinutes";
50 const char *kSecXPCPublicPeerId = "publicPeerId"; // Public peer id
51 const char *kSecXPCOTRSession = "otrsess"; // OTR session bytes
52 const char *kSecXPCData = "data"; // Data to process
53 const char *kSecXPCOTRReady = "otrrdy"; // OTR ready for messages
54 const char *kSecXPCKeyDeviceID = "deviceID";
55
56 //
57 // XPC Functions for both client and server.
58 //
59
60
61 CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op)
62 {
63 switch (op) {
64 case sec_item_add_id:
65 return CFSTR("add");
66 case sec_item_copy_matching_id:
67 return CFSTR("copy_matching");
68 case sec_item_update_id:
69 return CFSTR("update");
70 case sec_item_delete_id:
71 return CFSTR("delete");
72 case sec_trust_store_contains_id:
73 return CFSTR("trust_store_contains");
74 case sec_trust_store_set_trust_settings_id:
75 return CFSTR("trust_store_set_trust_settings");
76 case sec_trust_store_remove_certificate_id:
77 return CFSTR("trust_store_remove_certificate");
78 case sec_delete_all_id:
79 return CFSTR("delete_all");
80 case sec_trust_evaluate_id:
81 return CFSTR("trust_evaluate");
82 case sec_keychain_backup_id:
83 return CFSTR("keychain_backup");
84 case sec_keychain_restore_id:
85 return CFSTR("keychain_restore");
86 case sec_keychain_sync_update_key_parameter_id:
87 return CFSTR("keychain_sync_update_key_parameter");
88 case sec_keychain_sync_update_circle_id:
89 return CFSTR("keychain_sync_update_circle");
90 case sec_keychain_sync_update_message_id:
91 return CFSTR("keychain_sync_update_message");
92 case sec_keychain_backup_syncable_id:
93 return CFSTR("keychain_backup_syncable");
94 case sec_keychain_restore_syncable_id:
95 return CFSTR("keychain_restore_syncable");
96 case sec_ota_pki_asset_version_id:
97 return CFSTR("ota_pki_asset_version");
98 case sec_add_shared_web_credential_id:
99 return CFSTR("sec_add_shared_web_credential");
100 case sec_copy_shared_web_credential_id:
101 return CFSTR("sec_copy_shared_web_credential");
102 case sec_otr_session_create_remote_id:
103 return CFSTR("sec_otr_session_create_remote");
104 case sec_otr_session_process_packet_remote_id:
105 return CFSTR("sec_otr_session_process_packet_remote");
106 case kSecXPCOpTryUserCredentials:
107 return CFSTR("TryUserCredentials");
108 case kSecXPCOpSetUserCredentials:
109 return CFSTR("SetUserCredentials");
110 case kSecXPCOpCanAuthenticate:
111 return CFSTR("CanAuthenticate");
112 case kSecXPCOpPurgeUserCredentials:
113 return CFSTR("PurgeUserCredentials");
114 case kSecXPCOpDeviceInCircle:
115 return CFSTR("DeviceInCircle");
116 case kSecXPCOpRequestToJoin:
117 return CFSTR("RequestToJoin");
118 case kSecXPCOpResetToOffering:
119 return CFSTR("ResetToOffering");
120 case kSecXPCOpResetToEmpty:
121 return CFSTR("ResetToEmpty");
122 case kSecXPCOpRemoveThisDeviceFromCircle:
123 return CFSTR("RemoveThisDevice");
124 case kSecXPCOpBailFromCircle:
125 return CFSTR("BailFromCircle");
126 case kSecXPCOpAcceptApplicants:
127 return CFSTR("AcceptApplicants");
128 case kSecXPCOpRejectApplicants:
129 return CFSTR("RejectApplicants");
130 case kSecXPCOpValidateUserPublic:
131 return CFSTR("ValidateUserPublic");
132 case kSecXPCOpCopyValidPeerPeerInfo:
133 return CFSTR("ValidPeers");
134 case kSecXPCOpCopyNotValidPeerPeerInfo:
135 return CFSTR("NotValidPeers");
136 case kSecXPCOpCopyApplicantPeerInfo:
137 return CFSTR("ApplicantPeerInfo");
138 case kSecXPCOpCopyPeerPeerInfo:
139 return CFSTR("PeerPeerInfo");
140 case kSecXPCOpCopyConcurringPeerPeerInfo:
141 return CFSTR("ConcurringPeerPeerInfo");
142 case kSecXPCOpOTAGetEscrowCertificates:
143 return CFSTR("OTAGetEscrowCertificates");
144 case kSecXPCOpOTAPKIGetNewAsset:
145 return CFSTR("sec_ota_pki_get_new_asset");
146 case kSecXPCOpProcessSyncWithAllPeers:
147 return CFSTR("ProcessSyncWithAllPeers");
148 case soscc_EnsurePeerRegistration_id:
149 return CFSTR("EnsurePeerRegistration");
150 case kSecXPCOpCopyRetirementPeerInfo:
151 return CFSTR("RetirementPeerInfo");
152 case kSecXPCOpCopyGenerationPeerInfo:
153 return CFSTR("GenerationPeerInfo");
154 case kSecXPCOpRollKeys:
155 return CFSTR("RollKeys");
156 case kSecXPCOpSetDeviceID:
157 return CFSTR("SetDeviceID");
158 default:
159 return CFSTR("Unknown xpc operation");
160 }
161 }
162
163 bool SecXPCDictionarySetPList(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error)
164 {
165 if (!object)
166 return SecError(errSecParam, error, CFSTR("object for key %s is NULL"), key);
167
168 size_t size = der_sizeof_plist(object, error);
169 if (!size)
170 return false;
171 uint8_t *der = malloc(size);
172 uint8_t *der_end = der + size;
173 uint8_t *der_start = der_encode_plist(object, error, der, der_end);
174 if (!der_start) {
175 free(der);
176 return false;
177 }
178
179 assert(der == der_start);
180 xpc_dictionary_set_data(message, key, der_start, der_end - der_start);
181 free(der);
182 return true;
183 }
184
185 bool SecXPCDictionarySetPListOptional(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error) {
186 return !object || SecXPCDictionarySetPList(message, key, object, error);
187 }
188
189 bool SecXPCDictionarySetData(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error)
190 {
191 if (!data)
192 return SecError(errSecParam, error, CFSTR("data for key %s is NULL"), key);
193
194 xpc_dictionary_set_data(message, key, CFDataGetBytePtr(data), CFDataGetLength(data));
195 return true;
196 }
197
198 bool SecXPCDictionarySetString(xpc_object_t message, const char *key, CFStringRef string, CFErrorRef *error)
199 {
200 if (!string)
201 return SecError(errSecParam, error, CFSTR("string for key %s is NULL"), key);
202
203 __block bool ok = true;
204 CFStringPerformWithCString(string, ^(const char *utf8Str) {
205 if (utf8Str)
206 xpc_dictionary_set_string(message, key, utf8Str);
207 else
208 ok = SecError(errSecParam, error, CFSTR("failed to convert string for key %s to utf8"), key);
209 });
210 return ok;
211 }
212
213 bool SecXPCDictionarySetDataOptional(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error) {
214 return !data || SecXPCDictionarySetData(message, key, data, error);
215 }
216
217 CFArrayRef SecXPCDictionaryCopyArray(xpc_object_t message, const char *key, CFErrorRef *error) {
218 CFTypeRef array = SecXPCDictionaryCopyPList(message, key, error);
219 if (array) {
220 CFTypeID type_id = CFGetTypeID(array);
221 if (type_id != CFArrayGetTypeID()) {
222 CFStringRef description = CFCopyTypeIDDescription(type_id);
223 SecError(errSecParam, error, CFSTR("object for key %s not array but %@"), key, description);
224 CFReleaseNull(description);
225 CFReleaseNull(array);
226 }
227 }
228 return (CFArrayRef)array;
229 }
230
231 bool SecXPCDictionaryCopyArrayOptional(xpc_object_t message, const char *key, CFArrayRef *parray, CFErrorRef *error) {
232 if (!xpc_dictionary_get_value(message, key)) {
233 *parray = NULL;
234 return true;
235 }
236 *parray = SecXPCDictionaryCopyArray(message, key, error);
237 return *parray;
238 }
239
240 CFDataRef SecXPCDictionaryCopyData(xpc_object_t message, const char *key, CFErrorRef *error) {
241 CFDataRef data = NULL;
242 size_t size = 0;
243 const uint8_t *bytes = xpc_dictionary_get_data(message, key, &size);
244 if (!bytes) {
245 SecError(errSecParam, error, CFSTR("no data for key %s"), key);
246 return NULL;
247 }
248
249 data = CFDataCreate(kCFAllocatorDefault, bytes, size);
250 if (!data)
251 SecError(errSecParam, error, CFSTR("failed to create data for key %s"), key);
252
253 return data;
254 }
255
256 bool SecXPCDictionaryCopyDataOptional(xpc_object_t message, const char *key, CFDataRef *pdata, CFErrorRef *error) {
257 size_t size = 0;
258 if (!xpc_dictionary_get_data(message, key, &size)) {
259 *pdata = NULL;
260 return true;
261 }
262 *pdata = SecXPCDictionaryCopyData(message, key, error);
263 return *pdata;
264 }
265
266 CFDictionaryRef SecXPCDictionaryCopyDictionary(xpc_object_t message, const char *key, CFErrorRef *error) {
267 CFTypeRef dict = SecXPCDictionaryCopyPList(message, key, error);
268 if (dict) {
269 CFTypeID type_id = CFGetTypeID(dict);
270 if (type_id != CFDictionaryGetTypeID()) {
271 CFStringRef description = CFCopyTypeIDDescription(type_id);
272 SecError(errSecParam, error, CFSTR("object for key %s not dictionary but %@"), key, description);
273 CFReleaseNull(description);
274 CFReleaseNull(dict);
275 }
276 }
277 return (CFDictionaryRef)dict;
278 }
279
280 bool SecXPCDictionaryCopyDictionaryOptional(xpc_object_t message, const char *key, CFDictionaryRef *pdictionary, CFErrorRef *error) {
281 if (!xpc_dictionary_get_value(message, key)) {
282 *pdictionary = NULL;
283 return true;
284 }
285 *pdictionary = SecXPCDictionaryCopyDictionary(message, key, error);
286 return *pdictionary;
287 }
288
289 CFTypeRef SecXPCDictionaryCopyPList(xpc_object_t message, const char *key, CFErrorRef *error)
290 {
291 CFTypeRef cfobject = NULL;
292 size_t size = 0;
293 const uint8_t *der = xpc_dictionary_get_data(message, key, &size);
294 if (!der) {
295 SecError(errSecParam, error, CFSTR("no object for key %s"), key);
296 return NULL;
297 }
298
299 const uint8_t *der_end = der + size;
300 der = der_decode_plist(kCFAllocatorDefault, kCFPropertyListImmutable,
301 &cfobject, error, der, der_end);
302 if (der != der_end) {
303 SecError(errSecParam, error, CFSTR("trailing garbage after der decoded object for key %s"), key);
304 CFReleaseNull(cfobject);
305 }
306 return cfobject;
307 }
308
309 bool SecXPCDictionaryCopyPListOptional(xpc_object_t message, const char *key, CFTypeRef *pobject, CFErrorRef *error) {
310 size_t size = 0;
311 if (!xpc_dictionary_get_data(message, key, &size)) {
312 *pobject = NULL;
313 return true;
314 }
315 *pobject = SecXPCDictionaryCopyPList(message, key, error);
316 return *pobject;
317 }
318
319 CFStringRef SecXPCDictionaryCopyString(xpc_object_t message, const char *key, CFErrorRef *error) {
320 const char *string = xpc_dictionary_get_string(message, key);
321 if (string) {
322 CFStringRef result = CFStringCreateWithCString(kCFAllocatorDefault, string, kCFStringEncodingUTF8);
323 if (!result) {
324 SecError(errSecAllocate, error, CFSTR("object for key %s failed to convert %s to CFString"), key, string);
325 }
326 return result;
327 } else {
328 SecError(errSecParam, error, CFSTR("object for key %s not string"), key);
329 return NULL;
330 }
331 }