mirror of
https://github.com/seemoo-lab/openhaystack.git
synced 2026-02-14 17:49:54 +00:00
Initial commit
This commit is contained in:
47
OpenHaystack/OpenHaystackMail/ALTAnisetteData.h
Normal file
47
OpenHaystack/OpenHaystackMail/ALTAnisetteData.h
Normal file
@@ -0,0 +1,47 @@
|
||||
// ALTAnisetteData.h
|
||||
// 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 <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ALTAnisetteData : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
@property (nonatomic, copy) NSString *machineID;
|
||||
@property (nonatomic, copy) NSString *oneTimePassword;
|
||||
@property (nonatomic, copy) NSString *localUserID;
|
||||
@property (nonatomic) unsigned long long routingInfo;
|
||||
|
||||
@property (nonatomic, copy) NSString *deviceUniqueIdentifier;
|
||||
@property (nonatomic, copy) NSString *deviceSerialNumber;
|
||||
@property (nonatomic, copy) NSString *deviceDescription;
|
||||
|
||||
@property (nonatomic, copy) NSDate *date;
|
||||
@property (nonatomic, copy) NSLocale *locale;
|
||||
@property (nonatomic, copy) NSTimeZone *timeZone;
|
||||
|
||||
- (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;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
158
OpenHaystack/OpenHaystackMail/ALTAnisetteData.m
Normal file
158
OpenHaystack/OpenHaystackMail/ALTAnisetteData.m
Normal file
@@ -0,0 +1,158 @@
|
||||
// ALTAnisetteData.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 "ALTAnisetteData.h"
|
||||
|
||||
@implementation ALTAnisetteData
|
||||
|
||||
- (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];
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
ALTAnisetteData *anisetteData = (ALTAnisetteData *)object;
|
||||
if (![anisetteData isKindOfClass:[ALTAnisetteData 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.timeZone.hash);
|
||||
;
|
||||
}
|
||||
|
||||
#pragma mark - <NSCopying> -
|
||||
|
||||
- (nonnull id)copyWithZone:(nullable NSZone *)zone
|
||||
{
|
||||
ALTAnisetteData *copy = [[ALTAnisetteData 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 - <NSSecureCoding> -
|
||||
|
||||
- (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))];
|
||||
|
||||
|
||||
self = [self initWithMachineID:machineID
|
||||
oneTimePassword:oneTimePassword
|
||||
localUserID:localUserID
|
||||
routingInfo:[routingInfo unsignedLongLongValue]
|
||||
deviceUniqueIdentifier:deviceUniqueIdentifier
|
||||
deviceSerialNumber:deviceSerialNumber
|
||||
deviceDescription:deviceDescription
|
||||
date:date
|
||||
locale:locale
|
||||
timeZone:timeZone
|
||||
];
|
||||
|
||||
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))];
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
52
OpenHaystack/OpenHaystackMail/AppleAccountData.h
Normal file
52
OpenHaystack/OpenHaystackMail/AppleAccountData.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// AppleAccountData.h
|
||||
// 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 <Foundation/Foundation.h>
|
||||
#import "ALTAnisetteData.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AppleAccountData : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
@property (nonatomic, copy) NSString *machineID;
|
||||
@property (nonatomic, copy) NSString *oneTimePassword;
|
||||
@property (nonatomic, copy) NSString *localUserID;
|
||||
@property (nonatomic) unsigned long long routingInfo;
|
||||
|
||||
@property (nonatomic, copy) NSString *deviceUniqueIdentifier;
|
||||
@property (nonatomic, copy) NSString *deviceSerialNumber;
|
||||
@property (nonatomic, copy) NSString *deviceDescription;
|
||||
|
||||
@property (nonatomic, copy) NSDate *date;
|
||||
@property (nonatomic, copy) NSLocale *locale;
|
||||
@property (nonatomic, copy) NSTimeZone *timeZone;
|
||||
|
||||
@property (nonatomic, copy) NSData *searchPartyToken;
|
||||
|
||||
- (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;
|
||||
|
||||
- (instancetype) initFromALTAnissetteData:(ALTAnisetteData *) altAnisetteData;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
186
OpenHaystack/OpenHaystackMail/AppleAccountData.m
Normal file
186
OpenHaystack/OpenHaystackMail/AppleAccountData.m
Normal file
@@ -0,0 +1,186 @@
|
||||
// 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 - <NSCopying> -
|
||||
|
||||
- (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 - <NSSecureCoding> -
|
||||
|
||||
- (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
|
||||
64
OpenHaystack/OpenHaystackMail/Info.plist
Normal file
64
OpenHaystack/OpenHaystackMail/Info.plist
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2021 SEEMOO – TU Darmstadt</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>OpenHaystackPluginService</string>
|
||||
<key>Supported10.15PluginCompatibilityUUIDs</key>
|
||||
<array>
|
||||
<string># UUIDs for versions from 10.12 to 99.99.99</string>
|
||||
<string># For mail version 10.0 (3226) on OS X Version 10.12 (build 16A319)</string>
|
||||
<string>36CCB8BB-2207-455E-89BC-B9D6E47ABB5B</string>
|
||||
<string># For mail version 10.1 (3251) on OS X Version 10.12.1 (build 16B2553a)</string>
|
||||
<string>9054AFD9-2607-489E-8E63-8B09A749BC61</string>
|
||||
<string># For mail version 10.2 (3259) on OS X Version 10.12.2 (build 16D12b)</string>
|
||||
<string>1CD3B36A-0E3B-4A26-8F7E-5BDF96AAC97E</string>
|
||||
<string># For mail version 10.3 (3273) on OS X Version 10.12.4 (build 16G1036)</string>
|
||||
<string>21560BD9-A3CC-482E-9B99-95B7BF61EDC1</string>
|
||||
<string># For mail version 11.0 (3441.0.1) on OS X Version 10.13 (build 17A315i)</string>
|
||||
<string>C86CD990-4660-4E36-8CDA-7454DEB2E199</string>
|
||||
<string># For mail version 12.0 (3445.100.39) on OS X Version 10.14.1 (build 18B45d)</string>
|
||||
<string>A4343FAF-AE18-40D0-8A16-DFAE481AF9C1</string>
|
||||
<string># For mail version 13.0 (3594.4.2) on OS X Version 10.15 (build 19A558d)</string>
|
||||
<string>6EEA38FB-1A0B-469B-BB35-4C2E0EEA9053</string>
|
||||
</array>
|
||||
<key>Supported11.0PluginCompatibilityUUIDs</key>
|
||||
<array>
|
||||
<string>D985F0E4-3BBC-4B95-BBA1-12056AC4A531</string>
|
||||
</array>
|
||||
<key>Supported11.1PluginCompatibilityUUIDs</key>
|
||||
<array>
|
||||
<string>D985F0E4-3BBC-4B95-BBA1-12056AC4A531</string>
|
||||
</array>
|
||||
<key>Supported11.2PluginCompatibilityUUIDs</key>
|
||||
<array>
|
||||
<string>D985F0E4-3BBC-4B95-BBA1-12056AC4A531</string>
|
||||
</array>
|
||||
<key>Supported11.3PluginCompatibilityUUIDs</key>
|
||||
<array>
|
||||
<string>D985F0E4-3BBC-4B95-BBA1-12056AC4A531</string>
|
||||
</array>
|
||||
<key>Supported11.4PluginCompatibilityUUIDs</key>
|
||||
<array>
|
||||
<string>D985F0E4-3BBC-4B95-BBA1-12056AC4A531</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
24
OpenHaystack/OpenHaystackMail/OpenHaystackPluginService.h
Normal file
24
OpenHaystack/OpenHaystackMail/OpenHaystackPluginService.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// ALTPluginService.h
|
||||
// AltPlugin
|
||||
//
|
||||
// Created by Riley Testut on 11/14/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 <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OpenHaystackPluginService : NSObject
|
||||
|
||||
+ (instancetype)sharedService;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
131
OpenHaystack/OpenHaystackMail/OpenHaystackPluginService.m
Normal file
131
OpenHaystack/OpenHaystackMail/OpenHaystackPluginService.m
Normal file
@@ -0,0 +1,131 @@
|
||||
// ALTPluginService.m
|
||||
// AltPlugin
|
||||
//
|
||||
// Created by Riley Testut on 11/14/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 "OpenHaystackPluginService.h"
|
||||
|
||||
#import <dlfcn.h>
|
||||
|
||||
#import "AppleAccountData.h"
|
||||
#import <Security/Security.h>
|
||||
#import <Accounts/Accounts.h>
|
||||
|
||||
@import AppKit;
|
||||
|
||||
@interface AKAppleIDSession : NSObject
|
||||
- (id)appleIDHeadersForRequest:(id)arg1;
|
||||
@end
|
||||
|
||||
@interface AKDevice
|
||||
+ (AKDevice *)currentDevice;
|
||||
- (NSString *)uniqueDeviceIdentifier;
|
||||
- (NSString *)serialNumber;
|
||||
- (NSString *)serverFriendlyDescription;
|
||||
@end
|
||||
|
||||
@interface OpenHaystackPluginService ()
|
||||
|
||||
@property (nonatomic, readonly) NSISO8601DateFormatter *dateFormatter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OpenHaystackPluginService
|
||||
|
||||
+ (instancetype)sharedService
|
||||
{
|
||||
static OpenHaystackPluginService *_service = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_service = [[self alloc] init];
|
||||
});
|
||||
|
||||
return _service;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
_dateFormatter = [[NSISO8601DateFormatter alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
[[OpenHaystackPluginService sharedService] start];
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
dlopen("/System/Library/PrivateFrameworks/AuthKit.framework/AuthKit", RTLD_NOW);
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:@"de.tu-darmstadt.seemoo.OpenHaystack.FetchAnisetteData" object:nil];
|
||||
}
|
||||
|
||||
- (void)receiveNotification:(NSNotification *)notification
|
||||
{
|
||||
NSString *requestUUID = notification.userInfo[@"requestUUID"];
|
||||
|
||||
NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://developerservices2.apple.com/services/QH65B2/listTeams.action?clientId=XABBG36SBA"]];
|
||||
[req setHTTPMethod:@"POST"];
|
||||
|
||||
AKAppleIDSession *session = [[NSClassFromString(@"AKAppleIDSession") alloc] initWithIdentifier:@"com.apple.gs.xcode.auth"];
|
||||
NSDictionary *headers = [session appleIDHeadersForRequest:req];
|
||||
|
||||
AKDevice *device = [NSClassFromString(@"AKDevice") currentDevice];
|
||||
NSDate *date = [self.dateFormatter dateFromString:headers[@"X-Apple-I-Client-Time"]];
|
||||
|
||||
NSData *sptoken = [self fetchSearchpartyToken];
|
||||
AppleAccountData *anisetteData = [[NSClassFromString(@"AppleAccountData") alloc] initWithMachineID:headers[@"X-Apple-I-MD-M"]
|
||||
oneTimePassword:headers[@"X-Apple-I-MD"]
|
||||
localUserID:headers[@"X-Apple-I-MD-LU"]
|
||||
routingInfo:[headers[@"X-Apple-I-MD-RINFO"] longLongValue]
|
||||
deviceUniqueIdentifier:device.uniqueDeviceIdentifier
|
||||
deviceSerialNumber:device.serialNumber
|
||||
deviceDescription:device.serverFriendlyDescription
|
||||
date:date
|
||||
locale:[NSLocale currentLocale]
|
||||
timeZone:[NSTimeZone localTimeZone]];
|
||||
if (sptoken != nil) {
|
||||
anisetteData.searchPartyToken = [sptoken copy];
|
||||
}
|
||||
|
||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:anisetteData requiringSecureCoding:YES error:nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"de.tu-darmstadt.seemoo.OpenHaystack.AnisetteDataResponse" object:nil userInfo:@{@"requestUUID": requestUUID, @"anisetteData": data} deliverImmediately:YES];
|
||||
}
|
||||
|
||||
- (NSData * _Nullable) fetchSearchpartyToken {
|
||||
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
|
||||
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:@"com.apple.account.AppleAccount"];
|
||||
|
||||
NSArray *appleAccounts = [accountStore accountsWithAccountType:accountType];
|
||||
|
||||
if (appleAccounts == nil && appleAccounts.count > 0) {return nil;}
|
||||
|
||||
ACAccount *iCloudAccount = appleAccounts[0];
|
||||
ACAccountCredential *iCloudCredentials = iCloudAccount.credential;
|
||||
|
||||
if ([iCloudCredentials respondsToSelector:NSSelectorFromString(@"credentialItems")]) {
|
||||
NSDictionary* credentialItems = [iCloudCredentials performSelector:NSSelectorFromString(@"credentialItems")];
|
||||
NSString *searchPartyToken = credentialItems[@"search-party-token"];
|
||||
NSData *tokenData = [searchPartyToken dataUsingEncoding:NSASCIIStringEncoding];
|
||||
return tokenData;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user