2 #import <Foundation/Foundation.h>
5 #import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h"
6 #import "utilities/debugging.h"
7 #import <CloudKit/CloudKit.h>
8 #import <CloudKit/CloudKit_Private.h>
11 NSXPCInterface* TrustedPeersHelperSetupProtocol(NSXPCInterface* interface)
14 static NSMutableSet *errClasses;
16 static dispatch_once_t onceToken;
17 dispatch_once(&onceToken, ^{
18 errClasses = [NSMutableSet setWithSet:CKAcceptableValueClasses()];
36 for (unsigned n = 0; n < sizeof(classes)/sizeof(classes[0]); n++) {
37 Class cls = objc_getClass(classes[n]);
39 [errClasses addObject:cls];
45 NSSet* arrayOfKeySets = [NSSet setWithArray:@[[NSArray class], [CKKSKeychainBackedKeySet class]]];
46 NSSet* arrayOfTLKShares = [NSSet setWithArray:@[[NSArray class], [CKKSTLKShare class]]];
47 NSSet* arrayOfCKRecords = [NSSet setWithArray:@[[NSArray class], [CKRecord class]]];
48 NSSet* arrayOfStrings = [NSSet setWithArray:@[[NSArray class], [NSString class]]];
49 NSSet* trustedPeersHelperPeerState = [NSSet setWithObject:[TrustedPeersHelperPeerState class]];
51 NSSet* arrayOfTrustedPeersHelperPeer = [NSSet setWithArray:@[[NSArray class], [TrustedPeersHelperPeer class]]];
53 [interface setClasses:arrayOfStrings forSelector:@selector(addAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:2 ofReply:NO];
54 [interface setClasses:arrayOfStrings forSelector:@selector(removeAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:2 ofReply:NO];
56 [interface setClasses:arrayOfKeySets forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:2 ofReply:NO];
57 [interface setClasses:arrayOfTLKShares forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:NO];
58 [interface setClasses:arrayOfCKRecords forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
60 [interface setClasses:arrayOfKeySets forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:4 ofReply:NO];
61 [interface setClasses:arrayOfTLKShares forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:5 ofReply:NO];
62 [interface setClasses:arrayOfCKRecords forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
64 [interface setClasses:arrayOfKeySets forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:2 ofReply:NO];
65 [interface setClasses:arrayOfTLKShares forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:NO];
66 [interface setClasses:arrayOfCKRecords forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
68 [interface setClasses:arrayOfKeySets forSelector:@selector(vouchWithContainer:
76 reply:) argumentIndex:7 ofReply:NO];
78 [interface setClasses:arrayOfTLKShares forSelector:@selector(vouchWithBottleWithContainer:
84 reply:) argumentIndex:5 ofReply:NO];
85 [interface setClasses:arrayOfKeySets forSelector:@selector(setRecoveryKeyWithContainer:
90 reply:) argumentIndex:4 ofReply:NO];
91 [interface setClasses:arrayOfTLKShares forSelector:@selector(vouchWithRecoveryKeyWithContainer:
96 reply:) argumentIndex:4 ofReply:NO];
98 [interface setClasses:[NSSet setWithObject:[TPPolicy class]] forSelector:@selector(fetchPolicyWithContainer:
100 reply:) argumentIndex:0 ofReply:YES];
102 [interface setClasses:trustedPeersHelperPeerState forSelector:@selector(updateWithContainer:
109 reply:) argumentIndex:0 ofReply:YES];
111 [interface setClasses:trustedPeersHelperPeerState forSelector:@selector(fetchTrustStateWithContainer:
113 reply:) argumentIndex:0 ofReply:YES];
114 [interface setClasses:arrayOfTrustedPeersHelperPeer forSelector:@selector(fetchTrustStateWithContainer:
116 reply:) argumentIndex:1 ofReply:YES];
118 [interface setClasses:arrayOfKeySets forSelector:@selector(updateTLKsWithContainer:
122 reply:) argumentIndex:2 ofReply:NO];
123 [interface setClasses:arrayOfTLKShares forSelector:@selector(updateTLKsWithContainer:
127 reply:) argumentIndex:3 ofReply:NO];
128 [interface setClasses:arrayOfCKRecords forSelector:@selector(updateTLKsWithContainer:
132 reply:) argumentIndex:0 ofReply:YES];
134 @catch(NSException* e) {
135 secerror("TrustedPeersHelperSetupProtocol failed, continuing, but you might crash later: %@", e);
145 @implementation TrustedPeersHelperPeerState
147 - (instancetype)initWithPeerID:(NSString* _Nullable)peerID
148 isPreapproved:(BOOL)isPreapproved
149 status:(TPPeerStatus)peerStatus
150 memberChanges:(BOOL)memberChanges
151 unknownMachineIDs:(BOOL)unknownMachineIDs
152 osVersion:(NSString *)osVersion
154 if((self = [super init])) {
156 _identityIsPreapproved = isPreapproved;
157 _peerStatus = peerStatus;
158 _memberChanges = memberChanges;
159 _unknownMachineIDsPresent = unknownMachineIDs;
160 _osVersion = osVersion;
165 - (NSString*)description
167 return [NSString stringWithFormat:@"<TPHPeerState: %@ preapproved:%d status:%lld memberChanges: %@ unk. mIDs: %@ osVersion: %@>",
169 self.identityIsPreapproved,
170 (int64_t)self.peerStatus,
171 self.memberChanges ? @"YES" : @"NO",
172 self.unknownMachineIDsPresent ? @"YES" : @"NO",
173 self.osVersion?:@"unknown"];
176 + (BOOL)supportsSecureCoding {
180 - (instancetype)initWithCoder:(NSCoder *)coder {
181 if ((self = [super init])) {
182 _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
183 _identityIsPreapproved = [coder decodeBoolForKey:@"identityIsPreapproved"];
184 _peerStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"peerStatus"];
185 _memberChanges = (BOOL)[coder decodeInt64ForKey:@"memberChanges"];
186 _unknownMachineIDsPresent = (BOOL)[coder decodeInt64ForKey:@"unknownMachineIDs"];
187 _osVersion = [coder decodeObjectOfClass:[NSString class] forKey:@"osVersion"];
192 - (void)encodeWithCoder:(NSCoder *)coder {
193 [coder encodeObject:self.peerID forKey:@"peerID"];
194 [coder encodeBool:self.identityIsPreapproved forKey:@"identityIsPreapproved"];
195 [coder encodeInt64:(int64_t)self.peerStatus forKey:@"peerStatus"];
196 [coder encodeInt64:(int64_t)self.memberChanges forKey:@"memberChanges"];
197 [coder encodeInt64:(int64_t)self.unknownMachineIDsPresent forKey:@"unknownMachineIDs"];
198 [coder encodeObject:self.osVersion forKey:@"osVersion"];
203 @implementation TrustedPeersHelperEgoPeerStatus
205 - (instancetype)initWithEgoPeerID:(NSString* _Nullable)egoPeerID
206 status:(TPPeerStatus)egoStatus
207 viablePeerCountsByModelID:(NSDictionary<NSString*, NSNumber*>*)viablePeerCountsByModelID
208 isExcluded:(BOOL)isExcluded
209 isLocked:(BOOL)isLocked
211 if((self = [super init])) {
212 _egoPeerID = egoPeerID;
213 _egoStatus = egoStatus;
214 _viablePeerCountsByModelID = viablePeerCountsByModelID;
215 _numberOfPeersInOctagon = 0;
216 for(NSNumber* n in viablePeerCountsByModelID.allValues) {
217 _numberOfPeersInOctagon += [n unsignedIntegerValue];
219 _isExcluded = isExcluded;
220 _isLocked = isLocked;
225 - (NSString*)description
227 return [NSString stringWithFormat:@"<TPHEgoPeerState: %@>", self.egoPeerID];
230 + (BOOL)supportsSecureCoding {
234 - (instancetype)initWithCoder:(NSCoder *)coder {
235 if ((self = [super init])) {
236 _egoPeerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
237 _egoStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"egoStatus"];
238 _viablePeerCountsByModelID = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSDictionary class], [NSString class], [NSNumber class]]] forKey:@"viablePeerCountsByModelID"];
239 _numberOfPeersInOctagon = 0;
240 for(NSNumber* n in _viablePeerCountsByModelID.allValues) {
241 _numberOfPeersInOctagon += [n unsignedIntegerValue];
244 _isExcluded = (BOOL)[coder decodeBoolForKey:@"isExcluded"];
245 _isLocked = (BOOL)[coder decodeBoolForKey:@"isLocked"];
250 - (void)encodeWithCoder:(NSCoder *)coder {
251 [coder encodeObject:self.egoPeerID forKey:@"peerID"];
252 [coder encodeInt64:self.egoStatus forKey:@"egoStatus"];
253 [coder encodeObject:self.viablePeerCountsByModelID forKey:@"viablePeerCountsByModelID"];
254 [coder encodeBool:self.isExcluded forKey:@"isExcluded"];
255 [coder encodeBool:self.isLocked forKey:@"isLocked"];
261 @implementation TrustedPeersHelperPeer
262 - (instancetype)initWithPeerID:(NSString*)peerID
263 signingSPKI:(NSData*)signingSPKI
264 encryptionSPKI:(NSData*)encryptionSPKI
265 viewList:(NSSet<NSString*>*)viewList
267 if((self = [super init])) {
269 _signingSPKI = signingSPKI;
270 _encryptionSPKI = encryptionSPKI;
271 _viewList = viewList;
276 - (NSString*)description
278 return [NSString stringWithFormat:@"<TPHPeer: %@ %@ %@ (%lu views)>",
282 (unsigned long)self.viewList.count];
285 + (BOOL)supportsSecureCoding {
289 - (instancetype)initWithCoder:(NSCoder *)coder {
290 if ((self = [super init])) {
291 _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
292 _signingSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"signingSPKI"];
293 _encryptionSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"encryptionSPKI"];
294 _viewList = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSSet class], [NSString class]]] forKey:@"viewList"];
299 - (void)encodeWithCoder:(NSCoder *)coder {
300 [coder encodeObject:self.peerID forKey:@"peerID"];
301 [coder encodeObject:self.signingSPKI forKey:@"signingSPKI"];
302 [coder encodeObject:self.encryptionSPKI forKey:@"encryptionSPKI"];
303 [coder encodeObject:self.viewList forKey:@"viewList"];