2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
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>
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";
57 // XPC Functions for both client and server.
61 CFStringRef
SOSCCGetOperationDescription(enum SecXPCOperation op
)
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");
159 return CFSTR("Unknown xpc operation");
163 bool SecXPCDictionarySetPList(xpc_object_t message
, const char *key
, CFTypeRef object
, CFErrorRef
*error
)
166 return SecError(errSecParam
, error
, CFSTR("object for key %s is NULL"), key
);
168 size_t size
= der_sizeof_plist(object
, error
);
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
);
179 assert(der
== der_start
);
180 xpc_dictionary_set_data(message
, key
, der_start
, der_end
- der_start
);
185 bool SecXPCDictionarySetPListOptional(xpc_object_t message
, const char *key
, CFTypeRef object
, CFErrorRef
*error
) {
186 return !object
|| SecXPCDictionarySetPList(message
, key
, object
, error
);
189 bool SecXPCDictionarySetData(xpc_object_t message
, const char *key
, CFDataRef data
, CFErrorRef
*error
)
192 return SecError(errSecParam
, error
, CFSTR("data for key %s is NULL"), key
);
194 xpc_dictionary_set_data(message
, key
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
198 bool SecXPCDictionarySetString(xpc_object_t message
, const char *key
, CFStringRef string
, CFErrorRef
*error
)
201 return SecError(errSecParam
, error
, CFSTR("string for key %s is NULL"), key
);
203 __block
bool ok
= true;
204 CFStringPerformWithCString(string
, ^(const char *utf8Str
) {
206 xpc_dictionary_set_string(message
, key
, utf8Str
);
208 ok
= SecError(errSecParam
, error
, CFSTR("failed to convert string for key %s to utf8"), key
);
213 bool SecXPCDictionarySetDataOptional(xpc_object_t message
, const char *key
, CFDataRef data
, CFErrorRef
*error
) {
214 return !data
|| SecXPCDictionarySetData(message
, key
, data
, error
);
217 CFArrayRef
SecXPCDictionaryCopyArray(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
218 CFTypeRef array
= SecXPCDictionaryCopyPList(message
, key
, error
);
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
);
228 return (CFArrayRef
)array
;
231 bool SecXPCDictionaryCopyArrayOptional(xpc_object_t message
, const char *key
, CFArrayRef
*parray
, CFErrorRef
*error
) {
232 if (!xpc_dictionary_get_value(message
, key
)) {
236 *parray
= SecXPCDictionaryCopyArray(message
, key
, error
);
240 CFDataRef
SecXPCDictionaryCopyData(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
241 CFDataRef data
= NULL
;
243 const uint8_t *bytes
= xpc_dictionary_get_data(message
, key
, &size
);
245 SecError(errSecParam
, error
, CFSTR("no data for key %s"), key
);
249 data
= CFDataCreate(kCFAllocatorDefault
, bytes
, size
);
251 SecError(errSecParam
, error
, CFSTR("failed to create data for key %s"), key
);
256 bool SecXPCDictionaryCopyDataOptional(xpc_object_t message
, const char *key
, CFDataRef
*pdata
, CFErrorRef
*error
) {
258 if (!xpc_dictionary_get_data(message
, key
, &size
)) {
262 *pdata
= SecXPCDictionaryCopyData(message
, key
, error
);
266 CFDictionaryRef
SecXPCDictionaryCopyDictionary(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
267 CFTypeRef dict
= SecXPCDictionaryCopyPList(message
, key
, error
);
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
);
277 return (CFDictionaryRef
)dict
;
280 bool SecXPCDictionaryCopyDictionaryOptional(xpc_object_t message
, const char *key
, CFDictionaryRef
*pdictionary
, CFErrorRef
*error
) {
281 if (!xpc_dictionary_get_value(message
, key
)) {
285 *pdictionary
= SecXPCDictionaryCopyDictionary(message
, key
, error
);
289 CFTypeRef
SecXPCDictionaryCopyPList(xpc_object_t message
, const char *key
, CFErrorRef
*error
)
291 CFTypeRef cfobject
= NULL
;
293 const uint8_t *der
= xpc_dictionary_get_data(message
, key
, &size
);
295 SecError(errSecParam
, error
, CFSTR("no object for key %s"), key
);
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
);
309 bool SecXPCDictionaryCopyPListOptional(xpc_object_t message
, const char *key
, CFTypeRef
*pobject
, CFErrorRef
*error
) {
311 if (!xpc_dictionary_get_data(message
, key
, &size
)) {
315 *pobject
= SecXPCDictionaryCopyPList(message
, key
, error
);
319 CFStringRef
SecXPCDictionaryCopyString(xpc_object_t message
, const char *key
, CFErrorRef
*error
) {
320 const char *string
= xpc_dictionary_get_string(message
, key
);
322 CFStringRef result
= CFStringCreateWithCString(kCFAllocatorDefault
, string
, kCFStringEncodingUTF8
);
324 SecError(errSecAllocate
, error
, CFSTR("object for key %s failed to convert %s to CFString"), key
, string
);
328 SecError(errSecParam
, error
, CFSTR("object for key %s not string"), key
);