5 // Created by Richard Murphy on 3/23/15.
9 #include "SOSAccountHSAJoin.h"
10 #include "SOSAccountPriv.h"
11 #include <Security/SecureObjectSync/SOSPeerInfo.h>
12 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
13 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
14 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
15 #include <Security/SecureObjectSync/SOSTransportCircle.h>
16 #include <Security/SecureObjectSync/SOSTransportMessage.h>
17 #include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
18 #include <Security/SecureObjectSync/SOSKVSKeys.h>
19 #include <Security/SecureObjectSync/SOSTransport.h>
20 #include <Security/SecureObjectSync/SOSTransportKeyParameter.h>
21 #include <Security/SecureObjectSync/SOSTransportKeyParameterKVS.h>
22 #include <Security/SecureObjectSync/SOSEngine.h>
23 #include <Security/SecureObjectSync/SOSPeerCoder.h>
24 #include <Security/SecureObjectSync/SOSInternal.h>
25 #include <sys/unistd.h>
27 const CFStringRef kSOSHsaPreApprovedPeerKeyInfo
= CFSTR("HSAPreApprovedPeer");
29 const CFStringRef kSOSHsaCrKeyUUID
= CFSTR("HSAUUID");
30 const CFStringRef kSOSHsaCrKeyDescription
= CFSTR("HSADESC");
32 CFMutableSetRef
SOSAccountCopyPreApprovedHSA2Info(SOSAccountRef account
) {
33 CFMutableSetRef preApprovedPeers
= (CFMutableSetRef
) SOSAccountGetValue(account
, kSOSHsaPreApprovedPeerKeyInfo
, NULL
);
34 if(preApprovedPeers
) {
35 preApprovedPeers
= CFSetCreateMutableCopy(NULL
, 0, preApprovedPeers
);
37 preApprovedPeers
= CFSetCreateMutableForCFTypes(NULL
);
39 return preApprovedPeers
;
42 static bool sosAccountSetPreApprovedInfo(SOSAccountRef account
, CFStringRef peerID
, CFErrorRef
*error
) {
44 CFMutableSetRef preApprovedPeers
= SOSAccountCopyPreApprovedHSA2Info(account
);
45 require_action_quiet(preApprovedPeers
, errOut
, SOSCreateError(kSOSErrorAllocationFailure
, CFSTR("Can't Alloc Pre-Approved Peers Set"), NULL
, error
));
46 CFSetSetValue(preApprovedPeers
, peerID
);
47 require(SOSAccountSetValue(account
, kSOSHsaPreApprovedPeerKeyInfo
, preApprovedPeers
, error
), errOut
);
50 CFReleaseNull(preApprovedPeers
);
54 bool SOSAccountSetHSAPubKeyExpected(SOSAccountRef account
, CFDataRef pubKeyBytes
, CFErrorRef
*error
) {
56 SecKeyRef publicKey
= SecKeyCreateFromPublicBytes(NULL
, kSecECDSAAlgorithmID
, CFDataGetBytePtr(pubKeyBytes
), CFDataGetLength(pubKeyBytes
));
57 CFStringRef peerID
= SOSCopyIDOfKey(publicKey
, error
);
58 require(sosAccountSetPreApprovedInfo(account
, peerID
, error
), errOut
);
61 CFReleaseNull(publicKey
);
62 CFReleaseNull(peerID
);
66 bool SOSAccountVerifyAndAcceptHSAApplicants(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
) {
67 SOSFullPeerInfoRef fpi
= account
->my_identity
;
68 __block
bool circleChanged
= false;
69 CFMutableSetRef approvals
= SOSAccountCopyPreApprovedHSA2Info(account
);
70 if(approvals
&& CFSetGetCount(approvals
) > 0) {
71 SOSCircleForEachApplicant(newCircle
, ^(SOSPeerInfoRef peer
) {
72 CFStringRef peerID
= SOSPeerInfoGetPeerID(peer
);
73 if(CFSetContainsValue(approvals
, peerID
)) {
74 SOSPeerInfoRef copypi
= SOSPeerInfoCreateCopy(NULL
, peer
, NULL
);
75 circleChanged
= SOSCircleAcceptRequest(newCircle
, SOSAccountGetPrivateCredential(account
, NULL
), fpi
, copypi
, error
);
76 CFSetRemoveValue(approvals
, peerID
);
81 bool local
= SOSAccountSetValue(account
, kSOSHsaPreApprovedPeerKeyInfo
, approvals
, error
);
82 if(!local
) secnotice("hsa2approval", "Couldn't clean pre-approved peer list");
84 CFReleaseNull(approvals
);
88 bool SOSAccountClientPing(SOSAccountRef account
) {
89 if (account
->trusted_circle
&& account
->my_identity
90 && SOSFullPeerInfoPing(account
->my_identity
, NULL
)) {
91 SOSAccountModifyCircle(account
, NULL
, ^(SOSCircleRef circle_to_change
) {
92 secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for gestalt change");
93 return SOSCircleUpdatePeerInfo(circle_to_change
, SOSFullPeerInfoGetPeerInfo(account
->my_identity
));