// // AppleAccountData.m // AltSign // // Created by Riley Testut on 11/13/19. // Copyright © 2019 Riley Testut. All rights reserved. // // OpenHaystack – Tracking personal Bluetooth devices via Apple's Find My network // // Copyright © 2021 Secure Mobile Networking Lab (SEEMOO) // Copyright © 2021 The Open Wireless Link Project // // SPDX-License-Identifier: AGPL-3.0-only // #import "AppleAccountData.h" #import "ALTAnisetteData.h" @implementation AppleAccountData - (instancetype)initWithMachineID:(NSString *)machineID oneTimePassword:(NSString *)oneTimePassword localUserID:(NSString *)localUserID routingInfo:(unsigned long long)routingInfo deviceUniqueIdentifier:(NSString *)deviceUniqueIdentifier deviceSerialNumber:(NSString *)deviceSerialNumber deviceDescription:(NSString *)deviceDescription date:(NSDate *)date locale:(NSLocale *)locale timeZone:(NSTimeZone *)timeZone { self = [super init]; if (self) { _machineID = [machineID copy]; _oneTimePassword = [oneTimePassword copy]; _localUserID = [localUserID copy]; _routingInfo = routingInfo; _deviceUniqueIdentifier = [deviceUniqueIdentifier copy]; _deviceSerialNumber = [deviceSerialNumber copy]; _deviceDescription = [deviceDescription copy]; _date = [date copy]; _locale = [locale copy]; _timeZone = [timeZone copy]; _searchPartyToken = nil; } return self; } - (instancetype)initFromALTAnissetteData:(ALTAnisetteData *)altAnisetteData { self = [super init]; if (self) { _machineID = [altAnisetteData.machineID copy]; _oneTimePassword = [altAnisetteData.oneTimePassword copy]; _localUserID = [altAnisetteData.localUserID copy]; _routingInfo = altAnisetteData.routingInfo; _deviceUniqueIdentifier = [altAnisetteData.deviceUniqueIdentifier copy]; _deviceSerialNumber = [altAnisetteData.deviceSerialNumber copy]; _deviceDescription = [altAnisetteData.deviceDescription copy]; _date = [altAnisetteData.date copy]; _locale = [altAnisetteData.locale copy]; _timeZone = [altAnisetteData.timeZone copy]; _searchPartyToken = nil; } return self; } #pragma mark - NSObject - - (NSString *)description { return [NSString stringWithFormat:@"Machine ID: %@\nOne-Time Password: %@\nLocal User ID: %@\nRouting Info: %@\nDevice UDID: %@\nDevice Serial Number: %@\nDevice Description: " @"%@\nDate: %@\nLocale: %@\nTime Zone: %@ Search Party token %@", self.machineID, self.oneTimePassword, self.localUserID, @(self.routingInfo), self.deviceUniqueIdentifier, self.deviceSerialNumber, self.deviceDescription, self.date, self.locale.localeIdentifier, self.timeZone, self.searchPartyToken]; } - (BOOL)isEqual:(id)object { AppleAccountData *anisetteData = (AppleAccountData *)object; if (![anisetteData isKindOfClass:[AppleAccountData class]]) { return NO; } BOOL isEqual = ([self.machineID isEqualToString:anisetteData.machineID] && [self.oneTimePassword isEqualToString:anisetteData.oneTimePassword] && [self.localUserID isEqualToString:anisetteData.localUserID] && [@(self.routingInfo) isEqualToNumber:@(anisetteData.routingInfo)] && [self.deviceUniqueIdentifier isEqualToString:anisetteData.deviceUniqueIdentifier] && [self.deviceSerialNumber isEqualToString:anisetteData.deviceSerialNumber] && [self.deviceDescription isEqualToString:anisetteData.deviceDescription] && [self.date isEqualToDate:anisetteData.date] && [self.locale isEqual:anisetteData.locale] && [self.timeZone isEqualToTimeZone:anisetteData.timeZone]); return isEqual; } - (NSUInteger)hash { return (self.machineID.hash ^ self.oneTimePassword.hash ^ self.localUserID.hash ^ @(self.routingInfo).hash ^ self.deviceUniqueIdentifier.hash ^ self.deviceSerialNumber.hash ^ self.deviceDescription.hash ^ self.date.hash ^ self.locale.hash ^ self.searchPartyToken.hash ^ self.timeZone.hash); ; } #pragma mark - - - (nonnull id)copyWithZone:(nullable NSZone *)zone { AppleAccountData *copy = [[AppleAccountData alloc] initWithMachineID:self.machineID oneTimePassword:self.oneTimePassword localUserID:self.localUserID routingInfo:self.routingInfo deviceUniqueIdentifier:self.deviceUniqueIdentifier deviceSerialNumber:self.deviceSerialNumber deviceDescription:self.deviceDescription date:self.date locale:self.locale timeZone:self.timeZone]; return copy; } #pragma mark - - - (instancetype)initWithCoder:(NSCoder *)decoder { NSString *machineID = [decoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(machineID))]; NSString *oneTimePassword = [decoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(oneTimePassword))]; NSString *localUserID = [decoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(localUserID))]; NSNumber *routingInfo = [decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(routingInfo))]; NSString *deviceUniqueIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(deviceUniqueIdentifier))]; NSString *deviceSerialNumber = [decoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(deviceSerialNumber))]; NSString *deviceDescription = [decoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(deviceDescription))]; NSDate *date = [decoder decodeObjectOfClass:[NSDate class] forKey:NSStringFromSelector(@selector(date))]; NSLocale *locale = [decoder decodeObjectOfClass:[NSLocale class] forKey:NSStringFromSelector(@selector(locale))]; NSTimeZone *timeZone = [decoder decodeObjectOfClass:[NSTimeZone class] forKey:NSStringFromSelector(@selector(timeZone))]; NSData *searchPartyToken = [decoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(searchPartyToken))]; self = [self initWithMachineID:machineID oneTimePassword:oneTimePassword localUserID:localUserID routingInfo:[routingInfo unsignedLongLongValue] deviceUniqueIdentifier:deviceUniqueIdentifier deviceSerialNumber:deviceSerialNumber deviceDescription:deviceDescription date:date locale:locale timeZone:timeZone]; self.searchPartyToken = searchPartyToken; return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.machineID forKey:NSStringFromSelector(@selector(machineID))]; [encoder encodeObject:self.oneTimePassword forKey:NSStringFromSelector(@selector(oneTimePassword))]; [encoder encodeObject:self.localUserID forKey:NSStringFromSelector(@selector(localUserID))]; [encoder encodeObject:@(self.routingInfo) forKey:NSStringFromSelector(@selector(routingInfo))]; [encoder encodeObject:self.deviceUniqueIdentifier forKey:NSStringFromSelector(@selector(deviceUniqueIdentifier))]; [encoder encodeObject:self.deviceSerialNumber forKey:NSStringFromSelector(@selector(deviceSerialNumber))]; [encoder encodeObject:self.deviceDescription forKey:NSStringFromSelector(@selector(deviceDescription))]; [encoder encodeObject:self.date forKey:NSStringFromSelector(@selector(date))]; [encoder encodeObject:self.locale forKey:NSStringFromSelector(@selector(locale))]; [encoder encodeObject:self.timeZone forKey:NSStringFromSelector(@selector(timeZone))]; [encoder encodeObject:self.searchPartyToken forKey:NSStringFromSelector(@selector(searchPartyToken))]; } + (BOOL)supportsSecureCoding { return YES; } @end