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
153 if((self = [super init])) {
155 _identityIsPreapproved = isPreapproved;
156 _peerStatus = peerStatus;
157 _memberChanges = memberChanges;
158 _unknownMachineIDsPresent = unknownMachineIDs;
163 - (NSString*)description
165 return [NSString stringWithFormat:@"<TPHPeerState: %@ preapproved:%d status:%lld memberChanges: %@ unk. mIDs: %@>",
167 self.identityIsPreapproved,
168 (int64_t)self.peerStatus,
169 self.memberChanges ? @"YES" : @"NO",
170 self.unknownMachineIDsPresent ? @"YES" : @"NO"];
173 + (BOOL)supportsSecureCoding {
177 - (instancetype)initWithCoder:(NSCoder *)coder {
178 if ((self = [super init])) {
179 _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
180 _identityIsPreapproved = [coder decodeBoolForKey:@"identityIsPreapproved"];
181 _peerStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"peerStatus"];
182 _memberChanges = (BOOL)[coder decodeInt64ForKey:@"memberChanges"];
183 _unknownMachineIDsPresent = (BOOL)[coder decodeInt64ForKey:@"unknownMachineIDs"];
188 - (void)encodeWithCoder:(NSCoder *)coder {
189 [coder encodeObject:self.peerID forKey:@"peerID"];
190 [coder encodeBool:self.identityIsPreapproved forKey:@"identityIsPreapproved"];
191 [coder encodeInt64:(int64_t)self.peerStatus forKey:@"peerStatus"];
192 [coder encodeInt64:(int64_t)self.memberChanges forKey:@"memberChanges"];
193 [coder encodeInt64:(int64_t)self.unknownMachineIDsPresent forKey:@"unknownMachineIDs"];
198 @implementation TrustedPeersHelperEgoPeerStatus
200 - (instancetype)initWithEgoPeerID:(NSString* _Nullable)egoPeerID
201 status:(TPPeerStatus)egoStatus
202 peerCountsByModelID:(NSDictionary<NSString*, NSNumber*>*)peerCountsByModelID
203 isExcluded:(BOOL)isExcluded
204 isLocked:(BOOL)isLocked
206 if((self = [super init])) {
207 _egoPeerID = egoPeerID;
208 _egoStatus = egoStatus;
209 _peerCountsByModelID = peerCountsByModelID;
210 _numberOfPeersInOctagon = 0;
211 for(NSNumber* n in peerCountsByModelID.allValues) {
212 _numberOfPeersInOctagon += [n unsignedIntegerValue];
214 _isExcluded = isExcluded;
215 _isLocked = isLocked;
220 - (NSString*)description
222 return [NSString stringWithFormat:@"<TPHEgoPeerState: %@>", self.egoPeerID];
225 + (BOOL)supportsSecureCoding {
229 - (instancetype)initWithCoder:(NSCoder *)coder {
230 if ((self = [super init])) {
231 _egoPeerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
232 _egoStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"egoStatus"];
233 _peerCountsByModelID = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSDictionary class], [NSString class], [NSNumber class]]] forKey:@"peerCountsByModelID"];
234 _numberOfPeersInOctagon = 0;
235 for(NSNumber* n in _peerCountsByModelID.allValues) {
236 _numberOfPeersInOctagon += [n unsignedIntegerValue];
239 _isExcluded = (BOOL)[coder decodeBoolForKey:@"isExcluded"];
240 _isLocked = (BOOL)[coder decodeBoolForKey:@"isLocked"];
245 - (void)encodeWithCoder:(NSCoder *)coder {
246 [coder encodeObject:self.egoPeerID forKey:@"peerID"];
247 [coder encodeInt64:self.egoStatus forKey:@"egoStatus"];
248 [coder encodeObject:self.peerCountsByModelID forKey:@"peerCountsByModelID"];
249 [coder encodeBool:self.isExcluded forKey:@"isExcluded"];
250 [coder encodeBool:self.isLocked forKey:@"isLocked"];
256 @implementation TrustedPeersHelperPeer
257 - (instancetype)initWithPeerID:(NSString*)peerID
258 signingSPKI:(NSData*)signingSPKI
259 encryptionSPKI:(NSData*)encryptionSPKI
260 viewList:(NSSet<NSString*>*)viewList
262 if((self = [super init])) {
264 _signingSPKI = signingSPKI;
265 _encryptionSPKI = encryptionSPKI;
266 _viewList = viewList;
271 - (NSString*)description
273 return [NSString stringWithFormat:@"<TPHPeer: %@ %@ %@ (%lu views)>",
277 (unsigned long)self.viewList.count];
280 + (BOOL)supportsSecureCoding {
284 - (instancetype)initWithCoder:(NSCoder *)coder {
285 if ((self = [super init])) {
286 _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
287 _signingSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"signingSPKI"];
288 _encryptionSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"encryptionSPKI"];
289 _viewList = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSSet class], [NSString class]]] forKey:@"viewList"];
294 - (void)encodeWithCoder:(NSCoder *)coder {
295 [coder encodeObject:self.peerID forKey:@"peerID"];
296 [coder encodeObject:self.signingSPKI forKey:@"signingSPKI"];
297 [coder encodeObject:self.encryptionSPKI forKey:@"encryptionSPKI"];
298 [coder encodeObject:self.viewList forKey:@"viewList"];