]> git.saurik.com Git - apple/security.git/blob - keychain/SecureObjectSync/SOSRingV0.m
Security-59754.80.3.tar.gz
[apple/security.git] / keychain / SecureObjectSync / SOSRingV0.m
1 //
2 // SOSRingV0.c
3 // sec
4 //
5 // Created by Richard Murphy on 3/5/15.
6 //
7 //
8
9 #include "SOSRingV0.h"
10
11 #include <AssertMacros.h>
12
13 #include "keychain/SecureObjectSync/SOSInternal.h"
14 #include "keychain/SecureObjectSync/SOSPeerInfoInternal.h"
15 #include "keychain/SecureObjectSync/SOSPeerInfoCollections.h"
16 #include "keychain/SecureObjectSync/SOSCircle.h"
17 #include <Security/SecFramework.h>
18
19 #include <Security/SecKey.h>
20 #include <Security/SecKeyPriv.h>
21 #include <CoreFoundation/CoreFoundation.h>
22
23 #include <utilities/SecCFWrappers.h>
24
25 #include <stdlib.h>
26
27 #include "SOSRingUtils.h"
28 #include "SOSRingTypes.h"
29
30 // MARK: V0 Ring Ops - same operation as V0 Circles
31
32 static SOSRingRef SOSRingCreate_V0(CFStringRef name, CFStringRef myPeerID, CFErrorRef *error) {
33 SOSRingRef retval = NULL;
34 retval = SOSRingCreate_Internal(name, 0, error);
35 if(!retval) return NULL;
36 SOSRingSetLastModifier(retval, myPeerID);
37 return retval;
38 }
39
40 static bool SOSRingResetToEmpty_V0(SOSRingRef ring, CFStringRef myPeerID, CFErrorRef *error) {
41 return SOSRingResetToEmpty_Internal(ring, error) && SOSRingSetLastModifier(ring, myPeerID);
42 }
43
44 static bool SOSRingResetToOffering_V0(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
45 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
46 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
47 bool retval = priv && myPeerID &&
48 SOSRingResetToEmpty_Internal(ring, error) &&
49 SOSRingAddPeerID(ring, myPeerID) &&
50 SOSRingSetLastModifier(ring, myPeerID) &&
51 SOSRingGenerationSign_Internal(ring, user_privkey, error);
52 SOSRingConcordanceSign_Internal(ring, priv, error);
53 CFReleaseNull(priv);
54 return retval;
55 }
56
57 static SOSRingStatus SOSRingDeviceIsInRing_V0(SOSRingRef ring, CFStringRef peerID) {
58 if(SOSRingHasPeerID(ring, peerID)) return kSOSRingMember;
59 if(SOSRingHasApplicant(ring, peerID)) return kSOSRingApplicant;
60 if(SOSRingHasRejection(ring, peerID)) return kSOSRingReject;
61 return kSOSRingNotInRing;
62 }
63
64 static bool SOSRingApply_V0(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
65 bool retval = false;
66 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
67 if(SOSRingDeviceIsInRing_V0(ring, myPeerID) == kSOSRingReject) SOSRingRemoveRejection(ring, myPeerID);
68 require_action_quiet(SOSRingDeviceIsInRing_V0(ring, myPeerID) == kSOSRingNotInRing, errOut, secnotice("ring", "Already associated with ring"));
69 retval = myPeerID &&
70 SOSRingAddApplicant(ring, myPeerID) &&
71 SOSRingSetLastModifier(ring, myPeerID);
72 errOut:
73 return retval;
74 }
75
76 static bool SOSRingWithdraw_V0(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
77 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
78 SOSRingSetLastModifier(ring, myPeerID);
79 if(SOSRingHasPeerID(ring, myPeerID)) {
80 SOSRingRemovePeerID(ring, myPeerID);// Maybe we need a retired peerID list?
81 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
82 SOSRingGenerationSign_Internal(ring, priv, error);
83 if(user_privkey) SOSRingGenerationSign_Internal(ring, user_privkey, error);
84 CFReleaseNull(priv);
85 } else if(SOSRingHasApplicant(ring, myPeerID)) {
86 SOSRingRemoveApplicant(ring, myPeerID);
87 } else if(SOSRingHasRejection(ring, myPeerID)) {
88 SOSRingRemoveRejection(ring, myPeerID);
89 } else {
90 SOSCreateError(kSOSErrorPeerNotFound, CFSTR("Not associated with Ring"), NULL, error);
91 return false;
92 }
93
94 return true;
95 }
96
97 static bool SOSRingGenerationSign_V0(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
98 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
99 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
100 bool retval = priv && myPeerID &&
101 SOSRingSetLastModifier(ring, myPeerID) &&
102 SOSRingGenerationSign_Internal(ring, priv, error);
103 if(user_privkey) SOSRingGenerationSign_Internal(ring, user_privkey, error);
104 CFReleaseNull(priv);
105 return retval;
106 }
107
108 static bool SOSRingConcordanceSign_V0(SOSRingRef ring, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
109 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
110 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
111 bool retval = priv && myPeerID &&
112 SOSRingSetLastModifier(ring, myPeerID) &&
113 SOSRingConcordanceSign_Internal(ring, priv, error);
114 CFReleaseNull(priv);
115 return retval;
116 }
117
118
119 ringFuncStruct ringsV0 = {
120 "V0",
121 1,
122 SOSRingCreate_V0,
123 SOSRingResetToEmpty_V0,
124 SOSRingResetToOffering_V0,
125 SOSRingDeviceIsInRing_V0,
126 SOSRingApply_V0,
127 SOSRingWithdraw_V0,
128 SOSRingGenerationSign_V0,
129 SOSRingConcordanceSign_V0,
130 SOSRingUserKeyConcordanceTrust,
131 NULL,
132 NULL
133 };