mirror of
https://github.com/seemoo-lab/openhaystack.git
synced 2026-02-14 09:39:52 +00:00
Add clang-format as an Xcode build phase
This commit is contained in:
3
OpenHaystack/.clang-format
Normal file
3
OpenHaystack/.clang-format
Normal file
@@ -0,0 +1,3 @@
|
||||
BasedOnStyle: llvm
|
||||
ColumnLimit: 180
|
||||
IndentWidth: 4
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
#import "ReportsFetcher.h"
|
||||
#import "BoringSSL.h"
|
||||
#import "ALTAnisetteData.h"
|
||||
#import "AppleAccountData.h"
|
||||
#import "BoringSSL.h"
|
||||
#import "ReportsFetcher.h"
|
||||
|
||||
@@ -339,11 +339,12 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 781EB40525DAD7EA00FEAA19 /* Build configuration list for PBXNativeTarget "OpenHaystack" */;
|
||||
buildPhases = (
|
||||
78EC227325DBC9240042B775 /* Run SwiftLint */,
|
||||
F125DE4525F65E0700135D32 /* Run swift-format */,
|
||||
F1D0A05C25F6BBC7004F9326 /* Run clang-format */,
|
||||
781EB3E925DAD7EA00FEAA19 /* Sources */,
|
||||
781EB3F625DAD7EA00FEAA19 /* Frameworks */,
|
||||
781EB3FC25DAD7EA00FEAA19 /* Resources */,
|
||||
78EC227325DBC9240042B775 /* SwiftLint */,
|
||||
F125DE4525F65E0700135D32 /* Run swift-format */,
|
||||
78286DC225E5669100F65511 /* Embed PlugIns */,
|
||||
F14B2C7E25EFBB11002DC056 /* Set Version Number from Git */,
|
||||
);
|
||||
@@ -476,7 +477,7 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
78EC227325DBC9240042B775 /* SwiftLint */ = {
|
||||
78EC227325DBC9240042B775 /* Run SwiftLint */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -485,14 +486,14 @@
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = SwiftLint;
|
||||
name = "Run SwiftLint";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if which swiftlint >/dev/null; then\n swiftlint autocorrect && swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
shellScript = "if command -v swiftlint >/dev/null; then\n swiftlint autocorrect && swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
};
|
||||
F125DE4525F65E0700135D32 /* Run swift-format */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -510,7 +511,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if which swift-format >/dev/null; then\n swift-format format -r -i \"$SRCROOT\" && swift-format lint -r \"$SRCROOT\"\nelse\n echo \"warning: swift-format not installed, download from https://github.com/apple/swift-format\"\nfi\n";
|
||||
shellScript = "if command -v swift-format >/dev/null; then\n swift-format format -r -i \"$SRCROOT\" && swift-format lint -r \"$SRCROOT\"\nelse\n echo \"warning: swift-format not installed, download from https://github.com/apple/swift-format\"\nfi\n";
|
||||
};
|
||||
F14B2C7E25EFBB11002DC056 /* Set Version Number from Git */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -548,6 +549,24 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "GIT_RELEASE_VERSION=$(git describe --tags --always --dirty)\nCOMMITS=$(git rev-list HEAD | wc -l)\nCOMMITS=$(($COMMITS))\ndefaults write \"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH%.*}\" \"CFBundleShortVersionString\" \"${GIT_RELEASE_VERSION#*v}\"\ndefaults write \"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH%.*}\" \"CFBundleVersion\" \"${COMMITS}\"\n";
|
||||
};
|
||||
F1D0A05C25F6BBC7004F9326 /* Run clang-format */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run clang-format";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if command -v clang-format >/dev/null; then\n clang-format -i \"$SRCROOT\"/**/*.{h,m}\nelse\n echo \"warning: clang-format not installed\"\nfi\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
||||
@@ -11,16 +11,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface BoringSSL : NSObject
|
||||
|
||||
+ (NSData * _Nullable) deriveSharedKeyFromPrivateKey: (NSData *) privateKey andEphemeralKey: (NSData*) ephemeralKeyPoint;
|
||||
+ (NSData *_Nullable)deriveSharedKeyFromPrivateKey:(NSData *)privateKey andEphemeralKey:(NSData *)ephemeralKeyPoint;
|
||||
|
||||
/// Derive a public key from a given private key
|
||||
/// @param privateKeyData an EC private key on the P-224 curve
|
||||
/// @returns The public key in a compressed format using 29 bytes. The first byte is used for identifying if its odd or even.
|
||||
/// For OF the first byte has to be dropped
|
||||
+ (NSData * _Nullable) derivePublicKeyFromPrivateKey: (NSData*) privateKeyData;
|
||||
/// For OF the first byte has to be dropped
|
||||
+ (NSData *_Nullable)derivePublicKeyFromPrivateKey:(NSData *)privateKeyData;
|
||||
|
||||
/// Generate a new EC private key and exports it as data
|
||||
+ (NSData * _Nullable) generateNewPrivateKey;
|
||||
+ (NSData *_Nullable)generateNewPrivateKey;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -16,29 +16,29 @@
|
||||
|
||||
@implementation BoringSSL
|
||||
|
||||
+ (NSData * _Nullable) deriveSharedKeyFromPrivateKey: (NSData *) privateKey andEphemeralKey: (NSData*) ephemeralKeyPoint {
|
||||
|
||||
+ (NSData *_Nullable)deriveSharedKeyFromPrivateKey:(NSData *)privateKey andEphemeralKey:(NSData *)ephemeralKeyPoint {
|
||||
|
||||
NSLog(@"Private key %@", [privateKey base64EncodedStringWithOptions:0]);
|
||||
NSLog(@"Ephemeral key %@", [ephemeralKeyPoint base64EncodedStringWithOptions:0]);
|
||||
|
||||
|
||||
EC_GROUP *curve = EC_GROUP_new_by_curve_name(NID_secp224r1);
|
||||
|
||||
|
||||
EC_KEY *key = [self deriveEllipticCurvePrivateKey:privateKey group:curve];
|
||||
|
||||
|
||||
const EC_POINT *genPubKey = EC_KEY_get0_public_key(key);
|
||||
[self printPoint:genPubKey withGroup:curve];
|
||||
|
||||
|
||||
EC_POINT *publicKey = EC_POINT_new(curve);
|
||||
size_t load_success = EC_POINT_oct2point(curve, publicKey, ephemeralKeyPoint.bytes, ephemeralKeyPoint.length, NULL);
|
||||
if (load_success == 0) {
|
||||
NSLog(@"Failed loading public key!");
|
||||
return nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
NSMutableData *sharedKey = [[NSMutableData alloc] initWithLength:28];
|
||||
|
||||
|
||||
int res = ECDH_compute_key(sharedKey.mutableBytes, sharedKey.length, publicKey, key, nil);
|
||||
|
||||
|
||||
if (res < 1) {
|
||||
NSLog(@"Failed with error: %d", res);
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
@@ -46,52 +46,50 @@
|
||||
char *buf;
|
||||
BIO_get_mem_data(bio, &buf);
|
||||
NSLog(@"Generating shared key failed %s", buf);
|
||||
free(buf);
|
||||
free(buf);
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
|
||||
NSLog(@"Shared key: %@", [sharedKey base64EncodedStringWithOptions:0]);
|
||||
|
||||
|
||||
return sharedKey;
|
||||
}
|
||||
|
||||
+ (EC_POINT * _Nullable) loadEllipticCurvePublicBytesWith: (EC_GROUP *) group andPointBytes: (NSData *) pointBytes {
|
||||
|
||||
EC_POINT* point = EC_POINT_new(group);
|
||||
|
||||
//Create big number context
|
||||
+ (EC_POINT *_Nullable)loadEllipticCurvePublicBytesWith:(EC_GROUP *)group andPointBytes:(NSData *)pointBytes {
|
||||
|
||||
EC_POINT *point = EC_POINT_new(group);
|
||||
|
||||
// Create big number context
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
//Public key will be stored in point
|
||||
|
||||
// Public key will be stored in point
|
||||
int res = EC_POINT_oct2point(group, point, pointBytes.bytes, pointBytes.length, ctx);
|
||||
[self printPoint:point withGroup:group];
|
||||
|
||||
//Free the big numbers
|
||||
|
||||
// Free the big numbers
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
|
||||
if (res != 1) {
|
||||
//Failed
|
||||
// Failed
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
/// Get the private key on the curve from the private key bytes
|
||||
/// @param privateKeyData NSData representing the private key
|
||||
/// @param group The EC group representing the curve to use
|
||||
+ (EC_KEY * _Nullable) deriveEllipticCurvePrivateKey: (NSData *)privateKeyData group: (EC_GROUP *) group {
|
||||
+ (EC_KEY *_Nullable)deriveEllipticCurvePrivateKey:(NSData *)privateKeyData group:(EC_GROUP *)group {
|
||||
EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp224r1);
|
||||
EC_POINT *point = EC_POINT_new(group);
|
||||
|
||||
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
|
||||
|
||||
BIGNUM *privateKeyNum = BN_bin2bn(privateKeyData.bytes, privateKeyData.length, nil);
|
||||
|
||||
|
||||
int res = EC_POINT_mul(group, point, privateKeyNum, nil, nil, ctx);
|
||||
if (res != 1) {
|
||||
NSLog(@"Failed");
|
||||
@@ -103,71 +101,68 @@
|
||||
NSLog(@"Failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
privateKeyNum = BN_bin2bn(privateKeyData.bytes, privateKeyData.length, nil);
|
||||
EC_KEY_set_private_key(key, privateKeyNum);
|
||||
|
||||
|
||||
//Free the big numbers
|
||||
|
||||
// Free the big numbers
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
/// Derive a public key from a given private key
|
||||
/// @param privateKeyData an EC private key on the P-224 curve
|
||||
+ (NSData * _Nullable) derivePublicKeyFromPrivateKey: (NSData*) privateKeyData {
|
||||
+ (NSData *_Nullable)derivePublicKeyFromPrivateKey:(NSData *)privateKeyData {
|
||||
EC_GROUP *curve = EC_GROUP_new_by_curve_name(NID_secp224r1);
|
||||
EC_KEY *key = [self deriveEllipticCurvePrivateKey:privateKeyData group:curve];
|
||||
|
||||
|
||||
const EC_POINT *publicKey = EC_KEY_get0_public_key(key);
|
||||
|
||||
|
||||
size_t keySize = 28 + 1;
|
||||
NSMutableData *publicKeyBytes = [[NSMutableData alloc] initWithLength:keySize];
|
||||
|
||||
|
||||
size_t size = EC_POINT_point2oct(curve, publicKey, POINT_CONVERSION_COMPRESSED, publicKeyBytes.mutableBytes, keySize, NULL);
|
||||
|
||||
|
||||
if (size == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
return publicKeyBytes;
|
||||
}
|
||||
|
||||
+ (NSData * _Nullable)generateNewPrivateKey {
|
||||
+ (NSData *_Nullable)generateNewPrivateKey {
|
||||
EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp224r1);
|
||||
if (EC_KEY_generate_key_fips(key) == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
const BIGNUM *privateKey = EC_KEY_get0_private_key(key);
|
||||
size_t keySize = BN_num_bytes(privateKey);
|
||||
//Convert to bytes
|
||||
// Convert to bytes
|
||||
NSMutableData *privateKeyBytes = [[NSMutableData alloc] initWithLength:keySize];
|
||||
|
||||
|
||||
|
||||
size_t size = BN_bn2bin(privateKey, privateKeyBytes.mutableBytes);
|
||||
|
||||
|
||||
if (size == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
return privateKeyBytes;
|
||||
}
|
||||
|
||||
+ (void) printPoint: (const EC_POINT *)point withGroup:(EC_GROUP *)group {
|
||||
+ (void)printPoint:(const EC_POINT *)point withGroup:(EC_GROUP *)group {
|
||||
NSMutableData *pointData = [[NSMutableData alloc] initWithLength:256];
|
||||
|
||||
|
||||
size_t len = pointData.length;
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
BN_CTX_start(ctx);
|
||||
size_t res = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, pointData.mutableBytes, len, ctx);
|
||||
//Free the big numbers
|
||||
// Free the big numbers
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
|
||||
NSData *written = [[NSData alloc] initWithBytes:pointData.bytes length:res];
|
||||
|
||||
|
||||
NSLog(@"Point data is: %@", [written base64EncodedStringWithOptions:0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
//https://github.com/Matchstic/ReProvision/issues/96#issuecomment-551928795
|
||||
// https://github.com/Matchstic/ReProvision/issues/96#issuecomment-551928795
|
||||
#import <Security/Security.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -37,8 +37,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (NSString *)serverFriendlyDescription;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface ReportsFetcher : NSObject
|
||||
|
||||
/// WARNING: Runs synchronous network request. Please run this in a background thread.
|
||||
@@ -48,13 +46,17 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/// @param duration Duration checked
|
||||
/// @param searchPartyToken Search Party token
|
||||
/// @param completion Called when finished
|
||||
- (void) queryForHashes:(NSArray *)publicKeys startDate: (NSDate *) date duration: (double) duration searchPartyToken:(nonnull NSData *)searchPartyToken completion: (void (^)(NSData* _Nullable)) completion;
|
||||
- (void)queryForHashes:(NSArray *)publicKeys
|
||||
startDate:(NSDate *)date
|
||||
duration:(double)duration
|
||||
searchPartyToken:(nonnull NSData *)searchPartyToken
|
||||
completion:(void (^)(NSData *_Nullable))completion;
|
||||
|
||||
/// Fetches the search party token from the macOS Keychain. Returns null if it fails
|
||||
- (NSData * _Nullable) fetchSearchpartyToken;
|
||||
/// Fetches the search party token from the macOS Keychain. Returns null if it fails
|
||||
- (NSData *_Nullable)fetchSearchpartyToken;
|
||||
|
||||
/// Get AnisetteData from AuthKit or return an empty dictionary
|
||||
- (NSDictionary *_Nonnull) anisetteDataDictionary;
|
||||
- (NSDictionary *_Nonnull)anisetteDataDictionary;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
186
OpenHaystack/OpenHaystack/ReportsFetcher/ReportsFetcher.m
Executable file → Normal file
186
OpenHaystack/OpenHaystack/ReportsFetcher/ReportsFetcher.m
Executable file → Normal file
@@ -14,46 +14,48 @@
|
||||
|
||||
@implementation ReportsFetcher
|
||||
|
||||
- (NSData * _Nullable) fetchSearchpartyToken {
|
||||
- (NSData *_Nullable)fetchSearchpartyToken {
|
||||
NSDictionary *query = @{
|
||||
(NSString*) kSecClass : (NSString*) kSecClassGenericPassword,
|
||||
(NSString*) kSecAttrService: @"com.apple.account.AppleAccount.search-party-token",
|
||||
(NSString*) kSecMatchLimit: (id) kSecMatchLimitOne,
|
||||
(NSString*) kSecReturnData: @true
|
||||
(NSString *)kSecClass : (NSString *)kSecClassGenericPassword,
|
||||
(NSString *)kSecAttrService : @"com.apple.account.AppleAccount.search-party-token",
|
||||
(NSString *)kSecMatchLimit : (id)kSecMatchLimitOne,
|
||||
(NSString *)kSecReturnData : @true
|
||||
};
|
||||
|
||||
|
||||
CFTypeRef item;
|
||||
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) query, &item);
|
||||
|
||||
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &item);
|
||||
|
||||
if (status == errSecSuccess) {
|
||||
NSData *securityToken = (__bridge NSData *)(item);
|
||||
|
||||
|
||||
NSLog(@"Fetched token %@", [[NSString alloc] initWithData:securityToken encoding:NSUTF8StringEncoding]);
|
||||
|
||||
|
||||
if (securityToken.length == 0) {
|
||||
return [self fetchSearchpartyTokenFromAccounts];
|
||||
}
|
||||
|
||||
|
||||
return securityToken;
|
||||
}
|
||||
|
||||
|
||||
return [self fetchSearchpartyTokenFromAccounts];;
|
||||
return [self fetchSearchpartyTokenFromAccounts];
|
||||
;
|
||||
}
|
||||
|
||||
- (NSData * _Nullable) fetchSearchpartyTokenFromAccounts {
|
||||
- (NSData *_Nullable)fetchSearchpartyTokenFromAccounts {
|
||||
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;}
|
||||
|
||||
|
||||
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")];
|
||||
NSDictionary *credentialItems = [iCloudCredentials performSelector:NSSelectorFromString(@"credentialItems")];
|
||||
NSString *searchPartyToken = credentialItems[@"search-party-token"];
|
||||
NSData *tokenData = [searchPartyToken dataUsingEncoding:NSASCIIStringEncoding];
|
||||
return tokenData;
|
||||
@@ -62,113 +64,109 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *) fetchAppleAccountId {
|
||||
- (NSString *)fetchAppleAccountId {
|
||||
NSDictionary *query = @{
|
||||
(NSString*) kSecClass : (NSString*) kSecClassGenericPassword,
|
||||
(NSString*) kSecAttrService: @"iCloud",
|
||||
(NSString*) kSecMatchLimit: (id) kSecMatchLimitOne,
|
||||
(NSString*) kSecReturnAttributes: @true
|
||||
(NSString *)kSecClass : (NSString *)kSecClassGenericPassword,
|
||||
(NSString *)kSecAttrService : @"iCloud",
|
||||
(NSString *)kSecMatchLimit : (id)kSecMatchLimitOne,
|
||||
(NSString *)kSecReturnAttributes : @true
|
||||
};
|
||||
|
||||
|
||||
CFTypeRef item;
|
||||
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) query, &item);
|
||||
|
||||
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &item);
|
||||
|
||||
if (status == errSecSuccess) {
|
||||
NSDictionary *itemDict = (__bridge NSDictionary *)(item);
|
||||
|
||||
NSString *accountId = itemDict[(NSString *) kSecAttrAccount];
|
||||
|
||||
|
||||
NSString *accountId = itemDict[(NSString *)kSecAttrAccount];
|
||||
|
||||
return accountId;
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *) basicAuthForAppleID: (NSString *) appleId andToken: (NSData*) token {
|
||||
NSString * tokenString = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding];
|
||||
NSString * authText = [NSString stringWithFormat:@"%@:%@", appleId, tokenString];
|
||||
NSString * base64Auth = [[authText dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
|
||||
- (NSString *)basicAuthForAppleID:(NSString *)appleId andToken:(NSData *)token {
|
||||
NSString *tokenString = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding];
|
||||
NSString *authText = [NSString stringWithFormat:@"%@:%@", appleId, tokenString];
|
||||
NSString *base64Auth = [[authText dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
|
||||
NSString *auth = [NSString stringWithFormat:@"Basic %@", base64Auth];
|
||||
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
- (NSDictionary *) anisetteDataDictionary {
|
||||
#if AUTHKIT
|
||||
NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://gateway.icloud.com/acsnservice/fetch"]];
|
||||
- (NSDictionary *)anisetteDataDictionary {
|
||||
#if AUTHKIT
|
||||
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://gateway.icloud.com/acsnservice/fetch"]];
|
||||
[req setHTTPMethod:@"POST"];
|
||||
|
||||
AKAppleIDSession* session = [[NSClassFromString(@"AKAppleIDSession") alloc] initWithIdentifier:@"com.apple.gs.xcode.auth"];
|
||||
|
||||
AKAppleIDSession *session = [[NSClassFromString(@"AKAppleIDSession") alloc] initWithIdentifier:@"com.apple.gs.xcode.auth"];
|
||||
NSDictionary *appleHeadersDict = [session appleIDHeadersForRequest:req];
|
||||
|
||||
|
||||
return appleHeadersDict;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return [NSDictionary new];
|
||||
}
|
||||
|
||||
- (void) fetchAnisetteData:(void (^)(NSDictionary* _Nullable)) completion {
|
||||
- (void)fetchAnisetteData:(void (^)(NSDictionary *_Nullable))completion {
|
||||
// Use the AltStore mail plugin
|
||||
[[AnisetteDataManager shared] requestAnisetteDataObjc:^(NSDictionary * _Nullable dict) {
|
||||
completion(dict);
|
||||
[[AnisetteDataManager shared] requestAnisetteDataObjc:^(NSDictionary *_Nullable dict) {
|
||||
completion(dict);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) queryForHashes:(NSArray *)publicKeys startDate: (NSDate *) date duration: (double) duration searchPartyToken:(nonnull NSData *)searchPartyToken completion: (void (^)(NSData* _Nullable)) completion {
|
||||
|
||||
- (void)queryForHashes:(NSArray *)publicKeys
|
||||
startDate:(NSDate *)date
|
||||
duration:(double)duration
|
||||
searchPartyToken:(nonnull NSData *)searchPartyToken
|
||||
completion:(void (^)(NSData *_Nullable))completion {
|
||||
|
||||
// calculate the timestamps for the defined duration
|
||||
long long startDate = [date timeIntervalSince1970] * 1000;
|
||||
long long endDate = ([date timeIntervalSince1970] + duration) * 1000.0;
|
||||
|
||||
|
||||
NSLog(@"Requesting data for %@", publicKeys);
|
||||
NSDictionary * query = @{
|
||||
@"search": @[
|
||||
@{
|
||||
@"endDate": [NSString stringWithFormat:@"%lli", endDate],
|
||||
@"ids": publicKeys,
|
||||
@"startDate": [NSString stringWithFormat:@"%lli", startDate]
|
||||
}
|
||||
]
|
||||
};
|
||||
NSDictionary *query =
|
||||
@{@"search" : @[ @{@"endDate" : [NSString stringWithFormat:@"%lli", endDate], @"ids" : publicKeys, @"startDate" : [NSString stringWithFormat:@"%lli", startDate]} ]};
|
||||
NSData *httpBody = [NSJSONSerialization dataWithJSONObject:query options:0 error:nil];
|
||||
|
||||
NSLog(@"Query : %@",query);
|
||||
|
||||
NSLog(@"Query : %@", query);
|
||||
NSString *authKey = @"authorization";
|
||||
NSData *securityToken = searchPartyToken;
|
||||
NSString *appleId = [self fetchAppleAccountId];
|
||||
NSString *authValue = [self basicAuthForAppleID:appleId andToken:securityToken];
|
||||
|
||||
[self fetchAnisetteData:^(NSDictionary * _Nullable dict) {
|
||||
if (dict == nil) {
|
||||
completion(nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://gateway.icloud.com/acsnservice/fetch"]];
|
||||
|
||||
[req setHTTPMethod:@"POST"];
|
||||
[req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||
[req setValue:@"application/json" forHTTPHeaderField:@"Accept"];
|
||||
[req setValue:authValue forHTTPHeaderField:authKey];
|
||||
|
||||
|
||||
NSDictionary *appleHeadersDict = dict;
|
||||
for(id key in appleHeadersDict)
|
||||
[req setValue:[appleHeadersDict objectForKey:key] forHTTPHeaderField:key];
|
||||
|
||||
NSLog(@"Headers:\n%@",req.allHTTPHeaderFields);
|
||||
|
||||
[req setHTTPBody:httpBody];
|
||||
|
||||
NSURLResponse * response;
|
||||
NSError * error = nil;
|
||||
NSData * data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
|
||||
|
||||
if (error) {
|
||||
NSLog(@"Error during request: \n\n%@", error);
|
||||
}
|
||||
|
||||
completion(data);
|
||||
|
||||
[self fetchAnisetteData:^(NSDictionary *_Nullable dict) {
|
||||
if (dict == nil) {
|
||||
completion(nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://gateway.icloud.com/acsnservice/fetch"]];
|
||||
|
||||
[req setHTTPMethod:@"POST"];
|
||||
[req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||
[req setValue:@"application/json" forHTTPHeaderField:@"Accept"];
|
||||
[req setValue:authValue forHTTPHeaderField:authKey];
|
||||
|
||||
NSDictionary *appleHeadersDict = dict;
|
||||
for (id key in appleHeadersDict)
|
||||
[req setValue:[appleHeadersDict objectForKey:key] forHTTPHeaderField:key];
|
||||
|
||||
NSLog(@"Headers:\n%@", req.allHTTPHeaderFields);
|
||||
|
||||
[req setHTTPBody:httpBody];
|
||||
|
||||
NSURLResponse *response;
|
||||
NSError *error = nil;
|
||||
NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
|
||||
|
||||
if (error) {
|
||||
NSLog(@"Error during request: \n\n%@", error);
|
||||
}
|
||||
|
||||
completion(data);
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,18 +17,18 @@ 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 *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) 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) NSDate *date;
|
||||
@property(nonatomic, copy) NSLocale *locale;
|
||||
@property(nonatomic, copy) NSTimeZone *timeZone;
|
||||
|
||||
- (instancetype)initWithMachineID:(NSString *)machineID
|
||||
oneTimePassword:(NSString *)oneTimePassword
|
||||
@@ -41,7 +41,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
locale:(NSLocale *)locale
|
||||
timeZone:(NSTimeZone *)timeZone;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -15,78 +15,68 @@
|
||||
|
||||
@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 {
|
||||
|
||||
- (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)
|
||||
{
|
||||
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: %@ ",
|
||||
self.machineID, self.oneTimePassword, self.localUserID, @(self.routingInfo), self.deviceUniqueIdentifier, self.deviceSerialNumber, self.deviceDescription, self.date, self.locale.localeIdentifier, self.timeZone];
|
||||
- (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: %@ ",
|
||||
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
|
||||
{
|
||||
- (BOOL)isEqual:(id)object {
|
||||
ALTAnisetteData *anisetteData = (ALTAnisetteData *)object;
|
||||
if (![anisetteData isKindOfClass:[ALTAnisetteData class]])
|
||||
{
|
||||
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)] &&
|
||||
|
||||
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]);
|
||||
[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);
|
||||
- (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
|
||||
{
|
||||
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
|
||||
ALTAnisetteData *copy = [[ALTAnisetteData alloc] initWithMachineID:self.machineID
|
||||
oneTimePassword:self.oneTimePassword
|
||||
localUserID:self.localUserID
|
||||
@@ -97,61 +87,56 @@
|
||||
date:self.date
|
||||
locale:self.locale
|
||||
timeZone:self.timeZone];
|
||||
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
#pragma mark - <NSSecureCoding> -
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
- (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
|
||||
oneTimePassword:oneTimePassword
|
||||
localUserID:localUserID
|
||||
routingInfo:[routingInfo unsignedLongLongValue]
|
||||
deviceUniqueIdentifier:deviceUniqueIdentifier
|
||||
deviceSerialNumber:deviceSerialNumber
|
||||
deviceDescription:deviceDescription
|
||||
date:date
|
||||
locale:locale
|
||||
timeZone:timeZone
|
||||
];
|
||||
|
||||
date:date
|
||||
locale:locale
|
||||
timeZone:timeZone];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
- (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
|
||||
{
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,27 +11,27 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "ALTAnisetteData.h"
|
||||
#import <Foundation/Foundation.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 *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) 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) NSDate *date;
|
||||
@property(nonatomic, copy) NSLocale *locale;
|
||||
@property(nonatomic, copy) NSTimeZone *timeZone;
|
||||
|
||||
@property (nonatomic, copy) NSData *searchPartyToken;
|
||||
@property(nonatomic, copy) NSData *searchPartyToken;
|
||||
|
||||
- (instancetype)initWithMachineID:(NSString *)machineID
|
||||
oneTimePassword:(NSString *)oneTimePassword
|
||||
@@ -44,8 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
locale:(NSLocale *)locale
|
||||
timeZone:(NSTimeZone *)timeZone;
|
||||
|
||||
- (instancetype) initFromALTAnissetteData:(ALTAnisetteData *) altAnisetteData;
|
||||
|
||||
- (instancetype)initFromALTAnissetteData:(ALTAnisetteData *)altAnisetteData;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -16,170 +16,156 @@
|
||||
|
||||
@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 {
|
||||
|
||||
- (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)
|
||||
{
|
||||
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 {
|
||||
- (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];
|
||||
- (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
|
||||
{
|
||||
- (BOOL)isEqual:(id)object {
|
||||
AppleAccountData *anisetteData = (AppleAccountData *)object;
|
||||
if (![anisetteData isKindOfClass:[AppleAccountData class]])
|
||||
{
|
||||
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)] &&
|
||||
|
||||
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]);
|
||||
[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);
|
||||
- (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
|
||||
{
|
||||
- (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];
|
||||
|
||||
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
|
||||
{
|
||||
- (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
|
||||
oneTimePassword:oneTimePassword
|
||||
localUserID:localUserID
|
||||
routingInfo:[routingInfo unsignedLongLongValue]
|
||||
deviceUniqueIdentifier:deviceUniqueIdentifier
|
||||
deviceSerialNumber:deviceSerialNumber
|
||||
deviceDescription:deviceDescription
|
||||
date:date
|
||||
locale:locale
|
||||
timeZone:timeZone
|
||||
];
|
||||
|
||||
self.searchPartyToken = searchPartyToken;
|
||||
|
||||
date:date
|
||||
locale:locale
|
||||
timeZone:timeZone];
|
||||
|
||||
self.searchPartyToken = searchPartyToken;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
- (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
|
||||
{
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#import <dlfcn.h>
|
||||
|
||||
#import "AppleAccountData.h"
|
||||
#import <Security/Security.h>
|
||||
#import <Accounts/Accounts.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
@import AppKit;
|
||||
|
||||
@@ -34,51 +34,49 @@
|
||||
|
||||
@interface OpenHaystackPluginService ()
|
||||
|
||||
@property (nonatomic, readonly) NSISO8601DateFormatter *dateFormatter;
|
||||
@property(nonatomic, readonly) NSISO8601DateFormatter *dateFormatter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OpenHaystackPluginService
|
||||
|
||||
+ (instancetype)sharedService
|
||||
{
|
||||
+ (instancetype)sharedService {
|
||||
static OpenHaystackPluginService *_service = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_service = [[self alloc] init];
|
||||
_service = [[self alloc] init];
|
||||
});
|
||||
|
||||
|
||||
return _service;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
if (self) {
|
||||
_dateFormatter = [[NSISO8601DateFormatter alloc] init];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
+ (void)initialize {
|
||||
[[OpenHaystackPluginService sharedService] start];
|
||||
}
|
||||
|
||||
- (void)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];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(receiveNotification:)
|
||||
name:@"de.tu-darmstadt.seemoo.OpenHaystack.FetchAnisetteData"
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)receiveNotification:(NSNotification *)notification
|
||||
{
|
||||
- (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"]];
|
||||
|
||||
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"];
|
||||
@@ -86,40 +84,45 @@
|
||||
|
||||
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]];
|
||||
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];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"de.tu-darmstadt.seemoo.OpenHaystack.AnisetteDataResponse"
|
||||
object:nil
|
||||
userInfo:@{@"requestUUID" : requestUUID, @"anisetteData" : data}
|
||||
deliverImmediately:YES];
|
||||
}
|
||||
|
||||
- (NSData * _Nullable) fetchSearchpartyToken {
|
||||
- (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;}
|
||||
|
||||
|
||||
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")];
|
||||
NSDictionary *credentialItems = [iCloudCredentials performSelector:NSSelectorFromString(@"credentialItems")];
|
||||
NSString *searchPartyToken = credentialItems[@"search-party-token"];
|
||||
NSData *tokenData = [searchPartyToken dataUsingEncoding:NSASCIIStringEncoding];
|
||||
return tokenData;
|
||||
|
||||
Reference in New Issue
Block a user