2 // SOSPeerInfoSecurityProperties.c
5 // Created by Richard Murphy on 3/14/15.
10 #include <AssertMacros.h>
11 #include <TargetConditionals.h>
13 #include "SOSPeerInfoSecurityProperties.h"
14 #include <utilities/SecCFWrappers.h>
15 #include <utilities/SecCFRelease.h>
16 #include <utilities/SecCFError.h>
17 #include <Security/SecureObjectSync/SOSInternal.h>
19 #include <Security/SecureObjectSync/SOSPeerInfo.h>
20 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
21 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
22 #include <Security/SecureObjectSync/SOSCloudCircle.h>
24 #define secpropMemError CFSTR("Failed to get memory for SecurityProperties in PeerInfo")
25 #define secpropUnknownError CFSTR("Unknown Security Property(%@) (SOSSecurityPropertyResultCode=%d)")
26 #define secpropInvalidError CFSTR("Peer is invalid for this security property(%@) (SOSSecurityPropertyResultCode=%d)")
28 const CFStringRef kSOSSecPropertyHasEntropy = CFSTR("SecPropEntropy");
29 const CFStringRef kSOSSecPropertyScreenLock = CFSTR("SecPropScreenLock");
30 const CFStringRef kSOSSecPropertySEP = CFSTR("SecPropSEP");
31 const CFStringRef kSOSSecPropertyIOS = CFSTR("SecPropIOS");
34 CFSetRef SOSSecurityPropertyGetAllCurrent(void) {
35 static dispatch_once_t dot;
36 static CFMutableSetRef allSecurityProperties = NULL;
37 dispatch_once(&dot, ^{
38 allSecurityProperties = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
39 CFSetAddValue(allSecurityProperties, kSOSSecPropertyHasEntropy);
40 CFSetAddValue(allSecurityProperties, kSOSSecPropertyScreenLock);
41 CFSetAddValue(allSecurityProperties, kSOSSecPropertySEP);
42 CFSetAddValue(allSecurityProperties, kSOSSecPropertyIOS);
44 return allSecurityProperties;
47 static bool SOSSecurityPropertyIsKnownProperty(CFStringRef secPropName) {
48 CFSetRef allSecurityProperties = SOSSecurityPropertyGetAllCurrent();
49 if(CFSetContainsValue(allSecurityProperties, secPropName)) return true;
50 secnotice("SecurityProperties","Not a known Security Property");
55 static CFMutableSetRef CFSetCreateMutableForSOSSecurityProperties(CFAllocatorRef allocator) {
56 return CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
59 CFMutableSetRef SOSPeerInfoCopySecurityProperty(SOSPeerInfoRef pi) {
60 if (!SOSPeerInfoVersionHasV2Data(pi)) {
63 CFMutableSetRef secproperty = (CFMutableSetRef)SOSPeerInfoV2DictionaryCopySet(pi, sSecurityPropertiesKey);
65 secerror("%@ v2 peer has no security properties", SOSPeerInfoGetPeerID(pi));
70 static void SOSPeerInfoSetSecurityProperty(SOSPeerInfoRef pi, CFSetRef newproperties) {
72 secnotice("secproperty","Asked to swap to NULL Security Properties");
75 SOSPeerInfoV2DictionarySetValue(pi, sSecurityPropertiesKey, newproperties);
78 static bool SOSPeerInfoSecurityPropertyIsValid(SOSPeerInfoRef pi, CFStringRef propertyname) {
82 CFMutableSetRef SOSSecurityPropertiesCreateDefault(SOSPeerInfoRef pi, CFErrorRef *error) {
83 return CFSetCreateMutableForSOSSecurityProperties(NULL);
86 SOSSecurityPropertyResultCode SOSSecurityPropertyEnable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) {
87 SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError;
89 CFMutableSetRef newSecurityProperties = SOSPeerInfoCopySecurityProperty(pi);
90 require_action_quiet(newSecurityProperties, fail,
91 SOSCreateError(kSOSErrorAllocationFailure, secpropMemError, NULL, error));
92 require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail,
93 SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropUnknownError, propertyname, retval = kSOSCCNoSuchSecurityProperty));
94 require_action_quiet(SOSPeerInfoSecurityPropertyIsValid(pi, propertyname), fail,
95 SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropInvalidError, propertyname, retval = kSOSCCSecurityPropertyNotQualified));
96 CFSetAddValue(newSecurityProperties, propertyname);
97 SOSPeerInfoSetSecurityProperty(pi, newSecurityProperties);
98 CFReleaseSafe(newSecurityProperties);
99 return kSOSCCSecurityPropertyValid;
102 CFReleaseNull(newSecurityProperties);
103 secnotice("SecurityProperties","Failed to enable Security Property(%@): %@", propertyname, *error);
107 SOSSecurityPropertyResultCode SOSSecurityPropertyDisable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) {
108 SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError;
109 CFMutableSetRef newSecurityProperties = SOSPeerInfoCopySecurityProperty(pi);
110 require_action_quiet(newSecurityProperties, fail,
111 SOSCreateError(kSOSErrorAllocationFailure, secpropMemError, NULL, error));
112 require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail,
113 SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropUnknownError, propertyname, retval = kSOSCCNoSuchSecurityProperty));
115 CFSetRemoveValue(newSecurityProperties, propertyname);
116 SOSPeerInfoSetSecurityProperty(pi, newSecurityProperties);
117 CFReleaseSafe(newSecurityProperties);
118 return kSOSCCSecurityPropertyNotValid;
121 CFReleaseNull(newSecurityProperties);
122 secnotice("SecurityProperties","Failed to disable Security Property(%@): %@", propertyname, *error);
126 SOSSecurityPropertyResultCode SOSSecurityPropertyQuery(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) {
127 SOSSecurityPropertyResultCode retval = kSOSCCNoSuchSecurityProperty;
128 secnotice("SecurityProperties", "Querying %@", propertyname);
129 require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail,
130 SOSCreateError(kSOSErrorNameMismatch, secpropUnknownError, NULL, error));
131 CFMutableSetRef secproperty = SOSPeerInfoCopySecurityProperty(pi);
132 if(!secproperty) return kSOSCCSecurityPropertyNotValid;
133 retval = (CFSetContainsValue(secproperty, propertyname)) ? kSOSCCSecurityPropertyValid: kSOSCCSecurityPropertyNotValid;
134 CFReleaseNull(secproperty);
137 secnotice("SecurityProperties","Failed to query Security Property(%@): %@", propertyname, *error);