]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSAccountHSAJoin.c
Security-57740.31.2.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSAccountHSAJoin.c
1 //
2 // SOSAccountHSAJoin.c
3 // sec
4 //
5 // Created by Richard Murphy on 3/23/15.
6 //
7 //
8
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>
26
27 const CFStringRef kSOSHsaPreApprovedPeerKeyInfo = CFSTR("HSAPreApprovedPeer");
28
29 const CFStringRef kSOSHsaCrKeyUUID = CFSTR("HSAUUID");
30 const CFStringRef kSOSHsaCrKeyDescription = CFSTR("HSADESC");
31
32 CFMutableSetRef SOSAccountCopyPreApprovedHSA2Info(SOSAccountRef account) {
33 CFMutableSetRef preApprovedPeers = (CFMutableSetRef) SOSAccountGetValue(account, kSOSHsaPreApprovedPeerKeyInfo, NULL);
34 if(preApprovedPeers) {
35 preApprovedPeers = CFSetCreateMutableCopy(NULL, 0, preApprovedPeers);
36 } else {
37 preApprovedPeers = CFSetCreateMutableForCFTypes(NULL);
38 }
39 return preApprovedPeers;
40 }
41
42 static bool sosAccountSetPreApprovedInfo(SOSAccountRef account, CFStringRef peerID, CFErrorRef *error) {
43 bool retval = false;
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);
48 retval = true;
49 errOut:
50 CFReleaseNull(preApprovedPeers);
51 return retval;
52 }
53
54 bool SOSAccountSetHSAPubKeyExpected(SOSAccountRef account, CFDataRef pubKeyBytes, CFErrorRef *error) {
55 bool retval = false;
56 SecKeyRef publicKey = SecKeyCreateFromPublicBytes(NULL, kSecECDSAAlgorithmID, CFDataGetBytePtr(pubKeyBytes), CFDataGetLength(pubKeyBytes));
57 CFStringRef peerID = SOSCopyIDOfKey(publicKey, error);
58 require(sosAccountSetPreApprovedInfo(account, peerID, error), errOut);
59 retval = true;
60 errOut:
61 CFReleaseNull(publicKey);
62 CFReleaseNull(peerID);
63 return retval;
64 }
65
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);
77 }
78 });
79 }
80 if(circleChanged) {
81 bool local = SOSAccountSetValue(account, kSOSHsaPreApprovedPeerKeyInfo, approvals, error);
82 if(!local) secnotice("hsa2approval", "Couldn't clean pre-approved peer list");
83 }
84 CFReleaseNull(approvals);
85 return circleChanged;
86 }
87
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));
94 });
95 }
96
97 return true;
98 }
99