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>
23 #include <Security/SecureObjectSync/SOSAccount.h>
24 #include <Security/SecureObjectSync/SOSAccountPriv.h>
26 CFStringRef secpropMemError
= CFSTR("Failed to get memory for SecurityProperties in PeerInfo");
27 CFStringRef secpropUnknownError
= CFSTR("Unknown Security Property(%@) (SOSSecurityPropertyResultCode=%d)");
28 CFStringRef secpropInvalidError
= CFSTR("Peer is invalid for this security property(%@) (SOSSecurityPropertyResultCode=%d)");
30 const CFStringRef kSOSSecPropertyHasEntropy
= CFSTR("SecPropEntropy");
31 const CFStringRef kSOSSecPropertyScreenLock
= CFSTR("SecPropScreenLock");
32 const CFStringRef kSOSSecPropertySEP
= CFSTR("SecPropSEP");
33 const CFStringRef kSOSSecPropertyIOS
= CFSTR("SecPropIOS");
36 CFSetRef
SOSSecurityPropertyGetAllCurrent(void) {
37 static dispatch_once_t dot
;
38 static CFMutableSetRef allSecurityProperties
= NULL
;
39 dispatch_once(&dot
, ^{
40 allSecurityProperties
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
41 CFSetAddValue(allSecurityProperties
, kSOSSecPropertyHasEntropy
);
42 CFSetAddValue(allSecurityProperties
, kSOSSecPropertyScreenLock
);
43 CFSetAddValue(allSecurityProperties
, kSOSSecPropertySEP
);
44 CFSetAddValue(allSecurityProperties
, kSOSSecPropertyIOS
);
46 return allSecurityProperties
;
49 static bool SOSSecurityPropertyIsKnownProperty(CFStringRef secPropName
) {
50 CFSetRef allSecurityProperties
= SOSSecurityPropertyGetAllCurrent();
51 if(CFSetContainsValue(allSecurityProperties
, secPropName
)) return true;
52 secnotice("SecurityProperties","Not a known Security Property");
57 static CFMutableSetRef
CFSetCreateMutableForSOSSecurityProperties(CFAllocatorRef allocator
) {
58 return CFSetCreateMutable(allocator
, 0, &kCFTypeSetCallBacks
);
61 CFMutableSetRef
SOSPeerInfoCopySecurityProperty(SOSPeerInfoRef pi
) {
62 if (!SOSPeerInfoVersionHasV2Data(pi
)) {
65 CFMutableSetRef secproperty
= (CFMutableSetRef
)SOSPeerInfoV2DictionaryCopySet(pi
, sSecurityPropertiesKey
);
67 secerror("%@ v2 peer has no security properties", SOSPeerInfoGetPeerID(pi
));
72 static void SOSPeerInfoSetSecurityProperty(SOSPeerInfoRef pi
, CFSetRef newproperties
) {
74 secnotice("secproperty","Asked to swap to NULL Security Properties");
77 SOSPeerInfoV2DictionarySetValue(pi
, sSecurityPropertiesKey
, newproperties
);
80 static bool SOSPeerInfoSecurityPropertyIsValid(SOSPeerInfoRef pi
, CFStringRef propertyname
) {
84 static bool secPropertyErrorReport(CFIndex errorCode
, CFErrorRef
*error
, CFStringRef format
, CFStringRef propertyname
, int retval
) {
85 return SOSCreateErrorWithFormat(errorCode
, NULL
, error
, NULL
, format
, propertyname
, retval
);
88 CFMutableSetRef
SOSSecurityPropertiesCreateDefault(SOSPeerInfoRef pi
, CFErrorRef
*error
) {
89 return CFSetCreateMutableForSOSSecurityProperties(NULL
);
92 SOSSecurityPropertyResultCode
SOSSecurityPropertyEnable(SOSPeerInfoRef pi
, CFStringRef propertyname
, CFErrorRef
*error
) {
93 SOSSecurityPropertyResultCode retval
= kSOSCCGeneralSecurityPropertyError
;
95 CFMutableSetRef newSecurityProperties
= SOSPeerInfoCopySecurityProperty(pi
);
96 require_action_quiet(newSecurityProperties
, fail
,
97 SOSCreateError(kSOSErrorAllocationFailure
, secpropMemError
, NULL
, error
));
98 require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname
), fail
,
99 secPropertyErrorReport(kSOSErrorNameMismatch
, error
, secpropUnknownError
, propertyname
, retval
= kSOSCCNoSuchSecurityProperty
));
100 require_action_quiet(SOSPeerInfoSecurityPropertyIsValid(pi
, propertyname
), fail
,
101 secPropertyErrorReport(kSOSErrorNameMismatch
, error
, secpropInvalidError
, propertyname
, retval
= kSOSCCSecurityPropertyNotQualified
));
102 CFSetAddValue(newSecurityProperties
, propertyname
);
103 SOSPeerInfoSetSecurityProperty(pi
, newSecurityProperties
);
104 CFReleaseSafe(newSecurityProperties
);
105 return kSOSCCSecurityPropertyValid
;
108 CFReleaseNull(newSecurityProperties
);
109 secnotice("SecurityProperties","Failed to enable Security Property(%@): %@", propertyname
, *error
);
113 SOSSecurityPropertyResultCode
SOSSecurityPropertyDisable(SOSPeerInfoRef pi
, CFStringRef propertyname
, CFErrorRef
*error
) {
114 SOSSecurityPropertyResultCode retval
= kSOSCCGeneralSecurityPropertyError
;
115 CFMutableSetRef newSecurityProperties
= SOSPeerInfoCopySecurityProperty(pi
);
116 require_action_quiet(newSecurityProperties
, fail
,
117 SOSCreateError(kSOSErrorAllocationFailure
, secpropMemError
, NULL
, error
));
118 require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname
), fail
,
119 secPropertyErrorReport(kSOSErrorNameMismatch
, error
, secpropUnknownError
, propertyname
, retval
= kSOSCCNoSuchSecurityProperty
));
121 CFSetRemoveValue(newSecurityProperties
, propertyname
);
122 SOSPeerInfoSetSecurityProperty(pi
, newSecurityProperties
);
123 CFReleaseSafe(newSecurityProperties
);
124 return kSOSCCSecurityPropertyNotValid
;
127 CFReleaseNull(newSecurityProperties
);
128 secnotice("SecurityProperties","Failed to disable Security Property(%@): %@", propertyname
, *error
);
132 SOSSecurityPropertyResultCode
SOSSecurityPropertyQuery(SOSPeerInfoRef pi
, CFStringRef propertyname
, CFErrorRef
*error
) {
133 SOSSecurityPropertyResultCode retval
= kSOSCCNoSuchSecurityProperty
;
134 secnotice("SecurityProperties", "Querying %@", propertyname
);
135 require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname
), fail
,
136 SOSCreateError(kSOSErrorNameMismatch
, secpropUnknownError
, NULL
, error
));
137 CFMutableSetRef secproperty
= SOSPeerInfoCopySecurityProperty(pi
);
138 if(!secproperty
) return kSOSCCSecurityPropertyNotValid
;
139 retval
= (CFSetContainsValue(secproperty
, propertyname
)) ? kSOSCCSecurityPropertyValid
: kSOSCCSecurityPropertyNotValid
;
140 CFReleaseNull(secproperty
);
143 secnotice("SecurityProperties","Failed to query Security Property(%@): %@", propertyname
, *error
);