]> git.saurik.com Git - apple/security.git/blob - sec/Security/SecuritydXPC.c
Security-55471.14.8.tar.gz
[apple/security.git] / sec / Security / SecuritydXPC.c
1 //
2 // SecuritydXPC.c
3 // sec
4 //
5 // Created by Mitch Adler on 11/16/12.
6 // Copyright (c) 2012-2013 Apple Inc. All rights reserved.
7 //
8
9 #include "SecuritydXPC.h"
10 #include <ipc/securityd_client.h>
11 #include <utilities/SecCFError.h>
12 #include <utilities/SecDb.h>
13 #include <utilities/SecCFWrappers.h>
14 #include <utilities/der_plist.h>
15
16 // TODO Shorten these string values to save ipc bandwidth.
17 const char *kSecXPCKeyOperation = "operation";
18 const char *kSecXPCKeyResult = "status";
19 const char *kSecXPCKeyError = "error";
20 const char *kSecXPCKeyPeerInfos = "peer-infos";
21 const char *kSecXPCKeyUserLabel = "userlabel";
22 const char *kSecXPCKeyBackup = "backup";
23 const char *kSecXPCKeyKeybag = "keybag";
24 const char *kSecXPCKeyUserPassword = "password";
25 const char *kSecXPCKeyQuery = "query";
26 const char *kSecXPCKeyAttributesToUpdate = "attributesToUpdate";
27 const char *kSecXPCKeyDomain = "domain";
28 const char *kSecXPCKeyDigest = "digest";
29 const char *kSecXPCKeyCertificate = "cert";
30 const char *kSecXPCKeySettings = "settings";
31 const char *kSecXPCKeyOTAFileDirectory = "path";
32 const char *kSecXPCLimitInMinutes = "limitMinutes";
33
34 //
35 // XPC Functions for both client and server.
36 //
37
38
39 CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op)
40 {
41 switch (op) {
42 case sec_item_add_id:
43 return CFSTR("add");
44 case sec_item_copy_matching_id:
45 return CFSTR("copy_matching");
46 case sec_item_update_id:
47 return CFSTR("update");
48 case sec_item_delete_id:
49 return CFSTR("delete");
50 case sec_trust_store_contains_id:
51 return CFSTR("trust_store_contains");
52 case sec_trust_store_set_trust_settings_id:
53 return CFSTR("trust_store_set_trust_settings");
54 case sec_trust_store_remove_certificate_id:
55 return CFSTR("trust_store_remove_certificate");
56 case sec_delete_all_id:
57 return CFSTR("delete_all");
58 case sec_trust_evaluate_id:
59 return CFSTR("trust_evaluate");
60 case sec_keychain_backup_id:
61 return CFSTR("keychain_backup");
62 case sec_keychain_restore_id:
63 return CFSTR("keychain_restore");
64 case sec_keychain_sync_update_id:
65 return CFSTR("keychain_sync_update");
66 case sec_keychain_backup_syncable_id:
67 return CFSTR("keychain_backup_syncable");
68 case sec_keychain_restore_syncable_id:
69 return CFSTR("keychain_restore_syncable");
70 case sec_ota_pki_asset_version_id:
71 return CFSTR("ota_pki_asset_version");
72 case kSecXPCOpTryUserCredentials:
73 return CFSTR("TryUserCredentials");
74 case kSecXPCOpSetUserCredentials:
75 return CFSTR("SetUserCredentials");
76 case kSecXPCOpCanAuthenticate:
77 return CFSTR("CanAuthenticate");
78 case kSecXPCOpPurgeUserCredentials:
79 return CFSTR("PurgeUserCredentials");
80 case kSecXPCOpDeviceInCircle:
81 return CFSTR("DeviceInCircle");
82 case kSecXPCOpRequestToJoin:
83 return CFSTR("RequestToJoin");
84 case kSecXPCOpResetToOffering:
85 return CFSTR("ResetToOffering");
86 case kSecXPCOpResetToEmpty:
87 return CFSTR("ResetToEmpty");
88 case kSecXPCOpRemoveThisDeviceFromCircle:
89 return CFSTR("RemoveThisDevice");
90 case kSecXPCOpBailFromCircle:
91 return CFSTR("BailFromCircle");
92 case kSecXPCOpAcceptApplicants:
93 return CFSTR("AcceptApplicants");
94 case kSecXPCOpRejectApplicants:
95 return CFSTR("RejectApplicants");
96 case kSecXPCOpCopyApplicantPeerInfo:
97 return CFSTR("ApplicantPeerInfo");
98 case kSecXPCOpCopyPeerPeerInfo:
99 return CFSTR("PeerPeerInfo");
100 case kSecXPCOpCopyConcurringPeerPeerInfo:
101 return CFSTR("ConcurringPeerPeerInfo");
102 case kSecXPCOpOTAGetEscrowCertificates:
103 return CFSTR("OTAGetEscrowCertificates");
104 case kSecXPCOpOTAPKIGetNewAsset:
105 return CFSTR("sec_ota_pki_get_new_asset");
106 case kSecXPCOpProcessSyncWithAllPeers:
107 return CFSTR("ProcessSyncWithAllPeers");
108 default:
109 return CFSTR("Unknown xpc operation");
110 }
111 }
112
113 bool SecXPCDictionarySetPList(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error)
114 {
115 if (!object)
116 return SecError(errSecParam, error, CFSTR("object for key %s is NULL"), key);
117
118 size_t size = der_sizeof_plist(object, error);
119 if (!size)
120 return false;
121 uint8_t *der = malloc(size);
122 uint8_t *der_end = der + size;
123 uint8_t *der_start = der_encode_plist(object, error, der, der_end);
124 if (!der_start) {
125 free(der);
126 return false;
127 }
128
129 assert(der == der_start);
130 xpc_dictionary_set_data(message, key, der_start, der_end - der_start);
131 free(der);
132 return true;
133 }
134
135 bool SecXPCDictionarySetPListOptional(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error) {
136 return !object || SecXPCDictionarySetPList(message, key, object, error);
137 }
138
139 bool SecXPCDictionarySetData(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error)
140 {
141 if (!data)
142 return SecError(errSecParam, error, CFSTR("data for key %s is NULL"), key);
143
144 xpc_dictionary_set_data(message, key, CFDataGetBytePtr(data), CFDataGetLength(data));
145 return true;
146 }
147
148 bool SecXPCDictionarySetString(xpc_object_t message, const char *key, CFStringRef string, CFErrorRef *error)
149 {
150 if (!string)
151 return SecError(errSecParam, error, CFSTR("string for key %s is NULL"), key);
152
153 __block bool ok = true;
154 CFStringPerformWithCString(string, ^(const char *utf8Str) {
155 if (utf8Str)
156 xpc_dictionary_set_string(message, key, utf8Str);
157 else
158 ok = SecError(errSecParam, error, CFSTR("failed to convert string for key %s to utf8"), key);
159 });
160 return ok;
161 }
162
163 bool SecXPCDictionarySetDataOptional(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error) {
164 return !data || SecXPCDictionarySetData(message, key, data, error);
165 }
166
167 CFArrayRef SecXPCDictionaryCopyArray(xpc_object_t message, const char *key, CFErrorRef *error) {
168 CFTypeRef array = SecXPCDictionaryCopyPList(message, key, error);
169 if (array) {
170 CFTypeID type_id = CFGetTypeID(array);
171 if (type_id != CFArrayGetTypeID()) {
172 CFStringRef description = CFCopyTypeIDDescription(type_id);
173 SecError(errSecParam, error, CFSTR("object for key %s not array but %@"), key, description);
174 CFReleaseNull(description);
175 CFReleaseNull(array);
176 }
177 }
178 return (CFArrayRef)array;
179 }
180
181 bool SecXPCDictionaryCopyArrayOptional(xpc_object_t message, const char *key, CFArrayRef *parray, CFErrorRef *error) {
182 if (!xpc_dictionary_get_value(message, key)) {
183 *parray = NULL;
184 return true;
185 }
186 *parray = SecXPCDictionaryCopyArray(message, key, error);
187 return *parray;
188 }
189
190 CFDataRef SecXPCDictionaryCopyData(xpc_object_t message, const char *key, CFErrorRef *error) {
191 CFDataRef data = NULL;
192 size_t size = 0;
193 const uint8_t *bytes = xpc_dictionary_get_data(message, key, &size);
194 if (!bytes) {
195 SecError(errSecParam, error, CFSTR("no data for key %s"), key);
196 return NULL;
197 }
198
199 data = CFDataCreate(kCFAllocatorDefault, bytes, size);
200 if (!data)
201 SecError(errSecParam, error, CFSTR("failed to create data for key %s"), key);
202
203 return data;
204 }
205
206 bool SecXPCDictionaryCopyDataOptional(xpc_object_t message, const char *key, CFDataRef *pdata, CFErrorRef *error) {
207 size_t size = 0;
208 if (!xpc_dictionary_get_data(message, key, &size)) {
209 *pdata = NULL;
210 return true;
211 }
212 *pdata = SecXPCDictionaryCopyData(message, key, error);
213 return *pdata;
214 }
215
216 CFDictionaryRef SecXPCDictionaryCopyDictionary(xpc_object_t message, const char *key, CFErrorRef *error) {
217 CFTypeRef dict = SecXPCDictionaryCopyPList(message, key, error);
218 if (dict) {
219 CFTypeID type_id = CFGetTypeID(dict);
220 if (type_id != CFDictionaryGetTypeID()) {
221 CFStringRef description = CFCopyTypeIDDescription(type_id);
222 SecError(errSecParam, error, CFSTR("object for key %s not dictionary but %@"), key, description);
223 CFReleaseNull(description);
224 CFReleaseNull(dict);
225 }
226 }
227 return (CFDictionaryRef)dict;
228 }
229
230 bool SecXPCDictionaryCopyDictionaryOptional(xpc_object_t message, const char *key, CFDictionaryRef *pdictionary, CFErrorRef *error) {
231 if (!xpc_dictionary_get_value(message, key)) {
232 *pdictionary = NULL;
233 return true;
234 }
235 *pdictionary = SecXPCDictionaryCopyDictionary(message, key, error);
236 return *pdictionary;
237 }
238
239 CFTypeRef SecXPCDictionaryCopyPList(xpc_object_t message, const char *key, CFErrorRef *error)
240 {
241 CFTypeRef cfobject = NULL;
242 size_t size = 0;
243 const uint8_t *der = xpc_dictionary_get_data(message, key, &size);
244 if (!der) {
245 SecError(errSecParam, error, CFSTR("no object for key %s"), key);
246 return NULL;
247 }
248
249 const uint8_t *der_end = der + size;
250 der = der_decode_plist(kCFAllocatorDefault, kCFPropertyListImmutable,
251 &cfobject, error, der, der_end);
252 if (der != der_end) {
253 SecError(errSecParam, error, CFSTR("trailing garbage after der decoded object for key %s"), key);
254 CFReleaseNull(cfobject);
255 }
256 return cfobject;
257 }
258
259 bool SecXPCDictionaryCopyPListOptional(xpc_object_t message, const char *key, CFTypeRef *pobject, CFErrorRef *error) {
260 size_t size = 0;
261 if (!xpc_dictionary_get_data(message, key, &size)) {
262 *pobject = NULL;
263 return true;
264 }
265 *pobject = SecXPCDictionaryCopyPList(message, key, error);
266 return *pobject;
267 }
268
269 CFStringRef SecXPCDictionaryCopyString(xpc_object_t message, const char *key, CFErrorRef *error) {
270 const char *string = xpc_dictionary_get_string(message, key);
271 if (string) {
272 CFStringRef result = CFStringCreateWithCString(kCFAllocatorDefault, string, kCFStringEncodingUTF8);
273 if (!result) {
274 SecError(errSecAllocate, error, CFSTR("object for key %s failed to convert %s to CFString"), key, string);
275 }
276 return result;
277 } else {
278 SecError(errSecParam, error, CFSTR("object for key %s not string"), key);
279 return NULL;
280 }
281 }