1// 2// SOSAccountPriv.h 3// sec 4// 5 6#ifndef sec_SOSAccountPriv_h 7#define sec_SOSAccountPriv_h 8 9#include "SOSAccount.h" 10 11#include <CoreFoundation/CoreFoundation.h> 12#include <CoreFoundation/CFRuntime.h> 13#include <utilities/SecCFWrappers.h> 14#include <utilities/SecCFError.h> 15#include <utilities/SecAKSWrappers.h> 16 17 18#include <Security/SecKeyPriv.h> 19 20#include <utilities/der_plist.h> 21#include <utilities/der_plist_internal.h> 22#include <corecrypto/ccder.h> 23 24#include <AssertMacros.h> 25#include <assert.h> 26 27#import <notify.h> 28 29#include <SecureObjectSync/SOSInternal.h> 30#include <SecureObjectSync/SOSCircle.h> 31#include <SecureObjectSync/SOSCloudCircle.h> 32#include <securityd/SOSCloudCircleServer.h> 33#include <SecureObjectSync/SOSEngine.h> 34#include <SecureObjectSync/SOSPeer.h> 35#include <SecureObjectSync/SOSFullPeerInfo.h> 36#include <SecureObjectSync/SOSPeerInfo.h> 37#include <SecureObjectSync/SOSPeerInfoInternal.h> 38#include <SecureObjectSync/SOSUserKeygen.h> 39#include <utilities/iCloudKeychainTrace.h> 40 41#include <Security/SecItemPriv.h> 42 43struct __OpaqueSOSAccount { 44 CFRuntimeBase _base; 45 46 dispatch_queue_t queue; 47 48 CFDictionaryRef gestalt; 49 50 CFMutableDictionaryRef circle_identities; 51 CFMutableDictionaryRef circles; 52 CFMutableDictionaryRef retired_peers; 53 54 bool user_public_trusted; 55 CFDataRef user_key_parameters; 56 SecKeyRef user_public; 57 SecKeyRef previous_public; 58 enum DepartureReason departure_code; 59 60 // Non-persistent data 61 62 SOSDataSourceFactoryRef factory; 63 SecKeyRef _user_private; 64 dispatch_source_t user_private_timer; 65 int lock_notification_token; 66 67 SOSTransportKeyParameterRef key_transport; 68 CFMutableDictionaryRef circle_transports; 69 CFMutableDictionaryRef message_transports; 70 71 // Live Notification 72 CFMutableArrayRef change_blocks; 73}; 74 75SOSAccountRef SOSAccountCreateBasic(CFAllocatorRef allocator, 76 CFDictionaryRef gestalt, 77 SOSDataSourceFactoryRef factory); 78 79bool SOSAccountEnsureFactoryCircles(SOSAccountRef a); 80 81void SOSAccountSetToNew(SOSAccountRef a); 82 83void SOSAccountForEachKnownCircle(SOSAccountRef account, 84 void (^handle_incompatible)(CFStringRef name), 85 void (^handle_no_peer)(SOSCircleRef circle), 86 void (^handle_peer)(SOSCircleRef circle, SOSFullPeerInfoRef full_peer)); 87 88bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 89bool SOSAccountIsMyPeerActiveInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFErrorRef* error); 90 91// DER Stuff 92 93 94size_t der_sizeof_data_or_null(CFDataRef data, CFErrorRef* error); 95 96uint8_t* der_encode_data_or_null(CFDataRef data, CFErrorRef* error, const uint8_t* der, uint8_t* der_end); 97 98const uint8_t* der_decode_data_or_null(CFAllocatorRef allocator, CFDataRef* data, 99 CFErrorRef* error, 100 const uint8_t* der, const uint8_t* der_end); 101 102size_t der_sizeof_public_bytes(SecKeyRef publicKey, CFErrorRef* error); 103 104uint8_t* der_encode_public_bytes(SecKeyRef publicKey, CFErrorRef* error, const uint8_t* der, uint8_t* der_end); 105 106const uint8_t* der_decode_public_bytes(CFAllocatorRef allocator, CFIndex algorithmID, SecKeyRef* publicKey, CFErrorRef* error, const uint8_t* der, const uint8_t* der_end); 107 108const uint8_t* ccder_decode_bool(bool* boolean, const uint8_t* der, const uint8_t *der_end); 109 110size_t ccder_sizeof_bool(bool value __unused, CFErrorRef *error); 111 112uint8_t* ccder_encode_bool(bool value, const uint8_t *der, uint8_t *der_end); 113 114// Persistence 115 116 117SOSAccountRef SOSAccountCreateFromDER_V1(CFAllocatorRef allocator, 118 SOSDataSourceFactoryRef factory, 119 CFErrorRef* error, 120 const uint8_t** der_p, const uint8_t *der_end); 121 122SOSAccountRef SOSAccountCreateFromDER_V2(CFAllocatorRef allocator, 123 SOSDataSourceFactoryRef factory, 124 CFErrorRef* error, 125 const uint8_t** der_p, const uint8_t *der_end); 126 127SOSAccountRef SOSAccountCreateFromDER_V3(CFAllocatorRef allocator, 128 SOSDataSourceFactoryRef factory, 129 CFErrorRef* error, 130 const uint8_t** der_p, const uint8_t *der_end); 131 132SOSAccountRef SOSAccountCreateFromDER(CFAllocatorRef allocator, 133 SOSDataSourceFactoryRef factory, 134 CFErrorRef* error, 135 const uint8_t** der_p, const uint8_t *der_end); 136 137SOSAccountRef SOSAccountCreateFromData(CFAllocatorRef allocator, CFDataRef circleData, 138 SOSDataSourceFactoryRef factory, 139 CFErrorRef* error); 140 141size_t SOSAccountGetDEREncodedSize(SOSAccountRef account, CFErrorRef *error); 142 143uint8_t* SOSAccountEncodeToDER(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end); 144 145size_t SOSAccountGetDEREncodedSize_V3(SOSAccountRef account, CFErrorRef *error); 146 147uint8_t* SOSAccountEncodeToDER_V3(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end); 148 149size_t SOSAccountGetDEREncodedSize_V2(SOSAccountRef account, CFErrorRef *error); 150 151uint8_t* SOSAccountEncodeToDER_V2(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end); 152 153size_t SOSAccountGetDEREncodedSize_V1(SOSAccountRef account, CFErrorRef *error); 154 155uint8_t* SOSAccountEncodeToDER_V1(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end); 156 157CFDataRef SOSAccountCopyEncodedData(SOSAccountRef account, CFAllocatorRef allocator, CFErrorRef *error); 158 159// Update 160 161bool SOSAccountHandleCircleMessage(SOSAccountRef account, 162 CFStringRef circleName, CFDataRef encodedCircleMessage, CFErrorRef *error); 163 164void SOSAccountRecordRetiredPeerInCircleNamed(SOSAccountRef account, CFStringRef circleName, SOSPeerInfoRef retiree); 165 166 167bool SOSAccountHandleUpdateCircle(SOSAccountRef account, 168 SOSCircleRef prospective_circle, 169 bool writeUpdate, 170 CFErrorRef *error); 171 172// Circles 173 174void SOSAccountForEachKnownCircle(SOSAccountRef account, 175 void (^handle_incompatible)(CFStringRef name), 176 void (^handle_no_peer)(SOSCircleRef circle), 177 void (^handle_peer)(SOSCircleRef circle, SOSFullPeerInfoRef full_peer)); 178 179int SOSAccountCountCircles(SOSAccountRef a); 180 181SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error); 182 183bool SOSAccountDestroyCirclePeerInfoNamed(SOSAccountRef account, CFStringRef name, CFErrorRef* error); 184 185bool SOSAccountDestroyCirclePeerInfo(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 186 187SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 188 189SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 190 191SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error); 192 193bool SOSAccountIsActivePeerInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFStringRef peerid, CFErrorRef* error); 194 195bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 196 197SOSCircleRef SOSAccountFindCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error); 198 199SOSCircleRef SOSAccountEnsureCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error); 200 201bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error); 202 203bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error); 204 205bool SOSAccountModifyCircle(SOSAccountRef account, 206 CFStringRef circleName, 207 CFErrorRef* error, 208 bool (^action)(SOSCircleRef circle)); 209 210SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamedIfPresent(SOSAccountRef account, CFStringRef name, CFErrorRef *error); 211 212void AppendCircleKeyName(CFMutableArrayRef array, CFStringRef name); 213 214CFStringRef SOSInterestListCopyDescription(CFArrayRef interests); 215 216 217// Peers and PeerInfos 218bool SOSAccountDestroyCirclePeerInfoNamed(SOSAccountRef account, CFStringRef name, CFErrorRef* error); 219 220bool SOSAccountDestroyCirclePeerInfo(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 221 222SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 223 224SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error); 225 226bool SOSAccountIsActivePeerInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFStringRef peerid, CFErrorRef* error); 227 228bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 229 230// FullPeerInfos - including Cloud Identity 231SOSFullPeerInfoRef CopyCloudKeychainIdentity(SOSPeerInfoRef cloudPeer, CFErrorRef *error); 232 233SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamedIfPresent(SOSAccountRef account, CFStringRef name, CFErrorRef *error); 234 235bool SOSAccountIsAccountIdentity(SOSAccountRef account, SOSPeerInfoRef peer_info, CFErrorRef *error); 236 237SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error); 238 239SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 240 241SOSPeerInfoRef GenerateNewCloudIdentityPeerInfo(CFErrorRef *error); 242 243// Credentials 244bool SOSAccountHasPublicKey(SOSAccountRef account, CFErrorRef* error); 245void SOSAccountSetPreviousPublic(SOSAccountRef account); 246bool SOSAccountPublishCloudParameters(SOSAccountRef account, CFErrorRef* error); 247bool SOSAccountRetrieveCloudParameters(SOSAccountRef account, SecKeyRef *newKey, 248 CFDataRef derparms, 249 CFDataRef *newParameters, CFErrorRef* error); 250 251//Testing 252void SOSAccountSetUserPublicTrustedForTesting(SOSAccountRef account); 253CFDictionaryRef SOSAccountGetMessageTransports(SOSAccountRef account); 254// Utility 255 256 257static inline void CFArrayAppendValueIfNot(CFMutableArrayRef array, CFTypeRef value, CFTypeRef excludedValue) 258{ 259 if (!CFEqualSafe(value, excludedValue)) 260 CFArrayAppendValue(array, value); 261} 262 263static inline CFMutableDictionaryRef CFDictionaryEnsureCFDictionaryAndGetCurrentValue(CFMutableDictionaryRef dict, CFTypeRef key) 264{ 265 CFMutableDictionaryRef result = (CFMutableDictionaryRef) CFDictionaryGetValue(dict, key); 266 267 if (!isDictionary(result)) { 268 result = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); 269 CFDictionarySetValue(dict, key, result); 270 CFReleaseSafe(result); 271 } 272 273 return result; 274} 275 276static inline CFMutableArrayRef CFDictionaryEnsureCFArrayAndGetCurrentValue(CFMutableDictionaryRef dict, CFTypeRef key) 277{ 278 CFMutableArrayRef result = (CFMutableArrayRef) CFDictionaryGetValue(dict, key); 279 280 if (!isArray(result)) { 281 result = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); 282 CFDictionarySetValue(dict, key, result); 283 CFReleaseSafe(result); 284 } 285 286 return result; 287} 288 289bool sosAccountLeaveCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error); 290 291bool SOSAccountEnsurePeerRegistration(SOSAccountRef account, CFErrorRef *error); 292 293#endif 294