CFGiblisWithHashFor(SOSFullPeerInfo);
-static CFStringRef sPublicKeyKey = CFSTR("PublicSigningKey");
CFStringRef kSOSFullPeerInfoDescriptionKey = CFSTR("SOSFullPeerInfoDescription");
CFStringRef kSOSFullPeerInfoSignatureKey = CFSTR("SOSFullPeerInfoSignature");
bool SOSFullPeerInfoUpdateToThisPeer(SOSFullPeerInfoRef peer, SOSPeerInfoRef pi, CFErrorRef *error) {
return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
- return SOSPeerInfoSign(key, pi, error) ? pi: NULL;
+ return SOSPeerInfoSign(key, pi, error) ? CFRetainSafe(pi): NULL;
});
}
SOSFullPeerInfoRef result = NULL;
SOSFullPeerInfoRef fpi = CFTypeAllocate(SOSFullPeerInfo, struct __OpaqueSOSFullPeerInfo, allocator);
- bool useIDS = whichTransportType == kSOSTransportIDS || whichTransportType == kSOSTransportFuture;
-
- CFStringRef transportType = useIDS ? SOSTransportMessageTypeIDS : SOSTransportMessageTypeKVS;
- CFBooleanRef preferIDS = useIDS ? kCFBooleanTrue : kCFBooleanFalse;
CFStringRef IDSID = CFSTR("");
-
+ CFStringRef transportType =SOSTransportMessageTypeIDSV2;
+ CFBooleanRef preferIDS = kCFBooleanFalse;
+ CFBooleanRef preferIDSFragmentation = kCFBooleanTrue;
+
fpi->peer_info = SOSPeerInfoCreateWithTransportAndViews(allocator, gestalt, backupKey,
IDSID, transportType, preferIDS,
- initialViews,
+ preferIDSFragmentation, initialViews,
signingKey, error);
require_quiet(fpi->peer_info, exit);
return result;
}
+SOSFullPeerInfoRef SOSFullPeerInfoCopyFullPeerInfo(SOSFullPeerInfoRef toCopy) {
+ SOSFullPeerInfoRef retval = NULL;
+ SOSFullPeerInfoRef fpi = CFTypeAllocate(SOSFullPeerInfo, struct __OpaqueSOSFullPeerInfo, kCFAllocatorDefault);
+ SOSPeerInfoRef piToCopy = SOSFullPeerInfoGetPeerInfo(toCopy);
+
+ require_quiet(piToCopy, errOut);
+ require_quiet(fpi, errOut);
+ fpi->peer_info = SOSPeerInfoCreateCopy(kCFAllocatorDefault, piToCopy, NULL);
+ require_quiet(fpi->peer_info, errOut);
+ fpi->key_ref = toCopy->key_ref;
+ CFTransferRetained(retval, fpi);
+
+errOut:
+ CFReleaseNull(fpi);
+ return retval;
+}
+
bool SOSFullPeerInfoUpdateTransportType(SOSFullPeerInfoRef peer, CFStringRef transportType, CFErrorRef* error)
{
return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
});
}
+bool SOSFullPeerInfoUpdateTransportFragmentationPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error){
+ return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
+ return SOSPeerInfoSetIDSFragmentationPreference(kCFAllocatorDefault, peer, preference, key, error);
+ });
+}
+
+
SOSFullPeerInfoRef SOSFullPeerInfoCreateCloudIdentity(CFAllocatorRef allocator, SOSPeerInfoRef peer, CFErrorRef* error) {
SOSFullPeerInfoRef fpi = CFTypeAllocate(SOSFullPeerInfo, struct __OpaqueSOSFullPeerInfo, allocator);
goto exit;
}
- pubKey = SOSPeerInfoCopyPubKey(peer);
+ pubKey = SOSPeerInfoCopyPubKey(peer, error);
+ require_quiet(pubKey, exit);
fpi->key_ref = SecKeyCreatePersistentRefToMatchingPrivateKey(pubKey, error);
{
__block SOSViewResultCode retval = kSOSCCGeneralViewError;
+ secnotice("viewChange", "%s view %@", SOSViewsXlateAction(action), viewname);
+
return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
return SOSPeerInfoCopyWithViewsChange(kCFAllocatorDefault, peer, action, viewname, &retval, key, error);
}) ? retval : kSOSCCGeneralViewError;
}
+static CFMutableSetRef SOSFullPeerInfoCopyViewUpdate(SOSFullPeerInfoRef peer, CFSetRef minimumViews, CFSetRef excludedViews) {
+ CFSetRef enabledViews = SOSPeerInfoCopyEnabledViews(peer->peer_info);
+ CFMutableSetRef newViews = SOSPeerInfoCopyEnabledViews(peer->peer_info);
-static bool CFSetIsSubset(CFSetRef smaller, CFSetRef bigger) {
- __block bool isSubset = true;
- CFSetForEach(smaller, ^(const void *value) {
- if (!CFSetContainsValue(bigger, value)) {
- isSubset = false;
- }
- });
+ if (isSet(minimumViews)) {
+ CFSetUnion(newViews, minimumViews);
+ }
+ if (isSet(excludedViews)) {
+ CFSetSubtract(newViews, excludedViews);
+ }
- return isSubset;
-}
+ if (CFEqualSafe(newViews, enabledViews)) {
+ CFReleaseNull(newViews);
+ }
-static void CFSetUnionSet(CFMutableSetRef target, CFSetRef source) {
- CFSetForEach(source, ^(const void *value) {
- CFSetAddValue(target, value);
- });
+ CFReleaseNull(enabledViews);
+ return newViews;
}
-static bool sosFullPeerInfoNeedsViewUpdate(SOSFullPeerInfoRef peer, CFSetRef minimumViews) {
- CFSetRef currentViews = SOSPeerInfoCopyEnabledViews(peer->peer_info);
- bool success = isSet(minimumViews) && (!isSet(currentViews) || !CFSetIsSubset(minimumViews, currentViews));
- CFReleaseNull(currentViews);
- return success;
+static bool SOSFullPeerInfoNeedsViewUpdate(SOSFullPeerInfoRef peer, CFSetRef minimumViews, CFSetRef excludedViews) {
+ CFSetRef updatedViews = SOSFullPeerInfoCopyViewUpdate(peer, minimumViews, excludedViews);
+ bool needsUpdate = (updatedViews != NULL);
+ CFReleaseNull(updatedViews);
+ return needsUpdate;
}
-static bool sosFullPeerInfoRequiresUpdate(SOSFullPeerInfoRef peer, CFSetRef minimumViews) {
+static bool sosFullPeerInfoRequiresUpdate(SOSFullPeerInfoRef peer, CFSetRef minimumViews, CFSetRef excludedViews) {
if(!SOSPeerInfoVersionIsCurrent(peer->peer_info)) return true;
if(!SOSPeerInfoSerialNumberIsSet(peer->peer_info)) return true;
if(!(SOSPeerInfoV2DictionaryHasString(peer->peer_info, sDeviceID)))return true;
if(!(SOSPeerInfoV2DictionaryHasString(peer->peer_info, sTransportType))) return true;
if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDS))) return true;
- if(sosFullPeerInfoNeedsViewUpdate(peer, minimumViews)) return true;
+ if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDSFragmentation))) return true;
+ if(SOSFullPeerInfoNeedsViewUpdate(peer, minimumViews, excludedViews)) return true;
return false;
}
// Returning false indicates we don't need to upgrade.
-bool SOSFullPeerInfoUpdateToCurrent(SOSFullPeerInfoRef peer, CFSetRef minimumViews) {
- CFMutableSetRef newViews = NULL;
-
- if(!sosFullPeerInfoRequiresUpdate(peer, minimumViews)) return false;
+bool SOSFullPeerInfoUpdateToCurrent(SOSFullPeerInfoRef peer, CFSetRef minimumViews, CFSetRef excludedViews) {
+ bool success = false;
- CFSetRef currentViews = SOSPeerInfoCopyEnabledViews(peer->peer_info);
- if (sosFullPeerInfoNeedsViewUpdate(peer, minimumViews)) {
- newViews = isSet(currentViews) ? CFSetCreateMutableCopy(kCFAllocatorDefault, 0, currentViews) : CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetUnionSet(newViews, minimumViews);
- }
-
+ CFMutableSetRef newViews = NULL;
CFErrorRef copyError = NULL;
CFErrorRef createError = NULL;
- SecKeyRef device_key = SOSFullPeerInfoCopyDeviceKey(peer, ©Error);
+ SecKeyRef device_key = NULL;
+
+ require_quiet(sosFullPeerInfoRequiresUpdate(peer, minimumViews, excludedViews), errOut);
+
+ newViews = SOSFullPeerInfoCopyViewUpdate(peer, minimumViews, excludedViews);
+
+ device_key = SOSFullPeerInfoCopyDeviceKey(peer, ©Error);
require_action_quiet(device_key, errOut,
secnotice("upgrade", "SOSFullPeerInfoCopyDeviceKey failed: %@", copyError));
SOSPeerInfoRef newPeer = SOSPeerInfoCreateCurrentCopy(kCFAllocatorDefault, peer->peer_info,
- NULL, NULL, NULL, newViews ? newViews : minimumViews,
+ NULL, NULL, kCFBooleanFalse, kCFBooleanTrue, newViews,
device_key, &createError);
require_action_quiet(newPeer, errOut,
secnotice("upgrade", "Peer info v2 create copy failed: %@", createError));
CFTransferRetained(peer->peer_info, newPeer);
-
- CFReleaseNull(currentViews);
- CFReleaseSafe(newViews);
- CFReleaseNull(device_key);
- return true;
-
+
+ success = true;
+
errOut:
- CFReleaseNull(currentViews);
- CFReleaseSafe(newViews);
+ CFReleaseNull(newViews);
CFReleaseNull(copyError);
CFReleaseNull(createError);
CFReleaseNull(device_key);
- return false;
+ return success;
}
SOSViewResultCode SOSFullPeerInfoViewStatus(SOSFullPeerInfoRef peer, CFStringRef viewname, CFErrorRef *error)
{
SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(peer);
- secnotice("views", "have pi %s", (pi)? "true": "false");
if(!pi) return kSOSCCGeneralViewError;
return SOSPeerInfoViewStatus(pi, viewname, error);
}
// MARK: Private Key Retrieval and Existence
-static SecKeyRef SOSFullPeerInfoCopyPubKey(SOSFullPeerInfoRef fpi) {
+static SecKeyRef SOSFullPeerInfoCopyPubKey(SOSFullPeerInfoRef fpi, CFErrorRef *error) {
SecKeyRef retval = NULL;
require_quiet(fpi, errOut);
SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi);
require_quiet(pi, errOut);
- retval = SOSPeerInfoCopyPubKey(pi);
+ retval = SOSPeerInfoCopyPubKey(pi, error);
errOut:
return retval;
}
static SecKeyRef SOSFullPeerInfoCopyMatchingPrivateKey(SOSFullPeerInfoRef fpi, CFErrorRef *error) {
- SecKeyRef pub = SOSFullPeerInfoCopyPubKey(fpi);
- SecKeyRef retval = SecKeyCopyMatchingPrivateKey(pub, error);
+ SecKeyRef retval = NULL;
+
+ SecKeyRef pub = SOSFullPeerInfoCopyPubKey(fpi, error);
+ require_quiet(pub, exit);
+ retval = SecKeyCopyMatchingPrivateKey(pub, error);
+exit:
CFReleaseNull(pub);
return retval;
}
static OSStatus SOSFullPeerInfoGetMatchingPrivateKeyStatus(SOSFullPeerInfoRef fpi, CFErrorRef *error) {
- SecKeyRef pub = SOSFullPeerInfoCopyPubKey(fpi);
- OSStatus retval = SecKeyGetMatchingPrivateKeyStatus(pub, error);
+ OSStatus retval = errSecParam;
+ SecKeyRef pub = SOSFullPeerInfoCopyPubKey(fpi, error);
+ require_quiet(pub, exit);
+ retval = SecKeyGetMatchingPrivateKeyStatus(pub, error);
+
+exit:
CFReleaseNull(pub);
return retval;
}
}
bool SOSFullPeerInfoPurgePersistentKey(SOSFullPeerInfoRef fpi, CFErrorRef* error) {
- SecKeyRef pub = SOSFullPeerInfoCopyPubKey(fpi);
- CFDictionaryRef privQuery = CreatePrivateKeyMatchingQuery(pub, false);
- CFMutableDictionaryRef query = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, privQuery);
+ bool result = false;
+ CFDictionaryRef privQuery = NULL;
+ CFMutableDictionaryRef query = NULL;
+
+ SecKeyRef pub = SOSFullPeerInfoCopyPubKey(fpi, error);
+ require_quiet(pub, fail);
+
+ privQuery = CreatePrivateKeyMatchingQuery(pub, false);
+ query = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, privQuery);
CFDictionaryAddValue(query, kSecUseTombstones, kCFBooleanFalse);
- SecItemDelete(query);
+
+ result = SecError(SecItemDelete(query), error, CFSTR("Deleting while purging"));
+
+fail:
CFReleaseNull(privQuery);
CFReleaseNull(query);
CFReleaseNull(pub);
- return true;
+ return result;
}
SecKeyRef SOSFullPeerInfoCopyDeviceKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error) {