]> git.saurik.com Git - apple/security.git/blob - keychain/trust/TrustedPeers/TPModel.h
Security-58286.41.2.tar.gz
[apple/security.git] / keychain / trust / TrustedPeers / TPModel.h
1 /*
2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #import <Foundation/Foundation.h>
25
26 #import "TPHash.h"
27 #import "TPSigningKey.h"
28 #import "TPDecrypter.h"
29 #import "TPTypes.h"
30
31 @class TPCircle;
32 @class TPPeerPermanentInfo;
33 @class TPPeerStableInfo;
34 @class TPPeerDynamicInfo;
35 @class TPVoucher;
36 @class TPPolicyDocument;
37
38
39 typedef NS_OPTIONS(NSUInteger, TPPeerStatus) {
40 // Set if at least one of the peers I trust trusts me.
41 TPPeerStatusPartiallyReciprocated = 1 << 0,
42
43 // Set if all of the peers I trust trust me.
44 TPPeerStatusFullyReciprocated = 1 << 1,
45
46 // Set if I have been kicked out of trust.
47 TPPeerStatusExcluded = 1 << 2,
48
49 // Set if my epoch is behind the latest epoch.
50 TPPeerStatusOutdatedEpoch = 1 << 3,
51
52 // Set if my epoch is two or more epochs behind the latest.
53 TPPeerStatusAncientEpoch = 1 << 4,
54 };
55
56
57 NS_ASSUME_NONNULL_BEGIN
58
59 /*!
60 TPModel implements the Octagon Trust model, as per
61 https://confluence.sd.apple.com/display/KEY/Octagon+Trust
62
63 It maintains a collection of peers and a collection of circles,
64 to track the peers and circles in CloudKit.
65 (This class does not communicate with CloudKit. The client of this class does that.)
66
67 Normally there would be just one instance of TPModel, associated with a particular Apple ID.
68 (This class doesn't need to know what the Apple ID is.)
69
70 This interface does not expose TPPeer* because the caller might mutate the peer object.
71 All the objects exposed by this interface are immutable.
72 */
73 @interface TPModel : NSObject
74
75 - (instancetype)initWithDecrypter:(id<TPDecrypter>)decrypter;
76
77 - (TPCounter)latestEpochAmongPeerIDs:(NSSet<NSString*> *)peerIDs;
78
79 - (void)registerPolicyDocument:(TPPolicyDocument *)policyDoc;
80
81 /*!
82 Register a peer with the given permanentInfo.
83
84 To access this peer invoke other TPModel methods and
85 pass permanentInfo.peerID as the peerID argument.
86
87 (If a peer with this permanentInfo is already registered then registering it again
88 does nothing, and the existing TPPeer object internal to TPModel retains its state.)
89 */
90 - (void)registerPeerWithPermanentInfo:(TPPeerPermanentInfo *)permanentInfo;
91
92 - (void)deletePeerWithID:(NSString *)peerID;
93
94 - (BOOL)hasPeerWithID:(NSString *)peerID;
95
96 /*!
97 Asserts that peerID is registered.
98 */
99 - (TPPeerStatus)statusOfPeerWithID:(NSString *)peerID;
100
101 /*!
102 Asserts that peerID is registered.
103 */
104 - (TPPeerPermanentInfo *)getPermanentInfoForPeerWithID:(NSString *)peerID;
105
106 /*!
107 Asserts that peerID is registered.
108 */
109 - (nullable TPPeerStableInfo *)getStableInfoForPeerWithID:(NSString *)peerID;
110
111 /*!
112 Asserts that peerID is registered.
113 */
114 - (nullable NSData *)getWrappedPrivateKeysForPeerWithID:(NSString *)peerID;
115
116 /*!
117 Asserts that peerID is registered.
118 */
119 - (void)setWrappedPrivateKeys:(nullable NSData *)wrappedPrivateKeys
120 forPeerWithID:(NSString *)peerID;
121
122 /*!
123 Asserts that peerID is registered.
124 */
125 - (nullable TPPeerDynamicInfo *)getDynamicInfoForPeerWithID:(NSString *)peerID;
126
127 /*!
128 Asserts that peerID is registered.
129 */
130 - (nullable TPCircle *)getCircleForPeerWithID:(NSString *)peerID;
131
132
133 - (void)registerCircle:(TPCircle *)circle;
134
135 - (void)deleteCircleWithID:(NSString *)circleID;
136
137 /*!
138 Returns nil if no circle matching circleID is registered.
139 */
140 - (nullable TPCircle *)circleWithID:(NSString *)circleID;
141
142
143 /*!
144 An "update" with unchanged data is considered success.
145 Asserts that peerID is registered.
146 */
147 - (TPResult)updateStableInfo:(TPPeerStableInfo *)stableInfo
148 forPeerWithID:(NSString *)peerID;
149
150 /*!
151 Returns nil with error if the peer's trustSigningKey is unable to create
152 a signature because the private key is unavailable, e.g. because the device is locked.
153
154 Asserts peerID is registered.
155 */
156 - (TPPeerStableInfo *)createStableInfoWithDictionary:(NSDictionary *)dict
157 policyVersion:(TPCounter)policyVersion
158 policyHash:(NSString *)policyHash
159 policySecrets:(nullable NSDictionary *)policySecrets
160 forPeerWithID:(NSString *)peerID
161 error:(NSError **)error;
162
163
164 /*!
165 An "update" with unchanged data is considered success.
166 Asserts peerID is registered.
167 */
168 - (TPResult)updateDynamicInfo:(TPPeerDynamicInfo *)dynamicInfo
169 forPeerWithID:(NSString *)peerID;
170
171
172 /*!
173 The returned voucher is not registered.
174 Asserts sponsorID is registered.
175
176 Returns nil with nil error if policy determines that the sponsor
177 is not permitted to introduce this candidate.
178
179 Returns nil with error if the sponsor's trustSigningKey is unable to create
180 a signature because the private key is unavailable, e.g. because the device is locked.
181
182 The candidate need not be registered before making this call.
183 */
184 - (nullable TPVoucher *)createVoucherForCandidate:(TPPeerPermanentInfo *)candidate
185 withSponsorID:(NSString *)sponsorID
186 error:(NSError **)error;
187
188 /*!
189 Asserts that the sponsor is registered, so that the signature check can be performed.
190 The beneficiary need not be registered.
191 */
192 - (TPResult)registerVoucher:(TPVoucher *)voucher;
193
194
195 - (NSSet<NSString*> *)calculateUnusedCircleIDs;
196
197 /*!
198 Calculates updated dynamic info for a given peer,
199 according to the membership convergence algorithm.
200
201 This method does not update the model. The calculated circle is not registered
202 and the peer is not updated with the calculated dynamicInfo. It is the caller's
203 responsibility to register/update them once they have been persisted to CloudKit.
204
205 Peers listed in addingPeerIDs are taken to have been explicitly trusted by the user.
206 When the user adds a member of addingPeerIDs into trust, the peers already trusted
207 by that new peer are also taken to be trusted, even if the new peer is not qualified by
208 policy to *introduce* them into trust. This is neccessary in a scenario where a mid-level
209 device approves a lowly device, and the new lowly device should trust the high-level devices
210 already in the circle. The mid-level device is not *introducing* the high-level devices.
211
212 Peers listed in removingPeerIDs are excluded from trust.
213
214 Returns nil with error if the peer's trustSigningKey is unable to create
215 a signature because the private key is unavailable, e.g. because the device is locked.
216
217 Asserts peerID is registered.
218 */
219 - (nullable TPPeerDynamicInfo *)calculateDynamicInfoForPeerWithID:(NSString *)peerID
220 addingPeerIDs:(nullable NSArray<NSString*> *)addingPeerIDs
221 removingPeerIDs:(nullable NSArray<NSString*> *)removingPeerIDs
222 createClique:(nullable NSString* (^)())createClique
223 updatedCircle:(TPCircle * _Nullable * _Nullable)updatedCircle
224 error:(NSError **)error;
225
226 /*!
227 A convenience method for tests, this calls calculateDynamicInfoForPeerWithID,
228 registers the results and returns the new circle.
229 */
230 - (TPCircle *)advancePeerWithID:(NSString *)peerID
231 addingPeerIDs:(nullable NSArray<NSString*> *)addingPeerIDs
232 removingPeerIDs:(nullable NSArray<NSString*> *)removingPeerIDs
233 createClique:(nullable NSString* (^)())createClique;
234
235 /*!
236 From our trusted peers, return the subset that is allowed
237 to access the given view, according to the current policy.
238
239 Asserts peerID is registered.
240 */
241 - (nullable NSSet<NSString*> *)getPeerIDsTrustedByPeerWithID:(NSString *)peerID
242 toAccessView:(NSString *)view
243 error:(NSError **)error;
244
245 /*!
246 Returns a dictionary mapping from each peer ID
247 to the most recent clock seen from that peer.
248 */
249 - (NSDictionary<NSString*,NSNumber*> *)vectorClock;
250
251 @end
252
253 NS_ASSUME_NONNULL_END