]> git.saurik.com Git - apple/security.git/blob - keychain/SecureObjectSync/SOSRingBasic.m
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / SecureObjectSync / SOSRingBasic.m
1 //
2 // SOSRingBasic.c
3 // sec
4 //
5 // Created by Richard Murphy on 3/3/15.
6 //
7 //
8
9 #include "SOSRingBasic.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: Basic Ring Ops
31
32 SOSRingRef SOSRingCreate_Basic(CFStringRef name, CFStringRef myPeerID, CFErrorRef *error) {
33 return SOSRingCreate_ForType(name, kSOSRingBase, myPeerID, error);
34 }
35
36 bool SOSRingResetToEmpty_Basic(SOSRingRef ring, CFStringRef myPeerID, CFErrorRef *error) {
37 return SOSRingResetToEmpty_Internal(ring, error) && SOSRingSetLastModifier(ring, myPeerID);
38 }
39
40 bool SOSRingResetToOffering_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
41 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
42 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
43 bool retval = priv && myPeerID &&
44 SOSRingResetToEmpty_Internal(ring, error) &&
45 SOSRingAddPeerID(ring, myPeerID) &&
46 SOSRingSetLastModifier(ring, myPeerID) &&
47 SOSRingGenerationSign_Internal(ring, priv, error);
48 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
49 CFReleaseNull(priv);
50 return retval;
51 }
52
53 SOSRingStatus SOSRingDeviceIsInRing_Basic(SOSRingRef ring, CFStringRef peerID) {
54 if(SOSRingHasPeerID(ring, peerID)) return kSOSRingMember;
55 if(SOSRingHasApplicant(ring, peerID)) return kSOSRingApplicant;
56 if(SOSRingHasRejection(ring, peerID)) return kSOSRingReject;
57 return kSOSRingNotInRing;
58 }
59
60 bool SOSRingApply_Basic(SOSRingRef ring, SecKeyRef user_pubkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
61 bool retval = false;
62 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
63 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
64 require_action_quiet(SOSRingDeviceIsInRing_Basic(ring, myPeerID) == kSOSRingNotInRing, errOut, secnotice("ring", "Already associated with ring"));
65 retval = priv && myPeerID &&
66 SOSRingAddPeerID(ring, myPeerID) &&
67 SOSRingSetLastModifier(ring, myPeerID) &&
68 SOSRingGenerationSign_Internal(ring, priv, error);
69 errOut:
70 CFReleaseNull(priv);
71 return retval;
72
73 }
74
75 bool SOSRingWithdraw_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
76 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
77 if(SOSRingHasPeerID(ring, myPeerID)) {
78 SOSRingRemovePeerID(ring, myPeerID);
79 } else if(SOSRingHasApplicant(ring, myPeerID)) {
80 SOSRingRemoveApplicant(ring, myPeerID);
81 } else if(SOSRingHasRejection(ring, myPeerID)) {
82 SOSRingRemoveRejection(ring, myPeerID);
83 } else {
84 SOSCreateError(kSOSErrorPeerNotFound, CFSTR("Not associated with Ring"), NULL, error);
85 return false;
86 }
87 SOSRingSetLastModifier(ring, myPeerID);
88
89 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
90 SOSRingGenerationSign_Internal(ring, priv, error);
91 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
92 CFReleaseNull(priv);
93 return true;
94 }
95
96 bool SOSRingGenerationSign_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
97 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
98 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
99 bool retval = priv && myPeerID &&
100 SOSRingSetLastModifier(ring, myPeerID) &&
101 SOSRingGenerationSign_Internal(ring, priv, error);
102 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
103 CFReleaseNull(priv);
104 return retval;
105 }
106
107 bool SOSRingConcordanceSign_Basic(SOSRingRef ring, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
108 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
109 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
110 bool retval = priv && myPeerID &&
111 SOSRingSetLastModifier(ring, myPeerID) &&
112 SOSRingConcordanceSign_Internal(ring, priv, error);
113 CFReleaseNull(priv);
114 return retval;
115 }
116
117 bool SOSRingSetPayload_Basic(SOSRingRef ring, SecKeyRef user_privkey, CFDataRef payload, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
118 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
119 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
120 bool retval = priv && myPeerID &&
121 SOSRingSetLastModifier(ring, myPeerID) &&
122 SOSRingSetPayload_Internal(ring, payload) &&
123 SOSRingGenerationSign_Internal(ring, priv, error);
124 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
125 CFReleaseNull(priv);
126 return retval;
127 }
128
129 CFDataRef SOSRingGetPayload_Basic(SOSRingRef ring, CFErrorRef *error) {
130 return SOSRingGetPayload_Internal(ring);
131 }
132
133
134 ringFuncStruct basic = {
135 "Basic",
136 1,
137 SOSRingCreate_Basic,
138 SOSRingResetToEmpty_Basic,
139 SOSRingResetToOffering_Basic,
140 SOSRingDeviceIsInRing_Basic,
141 SOSRingApply_Basic,
142 SOSRingWithdraw_Basic,
143 SOSRingGenerationSign_Basic,
144 SOSRingConcordanceSign_Basic,
145 SOSRingPeerKeyConcordanceTrust,
146 NULL,
147 NULL,
148 SOSRingSetPayload_Basic,
149 SOSRingGetPayload_Basic,
150 };