diff --git a/MMETestHost/AppDelegate.h b/MMETestHost/AppDelegate.h new file mode 100644 index 00000000..6548dc55 --- /dev/null +++ b/MMETestHost/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// MMETestHost +// +// Created by Alf Watt on 4/4/19. +// Copyright © 2019 Mapbox. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/MMETestHost/AppDelegate.m b/MMETestHost/AppDelegate.m new file mode 100644 index 00000000..624d125c --- /dev/null +++ b/MMETestHost/AppDelegate.m @@ -0,0 +1,51 @@ +// +// AppDelegate.m +// MMETestHost +// +// Created by Alf Watt on 4/4/19. +// Copyright © 2019 Mapbox. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + + +@end diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Contents.json b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..6d373ca5 --- /dev/null +++ b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Events-App-Logo_20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Events-App-Logo_20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Events-App-Logo_29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Events-App-Logo_29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Events-App-Logo_40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Events-App-Logo_40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Events-App-Logo_60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Events-App-Logo_60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Events-App-Logo_20x20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Events-App-Logo_20x20@2x-1.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Events-App-Logo_29x29.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Events-App-Logo_29x29@2x-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Events-App-Logo_40x40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Events-App-Logo_40x40@2x-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Events-App-Logo_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Events-App-Logo_76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Events-App-Logo_84x84@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Events-App-Logo_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_1024x1024.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_1024x1024.png new file mode 100644 index 00000000..f197292e Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_1024x1024.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20.png new file mode 100644 index 00000000..370f34b6 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@2x-1.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@2x-1.png new file mode 100644 index 00000000..6bb2b5dc Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@2x-1.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@2x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@2x.png new file mode 100644 index 00000000..6bb2b5dc Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@2x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@3x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@3x.png new file mode 100644 index 00000000..75327537 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_20x20@3x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29.png new file mode 100644 index 00000000..3f29a1f2 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@2x-1.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@2x-1.png new file mode 100644 index 00000000..6f5dd8cd Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@2x-1.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@2x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@2x.png new file mode 100644 index 00000000..6f5dd8cd Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@2x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@3x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@3x.png new file mode 100644 index 00000000..b8bb5a16 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_29x29@3x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40.png new file mode 100644 index 00000000..6bb2b5dc Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@2x-1.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@2x-1.png new file mode 100644 index 00000000..88a8a5e8 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@2x-1.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@2x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@2x.png new file mode 100644 index 00000000..88a8a5e8 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@2x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@3x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@3x.png new file mode 100644 index 00000000..539a1214 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_40x40@3x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_60x60@2x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_60x60@2x.png new file mode 100644 index 00000000..539a1214 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_60x60@2x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_60x60@3x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_60x60@3x.png new file mode 100644 index 00000000..172013d2 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_60x60@3x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_76x76.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_76x76.png new file mode 100644 index 00000000..58295b5b Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_76x76.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_76x76@2x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_76x76@2x.png new file mode 100644 index 00000000..f6cd53ab Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_76x76@2x.png differ diff --git a/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_84x84@2x.png b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_84x84@2x.png new file mode 100644 index 00000000..45b85b82 Binary files /dev/null and b/MMETestHost/Assets.xcassets/AppIcon.appiconset/Events-App-Logo_84x84@2x.png differ diff --git a/MMETestHost/Assets.xcassets/Contents.json b/MMETestHost/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/MMETestHost/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MMETestHost/Assets.xcassets/Events-App-Logo.imageset/Contents.json b/MMETestHost/Assets.xcassets/Events-App-Logo.imageset/Contents.json new file mode 100644 index 00000000..e8b145d5 --- /dev/null +++ b/MMETestHost/Assets.xcassets/Events-App-Logo.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Events-App-Logo.pdf", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/MMETestHost/Assets.xcassets/Events-App-Logo.imageset/Events-App-Logo.pdf b/MMETestHost/Assets.xcassets/Events-App-Logo.imageset/Events-App-Logo.pdf new file mode 100644 index 00000000..f48f6ae0 Binary files /dev/null and b/MMETestHost/Assets.xcassets/Events-App-Logo.imageset/Events-App-Logo.pdf differ diff --git a/MMETestHost/Base.lproj/LaunchScreen.storyboard b/MMETestHost/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..b47a2057 --- /dev/null +++ b/MMETestHost/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MMETestHost/Base.lproj/Main.storyboard b/MMETestHost/Base.lproj/Main.storyboard new file mode 100644 index 00000000..d5057e9d --- /dev/null +++ b/MMETestHost/Base.lproj/Main.storyboard @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MMETestHost/Info.plist b/MMETestHost/Info.plist new file mode 100644 index 00000000..16be3b68 --- /dev/null +++ b/MMETestHost/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/MMETestHost/MMETestHost.entitlements b/MMETestHost/MMETestHost.entitlements new file mode 100644 index 00000000..d235c200 --- /dev/null +++ b/MMETestHost/MMETestHost.entitlements @@ -0,0 +1,10 @@ + + + + + keychain-access-groups + + $(AppIdentifierPrefix)com.mapbox.MMETestHost + + + diff --git a/MMETestHost/ViewController.h b/MMETestHost/ViewController.h new file mode 100644 index 00000000..f371371f --- /dev/null +++ b/MMETestHost/ViewController.h @@ -0,0 +1,15 @@ +// +// ViewController.h +// MMETestHost +// +// Created by Alf Watt on 4/4/19. +// Copyright © 2019 Mapbox. All rights reserved. +// + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/MMETestHost/ViewController.m b/MMETestHost/ViewController.m new file mode 100644 index 00000000..8f3841e9 --- /dev/null +++ b/MMETestHost/ViewController.m @@ -0,0 +1,23 @@ +// +// ViewController.m +// MMETestHost +// +// Created by Alf Watt on 4/4/19. +// Copyright © 2019 Mapbox. All rights reserved. +// + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + + +@end diff --git a/MMETestHost/main.m b/MMETestHost/main.m new file mode 100644 index 00000000..55d6be45 --- /dev/null +++ b/MMETestHost/main.m @@ -0,0 +1,16 @@ +// +// main.m +// MMETestHost +// +// Created by Alf Watt on 4/4/19. +// Copyright © 2019 Mapbox. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/MapboxMobileEvents.xcodeproj/project.pbxproj b/MapboxMobileEvents.xcodeproj/project.pbxproj index a923873d..9e320e4c 100644 --- a/MapboxMobileEvents.xcodeproj/project.pbxproj +++ b/MapboxMobileEvents.xcodeproj/project.pbxproj @@ -78,50 +78,6 @@ 40AE586E1EA95EDD0046B437 /* MMEEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 40AE586C1EA95EDD0046B437 /* MMEEvent.m */; }; 40AE58711EAA87960046B437 /* MMEAPIClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 40AE586F1EAA87960046B437 /* MMEAPIClient.h */; }; 40AE58721EAA87960046B437 /* MMEAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 40AE58701EAA87960046B437 /* MMEAPIClient.m */; }; - 40C611471F18319000E30A6C /* configuration_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C6110A1F18319000E30A6C /* configuration_utils.h */; }; - 40C611481F18319000E30A6C /* configuration_utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6110B1F18319000E30A6C /* configuration_utils.m */; }; - 40C611491F18319000E30A6C /* configuration_utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6110B1F18319000E30A6C /* configuration_utils.m */; }; - 40C611601F18319000E30A6C /* parse_configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611231F18319000E30A6C /* parse_configuration.h */; }; - 40C611611F18319000E30A6C /* parse_configuration.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611241F18319000E30A6C /* parse_configuration.m */; }; - 40C611621F18319000E30A6C /* parse_configuration.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611241F18319000E30A6C /* parse_configuration.m */; }; - 40C611631F18319000E30A6C /* ssl_pin_verifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611261F18319000E30A6C /* ssl_pin_verifier.h */; }; - 40C611641F18319000E30A6C /* ssl_pin_verifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611271F18319000E30A6C /* ssl_pin_verifier.m */; }; - 40C611651F18319000E30A6C /* ssl_pin_verifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611271F18319000E30A6C /* ssl_pin_verifier.m */; }; - 40C611661F18319000E30A6C /* TSKPublicKeyAlgorithm.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611281F18319000E30A6C /* TSKPublicKeyAlgorithm.h */; }; - 40C611671F18319000E30A6C /* TSKSPKIHashCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611291F18319000E30A6C /* TSKSPKIHashCache.h */; }; - 40C611681F18319000E30A6C /* TSKSPKIHashCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6112A1F18319000E30A6C /* TSKSPKIHashCache.m */; }; - 40C611691F18319000E30A6C /* TSKSPKIHashCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6112A1F18319000E30A6C /* TSKSPKIHashCache.m */; }; - 40C6116A1F18319000E30A6C /* reporting_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C6112C1F18319000E30A6C /* reporting_utils.h */; }; - 40C6116B1F18319000E30A6C /* reporting_utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6112D1F18319000E30A6C /* reporting_utils.m */; }; - 40C6116C1F18319000E30A6C /* reporting_utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6112D1F18319000E30A6C /* reporting_utils.m */; }; - 40C6116D1F18319000E30A6C /* TSKBackgroundReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C6112E1F18319000E30A6C /* TSKBackgroundReporter.h */; }; - 40C6116E1F18319000E30A6C /* TSKBackgroundReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6112F1F18319000E30A6C /* TSKBackgroundReporter.m */; }; - 40C6116F1F18319000E30A6C /* TSKBackgroundReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6112F1F18319000E30A6C /* TSKBackgroundReporter.m */; }; - 40C611701F18319000E30A6C /* TSKPinFailureReport.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611301F18319000E30A6C /* TSKPinFailureReport.h */; }; - 40C611711F18319000E30A6C /* TSKPinFailureReport.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611311F18319000E30A6C /* TSKPinFailureReport.m */; }; - 40C611721F18319000E30A6C /* TSKPinFailureReport.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611311F18319000E30A6C /* TSKPinFailureReport.m */; }; - 40C611731F18319000E30A6C /* TSKReportsRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611321F18319000E30A6C /* TSKReportsRateLimiter.h */; }; - 40C611741F18319000E30A6C /* TSKReportsRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611331F18319000E30A6C /* TSKReportsRateLimiter.m */; }; - 40C611751F18319000E30A6C /* TSKReportsRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611331F18319000E30A6C /* TSKReportsRateLimiter.m */; }; - 40C611761F18319000E30A6C /* vendor_identifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611341F18319000E30A6C /* vendor_identifier.h */; }; - 40C611771F18319000E30A6C /* vendor_identifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611351F18319000E30A6C /* vendor_identifier.m */; }; - 40C611781F18319000E30A6C /* vendor_identifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611351F18319000E30A6C /* vendor_identifier.m */; }; - 40C6117F1F18319000E30A6C /* TrustKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C6113B1F18319000E30A6C /* TrustKit.h */; }; - 40C611801F18319000E30A6C /* TrustKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6113C1F18319000E30A6C /* TrustKit.m */; }; - 40C611811F18319000E30A6C /* TrustKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6113C1F18319000E30A6C /* TrustKit.m */; }; - 40C611821F18319000E30A6C /* TSKLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C6113D1F18319000E30A6C /* TSKLog.h */; }; - 40C611831F18319000E30A6C /* TSKPinningValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C6113E1F18319000E30A6C /* TSKPinningValidator.h */; }; - 40C611841F18319000E30A6C /* TSKPinningValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6113F1F18319000E30A6C /* TSKPinningValidator.m */; }; - 40C611851F18319000E30A6C /* TSKPinningValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C6113F1F18319000E30A6C /* TSKPinningValidator.m */; }; - 40C611861F18319000E30A6C /* TSKPinningValidator_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611401F18319000E30A6C /* TSKPinningValidator_Private.h */; }; - 40C611871F18319000E30A6C /* TSKPinningValidatorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611411F18319000E30A6C /* TSKPinningValidatorCallback.h */; }; - 40C611881F18319000E30A6C /* TSKPinningValidatorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611421F18319000E30A6C /* TSKPinningValidatorResult.h */; }; - 40C611891F18319000E30A6C /* TSKPinningValidatorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611431F18319000E30A6C /* TSKPinningValidatorResult.m */; }; - 40C6118A1F18319000E30A6C /* TSKPinningValidatorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611431F18319000E30A6C /* TSKPinningValidatorResult.m */; }; - 40C6118B1F18319000E30A6C /* TSKTrustDecision.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611441F18319000E30A6C /* TSKTrustDecision.h */; }; - 40C6118C1F18319000E30A6C /* TSKTrustKitConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C611451F18319000E30A6C /* TSKTrustKitConfig.h */; }; - 40C6118D1F18319000E30A6C /* TSKTrustKitConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611461F18319000E30A6C /* TSKTrustKitConfig.m */; }; - 40C6118E1F18319000E30A6C /* TSKTrustKitConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C611461F18319000E30A6C /* TSKTrustKitConfig.m */; }; 40C9E27B1EA542BC00744FE7 /* MMEEventsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C9E2791EA542BC00744FE7 /* MMEEventsManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 40C9E27C1EA542BC00744FE7 /* MMEEventsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 40C9E27A1EA542BC00744FE7 /* MMEEventsManager.m */; }; 40C9E27F1EA5473F00744FE7 /* MMELocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C9E27D1EA5473F00744FE7 /* MMELocationManager.h */; }; @@ -144,12 +100,21 @@ 40FB437D1EFAFAE900EC5BC0 /* MMETimerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FB437B1EFAFAE900EC5BC0 /* MMETimerManager.m */; }; 40FB437E1EFAFAE900EC5BC0 /* MMETimerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FB437B1EFAFAE900EC5BC0 /* MMETimerManager.m */; }; 40FB43801EFAFDCF00EC5BC0 /* MMETimerManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FB437F1EFAFDCF00EC5BC0 /* MMETimerManagerTests.m */; }; - 96AB5106216416AE00A261B8 /* MMEHashProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = AC2C7167211376DA004179E0 /* MMEHashProvider.m */; }; - 96AB5108216416E800A261B8 /* MMETrustKitProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC8C1CB210FAFF400C5055C /* MMETrustKitProvider.m */; }; 96AB510A2164178900A261B8 /* MMEConfigurator.h in Headers */ = {isa = PBXBuildFile; fileRef = AC2C7162211241CC004179E0 /* MMEConfigurator.h */; }; 96AB510B21641A6000A261B8 /* MMEUINavigation.m in Sources */ = {isa = PBXBuildFile; fileRef = ACE4F0191FD6102100035880 /* MMEUINavigation.m */; }; 9C6D98A622371DA400679292 /* MMEEventTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C6D98A322371DA400679292 /* MMEEventTests.mm */; }; 9C6D98A722371DA400679292 /* MMEEventsConfigurationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C6D98A422371DA400679292 /* MMEEventsConfigurationTests.mm */; }; + 9C65A25F2256BC55006E3FED /* MMETestCARoot.cer in Resources */ = {isa = PBXBuildFile; fileRef = 9C65A25E2256BBB2006E3FED /* MMETestCARoot.cer */; }; + 9C65A2602256BC55006E3FED /* MMETestCABranch.cer in Resources */ = {isa = PBXBuildFile; fileRef = 9C65A25D2256BBB2006E3FED /* MMETestCABranch.cer */; }; + 9C65A2612256BC55006E3FED /* MMETestCALeaf.cer in Resources */ = {isa = PBXBuildFile; fileRef = 9C65A25C2256BBB2006E3FED /* MMETestCALeaf.cer */; }; + 9C65A26A2256C110006E3FED /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C65A2692256C110006E3FED /* AppDelegate.m */; }; + 9C65A26D2256C110006E3FED /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C65A26C2256C110006E3FED /* ViewController.m */; }; + 9C65A2702256C110006E3FED /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C65A26E2256C110006E3FED /* Main.storyboard */; }; + 9C65A2722256C112006E3FED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C65A2712256C112006E3FED /* Assets.xcassets */; }; + 9C65A2752256C112006E3FED /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C65A2732256C112006E3FED /* LaunchScreen.storyboard */; }; + 9C65A2782256C112006E3FED /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C65A2772256C112006E3FED /* main.m */; }; + 9C65A27F2256C1CF006E3FED /* MapboxMobileEvents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 404807B91EA186D8008A6D50 /* MapboxMobileEvents.framework */; }; + 9C65A2802256C1CF006E3FED /* MapboxMobileEvents.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 404807B91EA186D8008A6D50 /* MapboxMobileEvents.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; AC1B091122137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = AC1B090F22137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.h */; }; AC1B091222137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = AC1B091022137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.m */; }; AC1B091322137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = AC1B091022137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.m */; }; @@ -158,8 +123,6 @@ AC2C716021124099004179E0 /* MMEDispatchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AC2C715D2112408A004179E0 /* MMEDispatchManager.m */; }; AC2C7163211241CC004179E0 /* MMEConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = AC2C7161211241CB004179E0 /* MMEConfigurator.m */; }; AC2C7165211241D0004179E0 /* MMEConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = AC2C7161211241CB004179E0 /* MMEConfigurator.m */; }; - AC2C7168211376DA004179E0 /* MMEHashProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = AC2C7166211376DA004179E0 /* MMEHashProvider.h */; }; - AC2C7169211376DA004179E0 /* MMEHashProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = AC2C7167211376DA004179E0 /* MMEHashProvider.m */; }; AC611F271FCDED2F00ABBF6D /* MMEEventLogReportViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = AC611F251FCDED2F00ABBF6D /* MMEEventLogReportViewController.h */; }; AC611F281FCDED2F00ABBF6D /* MMEEventLogReportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AC611F261FCDED2F00ABBF6D /* MMEEventLogReportViewController.m */; }; AC61FA09216BE7A0008519F5 /* MMEMetricsManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC61FA08216BE7A0008519F5 /* MMEMetricsManager.mm */; }; @@ -169,14 +132,19 @@ AC86FE1D2169250000D1B89C /* MMEMetricsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = AC86FE1B2169250000D1B89C /* MMEMetricsManager.h */; }; AC86FE1E2169250000D1B89C /* MMEMetricsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AC86FE1C2169250000D1B89C /* MMEMetricsManager.m */; }; AC86FE1F2169250000D1B89C /* MMEMetricsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AC86FE1C2169250000D1B89C /* MMEMetricsManager.m */; }; - ACA65F38213591ED00537748 /* MMEHashProviderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACA65F37213591ED00537748 /* MMEHashProviderTests.mm */; }; ACA65F3B2135C67F00537748 /* MMEDispatchManagerFake.m in Sources */ = {isa = PBXBuildFile; fileRef = ACA65F392135C67E00537748 /* MMEDispatchManagerFake.m */; }; ACB6F21E1F7BF71B0032A916 /* MMELocationManagerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACB6F21D1F7BF71B0032A916 /* MMELocationManagerTests.mm */; }; - ACC8C1CC210FAFF400C5055C /* MMETrustKitProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC8C1CB210FAFF400C5055C /* MMETrustKitProvider.m */; }; - ACC8C1CE210FB00500C5055C /* MMETrustKitProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC8C1CD210FB00500C5055C /* MMETrustKitProvider.h */; }; ACD86DA01F96A77700DD2A8D /* MMEAPIClientTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACD86D9F1F96A77700DD2A8D /* MMEAPIClientTests.mm */; }; ACE4F01A1FD6102100035880 /* MMEUINavigation.h in Headers */ = {isa = PBXBuildFile; fileRef = ACE4F0181FD6102100035880 /* MMEUINavigation.h */; }; ACE4F01B1FD6102100035880 /* MMEUINavigation.m in Sources */ = {isa = PBXBuildFile; fileRef = ACE4F0191FD6102100035880 /* MMEUINavigation.m */; }; + CF870EA22254A93200959A65 /* MMEAPIClientCertPinTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF870EA12254A93200959A65 /* MMEAPIClientCertPinTests.mm */; }; + CF93A6582241EDD500BBA199 /* MMECertPin.m in Sources */ = {isa = PBXBuildFile; fileRef = CF93A6562241EDD500BBA199 /* MMECertPin.m */; }; + CF93A6592241EDD500BBA199 /* MMECertPin.m in Sources */ = {isa = PBXBuildFile; fileRef = CF93A6562241EDD500BBA199 /* MMECertPin.m */; }; + CF93A65B2241EDD500BBA199 /* MMECertPin.h in Headers */ = {isa = PBXBuildFile; fileRef = CF93A6572241EDD500BBA199 /* MMECertPin.h */; }; + CF93A65E2244C01300BBA199 /* MMEPinningConfigurationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = CF93A65C2244C01300BBA199 /* MMEPinningConfigurationProvider.h */; }; + CF93A65F2244C01300BBA199 /* MMEPinningConfigurationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = CF93A65D2244C01300BBA199 /* MMEPinningConfigurationProvider.m */; }; + CF93A6602244C01300BBA199 /* MMEPinningConfigurationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = CF93A65D2244C01300BBA199 /* MMEPinningConfigurationProvider.m */; }; + CF93A66322488A4500BBA199 /* MMECertPinTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF93A66222488A4500BBA199 /* MMECertPinTests.mm */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -208,6 +176,20 @@ remoteGlobalIDString = 408596521ED084C0003BD29D; remoteInfo = MapboxMobileEventsStatic; }; + 9C65A27D2256C1C4006E3FED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 404807B01EA186D8008A6D50 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9C65A2652256C110006E3FED; + remoteInfo = MMETestHost; + }; + 9C65A2812256C1CF006E3FED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 404807B01EA186D8008A6D50 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 404807B81EA186D8008A6D50; + remoteInfo = MapboxMobileEvents; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -225,6 +207,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9C65A2832256C1CF006E3FED /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9C65A2802256C1CF006E3FED /* MapboxMobileEvents.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -282,37 +275,6 @@ 40AE586C1EA95EDD0046B437 /* MMEEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMEEvent.m; sourceTree = ""; }; 40AE586F1EAA87960046B437 /* MMEAPIClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMEAPIClient.h; sourceTree = ""; }; 40AE58701EAA87960046B437 /* MMEAPIClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMEAPIClient.m; sourceTree = ""; }; - 40C6110A1F18319000E30A6C /* configuration_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = configuration_utils.h; sourceTree = ""; }; - 40C6110B1F18319000E30A6C /* configuration_utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = configuration_utils.m; sourceTree = ""; }; - 40C611231F18319000E30A6C /* parse_configuration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parse_configuration.h; sourceTree = ""; }; - 40C611241F18319000E30A6C /* parse_configuration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = parse_configuration.m; sourceTree = ""; }; - 40C611261F18319000E30A6C /* ssl_pin_verifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssl_pin_verifier.h; sourceTree = ""; }; - 40C611271F18319000E30A6C /* ssl_pin_verifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ssl_pin_verifier.m; sourceTree = ""; }; - 40C611281F18319000E30A6C /* TSKPublicKeyAlgorithm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKPublicKeyAlgorithm.h; sourceTree = ""; }; - 40C611291F18319000E30A6C /* TSKSPKIHashCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKSPKIHashCache.h; sourceTree = ""; }; - 40C6112A1F18319000E30A6C /* TSKSPKIHashCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSKSPKIHashCache.m; sourceTree = ""; }; - 40C6112C1F18319000E30A6C /* reporting_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reporting_utils.h; sourceTree = ""; }; - 40C6112D1F18319000E30A6C /* reporting_utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = reporting_utils.m; sourceTree = ""; }; - 40C6112E1F18319000E30A6C /* TSKBackgroundReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKBackgroundReporter.h; sourceTree = ""; }; - 40C6112F1F18319000E30A6C /* TSKBackgroundReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSKBackgroundReporter.m; sourceTree = ""; }; - 40C611301F18319000E30A6C /* TSKPinFailureReport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKPinFailureReport.h; sourceTree = ""; }; - 40C611311F18319000E30A6C /* TSKPinFailureReport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSKPinFailureReport.m; sourceTree = ""; }; - 40C611321F18319000E30A6C /* TSKReportsRateLimiter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKReportsRateLimiter.h; sourceTree = ""; }; - 40C611331F18319000E30A6C /* TSKReportsRateLimiter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSKReportsRateLimiter.m; sourceTree = ""; }; - 40C611341F18319000E30A6C /* vendor_identifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vendor_identifier.h; sourceTree = ""; }; - 40C611351F18319000E30A6C /* vendor_identifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = vendor_identifier.m; sourceTree = ""; }; - 40C6113B1F18319000E30A6C /* TrustKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrustKit.h; sourceTree = ""; }; - 40C6113C1F18319000E30A6C /* TrustKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TrustKit.m; sourceTree = ""; }; - 40C6113D1F18319000E30A6C /* TSKLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKLog.h; sourceTree = ""; }; - 40C6113E1F18319000E30A6C /* TSKPinningValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKPinningValidator.h; sourceTree = ""; }; - 40C6113F1F18319000E30A6C /* TSKPinningValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSKPinningValidator.m; sourceTree = ""; }; - 40C611401F18319000E30A6C /* TSKPinningValidator_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKPinningValidator_Private.h; sourceTree = ""; }; - 40C611411F18319000E30A6C /* TSKPinningValidatorCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKPinningValidatorCallback.h; sourceTree = ""; }; - 40C611421F18319000E30A6C /* TSKPinningValidatorResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKPinningValidatorResult.h; sourceTree = ""; }; - 40C611431F18319000E30A6C /* TSKPinningValidatorResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSKPinningValidatorResult.m; sourceTree = ""; }; - 40C611441F18319000E30A6C /* TSKTrustDecision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKTrustDecision.h; sourceTree = ""; }; - 40C611451F18319000E30A6C /* TSKTrustKitConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSKTrustKitConfig.h; sourceTree = ""; }; - 40C611461F18319000E30A6C /* TSKTrustKitConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSKTrustKitConfig.m; sourceTree = ""; }; 40C9E2791EA542BC00744FE7 /* MMEEventsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMEEventsManager.h; sourceTree = ""; }; 40C9E27A1EA542BC00744FE7 /* MMEEventsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMEEventsManager.m; sourceTree = ""; }; 40C9E27D1EA5473F00744FE7 /* MMELocationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMELocationManager.h; sourceTree = ""; }; @@ -332,6 +294,20 @@ 40FB437F1EFAFDCF00EC5BC0 /* MMETimerManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMETimerManagerTests.m; sourceTree = ""; }; 9C6322622213530A00653792 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 9C6322632213530A00653792 /* readme.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = readme.md; sourceTree = ""; }; + 9C65A25C2256BBB2006E3FED /* MMETestCALeaf.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = MMETestCALeaf.cer; sourceTree = ""; }; + 9C65A25D2256BBB2006E3FED /* MMETestCABranch.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = MMETestCABranch.cer; sourceTree = ""; }; + 9C65A25E2256BBB2006E3FED /* MMETestCARoot.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = MMETestCARoot.cer; sourceTree = ""; }; + 9C65A2662256C110006E3FED /* MMETestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MMETestHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9C65A2682256C110006E3FED /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 9C65A2692256C110006E3FED /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9C65A26B2256C110006E3FED /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 9C65A26C2256C110006E3FED /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 9C65A26F2256C110006E3FED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 9C65A2712256C112006E3FED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 9C65A2742256C112006E3FED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 9C65A2762256C112006E3FED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9C65A2772256C112006E3FED /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 9C65A27C2256C175006E3FED /* MMETestHost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MMETestHost.entitlements; sourceTree = ""; }; 9C6D9881221F369000679292 /* Cartfile.private */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile.private; sourceTree = ""; }; 9C6D9883221F37FA00679292 /* package.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = package.json; sourceTree = ""; }; 9C6D9884221F37FA00679292 /* codecov.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = codecov.yml; sourceTree = ""; }; @@ -343,8 +319,6 @@ AC2C715D2112408A004179E0 /* MMEDispatchManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMEDispatchManager.m; sourceTree = ""; }; AC2C7161211241CB004179E0 /* MMEConfigurator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMEConfigurator.m; sourceTree = ""; }; AC2C7162211241CC004179E0 /* MMEConfigurator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMEConfigurator.h; sourceTree = ""; }; - AC2C7166211376DA004179E0 /* MMEHashProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMEHashProvider.h; sourceTree = ""; }; - AC2C7167211376DA004179E0 /* MMEHashProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MMEHashProvider.m; sourceTree = ""; }; AC611F251FCDED2F00ABBF6D /* MMEEventLogReportViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMEEventLogReportViewController.h; sourceTree = ""; }; AC611F261FCDED2F00ABBF6D /* MMEEventLogReportViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MMEEventLogReportViewController.m; sourceTree = ""; }; AC61FA08216BE7A0008519F5 /* MMEMetricsManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MMEMetricsManager.mm; sourceTree = ""; }; @@ -352,15 +326,18 @@ AC61FA5B217A04CC008519F5 /* MMEMetrics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MMEMetrics.m; sourceTree = ""; }; AC86FE1B2169250000D1B89C /* MMEMetricsManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMEMetricsManager.h; sourceTree = ""; }; AC86FE1C2169250000D1B89C /* MMEMetricsManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MMEMetricsManager.m; sourceTree = ""; }; - ACA65F37213591ED00537748 /* MMEHashProviderTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MMEHashProviderTests.mm; sourceTree = ""; }; ACA65F392135C67E00537748 /* MMEDispatchManagerFake.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMEDispatchManagerFake.m; sourceTree = ""; }; ACA65F3A2135C67F00537748 /* MMEDispatchManagerFake.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMEDispatchManagerFake.h; sourceTree = ""; }; ACB6F21D1F7BF71B0032A916 /* MMELocationManagerTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MMELocationManagerTests.mm; sourceTree = ""; }; - ACC8C1CB210FAFF400C5055C /* MMETrustKitProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMETrustKitProvider.m; sourceTree = ""; }; - ACC8C1CD210FB00500C5055C /* MMETrustKitProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMETrustKitProvider.h; sourceTree = ""; }; ACD86D9F1F96A77700DD2A8D /* MMEAPIClientTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MMEAPIClientTests.mm; sourceTree = ""; }; ACE4F0181FD6102100035880 /* MMEUINavigation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMEUINavigation.h; sourceTree = ""; }; ACE4F0191FD6102100035880 /* MMEUINavigation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MMEUINavigation.m; sourceTree = ""; }; + CF870EA12254A93200959A65 /* MMEAPIClientCertPinTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MMEAPIClientCertPinTests.mm; sourceTree = ""; }; + CF93A6562241EDD500BBA199 /* MMECertPin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMECertPin.m; sourceTree = ""; }; + CF93A6572241EDD500BBA199 /* MMECertPin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMECertPin.h; sourceTree = ""; }; + CF93A65C2244C01300BBA199 /* MMEPinningConfigurationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMEPinningConfigurationProvider.h; sourceTree = ""; }; + CF93A65D2244C01300BBA199 /* MMEPinningConfigurationProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMEPinningConfigurationProvider.m; sourceTree = ""; }; + CF93A66222488A4500BBA199 /* MMECertPinTests.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = MMECertPinTests.mm; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -394,18 +371,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9C65A2632256C110006E3FED /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9C65A27F2256C1CF006E3FED /* MapboxMobileEvents.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 401379661F16F26E00567137 /* Vendor */ = { - isa = PBXGroup; - children = ( - 40F16C931F04514100DF338D /* Reachability */, - 40C611091F18319000E30A6C /* TrustKit */, - ); - name = Vendor; - sourceTree = ""; - }; 4032F47C1F1FEDC6001C1FBD /* Frameworks */ = { isa = PBXGroup; children = ( @@ -423,6 +399,7 @@ 404807C61EA186D8008A6D50 /* MapboxMobileEventsTests */, 408596701ED08FF7003BD29D /* resources */, 9C6D9882221F37A200679292 /* Packaging */, + 9C65A2672256C110006E3FED /* MMETestHost */, 404807BA1EA186D8008A6D50 /* Products */, 4032F47C1F1FEDC6001C1FBD /* Frameworks */, ); @@ -435,6 +412,7 @@ 404807C21EA186D8008A6D50 /* MapboxMobileEventsTests.xctest */, 408596531ED084C0003BD29D /* libMapboxMobileEventsStatic.a */, 4085966F1ED08FF7003BD29D /* resources.bundle */, + 9C65A2662256C110006E3FED /* MMETestHost.app */, ); name = Products; sourceTree = ""; @@ -467,13 +445,11 @@ 40834B9E1FDF62C900C1BD0D /* MMENamespacedDependencies.h */, 40FB437A1EFAFAE900EC5BC0 /* MMETimerManager.h */, 40FB437B1EFAFAE900EC5BC0 /* MMETimerManager.m */, - ACC8C1CD210FB00500C5055C /* MMETrustKitProvider.h */, - ACC8C1CB210FAFF400C5055C /* MMETrustKitProvider.m */, 40AE584C1EA926710046B437 /* MMETypes.h */, 40AE584D1EA926710046B437 /* MMETypes.m */, 40AE58601EA94E4A0046B437 /* Categories */, 40C9E2841EA5615900744FE7 /* Utilities */, - 401379661F16F26E00567137 /* Vendor */, + 40F16C931F04514100DF338D /* Reachability */, ); path = MapboxMobileEvents; sourceTree = ""; @@ -482,7 +458,10 @@ isa = PBXGroup; children = ( 404807C91EA186D8008A6D50 /* Info.plist */, + CF93A66222488A4500BBA199 /* MMECertPinTests.mm */, + CF870EA12254A93200959A65 /* MMEAPIClientCertPinTests.mm */, ACD86D9F1F96A77700DD2A8D /* MMEAPIClientTests.mm */, + CF93A66222488A4500BBA199 /* MMECertPinTests.mm */, 403834FE1F7AC55D004205B9 /* MMEDateTests.mm */, 403835051F7AF860004205B9 /* MMEDependencyManagerTests.mm */, 9C6D98A422371DA400679292 /* MMEEventsConfigurationTests.mm */, @@ -493,6 +472,7 @@ AC61FA08216BE7A0008519F5 /* MMEMetricsManager.mm */, 40FB437F1EFAFDCF00EC5BC0 /* MMETimerManagerTests.m */, 40A7F9951F79A7CA002B931F /* MMEUniqueIdentifierTests.mm */, + 9C65A25B2256BB9A006E3FED /* Certs */, 40C9E28B1EA5762F00744FE7 /* Fakes */, 40AE58481EA80E5E0046B437 /* Utilities */, ); @@ -531,64 +511,13 @@ name = Categories; sourceTree = ""; }; - 40C611091F18319000E30A6C /* TrustKit */ = { - isa = PBXGroup; - children = ( - 40C6110A1F18319000E30A6C /* configuration_utils.h */, - 40C6110B1F18319000E30A6C /* configuration_utils.m */, - 40C611231F18319000E30A6C /* parse_configuration.h */, - 40C611241F18319000E30A6C /* parse_configuration.m */, - 40C611251F18319000E30A6C /* Pinning */, - 40C6112B1F18319000E30A6C /* Reporting */, - 40C6113B1F18319000E30A6C /* TrustKit.h */, - 40C6113C1F18319000E30A6C /* TrustKit.m */, - 40C6113D1F18319000E30A6C /* TSKLog.h */, - 40C6113E1F18319000E30A6C /* TSKPinningValidator.h */, - 40C6113F1F18319000E30A6C /* TSKPinningValidator.m */, - 40C611401F18319000E30A6C /* TSKPinningValidator_Private.h */, - 40C611411F18319000E30A6C /* TSKPinningValidatorCallback.h */, - 40C611421F18319000E30A6C /* TSKPinningValidatorResult.h */, - 40C611431F18319000E30A6C /* TSKPinningValidatorResult.m */, - 40C611441F18319000E30A6C /* TSKTrustDecision.h */, - 40C611451F18319000E30A6C /* TSKTrustKitConfig.h */, - 40C611461F18319000E30A6C /* TSKTrustKitConfig.m */, - ); - name = TrustKit; - path = vendor/TrustKit; - sourceTree = SOURCE_ROOT; - }; - 40C611251F18319000E30A6C /* Pinning */ = { - isa = PBXGroup; - children = ( - 40C611261F18319000E30A6C /* ssl_pin_verifier.h */, - 40C611271F18319000E30A6C /* ssl_pin_verifier.m */, - 40C611281F18319000E30A6C /* TSKPublicKeyAlgorithm.h */, - 40C611291F18319000E30A6C /* TSKSPKIHashCache.h */, - 40C6112A1F18319000E30A6C /* TSKSPKIHashCache.m */, - ); - path = Pinning; - sourceTree = ""; - }; - 40C6112B1F18319000E30A6C /* Reporting */ = { - isa = PBXGroup; - children = ( - 40C6112C1F18319000E30A6C /* reporting_utils.h */, - 40C6112D1F18319000E30A6C /* reporting_utils.m */, - 40C6112E1F18319000E30A6C /* TSKBackgroundReporter.h */, - 40C6112F1F18319000E30A6C /* TSKBackgroundReporter.m */, - 40C611301F18319000E30A6C /* TSKPinFailureReport.h */, - 40C611311F18319000E30A6C /* TSKPinFailureReport.m */, - 40C611321F18319000E30A6C /* TSKReportsRateLimiter.h */, - 40C611331F18319000E30A6C /* TSKReportsRateLimiter.m */, - 40C611341F18319000E30A6C /* vendor_identifier.h */, - 40C611351F18319000E30A6C /* vendor_identifier.m */, - ); - path = Reporting; - sourceTree = ""; - }; 40C9E2841EA5615900744FE7 /* Utilities */ = { isa = PBXGroup; children = ( + CF93A65C2244C01300BBA199 /* MMEPinningConfigurationProvider.h */, + CF93A65D2244C01300BBA199 /* MMEPinningConfigurationProvider.m */, + CF93A6572241EDD500BBA199 /* MMECertPin.h */, + CF93A6562241EDD500BBA199 /* MMECertPin.m */, 40AE585C1EA93B3A0046B437 /* MMECommonEventData.h */, 40AE585D1EA93B3A0046B437 /* MMECommonEventData.m */, 40F16C7F1F02DA9F00DF338D /* MMEDate.h */, @@ -597,8 +526,6 @@ 403835011F7AF145004205B9 /* MMEDependencyManager.m */, AC2C715C21124089004179E0 /* MMEDispatchManager.h */, AC2C715D2112408A004179E0 /* MMEDispatchManager.m */, - AC2C7166211376DA004179E0 /* MMEHashProvider.h */, - AC2C7167211376DA004179E0 /* MMEHashProvider.m */, AC61FA5A217A04CC008519F5 /* MMEMetrics.h */, AC61FA5B217A04CC008519F5 /* MMEMetrics.m */, 405172DB1EAFFA9400F8CDA1 /* MMENSURLSessionWrapper.h */, @@ -643,6 +570,33 @@ path = Reachability; sourceTree = ""; }; + 9C65A25B2256BB9A006E3FED /* Certs */ = { + isa = PBXGroup; + children = ( + 9C65A25E2256BBB2006E3FED /* MMETestCARoot.cer */, + 9C65A25D2256BBB2006E3FED /* MMETestCABranch.cer */, + 9C65A25C2256BBB2006E3FED /* MMETestCALeaf.cer */, + ); + name = Certs; + sourceTree = ""; + }; + 9C65A2672256C110006E3FED /* MMETestHost */ = { + isa = PBXGroup; + children = ( + 9C65A27C2256C175006E3FED /* MMETestHost.entitlements */, + 9C65A2682256C110006E3FED /* AppDelegate.h */, + 9C65A2692256C110006E3FED /* AppDelegate.m */, + 9C65A26B2256C110006E3FED /* ViewController.h */, + 9C65A26C2256C110006E3FED /* ViewController.m */, + 9C65A26E2256C110006E3FED /* Main.storyboard */, + 9C65A2712256C112006E3FED /* Assets.xcassets */, + 9C65A2732256C112006E3FED /* LaunchScreen.storyboard */, + 9C65A2762256C112006E3FED /* Info.plist */, + 9C65A2772256C112006E3FED /* main.m */, + ); + path = MMETestHost; + sourceTree = ""; + }; 9C6D9882221F37A200679292 /* Packaging */ = { isa = PBXGroup; children = ( @@ -664,54 +618,36 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 40C611881F18319000E30A6C /* TSKPinningValidatorResult.h in Headers */, - 40C611821F18319000E30A6C /* TSKLog.h in Headers */, 404807CA1EA186D8008A6D50 /* MapboxMobileEvents.h in Headers */, - ACC8C1CE210FB00500C5055C /* MMETrustKitProvider.h in Headers */, 40C9E27F1EA5473F00744FE7 /* MMELocationManager.h in Headers */, 40F16C811F02DA9F00DF338D /* MMEDate.h in Headers */, + CF93A65E2244C01300BBA199 /* MMEPinningConfigurationProvider.h in Headers */, 40AE584E1EA926710046B437 /* MMETypes.h in Headers */, 40F133541F20051E007B4096 /* NSData+MMEGZIP.h in Headers */, 40AE58431EA6C86C0046B437 /* MMEUIApplicationWrapper.h in Headers */, - 40C611871F18319000E30A6C /* TSKPinningValidatorCallback.h in Headers */, - 40C611471F18319000E30A6C /* configuration_utils.h in Headers */, 40AE585A1EA9373F0046B437 /* MMEUniqueIdentifier.h in Headers */, AC1B091122137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.h in Headers */, 409115351F16BCD200F4250B /* MMECategoryLoader.h in Headers */, 40AE58561EA932DB0046B437 /* MMEConstants.h in Headers */, - AC2C7168211376DA004179E0 /* MMEHashProvider.h in Headers */, 40AE585E1EA93B3A0046B437 /* MMECommonEventData.h in Headers */, AC61FA5C217A04CC008519F5 /* MMEMetrics.h in Headers */, 40FB437C1EFAFAE900EC5BC0 /* MMETimerManager.h in Headers */, AC2C715E2112408A004179E0 /* MMEDispatchManager.h in Headers */, 96AB510A2164178900A261B8 /* MMEConfigurator.h in Headers */, - 40C6118C1F18319000E30A6C /* TSKTrustKitConfig.h in Headers */, + CF93A65B2241EDD500BBA199 /* MMECertPin.h in Headers */, AC611F271FCDED2F00ABBF6D /* MMEEventLogReportViewController.h in Headers */, 4036EFBE1ED37D56009C40BA /* MMEEventLogger.h in Headers */, 40AE58711EAA87960046B437 /* MMEAPIClient.h in Headers */, 405172DD1EAFFA9400F8CDA1 /* MMENSURLSessionWrapper.h in Headers */, 40FB43771EF9EA7800EC5BC0 /* MMEEventsConfiguration.h in Headers */, - 40C6116D1F18319000E30A6C /* TSKBackgroundReporter.h in Headers */, - 40C611761F18319000E30A6C /* vendor_identifier.h in Headers */, - 40C611661F18319000E30A6C /* TSKPublicKeyAlgorithm.h in Headers */, 40AE58691EA953970046B437 /* CLLocation+MMEMobileEvents.h in Headers */, - 40C6118B1F18319000E30A6C /* TSKTrustDecision.h in Headers */, - 40C611601F18319000E30A6C /* parse_configuration.h in Headers */, - 40C6116A1F18319000E30A6C /* reporting_utils.h in Headers */, 403835021F7AF145004205B9 /* MMEDependencyManager.h in Headers */, 40AE586D1EA95EDD0046B437 /* MMEEvent.h in Headers */, AC86FE1D2169250000D1B89C /* MMEMetricsManager.h in Headers */, - 40C611631F18319000E30A6C /* ssl_pin_verifier.h in Headers */, - 40C6117F1F18319000E30A6C /* TrustKit.h in Headers */, ACE4F01A1FD6102100035880 /* MMEUINavigation.h in Headers */, - 40C611701F18319000E30A6C /* TSKPinFailureReport.h in Headers */, 40834B9F1FDF62C900C1BD0D /* MMENamespacedDependencies.h in Headers */, - 40C611861F18319000E30A6C /* TSKPinningValidator_Private.h in Headers */, - 40C611831F18319000E30A6C /* TSKPinningValidator.h in Headers */, 40C9E27B1EA542BC00744FE7 /* MMEEventsManager.h in Headers */, - 40C611731F18319000E30A6C /* TSKReportsRateLimiter.h in Headers */, 40F16C961F04514100DF338D /* MMEReachability.h in Headers */, - 40C611671F18319000E30A6C /* TSKSPKIHashCache.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -748,6 +684,7 @@ buildRules = ( ); dependencies = ( + 9C65A27E2256C1C4006E3FED /* PBXTargetDependency */, 404807C51EA186D8008A6D50 /* PBXTargetDependency */, ); name = MapboxMobileEventsTests; @@ -790,6 +727,25 @@ productReference = 4085966F1ED08FF7003BD29D /* resources.bundle */; productType = "com.apple.product-type.bundle"; }; + 9C65A2652256C110006E3FED /* MMETestHost */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9C65A2792256C112006E3FED /* Build configuration list for PBXNativeTarget "MMETestHost" */; + buildPhases = ( + 9C65A2622256C110006E3FED /* Sources */, + 9C65A2632256C110006E3FED /* Frameworks */, + 9C65A2642256C110006E3FED /* Resources */, + 9C65A2832256C1CF006E3FED /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 9C65A2822256C1CF006E3FED /* PBXTargetDependency */, + ); + name = MMETestHost; + productName = MMETestHost; + productReference = 9C65A2662256C110006E3FED /* MMETestHost.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -801,12 +757,14 @@ TargetAttributes = { 404807B81EA186D8008A6D50 = { CreatedOnToolsVersion = 8.3.1; + DevelopmentTeam = GJZR2MEM28; ProvisioningStyle = Manual; }; 404807C11EA186D8008A6D50 = { CreatedOnToolsVersion = 8.3.1; - DevelopmentTeam = 8G8GJ5WNL6; + DevelopmentTeam = GJZR2MEM28; ProvisioningStyle = Automatic; + TestTargetID = 9C65A2652256C110006E3FED; }; 408596521ED084C0003BD29D = { CreatedOnToolsVersion = 8.3.2; @@ -820,6 +778,16 @@ CreatedOnToolsVersion = 10.1; ProvisioningStyle = Automatic; }; + 9C65A2652256C110006E3FED = { + CreatedOnToolsVersion = 10.2; + DevelopmentTeam = GJZR2MEM28; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Keychain = { + enabled = 1; + }; + }; + }; }; }; buildConfigurationList = 404807B31EA186D8008A6D50 /* Build configuration list for PBXProject "MapboxMobileEvents" */; @@ -827,7 +795,9 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, + Base, ); mainGroup = 404807AF1EA186D8008A6D50; productRefGroup = 404807BA1EA186D8008A6D50 /* Products */; @@ -839,6 +809,7 @@ 408596521ED084C0003BD29D /* MapboxMobileEventsStatic */, 404807C11EA186D8008A6D50 /* MapboxMobileEventsTests */, 4085966E1ED08FF7003BD29D /* resources */, + 9C65A2652256C110006E3FED /* MMETestHost */, ); }; /* End PBXProject section */ @@ -855,6 +826,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9C65A25F2256BC55006E3FED /* MMETestCARoot.cer in Resources */, + 9C65A2602256BC55006E3FED /* MMETestCABranch.cer in Resources */, + 9C65A2612256BC55006E3FED /* MMETestCALeaf.cer in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -865,6 +839,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9C65A2642256C110006E3FED /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9C65A2752256C112006E3FED /* LaunchScreen.storyboard in Resources */, + 9C65A2722256C112006E3FED /* Assets.xcassets in Resources */, + 9C65A2702256C110006E3FED /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -880,7 +864,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks"; + shellScript = "/usr/local/bin/carthage copy-frameworks\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -889,45 +873,32 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 40C6118D1F18319000E30A6C /* TSKTrustKitConfig.m in Sources */, - 40C611741F18319000E30A6C /* TSKReportsRateLimiter.m in Sources */, AC86FE1E2169250000D1B89C /* MMEMetricsManager.m in Sources */, ACE4F01B1FD6102100035880 /* MMEUINavigation.m in Sources */, - 40C611481F18319000E30A6C /* configuration_utils.m in Sources */, - 40C6116B1F18319000E30A6C /* reporting_utils.m in Sources */, 409115361F16BCD200F4250B /* MMECategoryLoader.m in Sources */, - 40C6116E1F18319000E30A6C /* TSKBackgroundReporter.m in Sources */, 40F16C821F02DA9F00DF338D /* MMEDate.m in Sources */, - 40C611801F18319000E30A6C /* TrustKit.m in Sources */, AC2C715F2112408A004179E0 /* MMEDispatchManager.m in Sources */, 40C9E27C1EA542BC00744FE7 /* MMEEventsManager.m in Sources */, 40AE58571EA932DB0046B437 /* MMEConstants.m in Sources */, AC61FA5D217A04CC008519F5 /* MMEMetrics.m in Sources */, 40AE586A1EA953970046B437 /* CLLocation+MMEMobileEvents.m in Sources */, - ACC8C1CC210FAFF400C5055C /* MMETrustKitProvider.m in Sources */, 40AE58441EA6C86C0046B437 /* MMEUIApplicationWrapper.m in Sources */, 4036EFBF1ED37D56009C40BA /* MMEEventLogger.m in Sources */, - AC2C7169211376DA004179E0 /* MMEHashProvider.m in Sources */, AC1B091222137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.m in Sources */, + CF93A6582241EDD500BBA199 /* MMECertPin.m in Sources */, 40FB43781EF9EA7800EC5BC0 /* MMEEventsConfiguration.m in Sources */, - 40C611711F18319000E30A6C /* TSKPinFailureReport.m in Sources */, 40AE585F1EA93B3A0046B437 /* MMECommonEventData.m in Sources */, - 40C611611F18319000E30A6C /* parse_configuration.m in Sources */, - 40C611891F18319000E30A6C /* TSKPinningValidatorResult.m in Sources */, + CF93A65F2244C01300BBA199 /* MMEPinningConfigurationProvider.m in Sources */, 40F133531F20051E007B4096 /* NSData+MMEGZIP.m in Sources */, 40FB437D1EFAFAE900EC5BC0 /* MMETimerManager.m in Sources */, 403835031F7AF145004205B9 /* MMEDependencyManager.m in Sources */, 40AE58721EAA87960046B437 /* MMEAPIClient.m in Sources */, - 40C611681F18319000E30A6C /* TSKSPKIHashCache.m in Sources */, 40F16C971F04514100DF338D /* MMEReachability.m in Sources */, 40C9E2801EA5473F00744FE7 /* MMELocationManager.m in Sources */, AC2C7163211241CC004179E0 /* MMEConfigurator.m in Sources */, - 40C611841F18319000E30A6C /* TSKPinningValidator.m in Sources */, AC611F281FCDED2F00ABBF6D /* MMEEventLogReportViewController.m in Sources */, - 40C611641F18319000E30A6C /* ssl_pin_verifier.m in Sources */, 405172DE1EAFFA9400F8CDA1 /* MMENSURLSessionWrapper.m in Sources */, 40AE586E1EA95EDD0046B437 /* MMEEvent.m in Sources */, - 40C611771F18319000E30A6C /* vendor_identifier.m in Sources */, 40AE585B1EA9373F0046B437 /* MMEUniqueIdentifier.m in Sources */, 40AE584F1EA926710046B437 /* MMETypes.m in Sources */, ); @@ -940,12 +911,13 @@ 40031E5E1EFC5CA1009EAB33 /* MMEUniqueIdentifierFake.m in Sources */, ACB6F21E1F7BF71B0032A916 /* MMELocationManagerTests.mm in Sources */, AC61FA09216BE7A0008519F5 /* MMEMetricsManager.mm in Sources */, - ACA65F38213591ED00537748 /* MMEHashProviderTests.mm in Sources */, 40AE58471EA6C9F10046B437 /* MMEUIApplicationWrapperFake.m in Sources */, 403834FF1F7AC55D004205B9 /* MMEDateTests.mm in Sources */, 40AE584B1EA80EA90046B437 /* MMETestStub.m in Sources */, 40FB43801EFAFDCF00EC5BC0 /* MMETimerManagerTests.m in Sources */, + CF93A66322488A4500BBA199 /* MMECertPinTests.mm in Sources */, 4036EFBB1ED36F06009C40BA /* MMEAPIClientFake.m in Sources */, + CF870EA22254A93200959A65 /* MMEAPIClientCertPinTests.mm in Sources */, ACA65F3B2135C67F00537748 /* MMEDispatchManagerFake.m in Sources */, 9C6D98A722371DA400679292 /* MMEEventsConfigurationTests.mm in Sources */, 4002E6361F83155E0090D724 /* MMEEventsManagerTests.mm in Sources */, @@ -963,15 +935,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 40C6118E1F18319000E30A6C /* TSKTrustKitConfig.m in Sources */, - 40C611751F18319000E30A6C /* TSKReportsRateLimiter.m in Sources */, - 40C611491F18319000E30A6C /* configuration_utils.m in Sources */, - 40C6116C1F18319000E30A6C /* reporting_utils.m in Sources */, 409115371F16BCD200F4250B /* MMECategoryLoader.m in Sources */, - 40C6116F1F18319000E30A6C /* TSKBackgroundReporter.m in Sources */, 40F16C831F02DA9F00DF338D /* MMEDate.m in Sources */, - 40C611811F18319000E30A6C /* TrustKit.m in Sources */, AC1B091322137BB000DB56C8 /* CLLocationManager+MMEMobileEvents.m in Sources */, + CF93A6592241EDD500BBA199 /* MMECertPin.m in Sources */, 408596601ED086DF003BD29D /* MMELocationManager.m in Sources */, 408596641ED086EB003BD29D /* MMEUIApplicationWrapper.m in Sources */, 4085965F1ED086DC003BD29D /* MMEEventsManager.m in Sources */, @@ -979,30 +946,22 @@ AC61FA5E217A04CC008519F5 /* MMEMetrics.m in Sources */, 4036EFC01ED38489009C40BA /* MMEEventLogger.m in Sources */, 40FB43791EF9EA7800EC5BC0 /* MMEEventsConfiguration.m in Sources */, - 40C611721F18319000E30A6C /* TSKPinFailureReport.m in Sources */, 4085965E1ED086D9003BD29D /* MMEEvent.m in Sources */, - 40C611621F18319000E30A6C /* parse_configuration.m in Sources */, - 40C6118A1F18319000E30A6C /* TSKPinningValidatorResult.m in Sources */, AC2C7165211241D0004179E0 /* MMEConfigurator.m in Sources */, 96AB510B21641A6000A261B8 /* MMEUINavigation.m in Sources */, 40F133551F200524007B4096 /* NSData+MMEGZIP.m in Sources */, 40FB437E1EFAFAE900EC5BC0 /* MMETimerManager.m in Sources */, 403835041F7AF150004205B9 /* MMEDependencyManager.m in Sources */, + CF93A6602244C01300BBA199 /* MMEPinningConfigurationProvider.m in Sources */, AC2C716021124099004179E0 /* MMEDispatchManager.m in Sources */, 408596661ED086F1003BD29D /* MMEUniqueIdentifier.m in Sources */, - 40C611691F18319000E30A6C /* TSKSPKIHashCache.m in Sources */, 40F16C981F04514100DF338D /* MMEReachability.m in Sources */, 4085965D1ED086D6003BD29D /* MMETypes.m in Sources */, - 40C611851F18319000E30A6C /* TSKPinningValidator.m in Sources */, - 40C611651F18319000E30A6C /* ssl_pin_verifier.m in Sources */, 408596691ED086FA003BD29D /* MMENSURLSessionWrapper.m in Sources */, - 96AB5108216416E800A261B8 /* MMETrustKitProvider.m in Sources */, 408596671ED086F4003BD29D /* MMECommonEventData.m in Sources */, AC86FE1F2169250000D1B89C /* MMEMetricsManager.m in Sources */, 408596631ED086E8003BD29D /* CLLocation+MMEMobileEvents.m in Sources */, - 40C611781F18319000E30A6C /* vendor_identifier.m in Sources */, 408596611ED086E2003BD29D /* MMEAPIClient.m in Sources */, - 96AB5106216416AE00A261B8 /* MMEHashProvider.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1013,6 +972,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9C65A2622256C110006E3FED /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9C65A26D2256C110006E3FED /* ViewController.m in Sources */, + 9C65A2782256C112006E3FED /* main.m in Sources */, + 9C65A26A2256C110006E3FED /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -1036,8 +1005,37 @@ target = 408596521ED084C0003BD29D /* MapboxMobileEventsStatic */; targetProxy = 9C63226C221377CD00653792 /* PBXContainerItemProxy */; }; + 9C65A27E2256C1C4006E3FED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9C65A2652256C110006E3FED /* MMETestHost */; + targetProxy = 9C65A27D2256C1C4006E3FED /* PBXContainerItemProxy */; + }; + 9C65A2822256C1CF006E3FED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 404807B81EA186D8008A6D50 /* MapboxMobileEvents */; + targetProxy = 9C65A2812256C1CF006E3FED /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ +/* Begin PBXVariantGroup section */ + 9C65A26E2256C110006E3FED /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9C65A26F2256C110006E3FED /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 9C65A2732256C112006E3FED /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9C65A2742256C112006E3FED /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ 404807CB1EA186D8008A6D50 /* Debug */ = { isa = XCBuildConfiguration; @@ -1161,9 +1159,9 @@ 404807CE1EA186D8008A6D50 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GJZR2MEM28; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1190,9 +1188,9 @@ 404807CF1EA186D8008A6D50 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GJZR2MEM28; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1219,7 +1217,7 @@ 404807D11EA186D8008A6D50 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = 8G8GJ5WNL6; + DEVELOPMENT_TEAM = GJZR2MEM28; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS", @@ -1234,13 +1232,14 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxMobileMetricsTests; PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MMETestHost.app/MMETestHost"; }; name = Debug; }; 404807D21EA186D8008A6D50 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = 8G8GJ5WNL6; + DEVELOPMENT_TEAM = GJZR2MEM28; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS", @@ -1255,6 +1254,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxMobileMetricsTests; PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MMETestHost.app/MMETestHost"; }; name = Release; }; @@ -1329,6 +1329,51 @@ }; name = Release; }; + 9C65A27A2256C112006E3FED /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = MMETestHost/MMETestHost.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = GJZR2MEM28; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MMETestHost/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MMETestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 9C65A27B2256C112006E3FED /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = MMETestHost/MMETestHost.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = GJZR2MEM28; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MMETestHost/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MMETestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1386,6 +1431,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 9C65A2792256C112006E3FED /* Build configuration list for PBXNativeTarget "MMETestHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9C65A27A2256C112006E3FED /* Debug */, + 9C65A27B2256C112006E3FED /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 404807B01EA186D8008A6D50 /* Project object */; diff --git a/MapboxMobileEvents/MMECertPin.h b/MapboxMobileEvents/MMECertPin.h new file mode 100644 index 00000000..7805ba77 --- /dev/null +++ b/MapboxMobileEvents/MMECertPin.h @@ -0,0 +1,15 @@ +#import + +@class MMEEventsConfiguration; + +NS_ASSUME_NONNULL_BEGIN + +@interface MMECertPin : NSObject + +- (void)updateWithConfiguration:(MMEEventsConfiguration *)configuration; + +- (void)handleChallenge:(NSURLAuthenticationChallenge * _Nonnull)challenge completionHandler:(void (^ _Nonnull)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MapboxMobileEvents/MMECertPin.m b/MapboxMobileEvents/MMECertPin.m new file mode 100644 index 00000000..e302ea99 --- /dev/null +++ b/MapboxMobileEvents/MMECertPin.m @@ -0,0 +1,300 @@ +#import + +#import "MMECertPin.h" +#import "MMEPinningConfigurationProvider.h" +#import "MMEEventsConfiguration.h" + +@interface MMECertPin() + +@property (nonatomic) MMEPinningConfigurationProvider *pinningConfigProvider; +@property (nonatomic) NSMutableSet *serverSSLPinsSet; +@property (nonatomic) NSMutableDictionary *publicKeyInfoHashesCache; +@property (nonatomic) NSMutableSet *excludeSubdomainsSet; +@property (nonatomic) NSURLSessionAuthChallengeDisposition lastAuthChanllengeDisposition; + +@property (nonatomic) dispatch_queue_t lockQueue; + +@end + +@implementation MMECertPin + +- (instancetype)init { + if (self = [super init]) { + _pinningConfigProvider = [MMEPinningConfigurationProvider pinningConfigProviderWithConfiguration:nil]; + _serverSSLPinsSet = [NSMutableSet set]; + _excludeSubdomainsSet = [NSMutableSet set]; + _publicKeyInfoHashesCache = [NSMutableDictionary dictionary]; + _lockQueue = dispatch_queue_create("MMECertHashLock", DISPATCH_QUEUE_CONCURRENT); + + [self updateSSLPinSet]; + } + + return self; +} + +- (void) updateSSLPinSet { + [self.serverSSLPinsSet removeAllObjects]; + [self.publicKeyInfoHashesCache removeAllObjects]; + + if ([self.pinningConfigProvider.pinningConfig.allKeys containsObject:kMMEPinnedDomains]) { + NSDictionary *configPinnedDomains = self.pinningConfigProvider.pinningConfig[kMMEPinnedDomains]; + + for (NSString *pinnedDomain in configPinnedDomains.allKeys) { + NSDictionary *pinnedDomainConfig = configPinnedDomains[pinnedDomain]; + + if ([pinnedDomainConfig.allKeys containsObject:kMMEPublicKeyHashes]) { + for (NSString *pinnedKeyHashBase64 in pinnedDomainConfig[kMMEPublicKeyHashes]) { + NSData *pinnedKeyHash = [[NSData alloc] initWithBase64EncodedString:pinnedKeyHashBase64 options:(NSDataBase64DecodingOptions)0]; + if ([pinnedKeyHash length] != CC_SHA256_DIGEST_LENGTH){ + // The subject public key info hash doesn't have a valid size + [NSException raise:@"Hash value invalid" format:@"Hash value invalid: %@", pinnedKeyHash]; + } + [_serverSSLPinsSet addObject:pinnedKeyHash]; + } + } + + if ([pinnedDomainConfig.allKeys containsObject:kMMEExcludeSubdomainFromParentPolicy] + && [pinnedDomainConfig[kMMEExcludeSubdomainFromParentPolicy] boolValue]) { + [_excludeSubdomainsSet addObject:pinnedDomain]; + } + } + } +} + +- (void) updateWithConfiguration:(MMEEventsConfiguration *)configuration { + if (configuration && configuration.blacklist && configuration.blacklist.count > 0) { + self.pinningConfigProvider = [MMEPinningConfigurationProvider pinningConfigProviderWithConfiguration:configuration]; + + [self updateSSLPinSet]; + } +} + +- (void) handleChallenge:(NSURLAuthenticationChallenge * _Nonnull)challenge completionHandler:(void (^ _Nonnull)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{ + + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + + //Domain should be excluded + for (NSString *excludeSubdomains in _excludeSubdomainsSet) { + if ([challenge.protectionSpace.host isEqualToString:excludeSubdomains]) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.lastAuthChanllengeDisposition = NSURLSessionAuthChallengePerformDefaultHandling; + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); + }); + return; + } + } + + SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; + SecTrustResultType trustResult; + + // Validate the certificate chain with the device's trust store anyway + // This *might* give use revocation checking + SecTrustEvaluate(serverTrust, &trustResult); + if (trustResult == kSecTrustResultUnspecified) { + // Look for a pinned certificate in the server's certificate chain + long numKeys = SecTrustGetCertificateCount(serverTrust); + + BOOL found = NO; + for (int lc = 0; lc < numKeys; lc++) { + SecCertificateRef remoteCertificate = SecTrustGetCertificateAtIndex(serverTrust, lc); + NSData *remoteCertificatePublicKeyHash = [self hashSubjectPublicKeyInfoFromCertificate:remoteCertificate]; + + if ([_serverSSLPinsSet containsObject:remoteCertificatePublicKeyHash]) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.lastAuthChanllengeDisposition = NSURLSessionAuthChallengeUseCredential; + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + }); + found = YES; + break; + } + } + + if (!found) { + // The certificate wasn't found. Cancel the connection. + dispatch_async(dispatch_get_main_queue(), ^{ + self.lastAuthChanllengeDisposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + }); + } + } + else if (trustResult == kSecTrustResultProceed) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.lastAuthChanllengeDisposition = NSURLSessionAuthChallengePerformDefaultHandling; + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + }); + } + else { + // Certificate chain validation failed; cancel the connection + dispatch_async(dispatch_get_main_queue(), ^{ + self.lastAuthChanllengeDisposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + }); + } + } + else { + dispatch_async(dispatch_get_main_queue(), ^{ + self.lastAuthChanllengeDisposition = NSURLSessionAuthChallengePerformDefaultHandling; + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); + }); + } + +} + +- (NSData *)hashSubjectPublicKeyInfoFromCertificate:(SecCertificateRef)certificate{ + __block NSData *cachedSubjectPublicKeyInfo; + + // Have we seen this certificate before? + NSData *certificateData = (__bridge_transfer NSData *)(SecCertificateCopyData(certificate)); + + __weak __typeof__(self) weakSelf = self; + dispatch_sync(_lockQueue, ^{ + __strong __typeof__(weakSelf) strongSelf = weakSelf; + cachedSubjectPublicKeyInfo = strongSelf.publicKeyInfoHashesCache[certificateData]; + }); + + if (cachedSubjectPublicKeyInfo) { + return cachedSubjectPublicKeyInfo; + } + + // We didn't have this certificate in the cache + // First extract the public key bytes + NSData *publicKeyData = [self getPublicKeyDataFromCertificate:certificate]; + if (publicKeyData == nil) { + return nil; + } + + // Generate a hash of the subject public key info + NSMutableData *subjectPublicKeyInfoHash = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; + CC_SHA256_CTX shaCtx; + CC_SHA256_Init(&shaCtx); + + // Add the missing ASN1 header for public keys to re-create the subject public key info + CC_SHA256_Update(&shaCtx, rsa2048Asn1Header, sizeof(rsa2048Asn1Header)); + + // Add the public key + CC_SHA256_Update(&shaCtx, [publicKeyData bytes], (unsigned int)[publicKeyData length]); + CC_SHA256_Final((unsigned char *)[subjectPublicKeyInfoHash bytes], &shaCtx); + + + // Store the hash in our memory cache + dispatch_barrier_sync(_lockQueue, ^{ + __strong __typeof__(weakSelf) strongSelf = weakSelf; + strongSelf.publicKeyInfoHashesCache[certificateData] = subjectPublicKeyInfoHash; + }); + + return subjectPublicKeyInfoHash; +} + +#pragma mark - Generate Public Key Hash + +static const NSString *kMMEKeychainPublicKeyTag = @"MMEKeychainPublicKeyTag"; // Used to add and find the public key in the Keychain + +// These are the ASN1 headers for the Subject Public Key Info section of a certificate +static const unsigned char rsa2048Asn1Header[] = { + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00 +}; + +- (NSData *)getPublicKeyDataFromCertificate:(SecCertificateRef)certificate{ + // ****** iOS ****** +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 100000 + // Base SDK is iOS 8 or 9 + return [self getPublicKeyDataFromCertificate_legacy_ios:certificate ]; +#else + // Base SDK is iOS 10+ - try to use the unified Security APIs if available + NSProcessInfo *processInfo = [NSProcessInfo processInfo]; + if ([processInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] + && [processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 0, 0}]) + { + // iOS 10+ + return [self getPublicKeyDataFromCertificate_unified:certificate]; + } + else + { + // iOS 8 or 9 + return [self getPublicKeyDataFromCertificate_legacy_ios:certificate]; + } +#endif +} + +- (NSData *)getPublicKeyDataFromCertificate_legacy_ios:(SecCertificateRef)certificate +{ + __block NSData *publicKeyData = nil; + __block OSStatus resultAdd, __block resultDel = noErr; + SecKeyRef publicKey; + SecTrustRef tempTrust; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + + // Get a public key reference from the certificate + SecTrustCreateWithCertificates(certificate, policy, &tempTrust); + SecTrustResultType result; + SecTrustEvaluate(tempTrust, &result); + publicKey = SecTrustCopyPublicKey(tempTrust); + CFRelease(policy); + CFRelease(tempTrust); + + + /// Extract the actual bytes from the key reference using the Keychain + // Prepare the dictionary to add the key + NSMutableDictionary *peerPublicKeyAdd = [[NSMutableDictionary alloc] init]; + peerPublicKeyAdd[(__bridge id)kSecClass] = (__bridge id)kSecClassKey; + peerPublicKeyAdd[(__bridge id)kSecAttrApplicationTag] = kMMEKeychainPublicKeyTag; + peerPublicKeyAdd[(__bridge id)kSecValueRef] = (__bridge id)publicKey; + + // Avoid issues with background fetching while the device is locked + peerPublicKeyAdd[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; + + // Request the key's data to be returned + peerPublicKeyAdd[(__bridge id)kSecReturnData] = @YES; + + // Prepare the dictionary to retrieve and delete the key + NSMutableDictionary * publicKeyGet = [[NSMutableDictionary alloc] init]; + publicKeyGet[(__bridge id)kSecClass] = (__bridge id)kSecClassKey; + publicKeyGet[(__bridge id)kSecAttrApplicationTag] = kMMEKeychainPublicKeyTag; + publicKeyGet[(__bridge id)kSecReturnData] = @YES; + + + // Get the key bytes from the Keychain atomically + dispatch_sync(dispatch_queue_create("MMEKeychainLock", DISPATCH_QUEUE_SERIAL), ^{ + resultAdd = SecItemAdd((__bridge CFDictionaryRef) peerPublicKeyAdd, (void *)&publicKeyData); + resultDel = SecItemDelete((__bridge CFDictionaryRef)publicKeyGet); + }); + + CFRelease(publicKey); + if ((resultAdd != errSecSuccess) || (resultDel != errSecSuccess)) + { + // Something went wrong with the Keychain we won't know if we did get the right key data + publicKeyData = nil; + } + + return publicKeyData; +} + +- (NSData *)getPublicKeyDataFromCertificate_unified:(SecCertificateRef)certificate +{ + // Create an X509 trust using the using the certificate + SecTrustRef trust; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustCreateWithCertificates(certificate, policy, &trust); + + // Get a public key reference for the certificate from the trust + SecTrustResultType result; + SecTrustEvaluate(trust, &result); + SecKeyRef publicKey = SecTrustCopyPublicKey(trust); + CFRelease(policy); + CFRelease(trust); + + // Obtain the public key bytes from the key reference + // Silencing the warning since there is no way to reach here unless we are on iOS 10.0+ + // (this would otherwise warn if compiled for an app supporting < 10.0) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpartial-availability" + CFDataRef publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL); +#pragma clang diagnostic pop + + CFRelease(publicKey); + + return (__bridge_transfer NSData *)publicKeyData; +} + +@end diff --git a/MapboxMobileEvents/MMEHashProvider.h b/MapboxMobileEvents/MMEHashProvider.h deleted file mode 100644 index 5824e15f..00000000 --- a/MapboxMobileEvents/MMEHashProvider.h +++ /dev/null @@ -1,11 +0,0 @@ -#import -#import "MMEEventsConfiguration.h" - -@interface MMEHashProvider : NSObject - -@property (nonatomic, readonly) NSArray *cnHashes; -@property (nonatomic, readonly) NSArray *comHashes; - -- (void)updateHashesWithConfiguration:(MMEEventsConfiguration *)configuration; - -@end diff --git a/MapboxMobileEvents/MMEHashProvider.m b/MapboxMobileEvents/MMEHashProvider.m deleted file mode 100644 index efb27471..00000000 --- a/MapboxMobileEvents/MMEHashProvider.m +++ /dev/null @@ -1,156 +0,0 @@ -#import "MMEHashProvider.h" - -@interface MMEHashProvider() - -@property (nonatomic, readwrite) NSArray *cnHashes; -@property (nonatomic, readwrite) NSArray *comHashes; - -@end - -@implementation MMEHashProvider - -- (instancetype)init { - self = [super init]; - if (self) { - _cnHashes = @[ - @"T4XyKSRwZ5icOqGmJUXiDYGa+SaXKTGQXZwhqpwNTEo=", - @"KlV7emqpeM6V2MtDEzSDzcIob6VwkdWHiVsNQQzTIeo=", - @"16TK3iq9ZB4AukmDemjUyhcPTUnsSuqd5OB5zOrheZY=", - @"F16cPFncMDkB4XbRfK64H1dqncNg6JOdd+w2qElR/hM=", - @"45PQwWtFAHQd/cVzMVuhkwOQwCF+JE4ZViA4gkzvWeQ=", - @"mCzfopN5vqaerktI/172w8T7qw2sfRXgUL4Z7xA2e/c=", - @"rFFCqIOOKu7KH1v73IHb6mzZQth7cVvVDaH+EjkNfKM=", - @"pZBpEiH9vLwSICbogdpgyGG3NCjVKw4oG2rEWRf03Vk=", - @"gPgpSOzaLjbIpDLlh302x2irQTzWfsQqIWhUsreMMzI=", - @"wLHqvUDDQfFymRVS2O6AF5nkuAY+KJZpI4+pohK+SUE=", - @"yAEZR9ydeTrMlcUp91PHdmJ3lBa86IWsKRwiM0KzS6Q=", - @"k3NZbP68SikfwacfWDm4s3YJDsPVWJSOF4GlCWo5RJA=", - @"1PRG2KOhfDE+xMS1fxft5CtQO99mzqhpl4gPz/64IxQ=", - @"FBibSsaWfYYIkij1x4Oc9Lt0jHl+6AhBTWAypcOphhc=", - @"X0K6GmWp00Pb0YATdlCPeXaZR/NxxHTv41OAEkymkbU=", - @"DU/+Q9Itbb4WuSfuTvOgPtxtF6eAbTH7pUFn17/o5E0=", - @"BYGHyEqtaJEZn+02i4jy4dGRRFNr6xckQjTL7DMZFes=", - @"zr1/pj8y4FUbrxIYRaHVZWvhsMPzDVW0R+ljPHrX5Sw=", - @"fS9IR9OWsirEnSAqParPG0BzZJ+Dk4CiHfPv1vEjrf0=", - @"f1B7KmHknBSXNjTC8ac/Hf7hwU2goerE53TJppr0OH0=", - @"OKbbVU/+cTlszrJkxKaQraFAoVyjPOqa5Uq8Ndd4AUg=", - @"I0xGZF5s9kGHJHz6nKN+nYJKwf8ev1MdWkGt7EI7A7g=", - @"anATIIIqUd4o7Asto7X7OEJ+m7YTUr0aJKHZXqL92w0=", - @"JXFJ+lQK4GwJpJlHSZ2ZAR5luZDwMdaa2hJyhqHc1L8=", - @"64k4IzkPceL/hQywCCvJLQds8FPMPwtclhFOR/taKAQ=", - @"c079Pt5XXCwSv+pROEF+YW5gRoyzJ248bPxVLrUYkHM=", - @"46ofOPUGR3SYcMB+MmXqowYKan/c18LBTV2sAk13WKc=", - @"4qwz7KaBHxEX+YxO8STVowTg2BxlOd98GNU5feRjdjU=", - @"hp54/fY89ziuBBp1zv3YaC8H9/G8/Xp97hdzRVdcqQ0=", - @"BliQkuPecuHEp3FN3r1HogAkmsLtZz3ZImqLSpJoJzs=", - @"GayCH1YATG/OS5h1bq79XRmcq/aqwoObu2OYfPN7vQc=", - @"fW6I4HEBwa1Pwi1dldkb+ljs4re5ZY2JbsCiCxCOCgI=", - @"GcqilfT04N2efVIWlzJWO04gdpwYC4sLnOx3TJIKA9E=", - @"+1CHLRDE6ehp61cm8+NDMvd32z0Qc4bgnZRLH0OjE94=", - @"4vJWNxtoMLAY35dbzKeDI+4IAFOW97WNkTWnNMtY5TA=", - @"1YjWX9tieIA1iGkJhm7UapH6PiwGViZBWrXA3UJUAWc=", - @"X+RKpA7gtptrZ9yI1C96Isw5RV8dQyx5z7I/xfCaBl8=", - @"hqFsdAuHVvjX3NuaUBVZao94V30SdXLAsG1O0ajgixw=", - @"wYl9ZFQd2LWKfjDuEQxo7S0CcrPkP9A3vb20fbHf1ZQ=", - @"Y3ax6OgoQkcStQZ2hrIAqMDbaEEwX6xZfMZEnVcn/4k=", - @"taSOM7qPorxZ64Whrl5ZiNCGlZqLrVPOIBwPr/Nkw6U=", - @"KB5X/PyAAiRc7W/NjUyd6xbDdibuOTWBJB2MqHHF/Ao=", - @"hRQ7yTW/P5l76uNNP3MXNgshlmcbDNHMtBxCbUtGAWE=", - @"AoclhkrtKF+qHKKq0wUS4oXLwlJtWlywtiLndnNzS2U=", - @"5ikvGB5KkNlwesHRqjYvkZGlxP6OLMbaCkpflTM4DNM=", - @"qK2GksTrZ7LXDBkNWH6FnuNGxgxPpwNSK+NgknU7H1U=", - @"K3qyQniCBiGmfutYDE7ryDY2YoTORgp4DOgK1laOqfo=", - @"B7quINbFSUen02LQ9kwtYXnsJtixTpKafzXFkcRb7RU=", - @"Kc7lrHTlRfLaeRaEof6mKKmBH2eYHMYkxOy3yGlzUWg=", - @"7s1BUHi/AW/beA2jXamNTUgbDMH4gVPR9diIhnN1o0Q=", - //Digicert, 2018, SHA1 Fingerprint=5F:AB:D8:86:2E:7D:8D:F3:57:6B:D8:F2:F4:57:7B:71:41:90:E3:96 - @"3coVlMAEAYhOEJHgXwloiPDGaF+ZfxHZbVoK8AYYWVg=", - //Digicert, 2018, SHA1 Fingerprint=1F:B8:6B:11:68:EC:74:31:54:06:2E:8C:9C:C5:B1:71:A4:B7:CC:B4 - @"5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=", - //GeoTrust, 2018, SHA1 Fingerprint=57:46:0E:82:B0:3F:E7:2C:AE:AC:CA:AF:2B:1D:DA:25:B4:B3:8A:4A - @"+O+QJCmvoB/FkTd0/5FvmMSvFbMqjYU+Txrw1lyGkUQ=", - //GeoTrust, 2018, SHA1 Fingerprint=7C:CC:2A:87:E3:94:9F:20:57:2B:18:48:29:80:50:5F:A9:0C:AC:3B - @"zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=", - ]; - - _comHashes = @[ - @"6+ErFga5JfYfvwx2JbEJJNmUXJFnXIKllrbPKmvWqNc=", - @"vLkrnr8JTAVaYPwY/jBkKCe+YQWleaHPU3Tlqom+gCg=", - @"UofZo86l1bDjTiHyKXurqgfkYaYjtjyTrOYYR68XLG8=", - @"wSE/ahOwDVj7tMLMOjoAr1gIoBoWrUhQOBliQ82/bGk=", - @"RKHNDCiwHVTR5vKksBOcpfaojpsfCMFQ9MAE01ac8Tk=", - @"enUlaLivnHjrJBFVcvr8gwVTVcjXWOv8n96jU5towo8=", - @"Cul962ner+uZmwBQybZi0CHlFiZ3uFnZJe/lKqnqL6k=", - @"WswAtgVhFf6bIpavbiBL2GOP+e/zWqnECQrK17qKOLU=", - @"O+4Y2hugHTXgiaf6s2Zt4Vc7M3l3lLLu+6ugYGLI1x0=", - @"tfeXXd8OZXRbuZgeOanQAsgQlgdh4GBIIyCDvULtwLA=", - @"A+vWP93KGIMHeADZtj9S/mSIQtvzGz5G671aRKf3NlY=", - @"malXG7/2Qay6uSfQxLGm2Lob8MVjSPkzNrtdnwpHhuA=", - @"zfBsiWe9eHeGevBcYtrGiPQ0zCr2IvB08S7ESSWqVN8=", - @"o8bx+G1dysezoWAvOXBsl4/E6LcABFSqy6J8si5Cryk=", - @"YrsgZS2RzrUtunIndi031Ye/HyMn7WQQweav4xgR6qk=", - @"HQqyJQU7b+X/v1297LXK4TxKMwdC72Qzqy7Jx5W3LgA=", - @"00lmpHvG3dPLQ/hsewpHNLsK9vruPV+0hcQAl7FmRxI=", - @"lrmOBGfUptzfKOgSLUCKRvhfYNLH94x2ZKaX5ijBbTs=", - @"nf4V9/G5BE3bNy7TDkvqc7MaIkfcA625hjtQM7FJkcM=", - @"/0K/iJYfENe5o5arEhWfT7sailUd/QBY3ws0wD9dggU=", - @"SDnReAbazEH28n7pV5M/8A0M8ggJrO8/teE7oCJ7OGU=", - @"gruIKpo+vo5XKJ8t6yoPeNrpjWSsdnyaxkSLe/vSz2U=", - @"a4CTRze+fw6iUhnKA7Ph2Qt41eco42RBFcHITnYcNoY=", - @"8wc+3VCcufdq1JzdsxtaleFLA/u/peBtjfdPOeFKsIo=", - @"a5foMaNKMbLYMnB079u3G2oxhSRSHilwljENMsBiQwE=", - @"r1t+lUCzuncTnfM/QtclWIA7zhN8AYYUWlIimDhI0HM=", - @"dFS5RaEoQf7naXnfYnP1AuQMxyJwygHAXRG4bOZD6OM=", - @"zSAUiJZbnZdUu2bKUNf21r7RXJPzHGuMFxwPx7aLhfg=", - @"UmlVTDcbkUR075i+thE9Q1fOxPIGn8PmQ51R+XL4fK8=", - @"Zx+aoQE1cmiSN1TwvCo1Qpvuwjbq35eH4DsmkXKacIo=", - @"TAOftRoKGrOsFjgCtUzHswja6MykOf9UZaoljB6TYso=", - @"tW+psPLgOjPSsSMZPxc/PDGw0vBIpIZz32av4NEzVjc=", - @"35zTxuHmPcNqJ5OSW02V+9ghV3TJYmBI3arMTuC1z9w=", - @"ciiuiChtsyaTUEkDZ/N1KJaAgr4bIAIM13R0B9NVt6M=", - @"cwUwdyqZ6YOMWX5zcJcYarQ5okvMLxj/Rd4dUpkRFHM=", - @"tShTLeS4OltlKlE3MQUvXlJsGrCFgFo/nXvl5t0qba8=", - @"qy6BTLAetvqNOFfT/M3pZSRo9FRaF8KudDGgHy8Fxis=", - @"AOOutVCG4tDUsn13XyTAsx3cTZtIGajdCxSJoGZ+jp4=", - @"0LqMhNP7UHpAVl6+ON7AzsqeMWZb1ElB5AL0kPS6ktI=", - @"Zqng4S5spV0NeKT8MrE8CJFMBTP188PG9iEi7/9HDyo=", - @"i/4rsupujT8Ww/2yIGJ3wb6R7GDw2FHPyOM5sWh87DQ=", - @"cvlddgcP0XDOIKnCr+h+2zy2Tt8pnCPdw1l+PiEyS5o=", - @"UhpcxVytZbC4dx2Dnjjg6k02Ylf5jLo3C3AxchaKhh0=", - @"ZJfLxFuRg/1giSVrnj6aZmU5T//PP2eU7NLXXeqdH7s=", - @"ZnL4xB/aLV5W0YSZVefBRZSRTeoLzjJkk7CBvz75/m8=", - @"d4GNs3j9rUym4ogDTWX7AXTaI3K3gt46S2tvL6Hh/bQ=", - @"R9Wa2ON8VRWRF5OyDDaSDMhf7ysK1ykV1XSq20RMDFM=", - @"QMMBDJh3g1QgkGV6m+T4i2weBGj/W2+fVG73slK3mJE=", - @"ENU8M1yItdL5EP0G+I4hz4iuGlAUIHWCe4ipwXB/c/A=", - @"PA1lecwXNRXY/Vpy0VN+jQEYChN4hCAF36oB0Ygx3wQ=", - // Digicert, 2016, SHA1 Fingerprint=0A:80:27:6E:1C:A6:5D:ED:1D:C2:24:E7:7D:0C:A7:24:0B:51:C8:54 - @"Tb0uHZ/KQjWh8N9+CZFLc4zx36LONQ55l6laDi1qtT4=", - // Digicert, 2017, SHA1 Fingerprint=E2:8E:94:45:E0:B7:2F:28:62:D3:82:70:1F:C9:62:17:F2:9D:78:68 - @"yGp2XoimPmIK24X3bNV1IaK+HqvbGEgqar5nauDdC5E=", - // Geotrust, 2016, SHA1 Fingerprint=1A:62:1C:B8:1F:05:DD:02:A9:24:77:94:6C:B4:1B:53:BF:1D:73:6C - @"BhynraKizavqoC5U26qgYuxLZst6pCu9J5stfL6RSYY=", - // Geotrust, 2017, SHA1 Fingerprint=20:CE:AB:72:3C:51:08:B2:8A:AA:AB:B9:EE:9A:9B:E8:FD:C5:7C:F6 - @"yJLOJQLNTPNSOh3Btyg9UA1icIoZZssWzG0UmVEJFfA=", - ]; - } - return self; -} - -- (void)updateHashesWithConfiguration:(MMEEventsConfiguration *)configuration { - if (configuration.blacklist.count > 0) { - NSMutableArray *cnHashesMutable = [NSMutableArray arrayWithArray:self.cnHashes]; - [cnHashesMutable removeObjectsInArray:configuration.blacklist]; - self.cnHashes = [cnHashesMutable copy]; - - NSMutableArray *comHashesMutable = [NSMutableArray arrayWithArray:self.comHashes]; - [comHashesMutable removeObjectsInArray:configuration.blacklist]; - self.comHashes = [comHashesMutable copy]; - } -} - - - - - -@end diff --git a/MapboxMobileEvents/MMENSURLSessionWrapper.m b/MapboxMobileEvents/MMENSURLSessionWrapper.m index 9f684b9a..37d83123 100644 --- a/MapboxMobileEvents/MMENSURLSessionWrapper.m +++ b/MapboxMobileEvents/MMENSURLSessionWrapper.m @@ -1,13 +1,12 @@ #import "MMENSURLSessionWrapper.h" -#import "MMETrustKitProvider.h" -#import "TrustKit.h" +#import "MMECertPin.h" @interface MMENSURLSessionWrapper () @property (nonatomic) NSURLSession *session; @property (nonatomic) dispatch_queue_t serialQueue; -@property (nonatomic) TrustKit *trustKit; +@property (nonatomic) MMECertPin *certPin; @end @@ -18,13 +17,13 @@ - (instancetype)init { if (self) { _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil]; _serialQueue = dispatch_queue_create([[NSString stringWithFormat:@"%@.events.serial", NSStringFromClass([self class])] UTF8String], DISPATCH_QUEUE_SERIAL); - _trustKit = [MMETrustKitProvider trustKitWithUpdatedConfiguration:nil]; + _certPin = [[MMECertPin alloc]init]; } return self; } - (void)reconfigure:(MMEEventsConfiguration *)configuration { - self.trustKit = [MMETrustKitProvider trustKitWithUpdatedConfiguration:configuration]; + [self.certPin updateWithConfiguration:configuration]; } #pragma mark MMENSURLSessionWrapper @@ -45,36 +44,11 @@ - (void)processRequest:(NSURLRequest *)request completionHandler:(void (^)(NSDat #pragma mark NSURLSessionDelegate -- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { - __block void (^completion)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable) = nil; - - completion = ^(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential){ - dispatch_async(dispatch_get_main_queue(), ^{ - if (completionHandler) { - completionHandler(disposition, credential); - } - completion = nil; - }); - }; - - // From SecTrustEvaluate docs: - /* - This function will completely evaluate trust before returning, - possibly including network access to fetch intermediate certificates or to - perform revocation checking. Since this function can block during those - operations, you should call it from within a function that is placed on a - dispatch queue, or in a separate thread from your application's main - run loop. Alternatively, you can use the SecTrustEvaluateAsync function. - */ +- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ __typeof__(self) strongSelf = weakSelf; - // Call into TrustKit here to do pinning validation - if (![strongSelf.trustKit.pinningValidator handleChallenge:challenge completionHandler:completion]) { - // TrustKit did not handle this challenge: perhaps it was not for server trust - // or the domain was not pinned. Fall back to the default behavior - completion(NSURLSessionAuthChallengePerformDefaultHandling, nil); - } + [strongSelf.certPin handleChallenge:challenge completionHandler:completionHandler]; }); } diff --git a/MapboxMobileEvents/MMEPinningConfigurationProvider.h b/MapboxMobileEvents/MMEPinningConfigurationProvider.h new file mode 100644 index 00000000..be96712f --- /dev/null +++ b/MapboxMobileEvents/MMEPinningConfigurationProvider.h @@ -0,0 +1,15 @@ +#import +#import "MMEEventsConfiguration.h" + + +FOUNDATION_EXPORT const NSString *kMMEPinnedDomains; +FOUNDATION_EXPORT const NSString *kMMEPublicKeyHashes; +FOUNDATION_EXPORT const NSString *kMMEExcludeSubdomainFromParentPolicy; + +@interface MMEPinningConfigurationProvider : NSObject + ++ (MMEPinningConfigurationProvider *)pinningConfigProviderWithConfiguration:(MMEEventsConfiguration *)configuration; + +@property (nonatomic, readonly) NSDictionary *pinningConfig; // Dictionary> + +@end diff --git a/MapboxMobileEvents/MMEPinningConfigurationProvider.m b/MapboxMobileEvents/MMEPinningConfigurationProvider.m new file mode 100644 index 00000000..8d687525 --- /dev/null +++ b/MapboxMobileEvents/MMEPinningConfigurationProvider.m @@ -0,0 +1,211 @@ +#import "MMEPinningConfigurationProvider.h" + +@interface MMEHashProvider : NSObject + +@property (nonatomic, readwrite) NSArray *comHashes; +@property (nonatomic, readwrite) NSArray *cnHashes; + +- (void)updateHashesWithConfiguration:(MMEEventsConfiguration *)configuration; + +@end + + +@implementation MMEHashProvider + +- (instancetype)init { + self = [super init]; + if (self) { + _cnHashes = @[ + @"T4XyKSRwZ5icOqGmJUXiDYGa+SaXKTGQXZwhqpwNTEo=", + @"KlV7emqpeM6V2MtDEzSDzcIob6VwkdWHiVsNQQzTIeo=", + @"16TK3iq9ZB4AukmDemjUyhcPTUnsSuqd5OB5zOrheZY=", + @"F16cPFncMDkB4XbRfK64H1dqncNg6JOdd+w2qElR/hM=", + @"45PQwWtFAHQd/cVzMVuhkwOQwCF+JE4ZViA4gkzvWeQ=", + @"mCzfopN5vqaerktI/172w8T7qw2sfRXgUL4Z7xA2e/c=", + @"rFFCqIOOKu7KH1v73IHb6mzZQth7cVvVDaH+EjkNfKM=", + @"pZBpEiH9vLwSICbogdpgyGG3NCjVKw4oG2rEWRf03Vk=", + @"gPgpSOzaLjbIpDLlh302x2irQTzWfsQqIWhUsreMMzI=", + @"wLHqvUDDQfFymRVS2O6AF5nkuAY+KJZpI4+pohK+SUE=", + @"yAEZR9ydeTrMlcUp91PHdmJ3lBa86IWsKRwiM0KzS6Q=", + @"k3NZbP68SikfwacfWDm4s3YJDsPVWJSOF4GlCWo5RJA=", + @"1PRG2KOhfDE+xMS1fxft5CtQO99mzqhpl4gPz/64IxQ=", + @"FBibSsaWfYYIkij1x4Oc9Lt0jHl+6AhBTWAypcOphhc=", + @"X0K6GmWp00Pb0YATdlCPeXaZR/NxxHTv41OAEkymkbU=", + @"DU/+Q9Itbb4WuSfuTvOgPtxtF6eAbTH7pUFn17/o5E0=", + @"BYGHyEqtaJEZn+02i4jy4dGRRFNr6xckQjTL7DMZFes=", + @"zr1/pj8y4FUbrxIYRaHVZWvhsMPzDVW0R+ljPHrX5Sw=", + @"fS9IR9OWsirEnSAqParPG0BzZJ+Dk4CiHfPv1vEjrf0=", + @"f1B7KmHknBSXNjTC8ac/Hf7hwU2goerE53TJppr0OH0=", + @"OKbbVU/+cTlszrJkxKaQraFAoVyjPOqa5Uq8Ndd4AUg=", + @"I0xGZF5s9kGHJHz6nKN+nYJKwf8ev1MdWkGt7EI7A7g=", + @"anATIIIqUd4o7Asto7X7OEJ+m7YTUr0aJKHZXqL92w0=", + @"JXFJ+lQK4GwJpJlHSZ2ZAR5luZDwMdaa2hJyhqHc1L8=", + @"64k4IzkPceL/hQywCCvJLQds8FPMPwtclhFOR/taKAQ=", + @"c079Pt5XXCwSv+pROEF+YW5gRoyzJ248bPxVLrUYkHM=", + @"46ofOPUGR3SYcMB+MmXqowYKan/c18LBTV2sAk13WKc=", + @"4qwz7KaBHxEX+YxO8STVowTg2BxlOd98GNU5feRjdjU=", + @"hp54/fY89ziuBBp1zv3YaC8H9/G8/Xp97hdzRVdcqQ0=", + @"BliQkuPecuHEp3FN3r1HogAkmsLtZz3ZImqLSpJoJzs=", + @"GayCH1YATG/OS5h1bq79XRmcq/aqwoObu2OYfPN7vQc=", + @"fW6I4HEBwa1Pwi1dldkb+ljs4re5ZY2JbsCiCxCOCgI=", + @"GcqilfT04N2efVIWlzJWO04gdpwYC4sLnOx3TJIKA9E=", + @"+1CHLRDE6ehp61cm8+NDMvd32z0Qc4bgnZRLH0OjE94=", + @"4vJWNxtoMLAY35dbzKeDI+4IAFOW97WNkTWnNMtY5TA=", + @"1YjWX9tieIA1iGkJhm7UapH6PiwGViZBWrXA3UJUAWc=", + @"X+RKpA7gtptrZ9yI1C96Isw5RV8dQyx5z7I/xfCaBl8=", + @"hqFsdAuHVvjX3NuaUBVZao94V30SdXLAsG1O0ajgixw=", + @"wYl9ZFQd2LWKfjDuEQxo7S0CcrPkP9A3vb20fbHf1ZQ=", + @"Y3ax6OgoQkcStQZ2hrIAqMDbaEEwX6xZfMZEnVcn/4k=", + @"taSOM7qPorxZ64Whrl5ZiNCGlZqLrVPOIBwPr/Nkw6U=", + @"KB5X/PyAAiRc7W/NjUyd6xbDdibuOTWBJB2MqHHF/Ao=", + @"hRQ7yTW/P5l76uNNP3MXNgshlmcbDNHMtBxCbUtGAWE=", + @"AoclhkrtKF+qHKKq0wUS4oXLwlJtWlywtiLndnNzS2U=", + @"5ikvGB5KkNlwesHRqjYvkZGlxP6OLMbaCkpflTM4DNM=", + @"qK2GksTrZ7LXDBkNWH6FnuNGxgxPpwNSK+NgknU7H1U=", + @"K3qyQniCBiGmfutYDE7ryDY2YoTORgp4DOgK1laOqfo=", + @"B7quINbFSUen02LQ9kwtYXnsJtixTpKafzXFkcRb7RU=", + @"Kc7lrHTlRfLaeRaEof6mKKmBH2eYHMYkxOy3yGlzUWg=", + @"7s1BUHi/AW/beA2jXamNTUgbDMH4gVPR9diIhnN1o0Q=", + //Digicert, 2018, SHA1 Fingerprint=5F:AB:D8:86:2E:7D:8D:F3:57:6B:D8:F2:F4:57:7B:71:41:90:E3:96 + @"3coVlMAEAYhOEJHgXwloiPDGaF+ZfxHZbVoK8AYYWVg=", + //Digicert, 2018, SHA1 Fingerprint=1F:B8:6B:11:68:EC:74:31:54:06:2E:8C:9C:C5:B1:71:A4:B7:CC:B4 + @"5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=", + //GeoTrust, 2018, SHA1 Fingerprint=57:46:0E:82:B0:3F:E7:2C:AE:AC:CA:AF:2B:1D:DA:25:B4:B3:8A:4A + @"+O+QJCmvoB/FkTd0/5FvmMSvFbMqjYU+Txrw1lyGkUQ=", + //GeoTrust, 2018, SHA1 Fingerprint=7C:CC:2A:87:E3:94:9F:20:57:2B:18:48:29:80:50:5F:A9:0C:AC:3B + @"zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=", + ]; + _comHashes = @[ + @"6+ErFga5JfYfvwx2JbEJJNmUXJFnXIKllrbPKmvWqNc=", + @"vLkrnr8JTAVaYPwY/jBkKCe+YQWleaHPU3Tlqom+gCg=", + @"UofZo86l1bDjTiHyKXurqgfkYaYjtjyTrOYYR68XLG8=", + @"wSE/ahOwDVj7tMLMOjoAr1gIoBoWrUhQOBliQ82/bGk=", + @"RKHNDCiwHVTR5vKksBOcpfaojpsfCMFQ9MAE01ac8Tk=", + @"enUlaLivnHjrJBFVcvr8gwVTVcjXWOv8n96jU5towo8=", + @"Cul962ner+uZmwBQybZi0CHlFiZ3uFnZJe/lKqnqL6k=", + @"WswAtgVhFf6bIpavbiBL2GOP+e/zWqnECQrK17qKOLU=", + @"O+4Y2hugHTXgiaf6s2Zt4Vc7M3l3lLLu+6ugYGLI1x0=", + @"tfeXXd8OZXRbuZgeOanQAsgQlgdh4GBIIyCDvULtwLA=", + @"A+vWP93KGIMHeADZtj9S/mSIQtvzGz5G671aRKf3NlY=", + @"malXG7/2Qay6uSfQxLGm2Lob8MVjSPkzNrtdnwpHhuA=", + @"zfBsiWe9eHeGevBcYtrGiPQ0zCr2IvB08S7ESSWqVN8=", + @"o8bx+G1dysezoWAvOXBsl4/E6LcABFSqy6J8si5Cryk=", + @"YrsgZS2RzrUtunIndi031Ye/HyMn7WQQweav4xgR6qk=", + @"HQqyJQU7b+X/v1297LXK4TxKMwdC72Qzqy7Jx5W3LgA=", + @"00lmpHvG3dPLQ/hsewpHNLsK9vruPV+0hcQAl7FmRxI=", + @"lrmOBGfUptzfKOgSLUCKRvhfYNLH94x2ZKaX5ijBbTs=", + @"nf4V9/G5BE3bNy7TDkvqc7MaIkfcA625hjtQM7FJkcM=", + @"/0K/iJYfENe5o5arEhWfT7sailUd/QBY3ws0wD9dggU=", + @"SDnReAbazEH28n7pV5M/8A0M8ggJrO8/teE7oCJ7OGU=", + @"gruIKpo+vo5XKJ8t6yoPeNrpjWSsdnyaxkSLe/vSz2U=", + @"a4CTRze+fw6iUhnKA7Ph2Qt41eco42RBFcHITnYcNoY=", + @"8wc+3VCcufdq1JzdsxtaleFLA/u/peBtjfdPOeFKsIo=", + @"a5foMaNKMbLYMnB079u3G2oxhSRSHilwljENMsBiQwE=", + @"r1t+lUCzuncTnfM/QtclWIA7zhN8AYYUWlIimDhI0HM=", + @"dFS5RaEoQf7naXnfYnP1AuQMxyJwygHAXRG4bOZD6OM=", + @"zSAUiJZbnZdUu2bKUNf21r7RXJPzHGuMFxwPx7aLhfg=", + @"UmlVTDcbkUR075i+thE9Q1fOxPIGn8PmQ51R+XL4fK8=", + @"Zx+aoQE1cmiSN1TwvCo1Qpvuwjbq35eH4DsmkXKacIo=", + @"TAOftRoKGrOsFjgCtUzHswja6MykOf9UZaoljB6TYso=", + @"tW+psPLgOjPSsSMZPxc/PDGw0vBIpIZz32av4NEzVjc=", + @"35zTxuHmPcNqJ5OSW02V+9ghV3TJYmBI3arMTuC1z9w=", + @"ciiuiChtsyaTUEkDZ/N1KJaAgr4bIAIM13R0B9NVt6M=", + @"cwUwdyqZ6YOMWX5zcJcYarQ5okvMLxj/Rd4dUpkRFHM=", + @"tShTLeS4OltlKlE3MQUvXlJsGrCFgFo/nXvl5t0qba8=", + @"qy6BTLAetvqNOFfT/M3pZSRo9FRaF8KudDGgHy8Fxis=", + @"AOOutVCG4tDUsn13XyTAsx3cTZtIGajdCxSJoGZ+jp4=", + @"0LqMhNP7UHpAVl6+ON7AzsqeMWZb1ElB5AL0kPS6ktI=", + @"Zqng4S5spV0NeKT8MrE8CJFMBTP188PG9iEi7/9HDyo=", + @"i/4rsupujT8Ww/2yIGJ3wb6R7GDw2FHPyOM5sWh87DQ=", + @"cvlddgcP0XDOIKnCr+h+2zy2Tt8pnCPdw1l+PiEyS5o=", + @"UhpcxVytZbC4dx2Dnjjg6k02Ylf5jLo3C3AxchaKhh0=", + @"ZJfLxFuRg/1giSVrnj6aZmU5T//PP2eU7NLXXeqdH7s=", + @"ZnL4xB/aLV5W0YSZVefBRZSRTeoLzjJkk7CBvz75/m8=", + @"d4GNs3j9rUym4ogDTWX7AXTaI3K3gt46S2tvL6Hh/bQ=", + @"R9Wa2ON8VRWRF5OyDDaSDMhf7ysK1ykV1XSq20RMDFM=", + @"QMMBDJh3g1QgkGV6m+T4i2weBGj/W2+fVG73slK3mJE=", + @"ENU8M1yItdL5EP0G+I4hz4iuGlAUIHWCe4ipwXB/c/A=", + @"PA1lecwXNRXY/Vpy0VN+jQEYChN4hCAF36oB0Ygx3wQ=", + // Digicert, 2016, SHA1 Fingerprint=0A:80:27:6E:1C:A6:5D:ED:1D:C2:24:E7:7D:0C:A7:24:0B:51:C8:54 + @"Tb0uHZ/KQjWh8N9+CZFLc4zx36LONQ55l6laDi1qtT4=", + // Digicert, 2017, SHA1 Fingerprint=E2:8E:94:45:E0:B7:2F:28:62:D3:82:70:1F:C9:62:17:F2:9D:78:68 + @"yGp2XoimPmIK24X3bNV1IaK+HqvbGEgqar5nauDdC5E=", + // Geotrust, 2016, SHA1 Fingerprint=1A:62:1C:B8:1F:05:DD:02:A9:24:77:94:6C:B4:1B:53:BF:1D:73:6C + @"BhynraKizavqoC5U26qgYuxLZst6pCu9J5stfL6RSYY=", + // Geotrust, 2017, SHA1 Fingerprint=20:CE:AB:72:3C:51:08:B2:8A:AA:AB:B9:EE:9A:9B:E8:FD:C5:7C:F6 + @"yJLOJQLNTPNSOh3Btyg9UA1icIoZZssWzG0UmVEJFfA=", + ]; + } + return self; +} + + +- (void)updateHashesWithConfiguration:(MMEEventsConfiguration *)configuration { + if (configuration.blacklist.count > 0) { + NSMutableArray *cnHashesMutable = [NSMutableArray arrayWithArray:self.cnHashes]; + [cnHashesMutable removeObjectsInArray:configuration.blacklist]; + self.cnHashes = [cnHashesMutable copy]; + + NSMutableArray *comHashesMutable = [NSMutableArray arrayWithArray:self.comHashes]; + [comHashesMutable removeObjectsInArray:configuration.blacklist]; + self.comHashes = [comHashesMutable copy]; + } +} + + +@end + + +const NSString *kMMEPinnedDomains = @"kMMEPinnedDomains"; +const NSString *kMMEPublicKeyHashes = @"kMMEPublicKeyHashes"; +const NSString *kMMEExcludeSubdomainFromParentPolicy = @"kMMEExcludeSubdomainFromParentPolicy"; + +@interface MMEPinningConfigurationProvider() + +@property (nonatomic, readwrite) NSDictionary *pinningConfig; +@property (nonatomic) MMEHashProvider *hashProvider; + +@end + +@implementation MMEPinningConfigurationProvider + ++ (MMEPinningConfigurationProvider *)pinningConfigProviderWithConfiguration:(MMEEventsConfiguration *)configuration { + MMEPinningConfigurationProvider *pinningConfigurationProvider = [[MMEPinningConfigurationProvider alloc]init]; + + if (configuration) { + [pinningConfigurationProvider.hashProvider updateHashesWithConfiguration:configuration]; + } + + pinningConfigurationProvider.pinningConfig = @{ + kMMEPinnedDomains: @{ + @"events.mapbox.com": @{ + kMMEPublicKeyHashes: pinningConfigurationProvider.hashProvider.comHashes + }, + @"events.mapbox.cn": @{ + kMMEPublicKeyHashes: pinningConfigurationProvider.hashProvider.cnHashes + }, + /* Staging */ + @"api-events-staging.tilestream.net": @{ + kMMEPublicKeyHashes: @[ + // Digicert, SHA1 Fingerprint=C6:1B:FE:8C:59:8F:29:F0:36:2E:88:BB:A2:CD:08:3B:F6:59:08:22 + @"3euxrJOrEZI15R4104UsiAkDqe007EPyZ6eTL/XxdAY=", + // Stub: TrustKit requires 2 hashes for every endpoint + @"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + ] + }, + @"api.mapbox.com": @{ + kMMEExcludeSubdomainFromParentPolicy: @(YES) + } + } + }; + return pinningConfigurationProvider; +} + +- (id) init { + if (self = [super init]) { + _hashProvider = [MMEHashProvider new]; + } + return self; +} + +@end diff --git a/MapboxMobileEvents/MMETrustKitProvider.h b/MapboxMobileEvents/MMETrustKitProvider.h deleted file mode 100644 index ccab8908..00000000 --- a/MapboxMobileEvents/MMETrustKitProvider.h +++ /dev/null @@ -1,10 +0,0 @@ -#import -#import "MMEEventsConfiguration.h" - -@class TrustKit; - -@interface MMETrustKitProvider : NSObject - -+ (TrustKit *)trustKitWithUpdatedConfiguration:(MMEEventsConfiguration *)configuration; - -@end diff --git a/MapboxMobileEvents/MMETrustKitProvider.m b/MapboxMobileEvents/MMETrustKitProvider.m deleted file mode 100644 index 462e0c61..00000000 --- a/MapboxMobileEvents/MMETrustKitProvider.m +++ /dev/null @@ -1,53 +0,0 @@ -#import "MMETrustKitProvider.h" -#import "MMEHashProvider.h" -#import "MMEEventLogger.h" -#import "TrustKit.h" - -@implementation MMETrustKitProvider - -+ (TrustKit *)trustKitWithUpdatedConfiguration:(MMEEventsConfiguration *)configuration { - - MMEHashProvider *hashProvider = [[MMEHashProvider alloc] init]; - if (configuration) { - [hashProvider updateHashesWithConfiguration:configuration]; - } - - NSDictionary *trustKitConfig = - @{ - kTSKSwizzleNetworkDelegates: @NO, - kTSKPinnedDomains: @{ - /* Production */ - @"events.mapbox.com" : @{ - kTSKEnforcePinning:@YES, - kTSKDisableDefaultReportUri:@YES, - kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048], - kTSKPublicKeyHashes : - hashProvider.comHashes - }, - @"events.mapbox.cn" : @{ - kTSKEnforcePinning:@YES, - kTSKDisableDefaultReportUri:@YES, - kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048], - kTSKPublicKeyHashes : - hashProvider.cnHashes - }, - /* Staging */ - @"api-events-staging.tilestream.net" : @{ - kTSKEnforcePinning:@YES, - kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048], - kTSKPublicKeyHashes : @[ - // Digicert, SHA1 Fingerprint=C6:1B:FE:8C:59:8F:29:F0:36:2E:88:BB:A2:CD:08:3B:F6:59:08:22 - @"3euxrJOrEZI15R4104UsiAkDqe007EPyZ6eTL/XxdAY=", - // Stub: TrustKit requires 2 hashes for every endpoint - @"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", - ] - }, - @"api.mapbox.com" : @{ - kTSKExcludeSubdomainFromParentPolicy: @YES - }, - } - }; - return [[TrustKit alloc] initWithConfiguration:trustKitConfig]; -} - -@end diff --git a/MapboxMobileEventsTests/MMEAPIClientCertPinTests.mm b/MapboxMobileEventsTests/MMEAPIClientCertPinTests.mm new file mode 100644 index 00000000..69dc5fc4 --- /dev/null +++ b/MapboxMobileEventsTests/MMEAPIClientCertPinTests.mm @@ -0,0 +1,93 @@ +#import + +#import "MMECertPin.h" +#import "MMEAPIClient.h" +#import "MMENSURLSessionWrapper.h" +#import "MMECommonEventData.h" +#import "MMEEvent.h" + +using namespace Cedar::Matchers; +using namespace Cedar::Doubles; + +/* + Note: + + We test certificate pinning logic with a real network request just because we cannot manually make a fake `NSURLAuthenticationChallenge` object. + + Once you want to create a fake `NSURLAuthenticationChallenge` object, the sub property `NSURLProtectionSpace` + protectionSpace, will return a nil `SecTrustRef` serverTrust forever. + + It seems that is not as same as Apple's documentation: + `Nil if the authenticationMethod is not NSURLAuthenticationMethodServerTrust`. + See: https://developer.apple.com/documentation/foundation/nsurlprotectionspace/1409926-servertrust?language=objc + + This is why we can't simulate this behavior. + + */ + +@interface MMECertPin (CertPinTest) + +@property (nonatomic) NSURLSessionAuthChallengeDisposition lastAuthChanllengeDisposition; + +@end + +#pragma mark - + +@interface MMENSURLSessionWrapper (CertPinTest) + +@property (nonatomic) MMECertPin *certPin; + +@end + +#pragma mark - + +@interface MMEAPIClient (CertPinTest) + +@property (nonatomic) id sessionWrapper; + +@end + +#pragma mark - + +SPEC_BEGIN(MMEAPIClientCertPinSpec) + +describe(@"MMEAPIClientCertPin", ^{ + + it(@"should testPostASingleEvent", ^{ + MMEAPIClient *apiClient = [[MMEAPIClient alloc] initWithAccessToken:@"access-token" + userAgentBase:@"user-agent-base" + hostSDKVersion:@"host-sdk-1"]; + + MMENSURLSessionWrapper *sessionWrapper = [[MMENSURLSessionWrapper alloc] init]; + apiClient.sessionWrapper = sessionWrapper; + + MMECommonEventData *commonEventData = [[MMECommonEventData alloc] init]; + commonEventData.vendorId = @"vendor-id"; + commonEventData.model = @"model"; + commonEventData.osVersion = @"1"; + commonEventData.scale = 42; + + MMEEvent *event = [MMEEvent locationEventWithAttributes:@{} instanceIdentifer:@"instance-id-1" commonEventData:commonEventData]; + + [apiClient postEvent:event completionHandler:^(NSError * _Nullable error) { + error should be_nil; + sessionWrapper.certPin.lastAuthChanllengeDisposition should equal(NSURLSessionAuthChallengeUseCredential); + }]; + }); + + it(@"should testGetConfigurationWithExcludedDomain", ^{ + MMEAPIClient *apiClient = [[MMEAPIClient alloc] initWithAccessToken:@"access-token" + userAgentBase:@"user-agent-base" + hostSDKVersion:@"host-sdk-1"];; + __block MMENSURLSessionWrapper *sessionWrapper = [[MMENSURLSessionWrapper alloc] init]; + apiClient.sessionWrapper = sessionWrapper; + + [apiClient getConfigurationWithCompletionHandler:^(NSError * _Nullable error, NSData * _Nullable data) { + error should be_nil; + sessionWrapper.certPin.lastAuthChanllengeDisposition should equal(NSURLSessionAuthChallengePerformDefaultHandling); + }]; + }); + +}); + +SPEC_END diff --git a/MapboxMobileEventsTests/MMEAPIClientTests.mm b/MapboxMobileEventsTests/MMEAPIClientTests.mm index 30d7b3fb..4d3d3a3d 100644 --- a/MapboxMobileEventsTests/MMEAPIClientTests.mm +++ b/MapboxMobileEventsTests/MMEAPIClientTests.mm @@ -1,13 +1,12 @@ #import #import -#import "TrustKit.h" #import "MMEAPIClient.h" #import "MMEConstants.h" #import "MMEEvent.h" #import "MMECommonEventData.h" -#import "MMETrustKitProvider.h" #import "MMENSURLSessionWrapperFake.h" #import "MMEAPIClientFake.h" +#import "MMECertPin.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; @@ -28,7 +27,7 @@ - (void)setupUserAgent; @interface MMENSURLSessionWrapper (MMEAPIClientTests) -@property (nonatomic) TrustKit *trustKit; +@property (nonatomic) MMECertPin *certPin; @end @@ -39,13 +38,11 @@ @interface MMENSURLSessionWrapper (MMEAPIClientTests) __block MMEAPIClient *apiClient; __block NSURLSessionAuthChallengeDisposition receivedDisposition; __block MMENSURLSessionWrapper *sessionWrapper; - __block TSKPinningValidator *pinningValidator; __block NSURLSession *urlSession; __block NSURLAuthenticationChallenge *challenge; id delegateFake = fake_for(@protocol(NSURLAuthenticationChallengeSender)); int64_t timeoutInNanoseconds = 1000000000; - NSURLSessionAuthChallengeDisposition expectedDefaultDisposition = NSURLSessionAuthChallengePerformDefaultHandling; beforeEach(^{ apiClient = [[MMEAPIClient alloc] initWithAccessToken:@"access-token" @@ -53,8 +50,6 @@ @interface MMENSURLSessionWrapper (MMEAPIClientTests) hostSDKVersion:@"host-sdk-1"]; sessionWrapper = (MMENSURLSessionWrapper *)apiClient.sessionWrapper; - pinningValidator = sessionWrapper.trustKit.pinningValidator; - spy_on(pinningValidator); NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; urlSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:sessionWrapper delegateQueue:nil]; @@ -78,8 +73,6 @@ @interface MMENSURLSessionWrapper (MMEAPIClientTests) context(@"when the pinning validator does not handle the challenge", ^{ beforeEach(^{ - pinningValidator stub_method(@selector(handleChallenge:completionHandler:)).and_return(NO); - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeoutInNanoseconds), dispatch_get_main_queue(), ^{ @@ -102,8 +95,8 @@ @interface MMENSURLSessionWrapper (MMEAPIClientTests) isMainThread should be_truthy; }); - it(@"should call the completion with the default disposition", ^{ - receivedDisposition should equal(expectedDefaultDisposition); + it(@"should call the completion with the cancel disposition", ^{ + receivedDisposition should equal(NSURLSessionAuthChallengeCancelAuthenticationChallenge); }); }); @@ -113,8 +106,6 @@ @interface MMENSURLSessionWrapper (MMEAPIClientTests) beforeEach(^{ - pinningValidator stub_method(@selector(handleChallenge:completionHandler:)).and_return(NO); - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeoutInNanoseconds), dispatch_get_main_queue(), ^{ @@ -140,7 +131,7 @@ @interface MMENSURLSessionWrapper (MMEAPIClientTests) }); it(@"should equal expected DefaultHandling disposition", ^{ - receivedDisposition should equal(expectedDefaultDisposition); + receivedDisposition should equal(NSURLSessionAuthChallengeCancelAuthenticationChallenge); }); }); }); diff --git a/MapboxMobileEventsTests/MMECertPinTests.mm b/MapboxMobileEventsTests/MMECertPinTests.mm new file mode 100644 index 00000000..726e8990 --- /dev/null +++ b/MapboxMobileEventsTests/MMECertPinTests.mm @@ -0,0 +1,99 @@ +#import +#import +#import + +#import "MMECertPin.h" +#import "MMEEventsConfiguration.h" +#import "MMEPinningConfigurationProvider.h" +#import "MMENSURLSessionWrapper.h" +#import "MMEAPIClientFake.h" + +using namespace Cedar::Matchers; +using namespace Cedar::Doubles; + +@interface MMENSURLSessionWrapper (MMECertPinTests) + +@property (nonatomic) MMECertPin *certPin; + +@end + +#pragma mark - + +@interface MMECertPin (Tests) + +@property (nonatomic) MMEPinningConfigurationProvider *pinningConfigProvider; + +- (NSData *)getPublicKeyDataFromCertificate_legacy_ios:(SecCertificateRef)certificate; + +@end + +#pragma mark - + +SPEC_BEGIN(MMECertPinSpec) + +describe(@"MMECertPin", ^{ + + __block MMENSURLSessionWrapper *sessionWrapper; + __block MMEEventsConfiguration *configuration; + __block NSArray *blacklistFake; + + beforeEach(^{ + configuration = [MMEEventsConfiguration configuration]; + sessionWrapper = [[MMENSURLSessionWrapper alloc] init]; + blacklistFake = [NSArray arrayWithObjects:@"i/4rsupujT8Ww/2yIGJ3wb6R7GDw2FHPyOM5sWh87DQ=", @"+1CHLRDE6ehp61cm8+NDMvd32z0Qc4bgnZRLH0OjE94=", nil]; + configuration.blacklist = blacklistFake; + }); + + it(@"should have china hash array with a count of 54", ^{ + NSArray *cnHashes = sessionWrapper.certPin.pinningConfigProvider.pinningConfig[kMMEPinnedDomains][@"events.mapbox.cn"][kMMEPublicKeyHashes]; + cnHashes.count should equal(54); + }); + + it(@"should have .com hash array with a count of 54", ^{ + NSArray *comHashes = sessionWrapper.certPin.pinningConfigProvider.pinningConfig[kMMEPinnedDomains][@"events.mapbox.com"][kMMEPublicKeyHashes]; + comHashes.count should equal(54); + }); + + describe(@"- updateHashesWithConfiguration", ^{ + beforeEach(^{ + [sessionWrapper reconfigure:configuration]; + }); + + context(@"when hashes have been updated", ^{ + + it(@"should remove blacklisted hashes from .cnHashes", ^{ + NSArray *cnHashes = sessionWrapper.certPin.pinningConfigProvider.pinningConfig[kMMEPinnedDomains][@"events.mapbox.cn"][kMMEPublicKeyHashes]; + cnHashes.count should equal(53); + }); + + it(@"should remove blacklisted hashes from .comHashes", ^{ + NSArray *comHashes = sessionWrapper.certPin.pinningConfigProvider.pinningConfig[kMMEPinnedDomains][@"events.mapbox.com"][kMMEPublicKeyHashes]; + comHashes.count should equal(53); + }); + }); + }); + + it(@"should support legacy ios devices", ^{ + NSString *testCARoot = @"MMETestCARoot"; + NSBundle *testsBundle = [NSBundle bundleForClass:MMEAPIClientFake.class]; + NSString *testCARootCertPath = [testsBundle pathForResource:testCARoot ofType:@"cer"]; + NSData *testCARootCertData = [NSData dataWithContentsOfFile:testCARootCertPath]; + SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)testCARootCertData); + + certificate should_not be_nil; + + // for get publicKeyData to work we need to put MMETestCARoot into the kehchain + NSDictionary *addQuery = @{ + (id)kSecValueRef: (__bridge id)certificate, + (id)kSecClass: (id)kSecClassCertificate, + (id)kSecAttrLabel: testCARoot + }; + + SecItemAdd((__bridge CFDictionaryRef)addQuery, NULL); + + NSData* publicKey = [sessionWrapper.certPin getPublicKeyDataFromCertificate_legacy_ios:certificate]; + publicKey should_not be_nil; + }); +}); + +SPEC_END diff --git a/MapboxMobileEventsTests/MMEDateTests.mm b/MapboxMobileEventsTests/MMEDateTests.mm index 3ecfada6..9d7d7589 100644 --- a/MapboxMobileEventsTests/MMEDateTests.mm +++ b/MapboxMobileEventsTests/MMEDateTests.mm @@ -128,7 +128,7 @@ }); }); - it(@"should write encoded data to a file", ^{ + it(@"should write encoded data to a file/read data and decode from a file", ^{ [NSKeyedArchiver archiveRootObject:now toFile:tempFile]; [NSFileManager.defaultManager fileExistsAtPath:tempFile] should be_truthy; diff --git a/MapboxMobileEventsTests/MMEHashProviderTests.mm b/MapboxMobileEventsTests/MMEHashProviderTests.mm deleted file mode 100644 index 398ece37..00000000 --- a/MapboxMobileEventsTests/MMEHashProviderTests.mm +++ /dev/null @@ -1,57 +0,0 @@ - -#import -#import -#import "MMEHashProvider.h" -#import "MMEEventsConfiguration.h" - -using namespace Cedar::Matchers; -using namespace Cedar::Doubles; - -@interface MMEHashProvider (Tests) - -@end - -SPEC_BEGIN(MMEHashProvederSpec) - -describe(@"MMEHashProvider", ^{ - - __block MMEHashProvider *hashProvider; - __block MMEEventsConfiguration *configuration; - __block NSArray *blacklistFake; - - beforeEach(^{ - configuration = [MMEEventsConfiguration configuration]; - hashProvider = [[MMEHashProvider alloc] init]; - - blacklistFake = [NSArray arrayWithObjects:@"i/4rsupujT8Ww/2yIGJ3wb6R7GDw2FHPyOM5sWh87DQ=", @"+1CHLRDE6ehp61cm8+NDMvd32z0Qc4bgnZRLH0OjE94=", nil]; - - configuration.blacklist = blacklistFake; - }); - - it(@"should have china hash array with a count of 54", ^{ - hashProvider.cnHashes.count should equal(54); - }); - - it(@"should have .com hash array with a count of 54", ^{ - hashProvider.comHashes.count should equal(54); - }); - - describe(@"- updateHashesWithConfiguration", ^{ - beforeEach(^{ - [hashProvider updateHashesWithConfiguration:configuration]; - }); - - context(@"when hashes have been updated", ^{ - - it(@"should remove blacklisted hashes from .cnHashes", ^{ - hashProvider.cnHashes.count should equal(53); - }); - - it(@"should remove blacklisted hashes from .comHashes", ^{ - hashProvider.comHashes.count should equal(53); - }); - }); - }); -}); - -SPEC_END diff --git a/MapboxMobileEventsTests/MMETestCABranch.cer b/MapboxMobileEventsTests/MMETestCABranch.cer new file mode 100644 index 00000000..1022ab1f Binary files /dev/null and b/MapboxMobileEventsTests/MMETestCABranch.cer differ diff --git a/MapboxMobileEventsTests/MMETestCALeaf.cer b/MapboxMobileEventsTests/MMETestCALeaf.cer new file mode 100644 index 00000000..17d79d26 Binary files /dev/null and b/MapboxMobileEventsTests/MMETestCALeaf.cer differ diff --git a/MapboxMobileEventsTests/MMETestCARoot.cer b/MapboxMobileEventsTests/MMETestCARoot.cer new file mode 100644 index 00000000..95002a02 Binary files /dev/null and b/MapboxMobileEventsTests/MMETestCARoot.cer differ diff --git a/vendor/TrustKit/Dependencies/README.md b/vendor/TrustKit/Dependencies/README.md deleted file mode 100755 index 8f86cdf4..00000000 --- a/vendor/TrustKit/Dependencies/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Dependencies needed for building TrustKit. - -* RSSwizzle: https://github.com/rabovik/RSSwizzle -* domain\_registry\_provider: https://github.com/nabla-c0d3/domain-registry-provider/ diff --git a/vendor/TrustKit/Pinning/TSKPublicKeyAlgorithm.h b/vendor/TrustKit/Pinning/TSKPublicKeyAlgorithm.h deleted file mode 100755 index f6c1d1d3..00000000 --- a/vendor/TrustKit/Pinning/TSKPublicKeyAlgorithm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - - TSKPublicKeyAlgorithm.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#ifndef TSKPublicKeyAlgorithm_h -#define TSKPublicKeyAlgorithm_h - -@import Foundation; - -// The internal enum we use for public key algorithms; not to be confused with the exported TSKSupportedAlgorithm -typedef NS_ENUM(NSInteger, TSKPublicKeyAlgorithm) -{ - // Some assumptions are made about this specific ordering in public_key_utils.m - TSKPublicKeyAlgorithmRsa2048 = 0, - TSKPublicKeyAlgorithmRsa4096 = 1, - TSKPublicKeyAlgorithmEcDsaSecp256r1 = 2, - TSKPublicKeyAlgorithmEcDsaSecp384r1 = 3, - - TSKPublicKeyAlgorithmLast = TSKPublicKeyAlgorithmEcDsaSecp384r1 -}; - -#endif /* TSKPublicKeyAlgorithm_h */ diff --git a/vendor/TrustKit/Pinning/TSKSPKIHashCache.h b/vendor/TrustKit/Pinning/TSKSPKIHashCache.h deleted file mode 100755 index 5ed19da2..00000000 --- a/vendor/TrustKit/Pinning/TSKSPKIHashCache.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - - TSKSPKIHashCache.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKPublicKeyAlgorithm.h" - -@import Foundation; -@import Security; - -NS_ASSUME_NONNULL_BEGIN - -// The identifier used for the default shared hash cache. Use this identifier -// in the TSKSPKIHashCache constructor to use the shared cache. -static NSString * const kTSKSPKISharedHashCacheIdentifier = @"spki-hash.cache"; - -// Each key is a raw certificate data (for easy lookup) and each value is the certificate's raw SPKI data -typedef NSMutableDictionary SPKICacheDictionnary; - -@interface TSKSPKIHashCache : NSObject - -- (instancetype)new NS_UNAVAILABLE; -- (instancetype)init NS_UNAVAILABLE; - -/** - Create a new cache of SPKI hashes. The identifier is required to ensure that multiple cache - instances do not attempt to use the same file on disk for persistence. If nil, persistence - will be disabled (not recommended). - - @param uniqueIdentifier A unique identifier that is stable across app launches/instance creation - @return An initialized hash cache. - */ -- (instancetype _Nullable)initWithIdentifier:(NSString * _Nullable)uniqueIdentifier NS_DESIGNATED_INITIALIZER; - -/** - Get a pin cache for the provided certificate and public key algorithm. The pins - are cached so subsequent calls will be faster than the initial call. - - @param certificate The certificate containing the public key that will be hashed - @param publicKeyAlgorithm The public algorithm to expect was used in this certificate - @return The hash of the public key assuming it used the provided algorithm or nil if the hash could not be generated - */ -- (NSData * _Nullable)hashSubjectPublicKeyInfoFromCertificate:(SecCertificateRef)certificate publicKeyAlgorithm:(TSKPublicKeyAlgorithm)publicKeyAlgorithm; - -@end - -NS_ASSUME_NONNULL_END diff --git a/vendor/TrustKit/Pinning/TSKSPKIHashCache.m b/vendor/TrustKit/Pinning/TSKSPKIHashCache.m deleted file mode 100755 index 2c0357be..00000000 --- a/vendor/TrustKit/Pinning/TSKSPKIHashCache.m +++ /dev/null @@ -1,443 +0,0 @@ -/* - - TSKSPKIHashCache.m - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKSPKIHashCache.h" -#import "../TSKLog.h" -#import - -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED <= 100000 -// Need to support iOS before 10.0 -// The one and only way to get a key's data in a buffer on iOS is to put it in the Keychain and then ask for the data back... -#define LEGACY_IOS_KEY_EXTRACTION 1 -#endif - -#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 -#define LEGACY_MACOS_KEY_EXTRACTION 1 -#endif - -#if TARGET_OS_WATCH || TARGET_OS_TV || (TARGET_OS_IOS &&__IPHONE_OS_VERSION_MAX_ALLOWED >= 100000) || (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101200) -#define UNIFIED_KEY_EXTRACTION 1 -#endif - -#pragma mark Missing ASN1 SPKI Headers - -// These are the ASN1 headers for the Subject Public Key Info section of a certificate -static const unsigned char rsa2048Asn1Header[] = { - 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00 -}; - -static const unsigned char rsa4096Asn1Header[] = { - 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00 -}; - -static const unsigned char ecDsaSecp256r1Asn1Header[] = { - 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, - 0x42, 0x00 -}; - -static const unsigned char ecDsaSecp384r1Asn1Header[] = { - 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00 -}; - -// Careful with the order... must match how TSKPublicKeyAlgorithm is defined -static const unsigned char *asn1HeaderBytes[4] = { - rsa2048Asn1Header, - rsa4096Asn1Header, - ecDsaSecp256r1Asn1Header, - ecDsaSecp384r1Asn1Header -}; - -static const unsigned int asn1HeaderSizes[4] = { - sizeof(rsa2048Asn1Header), - sizeof(rsa4096Asn1Header), - sizeof(ecDsaSecp256r1Asn1Header), - sizeof(ecDsaSecp384r1Asn1Header) -}; - -@interface TSKSPKIHashCache () - -// Dictionnary to cache SPKI hashes instead of having to compute them on every connection -// We store one cache dictionnary per TSKPublicKeyAlgorithm we support -@property (nonatomic) NSMutableDictionary *subjectPublicKeyInfoHashesCache; -@property (nonatomic) dispatch_queue_t lockQueue; -@property (nonatomic) NSString *spkiCacheFilename; - - -/** - Load the SPKI cache from the filesystem. This triggers blocking file I/O. - */ -- (NSMutableDictionary *)loadSPKICacheFromFileSystem; - -@end - -#if LEGACY_IOS_KEY_EXTRACTION - -static const NSString *kTSKKeychainPublicKeyTag = @"TSKKeychainPublicKeyTag"; // Used to add and find the public key in the Keychain - -@interface TSKSPKIHashCache () -@property (nonatomic) dispatch_queue_t keychainQueue; -@end - -@interface TSKSPKIHashCache (LegacyIos) -- (NSData *)getPublicKeyDataFromCertificate_legacy_ios:(SecCertificateRef)certificate; -@end -#endif - -#if LEGACY_MACOS_KEY_EXTRACTION -@interface TSKSPKIHashCache (LegacyMacOS) -- (NSData *)getPublicKeyDataFromCertificate_legacy_macos:(SecCertificateRef)certificate; -@end -#endif - -#if UNIFIED_KEY_EXTRACTION -@interface TSKSPKIHashCache (Unified) -- (NSData *)getPublicKeyDataFromCertificate_unified:(SecCertificateRef)certificate; -@end -#endif - -@implementation TSKSPKIHashCache - -- (instancetype)initWithIdentifier:(NSString *)uniqueIdentifier -{ - self = [super init]; - if (self) { - // Initialize our locks - _lockQueue = dispatch_queue_create("TSKSPKIHashLock", DISPATCH_QUEUE_CONCURRENT); - - _spkiCacheFilename = uniqueIdentifier; // if this value is nil, persistence will always fail. - - // First try to load a cached version from the filesystem - _subjectPublicKeyInfoHashesCache = [self loadSPKICacheFromFileSystem]; - TSKLog(@"Loaded %lu SPKI cache entries from the filesystem", (unsigned long)_subjectPublicKeyInfoHashesCache.count); - if (_subjectPublicKeyInfoHashesCache == nil) - { - _subjectPublicKeyInfoHashesCache = [NSMutableDictionary new]; - } - - // Initialize any sub-dictionnary that hasn't been initialized - for (int i=0; i<=TSKPublicKeyAlgorithmLast; i++) - { - NSNumber *algorithmKey = @(i); - if (_subjectPublicKeyInfoHashesCache[algorithmKey] == nil) - { - _subjectPublicKeyInfoHashesCache[algorithmKey] = [NSMutableDictionary new]; - } - - } - -#if LEGACY_IOS_KEY_EXTRACTION - _keychainQueue = dispatch_queue_create("TSKSPKIKeychainLock", DISPATCH_QUEUE_SERIAL); - // Cleanup the Keychain in case the App previously crashed - NSMutableDictionary * publicKeyGet = [[NSMutableDictionary alloc] init]; - publicKeyGet[(__bridge id)kSecClass] = (__bridge id)kSecClassKey; - publicKeyGet[(__bridge id)kSecAttrApplicationTag] = kTSKKeychainPublicKeyTag; - publicKeyGet[(__bridge id)kSecReturnData] = @YES; - dispatch_sync(_keychainQueue, ^{ - SecItemDelete((__bridge CFDictionaryRef)publicKeyGet); - }); -#endif - } - return self; -} - -- (NSData *)hashSubjectPublicKeyInfoFromCertificate:(SecCertificateRef)certificate publicKeyAlgorithm:(TSKPublicKeyAlgorithm)publicKeyAlgorithm -{ - __block NSData *cachedSubjectPublicKeyInfo; - NSNumber *algorithmKey = [NSNumber numberWithInt:publicKeyAlgorithm]; - - // Have we seen this certificate before? Look for the SPKI in the cache - NSData *certificateData = (__bridge_transfer NSData *)(SecCertificateCopyData(certificate)); - - __weak __typeof__(self) weakSelf = self; - dispatch_sync(_lockQueue, ^{ - __strong __typeof__(weakSelf) strongSelf = weakSelf; - cachedSubjectPublicKeyInfo = strongSelf.subjectPublicKeyInfoHashesCache[algorithmKey][certificateData]; - }); - - if (cachedSubjectPublicKeyInfo) - { - TSKLog(@"Subject Public Key Info hash was found in the cache"); - return cachedSubjectPublicKeyInfo; - } - - // We didn't this certificate in the cache so we need to generate its SPKI hash - TSKLog(@"Generating Subject Public Key Info hash..."); - - // First extract the public key bytes - NSData *publicKeyData = [self getPublicKeyDataFromCertificate:certificate]; - if (publicKeyData == nil) - { - TSKLog(@"Error - could not extract the public key bytes"); - return nil; - } - - - // Generate a hash of the subject public key info - NSMutableData *subjectPublicKeyInfoHash = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; - CC_SHA256_CTX shaCtx; - CC_SHA256_Init(&shaCtx); - - // Add the missing ASN1 header for public keys to re-create the subject public key info - CC_SHA256_Update(&shaCtx, asn1HeaderBytes[publicKeyAlgorithm], asn1HeaderSizes[publicKeyAlgorithm]); - - // Add the public key - CC_SHA256_Update(&shaCtx, [publicKeyData bytes], (unsigned int)[publicKeyData length]); - CC_SHA256_Final((unsigned char *)[subjectPublicKeyInfoHash bytes], &shaCtx); - - - // Store the hash in our memory cache - dispatch_barrier_sync(_lockQueue, ^{ - __strong __typeof__(weakSelf) strongSelf = weakSelf; - strongSelf.subjectPublicKeyInfoHashesCache[algorithmKey][certificateData] = subjectPublicKeyInfoHash; - }); - - // Update the cache on the filesystem - if (self.spkiCacheFilename.length > 0) { - NSData *serializedSpkiCache = [NSKeyedArchiver archivedDataWithRootObject:_subjectPublicKeyInfoHashesCache]; - if ([serializedSpkiCache writeToURL:[self SPKICachePath] atomically:YES] == NO) - { - NSAssert(false, @"Failed to write cache"); - TSKLog(@"Could not persist SPKI cache to the filesystem"); - } - } - - return subjectPublicKeyInfoHash; -} - -- (NSMutableDictionary *)loadSPKICacheFromFileSystem -{ - NSMutableDictionary *spkiCache; - NSData *serializedSpkiCache = [NSData dataWithContentsOfURL:[self SPKICachePath]]; - if (serializedSpkiCache) { - spkiCache = [NSKeyedUnarchiver unarchiveObjectWithData:serializedSpkiCache]; - } - return spkiCache; -} - - -#pragma mark Private - -- (NSData *)getPublicKeyDataFromCertificate:(SecCertificateRef)certificate -{ - // ****** TvOS or WatchOS ****** -#if TARGET_OS_WATCH || TARGET_OS_TV - // watchOS 3+ or tvOS 10+ - return [self getPublicKeyDataFromCertificate_unified:certificate]; -#elif TARGET_OS_IOS - // ****** iOS ****** -#if __IPHONE_OS_VERSION_MAX_ALLOWED < 100000 - // Base SDK is iOS 8 or 9 - return [self getPublicKeyDataFromCertificate_legacy_ios:certificate ]; -#else - // Base SDK is iOS 10+ - try to use the unified Security APIs if available - NSProcessInfo *processInfo = [NSProcessInfo processInfo]; - if ([processInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] - && [processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 0, 0}]) - { - // iOS 10+ - return [self getPublicKeyDataFromCertificate_unified:certificate]; - } - else - { - // iOS 8 or 9 - return [self getPublicKeyDataFromCertificate_legacy_ios:certificate]; - } -#endif - // ****** macOS ****** -#else - // macOS 10.10+ -#if LEGACY_MACOS_KEY_EXTRACTION - // Base SDK is macOS 10.10 or 10.11 - return [self getPublicKeyDataFromCertificate_legacy_macos:certificate]; -#else - // Base SDK is macOS 10.12 - try to use the unified Security APIs if available - NSProcessInfo *processInfo = [NSProcessInfo processInfo]; - if ([processInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] - && [processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 12, 0}]) - { - // macOS 10.12+ - return [self getPublicKeyDataFromCertificate_unified:certificate]; - } - else - { - // macOS 10.10 or 10.11 - return [self getPublicKeyDataFromCertificate_legacy_macos:certificate]; - } -#endif -#endif -} - -- (NSURL *)SPKICachePath -{ - NSAssert(self.spkiCacheFilename, @"SPKI filename should not be nil"); - NSURL *cachesDirUrl = [NSFileManager.defaultManager URLsForDirectory:NSCachesDirectory - inDomains:NSUserDomainMask].firstObject; - return [cachesDirUrl URLByAppendingPathComponent:self.spkiCacheFilename]; -} - -@end - - -#pragma mark Public Key Converter - iOS 10.0+, macOS 10.12+, watchOS 3.0, tvOS 10.0 -#if UNIFIED_KEY_EXTRACTION -@implementation TSKSPKIHashCache (Unified) - -// Use the unified SecKey API (specifically SecKeyCopyExternalRepresentation()) -- (NSData *)getPublicKeyDataFromCertificate_unified:(SecCertificateRef)certificate -{ - // Create an X509 trust using the using the certificate - SecTrustRef trust; - SecPolicyRef policy = SecPolicyCreateBasicX509(); - SecTrustCreateWithCertificates(certificate, policy, &trust); - - // Get a public key reference for the certificate from the trust - SecTrustResultType result; - SecTrustEvaluate(trust, &result); - SecKeyRef publicKey = SecTrustCopyPublicKey(trust); - CFRelease(policy); - CFRelease(trust); - - // Obtain the public key bytes from the key reference - // Silencing the warning since there is no way to reach here unless we are on iOS 10.0+ - // (this would otherwise warn if compiled for an app supporting < 10.0) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpartial-availability" - CFDataRef publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL); -#pragma clang diagnostic pop - - CFRelease(publicKey); - - return (__bridge_transfer NSData *)publicKeyData; -} - -@end -#endif - - -#pragma mark Public Key Converter - iOS before 10.0 -#if LEGACY_IOS_KEY_EXTRACTION -@implementation TSKSPKIHashCache (LegacyIOS) - -- (NSData *)getPublicKeyDataFromCertificate_legacy_ios:(SecCertificateRef)certificate -{ - __block NSData *publicKeyData = nil; - __block OSStatus resultAdd, __block resultDel = noErr; - SecKeyRef publicKey; - SecTrustRef tempTrust; - SecPolicyRef policy = SecPolicyCreateBasicX509(); - - // Get a public key reference from the certificate - SecTrustCreateWithCertificates(certificate, policy, &tempTrust); - SecTrustResultType result; - SecTrustEvaluate(tempTrust, &result); - publicKey = SecTrustCopyPublicKey(tempTrust); - CFRelease(policy); - CFRelease(tempTrust); - - - /// Extract the actual bytes from the key reference using the Keychain - // Prepare the dictionary to add the key - NSMutableDictionary *peerPublicKeyAdd = [[NSMutableDictionary alloc] init]; - peerPublicKeyAdd[(__bridge id)kSecClass] = (__bridge id)kSecClassKey; - peerPublicKeyAdd[(__bridge id)kSecAttrApplicationTag] = kTSKKeychainPublicKeyTag; - peerPublicKeyAdd[(__bridge id)kSecValueRef] = (__bridge id)publicKey; - - // Avoid issues with background fetching while the device is locked - peerPublicKeyAdd[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; - - // Request the key's data to be returned - peerPublicKeyAdd[(__bridge id)kSecReturnData] = @YES; - - // Prepare the dictionary to retrieve and delete the key - NSMutableDictionary * publicKeyGet = [[NSMutableDictionary alloc] init]; - publicKeyGet[(__bridge id)kSecClass] = (__bridge id)kSecClassKey; - publicKeyGet[(__bridge id)kSecAttrApplicationTag] = kTSKKeychainPublicKeyTag; - publicKeyGet[(__bridge id)kSecReturnData] = @YES; - - - // Get the key bytes from the Keychain atomically - dispatch_sync(self.keychainQueue, ^{ - resultAdd = SecItemAdd((__bridge CFDictionaryRef) peerPublicKeyAdd, (void *)&publicKeyData); - resultDel = SecItemDelete((__bridge CFDictionaryRef)publicKeyGet); - }); - - CFRelease(publicKey); - if ((resultAdd != errSecSuccess) || (resultDel != errSecSuccess)) - { - // Something went wrong with the Keychain we won't know if we did get the right key data - TSKLog(@"Keychain error"); - publicKeyData = nil; - } - - return publicKeyData; -} - -@end -#endif - - -#pragma mark Public Key Converter - macOS before 10.12 -#if LEGACY_MACOS_KEY_EXTRACTION -@implementation TSKSPKIHashCache (LegacyMacOS) - -// Need to support macOS before 10.12 - -- (NSData *)getPublicKeyDataFromCertificate_legacy_macos:(SecCertificateRef)certificate -{ - NSData *publicKeyData = nil; - CFErrorRef error = NULL; - - // SecCertificateCopyValues() is macOS only - NSArray *oids = @[ (__bridge id)kSecOIDX509V1SubjectPublicKey ]; - NSDictionary *certificateValues = (__bridge_transfer NSDictionary *)SecCertificateCopyValues(certificate, (__bridge CFArrayRef)(oids), &error); - if (certificateValues == nil) - { - CFStringRef errorDescription = CFErrorCopyDescription(error); - TSKLog(@"SecCertificateCopyValues() error: %@", errorDescription); - CFRelease(errorDescription); - CFRelease(error); - return nil; - } - - for (NSString *fieldName in certificateValues) - { - NSDictionary *fieldDict = certificateValues[fieldName]; - NSString *fieldLabel = fieldDict[(__bridge id)kSecPropertyKeyLabel]; - if ([fieldLabel isEqualToString:@"Public Key Data"]) - { - publicKeyData = fieldDict[(__bridge id)kSecPropertyKeyValue]; - } - } - return publicKeyData; -} - -@end -#endif - -@implementation TSKSPKIHashCache (TestSupport) - -- (void)resetSubjectPublicKeyInfoDiskCache -{ - // Discard SPKI cache - [NSFileManager.defaultManager removeItemAtURL:[self SPKICachePath] error:nil]; -} - - -- (NSMutableDictionary *)getSubjectPublicKeyInfoHashesCache -{ - return _subjectPublicKeyInfoHashesCache; -} - -@end diff --git a/vendor/TrustKit/Pinning/ssl_pin_verifier.h b/vendor/TrustKit/Pinning/ssl_pin_verifier.h deleted file mode 100755 index 4f6712e7..00000000 --- a/vendor/TrustKit/Pinning/ssl_pin_verifier.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - - ssl_pin_verifier.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKTrustDecision.h" -@import Foundation; - -@class TSKSPKIHashCache; - -// Validate that the server trust contains at least one of the know/expected pins -TSKTrustEvaluationResult verifyPublicKeyPin(SecTrustRef _Nonnull serverTrust, - NSString * _Nonnull serverHostname, - NSArray * _Nonnull supportedAlgorithms, - NSSet * _Nonnull knownPins, - TSKSPKIHashCache * _Nullable hashCache); diff --git a/vendor/TrustKit/Pinning/ssl_pin_verifier.m b/vendor/TrustKit/Pinning/ssl_pin_verifier.m deleted file mode 100755 index 35066ade..00000000 --- a/vendor/TrustKit/Pinning/ssl_pin_verifier.m +++ /dev/null @@ -1,138 +0,0 @@ -/* - - ssl_pin_verifier.m - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "ssl_pin_verifier.h" -#import "TSKSPKIHashCache.h" -#import "../configuration_utils.h" -#import "../TSKLog.h" - - -#pragma mark SSL Pin Verifier - -TSKTrustEvaluationResult verifyPublicKeyPin(SecTrustRef serverTrust, NSString *serverHostname, NSArray *supportedAlgorithms, NSSet *knownPins, TSKSPKIHashCache *hashCache) -{ - NSCParameterAssert(serverTrust); - NSCParameterAssert(supportedAlgorithms); - NSCParameterAssert(knownPins); - if ((serverTrust == NULL) || (supportedAlgorithms == nil) || (knownPins == nil)) - { - TSKLog(@"Invalid pinning parameters for %@", serverHostname); - return TSKTrustEvaluationErrorInvalidParameters; - } - - // First re-check the certificate chain using the default SSL validation in case it was disabled - // This gives us revocation (only for EV certs I think?) and also ensures the certificate chain is sane - // And also gives us the exact path that successfully validated the chain - CFRetain(serverTrust); - - // Create and use a sane SSL policy to force hostname validation, even if the supplied trust has a bad - // policy configured (such as one from SecPolicyCreateBasicX509()) - SecPolicyRef SslPolicy = SecPolicyCreateSSL(YES, (__bridge CFStringRef)(serverHostname)); - SecTrustSetPolicies(serverTrust, SslPolicy); - CFRelease(SslPolicy); - - SecTrustResultType trustResult = 0; - if (SecTrustEvaluate(serverTrust, &trustResult) != errSecSuccess) - { - TSKLog(@"SecTrustEvaluate error for %@", serverHostname); - CFRelease(serverTrust); - return TSKTrustEvaluationErrorInvalidParameters; - } - - if ((trustResult != kSecTrustResultUnspecified) && (trustResult != kSecTrustResultProceed)) - { - // Default SSL validation failed - CFDictionaryRef evaluationDetails = SecTrustCopyResult(serverTrust); - TSKLog(@"Error: default SSL validation failed for %@: %@", serverHostname, evaluationDetails); - CFRelease(evaluationDetails); - CFRelease(serverTrust); - return TSKTrustEvaluationFailedInvalidCertificateChain; - } - - // Check each certificate in the server's certificate chain (the trust object); start with the CA all the way down to the leaf - CFIndex certificateChainLen = SecTrustGetCertificateCount(serverTrust); - for(int i=(int)certificateChainLen-1;i>=0;i--) - { - // Extract the certificate - SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); - CFStringRef certificateSubject = SecCertificateCopySubjectSummary(certificate); - TSKLog(@"Checking certificate with CN: %@", certificateSubject); - CFRelease(certificateSubject); - - // For each public key algorithm flagged as supported in the config, generate the subject public key info hash - for (NSNumber *savedAlgorithm in supportedAlgorithms) - { - TSKPublicKeyAlgorithm algorithm = [savedAlgorithm integerValue]; - NSData *subjectPublicKeyInfoHash = [hashCache hashSubjectPublicKeyInfoFromCertificate:certificate - publicKeyAlgorithm:algorithm]; - if (subjectPublicKeyInfoHash == nil) - { - TSKLog(@"Error - could not generate the SPKI hash for %@", serverHostname); - CFRelease(serverTrust); - return TSKTrustEvaluationErrorCouldNotGenerateSpkiHash; - } - - // Is the generated hash in our set of pinned hashes ? - TSKLog(@"Testing SSL Pin %@", subjectPublicKeyInfoHash); - if ([knownPins containsObject:subjectPublicKeyInfoHash]) - { - TSKLog(@"SSL Pin found for %@", serverHostname); - CFRelease(serverTrust); - return TSKTrustEvaluationSuccess; - } - } - } - -#if !TARGET_OS_IPHONE - // OS X only: if user-defined anchors are whitelisted, allow the App to not enforce pin validation - NSMutableArray *customRootCerts = [NSMutableArray array]; - - // Retrieve the OS X host's list of user-defined CA certificates - CFArrayRef userRootCerts; - OSStatus status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainUser, &userRootCerts); - if (status == errSecSuccess) - { - [customRootCerts addObjectsFromArray:(__bridge NSArray *)(userRootCerts)]; - CFRelease(userRootCerts); - } - CFArrayRef adminRootCerts; - status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainAdmin, &adminRootCerts); - if (status == errSecSuccess) - { - [customRootCerts addObjectsFromArray:(__bridge NSArray *)(adminRootCerts)]; - CFRelease(adminRootCerts); - } - - // Is any certificate in the chain a custom anchor that was manually added to the OS' trust store ? - // If we get there, we shouldn't have to check the custom certificates' trust setting (trusted / not trusted) - // as the chain validation was successful right before - if ([customRootCerts count] > 0) - { - for(int i=0;i - -///--------------------- -/// @name Initialization -///--------------------- - -/** - Initializes a background reporter. - - @param shouldRateLimitReports Prevent identical pin failure reports from being sent more than once per day. - @exception NSException Thrown when the App does not have a bundle ID, meaning we're running in unit tests where the background transfer service can't be used. - - */ -- (nonnull instancetype)initAndRateLimitReports:(BOOL)shouldRateLimitReports; - -///---------------------- -/// @name Sending Reports -///---------------------- - -/** - Send a pin validation failure report; each argument is described section 3. of RFC 7469. - */ -- (void) pinValidationFailedForHostname:(nonnull NSString *) serverHostname - port:(nullable NSNumber *) serverPort - certificateChain:(nonnull NSArray *) certificateChain - notedHostname:(nonnull NSString *) notedHostname - reportURIs:(nonnull NSArray *) reportURIs - includeSubdomains:(BOOL) includeSubdomains - enforcePinning:(BOOL) enforcePinning - knownPins:(nonnull NSSet *) knownPins - validationResult:(TSKTrustEvaluationResult) validationResult - expirationDate:(nullable NSDate *)knownPinsExpirationDate; - -- (void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error; - -@end - diff --git a/vendor/TrustKit/Reporting/TSKBackgroundReporter.m b/vendor/TrustKit/Reporting/TSKBackgroundReporter.m deleted file mode 100755 index 239073e7..00000000 --- a/vendor/TrustKit/Reporting/TSKBackgroundReporter.m +++ /dev/null @@ -1,233 +0,0 @@ -/* - - TSKBackgroundReporter.m - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKBackgroundReporter.h" -#import "../TSKTrustKitConfig.h" -#import "../TSKLog.h" -#import "TSKPinFailureReport.h" -#import "reporting_utils.h" -#import "TSKReportsRateLimiter.h" -#import "vendor_identifier.h" - - -// Session identifier for background uploads: .TSKBackgroundReporter -static NSString * const kTSKBackgroundSessionIdentifierFormat = @"%@.TSKBackgroundReporter.%@"; - -@interface TSKBackgroundReporter() - -@property (nonatomic, nonnull) NSURLSession *backgroundSession; -@property (nonatomic, nonnull) NSString *appBundleId; -@property (nonatomic, nonnull) NSString *appVersion; -@property (nonatomic, nonnull) NSString *appVendorId; -@property (nonatomic, nonnull) NSString *appPlatform; -@property (nonatomic, nonnull) NSString *appPlatformVersion; -@property (nonatomic, nonnull) TSKReportsRateLimiter *rateLimiter; -@property (nonatomic) BOOL shouldRateLimitReports; - -@end - -@implementation TSKBackgroundReporter - -#pragma mark Public methods - -- (nonnull instancetype)initAndRateLimitReports:(BOOL)shouldRateLimitReports -{ - self = [super init]; - if (self) - { - _shouldRateLimitReports = shouldRateLimitReports; - _rateLimiter = [TSKReportsRateLimiter new]; - - // Retrieve the App and device's information -#if TARGET_OS_IPHONE -#if TARGET_OS_TV - _appPlatform = @"TVOS"; -#elif TARGET_OS_WATCH - _appPlatform = @"WATCHOS"; -#else - _appPlatform = @"IOS"; -#endif -#else - _appPlatform = @"MACOS"; -#endif - - // If we don't have the OS version yet, we are on a device that provides the operatingSystemVersion method - if (_appPlatformVersion == nil) - { - NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion]; - _appPlatformVersion = [NSString stringWithFormat:@"%ld.%ld.%ld", - (long)version.majorVersion, - (long)version.minorVersion, - (long)version.patchVersion]; - } - - - CFBundleRef appBundle = CFBundleGetMainBundle(); - _appVersion = (__bridge NSString *)CFBundleGetValueForInfoDictionaryKey(appBundle, (CFStringRef) @"CFBundleShortVersionString"); - if (_appVersion == nil) - { - _appVersion = @""; - } - - _appBundleId = (__bridge NSString *)CFBundleGetIdentifier(appBundle); - if (_appBundleId == nil) - { - // The bundle ID we get is nil if we're running tests on Travis. If the bundle ID is nil, background sessions can't be used - // backgroundSessionConfigurationWithIdentifier: will throw an exception - TSKLog(@"Null bundle ID: we are running the test suite; falling back to a normal session."); - _appBundleId = @"N/A"; - _appVendorId = @"unit-tests"; - - _backgroundSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] - delegate:self - delegateQueue:nil]; - } - else - { - // Get the vendor identifier - _appVendorId = identifier_for_vendor(); - - - // We're not running unit tests - use a background session - // AppleDoc (currently 10.3) state that multiple background sessions with the same - // identifier should never be created, so ensure that cannot happen by creating - // a unique ID per instance. - NSString *backgroundSessionId = [NSString stringWithFormat:kTSKBackgroundSessionIdentifierFormat, - _appBundleId, [[NSUUID UUID] UUIDString]]; - - NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:backgroundSessionId]; - backgroundConfiguration.discretionary = YES; - -#if TARGET_OS_IPHONE - // iOS-only settings - // Do not wake up the App after completing the upload - backgroundConfiguration.sessionSendsLaunchEvents = NO; -#endif - - // We have to use a delegate as background sessions can't use completion handlers - _backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration - delegate:self - delegateQueue:nil]; - } - } - return self; -} - - -- (void) pinValidationFailedForHostname:(nonnull NSString *)serverHostname - port:(nullable NSNumber *)serverPort - certificateChain:(nonnull NSArray *)certificateChain - notedHostname:(nonnull NSString *)notedHostname - reportURIs:(nonnull NSArray *)reportURIs - includeSubdomains:(BOOL)includeSubdomains - enforcePinning:(BOOL)enforcePinning - knownPins:(nonnull NSSet *)knownPins - validationResult:(TSKTrustEvaluationResult)validationResult - expirationDate:(nullable NSDate *)knownPinsExpirationDate -{ - // Default port to 0 if not specified - if (serverPort == nil) - { - serverPort = @(0); - } - - if (reportURIs == nil) - { - [NSException raise:@"TSKBackgroundReporter configuration invalid" - format:@"Reporter was given an invalid value for reportURIs: %@ for domain %@", - reportURIs, notedHostname]; - } - - // Create the pin validation failure report - NSArray *formattedPins = convertPinsToHpkpPins(knownPins); - TSKPinFailureReport *report = [[TSKPinFailureReport alloc]initWithAppBundleId:_appBundleId - appVersion:_appVersion - appPlatform:_appPlatform - appPlatformVersion:_appPlatformVersion - appVendorId:_appVendorId - trustkitVersion:TrustKitVersion - hostname:serverHostname - port:serverPort - dateTime:[NSDate date] // current date & time - notedHostname:notedHostname - includeSubdomains:includeSubdomains - enforcePinning:enforcePinning - validatedCertificateChain:certificateChain - knownPins:formattedPins - validationResult:validationResult - expirationDate:knownPinsExpirationDate]; - - // Should we rate-limit this report? - if (_shouldRateLimitReports && [self.rateLimiter shouldRateLimitReport:report]) - { - // We recently sent the exact same report; do not send this report - TSKLog(@"Pin failure report for %@ was not sent due to rate-limiting", serverHostname); - return; - } - - // Create a temporary file for storing the JSON data in ~/tmp - NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES]; - NSURL *tmpFileURL = [[tmpDirURL URLByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]] - URLByAppendingPathExtension:@"tsk-report"]; - - // Write the JSON report data to the temporary file - NSError *error; - NSUInteger writeOptions = NSDataWritingAtomic; -#if TARGET_OS_IPHONE - // Ensure the report is accessible when locked on iOS, in case the App has the NSFileProtectionComplete entitlement - writeOptions = writeOptions | NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication; -#endif - - if (!([[report json] writeToURL:tmpFileURL options:writeOptions error:&error])) - { -#if DEBUG - // Only raise this exception for debug as not being able to save the report would crash a prod App - // https://github.com/datatheorem/TrustKit/issues/32 - // This might happen when the device's storage is full? - [NSException raise:@"TSKBackgroundReporter runtime error" - format:@"Report cannot be saved to file: %@", [error description]]; -#endif - } - TSKLog(@"Report for %@ created at: %@", serverHostname, [tmpFileURL path]); - - - // Create the HTTP request for all the configured report URIs and send it - for (NSURL *reportUri in reportURIs) - { - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:reportUri]; - [request setHTTPMethod:@"POST"]; - [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - - // Pass the URL and the temporary file to the background upload task and start uploading - NSURLSessionUploadTask *uploadTask = [_backgroundSession uploadTaskWithRequest:request - fromFile:tmpFileURL]; - - [uploadTask resume]; - } -} - - - -- (void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error -{ - if (error == nil) - { - TSKLog(@"Background upload - task completed successfully: pinning failure report sent"); - } - else - { - TSKLog(@"Background upload - task completed with error: %@ (code %ld)", [error localizedDescription], (long)error.code); - } -} - - -@end - diff --git a/vendor/TrustKit/Reporting/TSKPinFailureReport.h b/vendor/TrustKit/Reporting/TSKPinFailureReport.h deleted file mode 100755 index be47db58..00000000 --- a/vendor/TrustKit/Reporting/TSKPinFailureReport.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - - TSKPinFailureReport.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "ssl_pin_verifier.h" -@import Foundation; - -@interface TSKPinFailureReport : NSObject - -@property (readonly, nonatomic, nonnull) NSString *appBundleId; // Not part of the HPKP spec -@property (readonly, nonatomic, nonnull) NSString *appVersion; // Not part of the HPKP spec -@property (readonly, nonatomic, nonnull) NSString *appPlatform; // Not part of the HPKP spec -@property (readonly, nonatomic, nonnull) NSString *appPlatformVersion; // Not part of the HPKP spec -@property (readonly, nonatomic, nonnull) NSString *appVendorId; // Not part of the HPKP spec -@property (readonly, nonatomic, nonnull) NSString *trustkitVersion; // Not part of the HPKP spec -@property (readonly, nonatomic, nonnull) NSString *notedHostname; -@property (readonly, nonatomic, nonnull) NSString *hostname; -@property (readonly, nonatomic, nonnull) NSNumber *port; -@property (readonly, nonatomic, nonnull) NSDate *dateTime; -@property (readonly, nonatomic) BOOL includeSubdomains; -@property (readonly, nonatomic, nonnull) NSArray *validatedCertificateChain; -@property (readonly, nonatomic, nonnull) NSArray *knownPins; -@property (readonly, nonatomic) TSKTrustEvaluationResult validationResult; // Not part of the HPKP spec -@property (readonly, nonatomic) BOOL enforcePinning; // Not part of the HPKP spec -@property (readonly, nonatomic, nullable) NSDate *knownPinsExpirationDate; // Not part of the HPKP spec - - -// Init with default bundle ID and current time as the date-time -- (nonnull instancetype) initWithAppBundleId:(nonnull NSString *)appBundleId - appVersion:(nonnull NSString *)appVersion - appPlatform:(nonnull NSString *)appPlatform - appPlatformVersion:(nonnull NSString *)appPlatformVersion - appVendorId:(nonnull NSString *)appVendorId - trustkitVersion:(nonnull NSString *)trustkitVersion - hostname:(nonnull NSString *)serverHostname - port:(nonnull NSNumber *)serverPort - dateTime:(nonnull NSDate *)dateTime - notedHostname:(nonnull NSString *)notedHostname - includeSubdomains:(BOOL)includeSubdomains - enforcePinning:(BOOL)enforcePinning - validatedCertificateChain:(nonnull NSArray *)validatedCertificateChain - knownPins:(nonnull NSArray *)knownPins - validationResult:(TSKTrustEvaluationResult)validationResult - expirationDate:(nullable NSDate *)knownPinsExpirationDate; - -// Return the report in JSON format for POSTing it -- (nonnull NSData *)json; - -// Return a request ready to be sent with the report in JSON format in the response's body -- (nonnull NSMutableURLRequest *)requestToUri:(nonnull NSURL *)reportUri; - - -@end diff --git a/vendor/TrustKit/Reporting/TSKPinFailureReport.m b/vendor/TrustKit/Reporting/TSKPinFailureReport.m deleted file mode 100755 index 103794ea..00000000 --- a/vendor/TrustKit/Reporting/TSKPinFailureReport.m +++ /dev/null @@ -1,142 +0,0 @@ -/* - - TSKPinFailureReport.m - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKPinFailureReport.h" - -@implementation TSKPinFailureReport - -- (nonnull instancetype) initWithAppBundleId:(nonnull NSString *)appBundleId - appVersion:(nonnull NSString *)appVersion - appPlatform:(nonnull NSString *)appPlatform - appPlatformVersion:(nonnull NSString *)appPlatformVersion - appVendorId:(nonnull NSString *)appVendorId - trustkitVersion:(nonnull NSString *)trustkitVersion - hostname:(nonnull NSString *)serverHostname - port:(nonnull NSNumber *)serverPort - dateTime:(nonnull NSDate *)dateTime - notedHostname:(nonnull NSString *)notedHostname - includeSubdomains:(BOOL)includeSubdomains - enforcePinning:(BOOL)enforcePinning - validatedCertificateChain:(nonnull NSArray *)validatedCertificateChain - knownPins:(nonnull NSArray *)knownPins - validationResult:(TSKTrustEvaluationResult)validationResult - expirationDate:(nullable NSDate *)knownPinsExpirationDate -{ - self = [super init]; - if (self) - { - _appBundleId = appBundleId; - _appVersion = appVersion; - _appPlatform = appPlatform; - _appVendorId = appVendorId; - _trustkitVersion = trustkitVersion; - _appPlatformVersion = appPlatformVersion; - _hostname = serverHostname; - _port = serverPort; - _dateTime = dateTime; - _notedHostname = notedHostname; - _includeSubdomains = includeSubdomains; - _enforcePinning = enforcePinning; - _validatedCertificateChain = validatedCertificateChain; - _knownPins = knownPins; - _validationResult = validationResult; - _knownPinsExpirationDate = knownPinsExpirationDate; - } - return self; -} - - -- (nonnull NSData *)json -{ - // NSDateFormatter (and NSNumberFormatter) is extremely expensive to initialize, doesn't - // change, and is listed as explicitely thread safe, so lets reuse the instance. - static NSDateFormatter *DateTimeFormatter = nil; - static NSDateFormatter *DateFormatter = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - /// Date AND time formatter for JSON - DateTimeFormatter = ({ - NSDateFormatter *df = [[NSDateFormatter alloc] init]; - - // Explicitely set the locale to avoid an iOS 8 bug - // http://stackoverflow.com/questions/29374181/nsdateformatter-hh-returning-am-pm-on-ios-8-device - df.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; - - df.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; - df.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; - df; - }); - - /// Date ONLY formatter - DateFormatter = ({ - NSDateFormatter *df = [[NSDateFormatter alloc] init]; - - // Explicitely set the locale to avoid an iOS 8 bug - // http://stackoverflow.com/questions/29374181/nsdateformatter-hh-returning-am-pm-on-ios-8-device - df.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; - - df.dateFormat = @"yyyy-MM-dd"; - df.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; - df; - }); - }); - - id dateStr = [NSNull null]; - if (self.dateTime) - { - dateStr = [DateTimeFormatter stringFromDate:self.dateTime] ?: [NSNull null]; - } - - id expirationDateStr = [NSNull null]; - if (self.knownPinsExpirationDate) - { - // For the expiration date, only return the expiration day, as specified in the pinning policy - expirationDateStr = [DateFormatter stringFromDate:self.knownPinsExpirationDate] ?: [NSNull null]; - } - - // Create the dictionary - NSDictionary *requestData = @{ - @"app-bundle-id": self.appBundleId, - @"app-version": self.appVersion, - @"app-platform": self.appPlatform, - @"app-platform-version": self.appPlatformVersion, - @"app-vendor-id": self.appVendorId, - @"trustkit-version": self.trustkitVersion, - @"date-time": dateStr, - @"hostname": self.hostname, - @"port": self.port, - @"noted-hostname": self.notedHostname, - @"include-subdomains": @(self.includeSubdomains), - @"enforce-pinning": @(self.enforcePinning), - @"validated-certificate-chain": self.validatedCertificateChain, - @"known-pins": self.knownPins, - @"validation-result": @(self.validationResult), - @"known-pins-expiration-date": expirationDateStr - }; - - NSError *error; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:requestData options:(NSJSONWritingOptions)0 error:&error]; - // FIXME: error is unhandled. - return jsonData; -} - - -- (nonnull NSMutableURLRequest *)requestToUri:(NSURL *)reportUri -{ - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:reportUri]; - request.HTTPMethod = @"POST"; - [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - request.HTTPBody = [self json]; - return request; -} - - -@end diff --git a/vendor/TrustKit/Reporting/TSKReportsRateLimiter.h b/vendor/TrustKit/Reporting/TSKReportsRateLimiter.h deleted file mode 100755 index 6bfa460d..00000000 --- a/vendor/TrustKit/Reporting/TSKReportsRateLimiter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - - TSKReportsRateLimiter.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKPinFailureReport.h" -@import Foundation; - -/* - * Simple helper class which caches reports for 24 hours to prevent identical reports from being sent twice - * during this 24 hour period. - * This is best-effort as the class doesn't persist state across App restarts, so if the App - * gets killed, it will start sending reports again. - */ -@interface TSKReportsRateLimiter : NSObject - -/** - Determine if the report should be reported or ignored due to the rate limiting policy. - - @param report The report to check whether or not to rate limit - @return True if the report should be ignored under the rate-limiting policy that - is in effect. - */ -- (BOOL)shouldRateLimitReport:(TSKPinFailureReport * _Nonnull)report; - -@end diff --git a/vendor/TrustKit/Reporting/TSKReportsRateLimiter.m b/vendor/TrustKit/Reporting/TSKReportsRateLimiter.m deleted file mode 100755 index 1d5588fc..00000000 --- a/vendor/TrustKit/Reporting/TSKReportsRateLimiter.m +++ /dev/null @@ -1,91 +0,0 @@ -/* - - TSKReportsRateLimiter.m - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKReportsRateLimiter.h" -#import "reporting_utils.h" - -static const NSTimeInterval kIntervalBetweenReportsCacheReset = 3600 * 24; - -@interface TSKReportsRateLimiter () - -/** Cache to rate-limit the number of pin failure reports that get sent */ -@property (nonatomic) NSMutableSet *reportsCache; - -/** We reset the reports cache every 24 hours to ensure identical reports are only sent once per day */ -@property (nonatomic) NSDate *lastReportsCacheResetDate; - -/** Concurrent queue for multi-reader, single-writer to the reports cache using dispatch barriers */ -@property (nonatomic) dispatch_queue_t reportsCacheQueue; - -@end - -@implementation TSKReportsRateLimiter - -- (instancetype)init -{ - self = [super init]; - if (self) { - // Initialize all the internal state for rate-limiting report uploads - _reportsCache = [NSMutableSet set]; - _lastReportsCacheResetDate = [NSDate date]; - _reportsCacheQueue = dispatch_queue_create("TSKReportsRateLimiter", DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (BOOL)shouldRateLimitReport:(TSKPinFailureReport *)report -{ - NSParameterAssert(report); - - // Check if we need to clear the reports cache for rate-limiting - NSTimeInterval secondsSinceCacheReset = -[self.lastReportsCacheResetDate timeIntervalSinceNow]; - - // Create an array containg the gist of the pin failure report; do not include the dates - NSArray *pinFailureInfo = @[ report.notedHostname, - report.hostname, - report.port, - report.validatedCertificateChain, - report.knownPins, - @(report.validationResult) ]; - - __block BOOL shouldRateLimitReport = NO; - __weak typeof(self) weakSelf = self; - dispatch_sync(self.reportsCacheQueue, ^{ - typeof(self) strongSelf = weakSelf; - - if (secondsSinceCacheReset > kIntervalBetweenReportsCacheReset) - { - // Reset the cache - [strongSelf.reportsCache removeAllObjects]; - strongSelf.lastReportsCacheResetDate = [NSDate date]; - } - - // Check if the exact same report has already been sent recently - shouldRateLimitReport = [strongSelf.reportsCache containsObject:pinFailureInfo]; - if (shouldRateLimitReport == NO) - { - // An identical report has NOT been sent recently - // Add this report to the cache for rate-limiting - [strongSelf.reportsCache addObject:pinFailureInfo]; - } - }); - - return shouldRateLimitReport; -} - -- (void)setLastReportsCacheResetDate:(NSDate *)lastReportsCacheResetDate -{ - NSParameterAssert(lastReportsCacheResetDate); - _lastReportsCacheResetDate = lastReportsCacheResetDate; -} - -@end - diff --git a/vendor/TrustKit/Reporting/reporting_utils.h b/vendor/TrustKit/Reporting/reporting_utils.h deleted file mode 100755 index bf0d762b..00000000 --- a/vendor/TrustKit/Reporting/reporting_utils.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - - reporting_utils.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -@import Foundation; - -#ifndef TrustKit_reporting_utils_h -#define TrustKit_reporting_utils_h - -NSArray *convertTrustToPemArray(SecTrustRef serverTrust); -NSArray *convertPinsToHpkpPins(NSSet *knownPins); - -#endif diff --git a/vendor/TrustKit/Reporting/reporting_utils.m b/vendor/TrustKit/Reporting/reporting_utils.m deleted file mode 100755 index 9199127d..00000000 --- a/vendor/TrustKit/Reporting/reporting_utils.m +++ /dev/null @@ -1,47 +0,0 @@ -/* - - reporting_utils.m - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "reporting_utils.h" - - -NSArray *convertTrustToPemArray(SecTrustRef serverTrust) -{ - // Convert the trust object into an array of PEM certificates - // Warning: SecTrustEvaluate() always needs to be called first on the serverTrust to be able to extract the certificates - NSMutableArray *certificateChain = [NSMutableArray array]; - CFIndex chainLen = SecTrustGetCertificateCount(serverTrust); - for (CFIndex i=0;i *convertPinsToHpkpPins(NSSet *knownPins) -{ - // Convert the know pins from a set of data to an array of strings as described in the HPKP spec - NSMutableArray *formattedPins = [NSMutableArray array]; - for (NSData *pin in knownPins) - { - [formattedPins addObject:[NSString stringWithFormat:@"pin-sha256=\"%@\"", [pin base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]]]; - } - return formattedPins; -} - diff --git a/vendor/TrustKit/Reporting/vendor_identifier.h b/vendor/TrustKit/Reporting/vendor_identifier.h deleted file mode 100755 index 4a8bd6f2..00000000 --- a/vendor/TrustKit/Reporting/vendor_identifier.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - - vendor_identifier.h - TrustKit - - Copyright 2016 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -@import Foundation; - -// Will return the IDFV on platforms that support it (iOS, tvOS) and a randomly generated UUID on other platforms (macOS, watchOS) -NSString *identifier_for_vendor(void); diff --git a/vendor/TrustKit/Reporting/vendor_identifier.m b/vendor/TrustKit/Reporting/vendor_identifier.m deleted file mode 100755 index 54d52dd8..00000000 --- a/vendor/TrustKit/Reporting/vendor_identifier.m +++ /dev/null @@ -1,50 +0,0 @@ -/* - - vendor_identifier.m - TrustKit - - Copyright 2016 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "vendor_identifier.h" - -#if TARGET_OS_IPHONE && !TARGET_OS_WATCH - -#pragma mark Vendor identifier - iOS, tvOS - -@import UIKit; // for accessing the IDFV - -NSString *identifier_for_vendor(void) -{ - return UIDevice.currentDevice.identifierForVendor.UUIDString; -} - -#else - -#pragma mark Vendor identifier - macOS, watchOS - - -static NSString * const kTSKVendorIdentifierKey = @"TSKVendorIdentifier"; - - -NSString *identifier_for_vendor(void) -{ - // Try to retrieve the vendor ID from the preferences - NSUserDefaults *preferences = NSUserDefaults.standardUserDefaults; - NSString *vendorId = [preferences stringForKey:kTSKVendorIdentifierKey]; - if (vendorId == nil) - { - // Generate and store a new UUID - vendorId = NSUUID.UUID.UUIDString; - [preferences setObject:vendorId forKey:kTSKVendorIdentifierKey]; - [preferences synchronize]; - } - return vendorId; -} - - -#endif - diff --git a/vendor/TrustKit/TSKLog.h b/vendor/TrustKit/TSKLog.h deleted file mode 100755 index 2ddde3e7..00000000 --- a/vendor/TrustKit/TSKLog.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - - TSKLog.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -// Common header with internal constants and defines. - -#ifndef TSKLog_h -#define TSKLog_h - -// The logging function we use within TrustKit -void TSKLog(NSString *format, ...); - - -#endif /* TSKLog_h */ diff --git a/vendor/TrustKit/TSKPinningValidator.h b/vendor/TrustKit/TSKPinningValidator.h deleted file mode 100755 index d4dd4615..00000000 --- a/vendor/TrustKit/TSKPinningValidator.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - - TSKPinningValidator.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKTrustDecision.h" -@import Foundation; - -@class TSKPinningValidatorResult; -@class TSKSPKIHashCache; - - -/** - A `TSKPinningValidator` instance can be used to verify a server's identity against an SSL pinning policy. - - In specific scenarios, TrustKit cannot intercept outgoing SSL connections and automatically validate the server's identity against the pinning policy: - - * All connections within an App that disables TrustKit's network delegate swizzling by setting the `kTSKSwizzleNetworkDelegates` configuration key to `NO`. - * Connections that do not rely on the `NSURLConnection` or `NSURLSession` APIs: - * `WKWebView` connections. - * Connections leveraging low-level network APIs (such as `NSStream`). - * Connections initiated using a third-party SSL library such as OpenSSL. - - For these connections, pin validation must be manually triggered using one of the two available methods within `TSKPinningValidator`. - */ -@interface TSKPinningValidator : NSObject - -#pragma mark High-level Validation Method - -/** - Helper method for handling authentication challenges received within a `NSURLSessionDelegate`, `NSURLSessionTaskDelegate` or `WKNavigationDelegate`. - - This method will evaluate the server trust within the authentication challenge against the global SSL pinning policy previously configured, and then call the `completionHandler` with the corresponding `disposition` and `credential`. For example, this method can be leveraged in a NSURLSessionDelegate challenge handler method: - - - (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { - { - TSKPinningValidator *pinningValidator = [[TrustKit sharedInstance] pinningValidator]; - // Pass the authentication challenge to the validator; if the validation fails, the connection will be blocked - if (![pinningValidator handleChallenge:challenge completionHandler:completionHandler]) - { - // TrustKit did not handle this challenge: perhaps it was not for server trust - // or the domain was not pinned. Fall back to the default behavior - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); - } - } - - @param challenge The authentication challenge, supplied by the URL loading system to the delegate's challenge handler method. - - @param completionHandler A block to invoke to respond to the challenge, supplied by the URL loading system to the delegate's challenge handler method. - - @return `YES` if the challenge was handled and the `completionHandler` was successfuly invoked. `NO` if the challenge could not be handled because it was not for server certificate validation (ie. the challenge's `authenticationMethod` was not `NSURLAuthenticationMethodServerTrust`). - - @exception NSException Thrown when TrustKit has not been initialized with a pinning policy. - */ -- (BOOL)handleChallenge:(NSURLAuthenticationChallenge * _Nonnull)challenge - completionHandler:(void (^ _Nonnull)(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential * _Nullable credential))completionHandler; - - -#pragma mark Low-level Validation Method - -/** - Evaluate the supplied server trust against the SSL pinning policy previously configured. If the validation fails, a pin failure report will be sent. - - When using the `NSURLSession` or `WKWebView` network APIs, the `handleChallenge:completionHandler:` method should be called instead, as it is simpler to use. - - When using low-level network APIs (such as `NSStream`), instructions on how to retrieve the connection's `serverTrust` are available at https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html . - - @param serverTrust The trust object representing the server's certificate chain. The trust's evaluation policy is always overridden using `SecTrustSetPolicies()` to ensure all the proper SSL checks (expiration, hostname validation, etc.) are enabled. - - @param serverHostname The hostname of the server whose identity is being validated. - - @return A `TSKTrustDecision` which describes whether the SSL connection should be allowed or blocked, based on the configured pinning policy. - - @warning If no SSL pinning policy was configured for the supplied _serverHostname_, this method has no effect and will return `TSKTrustDecisionDomainNotPinned` without validating the supplied _serverTrust_ at all. This means that the server's _serverTrust_ object __must__ be verified against the device's trust store using `SecTrustEvaluate()`. Failing to do so will __disable SSL certificate validation__. - - @exception NSException Thrown when TrustKit has not been initialized with a pinning policy. - */ -- (TSKTrustDecision)evaluateTrust:(SecTrustRef _Nonnull)serverTrust forHostname:(NSString * _Nonnull)serverHostname; - - - -@end diff --git a/vendor/TrustKit/TSKPinningValidator.m b/vendor/TrustKit/TSKPinningValidator.m deleted file mode 100755 index 17f139d2..00000000 --- a/vendor/TrustKit/TSKPinningValidator.m +++ /dev/null @@ -1,247 +0,0 @@ -/* - - TSKPinningValidator.m - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKPinningValidator.h" -#import "TSKTrustKitConfig.h" -#import "TSKTrustDecision.h" -#import "TSKPinningValidatorResult.h" -#import "Pinning/TSKSPKIHashCache.h" -#import "Pinning/ssl_pin_verifier.h" -#import "configuration_utils.h" -#import "TrustKit.h" -#import "TSKLog.h" -#import "TSKPinningValidator_Private.h" - - -@interface TSKPinningValidator () - -@property (nonatomic) TSKSPKIHashCache *spkiHashCache; - -/** - If this property returns YES, pinning may include any additional trust anchors - provided in a domain configuration under the kTSKAdditionalTrustAnchors key. - - This property is YES only when the preprocessor flag DEBUG is set to 1 (the - default behavior for the "Debug" configuration of an Xcode project). Subclasses - may override this method – with extreme caution – to alter this behavior. - */ -@property (nonatomic, class, readonly) BOOL allowsAdditionalTrustAnchors; - -/** - The dictionary of domains that were configured and their corresponding pinning policy. - */ -@property (nonatomic, readonly, nonnull) NSDictionary *domainPinningPolicies; - -/** - Set to true to ignore the trust anchors in the user trust store. Only applicable - to platforms that support a user trust store (Mac OS). - */ -@property (nonatomic, readonly) BOOL ignorePinsForUserTrustAnchors; - -/** - The callback invoked with validation results. - */ -@property (nonatomic, readonly, nonnull) TSKPinningValidatorCallback validationCallback; - -/** - The queue use when invoking the `validationCallback`. - */ -@property (nonatomic, readonly, nonnull) dispatch_queue_t validationCallbackQueue; - -@end - -@implementation TSKPinningValidator - -+ (BOOL)allowsAdditionalTrustAnchors -{ - static const BOOL allowAdditionalTrustAnchors = { -#if DEBUG == 1 - YES -#else - NO -#endif - }; - return allowAdditionalTrustAnchors; -} - -#pragma mark Instance Methods - -- (instancetype _Nullable)initWithDomainPinningPolicies:(NSDictionary * _Nonnull)domainPinningPolicies - hashCache:(TSKSPKIHashCache * _Nonnull)hashCache - ignorePinsForUserTrustAnchors:(BOOL)ignorePinsForUserTrustAnchors - validationCallbackQueue:(dispatch_queue_t _Nonnull)validationCallbackQueue - validationCallback:(TSKPinningValidatorCallback)validationCallback -{ - self = [super init]; - if (self) { - _domainPinningPolicies = domainPinningPolicies; - _ignorePinsForUserTrustAnchors = ignorePinsForUserTrustAnchors; - _validationCallbackQueue = validationCallbackQueue; - _validationCallback = validationCallback; - _spkiHashCache = hashCache; - } - return self; -} - -- (TSKTrustDecision)evaluateTrust:(SecTrustRef _Nonnull)serverTrust forHostname:(NSString * _Nonnull)serverHostname -{ - TSKTrustDecision finalTrustDecision = TSKTrustDecisionShouldBlockConnection; - - if ((serverTrust == NULL) || (serverHostname == nil)) - { - TSKLog(@"Pin validation error - invalid parameters for %@", serverHostname); - return finalTrustDecision; - } - CFRetain(serverTrust); - - // Register start time for duration computations - NSTimeInterval validationStartTime = [NSDate timeIntervalSinceReferenceDate]; - - // Retrieve the pinning configuration for this specific domain, if there is one - NSString *domainConfigKey = getPinningConfigurationKeyForDomain(serverHostname, self.domainPinningPolicies); - if (domainConfigKey == nil) - { - // The domain has no pinning policy: nothing to do/validate - finalTrustDecision = TSKTrustDecisionDomainNotPinned; - } - else - { - // This domain has a pinning policy - NSDictionary *domainConfig = self.domainPinningPolicies[domainConfigKey]; - - // Has the pinning policy expired? - NSDate *expirationDate = domainConfig[kTSKExpirationDate]; - if (expirationDate != nil && [expirationDate compare:[NSDate date]] == NSOrderedAscending) - { - // Yes the policy has expired - finalTrustDecision = TSKTrustDecisionDomainNotPinned; - } - else if ([domainConfig[kTSKExcludeSubdomainFromParentPolicy] boolValue]) - { - // This is a subdomain that was explicitly excluded from the parent domain's policy - finalTrustDecision = TSKTrustDecisionDomainNotPinned; - } - else - { - // Add bundled trust anchors if specified in the configuration - if (self.class.allowsAdditionalTrustAnchors) { - NSArray *additionalTrustAnchors = domainConfig[kTSKAdditionalTrustAnchors]; - if (additionalTrustAnchors.count) - { - TSKLog(@"Pin validation includes %ld potentially unsafe trust anchors", (long)additionalTrustAnchors.count); - SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)additionalTrustAnchors); - SecTrustSetAnchorCertificatesOnly(serverTrust, false); // trust union of OS and user anchor certificate sets - } - } - - // The domain has a pinning policy that has not expired - // Look for one the configured public key pins in the server's evaluated certificate chain - TSKTrustEvaluationResult validationResult = verifyPublicKeyPin(serverTrust, - serverHostname, - domainConfig[kTSKPublicKeyAlgorithms], - domainConfig[kTSKPublicKeyHashes], - self.spkiHashCache); - - if (validationResult == TSKTrustEvaluationSuccess) - { - // Pin validation was successful - TSKLog(@"Pin validation succeeded for %@", serverHostname); - finalTrustDecision = TSKTrustDecisionShouldAllowConnection; - } - else - { - // Pin validation failed - TSKLog(@"Pin validation failed for %@", serverHostname); -#if !TARGET_OS_IPHONE - if ((validationResult == TSKTrustEvaluationFailedUserDefinedTrustAnchor) - && (self.ignorePinsForUserTrustAnchors)) - { - // OS-X only: user-defined trust anchors can be whitelisted (for corporate proxies, etc.) so don't send reports - TSKLog(@"Ignoring pinning failure due to user-defined trust anchor for %@", serverHostname); - finalTrustDecision = TSKTrustDecisionShouldAllowConnection; - } - else -#endif - { - if (validationResult == TSKTrustEvaluationFailedNoMatchingPin) - { - // Is pinning enforced? - if ([domainConfig[kTSKEnforcePinning] boolValue] == YES) - { - // Yes - Block the connection - finalTrustDecision = TSKTrustDecisionShouldBlockConnection; - } - else - { - finalTrustDecision = TSKTrustDecisionShouldAllowConnection; - } - } - else - { - // Misc pinning errors (such as invalid certificate chain) - block the connection - finalTrustDecision = TSKTrustDecisionShouldBlockConnection; - } - } - } - - // Send a notification after all validation is done; this will also trigger a report if pin validation failed - if (self.validationCallbackQueue && self.validationCallback) { - NSTimeInterval validationDuration = [NSDate timeIntervalSinceReferenceDate] - validationStartTime; - TSKPinningValidatorResult *result = [[TSKPinningValidatorResult alloc] initWithServerHostname:serverHostname - serverTrust:serverTrust - validationResult:validationResult - finalTrustDecision:finalTrustDecision - validationDuration:validationDuration]; - dispatch_async(self.validationCallbackQueue, ^{ - self.validationCallback(result, domainConfigKey, domainConfig); - }); - } - } - } - CFRelease(serverTrust); - - return finalTrustDecision; -} - - -- (BOOL)handleChallenge:(NSURLAuthenticationChallenge * _Nonnull)challenge completionHandler:(void (^ _Nonnull)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler -{ - BOOL wasChallengeHandled = NO; - if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) - { - // Check the trust object against the pinning policy - SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; - NSString *serverHostname = challenge.protectionSpace.host; - - TSKTrustDecision trustDecision = [self evaluateTrust:serverTrust forHostname:serverHostname]; - if (trustDecision == TSKTrustDecisionShouldAllowConnection) - { - // Success - wasChallengeHandled = YES; - completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]); - } - else if (trustDecision == TSKTrustDecisionDomainNotPinned) - { - // Domain was not pinned; we need to do the default validation to avoid disabling SSL validation for all non-pinned domains - wasChallengeHandled = YES; - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, NULL); - } - else - { - // Pinning validation failed - block the connection - wasChallengeHandled = YES; - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, NULL); - } - } - return wasChallengeHandled; -} - -@end diff --git a/vendor/TrustKit/TSKPinningValidatorCallback.h b/vendor/TrustKit/TSKPinningValidatorCallback.h deleted file mode 100755 index 3e67d94c..00000000 --- a/vendor/TrustKit/TSKPinningValidatorCallback.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - - TSKPinningValidatorCallback.h - TrustKit - - Copyright 2017 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#ifndef TSKPinningValidatorCallback_h -#define TSKPinningValidatorCallback_h - -#import "TSKPinningValidatorResult.h" -#import "TSKTrustKitConfig.h" - -/** - The pinning policy set for a specific hostname. - */ -typedef NSDictionary TKSDomainPinningPolicy; - - -/** - A block that can be set in a `TrustKit` instance to be invoked for every request that is going through - instance's pinning validation logic. - - The callback will be invoked every time the validator performs pinning validation against a server's - certificate chain; if the server's hostname is not defined in the pinning policy, no invocations will - result as no pinning validation was performed. - - The callback provides the following arguments: - - * The `TSKPinningValidatorResult` resulting from the validation of the server's identity. - * The `notedHostname`, which is the entry within the SSL pinning configuration that was used for the - server being validated. - * The `notedHostname`'s pinning policy, which was used for the server being validated. - - The callback can be used for advanced features such as performance measurement or customizing the - reporting mechanism. Hence, most Apps should not have to use this callback. If set, the callback may - be invoked very frequently and is not a suitable place for expensive tasks. - - Lastly, the callback is always invoked after the validation has been completed, and therefore - cannot be used to modify the result of the validation (for example to accept invalid certificates). - */ -typedef void (^TSKPinningValidatorCallback)(TSKPinningValidatorResult * _Nonnull result, NSString * _Nonnull notedHostname, TKSDomainPinningPolicy * _Nonnull policy); - - - -#endif /* TSKPinningValidatorCallback_h */ diff --git a/vendor/TrustKit/TSKPinningValidatorResult.h b/vendor/TrustKit/TSKPinningValidatorResult.h deleted file mode 100755 index 043e2885..00000000 --- a/vendor/TrustKit/TSKPinningValidatorResult.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - - TSKPinningValidator.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKTrustDecision.h" -@import Foundation; - - -/** - A `TSKPinningValidatorResult` instance contains all the details regarding a pinning validation - performed against a specific server. - */ -@interface TSKPinningValidatorResult : NSObject - -/** - The hostname of the server SSL pinning validation was performed against. - */ -@property (nonatomic, readonly, nonnull) NSString *serverHostname; - -/** - The original `SecTrustRef` that validation was performed against. - */ -@property (nonatomic, readonly, nonnull) SecTrustRef serverTrust; - -/** - The result of validating the server's certificate chain against the set of SSL pins configured for - the `notedHostname`. - */ -@property (nonatomic, readonly) TSKTrustEvaluationResult evaluationResult; - -/** - The trust decision returned for this connection, which describes whether the connection should be blocked - or allowed, based on the `evaluationResult` returned when evaluating the `serverTrust` and the SSL pining - policy configured for this server. - - For example, the pinning validation could have failed (ie. validationResult being - `TSKTrustEvaluationFailedNoMatchingPin`) but the policy might be set to ignore pinning validation failures - for this server, thereby returning `TSKTrustDecisionShouldAllowConnection`. - */ -@property (nonatomic, readonly) TSKTrustDecision finalTrustDecision; - -/** - The time it took for the SSL pinning validation to be performed. - */ -@property (nonatomic, readonly) NSTimeInterval validationDuration; - -/** - The certificate chain extracted from the `serverTrust` as PEM-formatted certificates. This is the - certificate chain sent by the server when establishing the connection. - */ -@property (nonatomic, readonly, nullable) NSArray *certificateChain; - -@end diff --git a/vendor/TrustKit/TSKPinningValidatorResult.m b/vendor/TrustKit/TSKPinningValidatorResult.m deleted file mode 100755 index 363b1a4b..00000000 --- a/vendor/TrustKit/TSKPinningValidatorResult.m +++ /dev/null @@ -1,49 +0,0 @@ -/* - - TSKPinningValidator.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKPinningValidatorResult.h" -#import "Reporting/reporting_utils.h" - -@implementation TSKPinningValidatorResult - -@synthesize certificateChain = _certificateChain; - -- (NSArray * _Nullable)certificateChain -{ - if (!_certificateChain) { - // Convert the server trust to a certificate chain - // This cannot be done in the dispatch_async() block as sometimes the serverTrust seems to become invalid once the block gets scheduled, even tho its retain count is still positive - _certificateChain = convertTrustToPemArray(self.serverTrust); - } - return _certificateChain; -} - -- (instancetype _Nullable)initWithServerHostname:(NSString * _Nonnull)serverHostname - serverTrust:(SecTrustRef _Nonnull)serverTrust - validationResult:(TSKTrustEvaluationResult)validationResult - finalTrustDecision:(TSKTrustDecision)finalTrustDecision - validationDuration:(NSTimeInterval)validationDuration -{ - NSParameterAssert(serverHostname); - NSParameterAssert(serverTrust); - - self = [super init]; - if (self) { - _serverHostname = serverHostname; - _serverTrust = serverTrust; - _evaluationResult = validationResult; - _finalTrustDecision = finalTrustDecision; - _validationDuration = validationDuration; - } - return self; -} - -@end diff --git a/vendor/TrustKit/TSKPinningValidator_Private.h b/vendor/TrustKit/TSKPinningValidator_Private.h deleted file mode 100755 index 3eb0b498..00000000 --- a/vendor/TrustKit/TSKPinningValidator_Private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - - TSKPinningValidator_Private.h - TrustKit - - Copyright 2017 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -NS_ASSUME_NONNULL_BEGIN - -/* Methods that are internal to TrustKit */ -@interface TSKPinningValidator (Internal) - -/** - Initialize an instance of TSKPinningValidator. - - @param domainPinningPolicies A dictionnary of domains and the corresponding pinning policy. - @param hashCache The hash cache to use. If nil, no caching is performed, performance may suffer. - @param ignorePinsForUserTrustAnchors Set to true to ignore the trust anchors in the user trust store - @param validationCallbackQueue The queue used when invoking the validationResultHandler - @param validationCallback The callback invoked with validation results - @return Initialized instance - */ -- (instancetype _Nullable)initWithDomainPinningPolicies:(NSDictionary *)domainPinningPolicies - hashCache:(TSKSPKIHashCache *)hashCache - ignorePinsForUserTrustAnchors:(BOOL)ignorePinsForUserTrustAnchors - validationCallbackQueue:(dispatch_queue_t)validationCallbackQueue - validationCallback:(TSKPinningValidatorCallback)validationCallback; - -@end - - -@interface TSKPinningValidatorResult (Internal) - -- (instancetype _Nullable)initWithServerHostname:(NSString *)serverHostname - serverTrust:(SecTrustRef)serverTrust - validationResult:(TSKTrustEvaluationResult)validationResult - finalTrustDecision:(TSKTrustDecision)finalTrustDecision - validationDuration:(NSTimeInterval)validationDuration; - -@end - -NS_ASSUME_NONNULL_END diff --git a/vendor/TrustKit/TSKTrustDecision.h b/vendor/TrustKit/TSKTrustDecision.h deleted file mode 100755 index 50a684e2..00000000 --- a/vendor/TrustKit/TSKTrustDecision.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - - TSKTrustDecision.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -@import Foundation; - -/** - Possible return values when verifying a server's identity against a set of pins. - */ -typedef NS_ENUM(NSInteger, TSKTrustEvaluationResult) -{ - /** - The server trust was succesfully evaluated and contained at least one of the configured pins. - */ - TSKTrustEvaluationSuccess, - - /** - The server trust was succesfully evaluated but did not contain any of the configured pins. - */ - TSKTrustEvaluationFailedNoMatchingPin, - - /** - The server trust's evaluation failed: the server's certificate chain is not trusted. - */ - TSKTrustEvaluationFailedInvalidCertificateChain, - - /** - The server trust could not be evaluated due to invalid parameters. - */ - TSKTrustEvaluationErrorInvalidParameters, - - /** - The server trust was succesfully evaluated but did not contain any of the configured pins. However, the certificate chain terminates at a user-defined trust anchor (ie. a custom/private CA that was manually added to the macOS trust store). Only available on macOS. - */ - TSKTrustEvaluationFailedUserDefinedTrustAnchor NS_AVAILABLE_MAC(10_9), - - /** - The server trust could not be evaluated due to an error when trying to generate the certificate's subject public key info hash. On iOS 9 or below, this could be caused by a Keychain failure when trying to extract the certificate's public key bytes. - */ - TSKTrustEvaluationErrorCouldNotGenerateSpkiHash, -}; - -/** - Possible return values when verifying a server's identity against an SSL pinning policy. - */ -typedef NS_ENUM(NSInteger, TSKTrustDecision) -{ - /** - Based on the server's certificate chain and the configured pinning policy for this domain, the SSL connection should be allowed. - This return value does not necessarily mean that the pinning validation succeded (for example if `kTSKEnforcePinning` was set to `NO` for this domain). If a pinning validation failure occured and if a report URI was configured, a pin failure report was sent. - */ - TSKTrustDecisionShouldAllowConnection, - - /** - Based on the server's certificate chain and the configured pinning policy for this domain, the SSL connection should be blocked. - A pinning validation failure occured and if a report URI was configured, a pin failure report was sent. - */ - TSKTrustDecisionShouldBlockConnection, - - /** - No pinning policy was configured for this domain and TrustKit did not validate the server's identity. - Because this will happen in an authentication handler, it means that the server's _serverTrust_ object __needs__ to be verified against the device's trust store using `SecTrustEvaluate()`. Failing to do so will __disable SSL certificate validation__. - */ - TSKTrustDecisionDomainNotPinned, -}; diff --git a/vendor/TrustKit/TSKTrustKitConfig.h b/vendor/TrustKit/TSKTrustKitConfig.h deleted file mode 100755 index c7946a55..00000000 --- a/vendor/TrustKit/TSKTrustKitConfig.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - - TSKTrustKitConfig.h - TrustKit - - Copyright 2017 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -@import Foundation; - - -/** - The version of TrustKit, such as "1.4.0". - */ -FOUNDATION_EXPORT NSString * const TrustKitVersion; - - -#pragma mark Configuration Keys - - -/** - A global, App-wide configuration key that can be set in the pinning policy. - */ -typedef NSString *TSKGlobalConfigurationKey; - - -/** - A domain-specific configuration key (to defined for a domain under the `kTSKPinnedDomains` - key) that can be set in the pinning policy. - */ -typedef NSString *TSKDomainConfigurationKey; - - -#pragma mark Global Configuration Keys - Required - - -/** - A boolean. If set to `YES`, TrustKit will perform method swizzling on the App's - `NSURLConnection` and `NSURLSession` delegates in order to automatically add SSL pinning - validation to the App's connections. This option can only be used if TrustKit is - initialized in singleton mode; default value is `NO`. - - Swizzling allows enabling pinning within an App without having to find and modify each - and every instance of `NSURLConnection` or `NSURLSession` delegates. - However, it should only be enabled for simple Apps, as it may not work properly in several - scenarios including: - - * Apps with complex connection delegates, for example to handle client authentication - via certificates or basic authentication. - * Apps where method swizzling of the connection delegates is already performed by another - module or library (such as Analytics SDKs). - * Apps that do no use `NSURLSession` or `NSURLConnection` for their connections. - - In such scenarios or if the developer wants a tigher control on the App's networking - behavior, `kTSKSwizzleNetworkDelegates` should be set to `NO`; the developer should then - manually add pinning validation to the App's authentication handlers. - - See the `TSKPinningValidator` class for instructions on how to do so. - */ -FOUNDATION_EXPORT const TSKGlobalConfigurationKey kTSKSwizzleNetworkDelegates; - - -/** - A dictionary with domains (such as _www.domain.com_) as keys and dictionaries as values. - - Each entry should contain domain-specific settings for performing pinning validation when - connecting to the domain, including for example the domain's public key hashes. A list of - all domain-specific keys is available in the "Domain-specific Keys" sections. - */ -FOUNDATION_EXPORT const TSKGlobalConfigurationKey kTSKPinnedDomains; - - - -#pragma mark Global Configuration Keys - Optional - - -/** - A boolean. If set to `YES`, pinning validation will be skipped if the server's certificate - chain terminates at a user-defined trust anchor (such as a root CA that isn't part of OS X's - default trust store) and no pin failure reports will be sent; default value is `YES`. - - This is useful for allowing SSL connections through corporate proxies or firewalls. See - "How does key pinning interact with local proxies and filters?" within the Chromium security - FAQ at https://www.chromium.org/Home/chromium-security/security-faq for more information. - - Only available on macOS. - */ -FOUNDATION_EXPORT const TSKGlobalConfigurationKey kTSKIgnorePinningForUserDefinedTrustAnchors NS_AVAILABLE_MAC(10_9); - - -#pragma mark Domain-Specific Configuration Keys - Required - -/** - An array of SSL pins, where each pin is the base64-encoded SHA-256 hash of a certificate's - Subject Public Key Info. - - TrustKit will verify that at least one of the specified pins is found in the server's - evaluated certificate chain. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKPublicKeyHashes; - - -/** - An array of `TSKSupportedAlgorithm` constants to specify the public key algorithms for the - keys to be pinned. - - TrustKit requires this information in order to compute SSL pins when validating a server's - certificate chain, because the `Security` framework does not provide APIs to extract the - key's algorithm from an SSL certificate. To minimize the performance impact of Trustkit, - only one algorithm should be enabled. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKPublicKeyAlgorithms; - - -#pragma mark Domain-Specific Configuration Keys - Optional - -/** - A boolean. If set to `NO`, TrustKit will not block SSL connections that caused a pin or - certificate validation error; default value is `YES`. - - When a pinning failure occurs, pin failure reports will always be sent to the configured - report URIs regardless of the value of `kTSKEnforcePinning`. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKEnforcePinning; - - -/** - A boolean. If set to `YES`, also pin all the subdomains of the specified domain; default - value is `NO`. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKIncludeSubdomains; - - -/** - A boolean. If set to `YES`, TrustKit will not pin this specific domain if `kTSKIncludeSubdomains` - was set for this domain's parent domain. - - This allows excluding specific subdomains from a pinning policy that was applied to a - parent domain. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKExcludeSubdomainFromParentPolicy; - - -/** - An array of URLs to which pin validation failures should be reported. - - To minimize the performance impact of sending reports on each validation failure, the reports - are uploaded using the background transfer service and are also rate-limited to one per day - and per type of failure. For HTTPS report URLs, the HTTPS connections will ignore the SSL - pinning policy and use the default certificate validation mechanisms, in order to maximize - the chance of the reports reaching the server. The format of the reports is similar to the - one described in RFC 7469 for the HPKP specification: - - { - "app-bundle-id": "com.datatheorem.testtrustkit2", - "app-version": "1", - "app-vendor-id": "599F9C00-92DC-4B5C-9464-7971F01F8370", - "app-platform": "IOS", - "app-platform-version": "10.2.0", - "trustkit-version": "1.3.1", - "hostname": "www.datatheorem.com", - "port": 0, - "noted-hostname": "datatheorem.com", - "include-subdomains": true, - "enforce-pinning": true, - "validated-certificate-chain": [ - pem1, ... pemN - ], - "known-pins": [ - "pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\"", - "pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\"" - ], - "validation-result":1 - } - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKReportUris; - - -/** - A boolean. If set to `YES`, the default report URL for sending pin failure reports will - be disabled; default value is `NO`. - - By default, pin failure reports are sent to a report server hosted by Data Theorem, for - detecting potential CA compromises and man-in-the-middle attacks, as well as providing a - free dashboard for developers; email info@datatheorem.com if you'd like a dashboard for - your App. Only pin failure reports are sent, which contain the App's bundle ID, the IDFV, - and the server's hostname and certificate chain that failed validation. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKDisableDefaultReportUri; - - -/** - A string containing the date, in yyyy-MM-dd format, on which the domain's configured SSL - pins expire, thus disabling pinning validation. If the key is not set, then the pins do - not expire. - - Expiration helps prevent connectivity issues in Apps which do not get updates to their - pin set, such as when the user disables App updates. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKExpirationDate; - -/** - An array of strings representing additional trust anchors usable for validating - the trust chain of pinned certificates that do not end in an OS trust anchor. - - The default behavior of TrustKit is to ignore these trust anchors unless compiled - in debug mode (pass -DDEBUG=1 to the preprocessor). This behavior can be modified - by subclassing TSKPinningValidator and overriding +allowsAdditionalTrustAnchors. - - The entries in the array should each be a single PEM-encoded public certificate. - Standard RFC-7468 PEM format is supported (see https://tools.ietf.org/html/rfc7468#section-2 ). - Note that the header, footer and any newlines are optional, but aid in readability. - - __SECURITY WARNING:__ - Misuse of this configuration option could potentially render your application - vulnerable to exploits since it bypasses the normal operating system trust store. - It is intended for enterprise scenarios where a company might be running their - own internal production-grade certificate authority for debugging purposes. - */ -FOUNDATION_EXPORT const TSKDomainConfigurationKey kTSKAdditionalTrustAnchors; - - -#pragma mark Supported Public Key Algorithm Keys - - -/** - A public key algorithm supported by TrustKit for generating the SSL pin for a certificate. - */ -typedef NSString *TSKSupportedAlgorithm; - - -/** - RSA 2048. - */ -FOUNDATION_EXPORT const TSKSupportedAlgorithm kTSKAlgorithmRsa2048; - - -/** - RSA 4096. - */ -FOUNDATION_EXPORT const TSKSupportedAlgorithm kTSKAlgorithmRsa4096; - - -/** - ECDSA with secp256r1 curve. - */ -FOUNDATION_EXPORT const TSKSupportedAlgorithm kTSKAlgorithmEcDsaSecp256r1; - - -/** - ECDSA with secp384r1 curve. - */ -FOUNDATION_EXPORT const TSKSupportedAlgorithm kTSKAlgorithmEcDsaSecp384r1; diff --git a/vendor/TrustKit/TSKTrustKitConfig.m b/vendor/TrustKit/TSKTrustKitConfig.m deleted file mode 100755 index e03d5a31..00000000 --- a/vendor/TrustKit/TSKTrustKitConfig.m +++ /dev/null @@ -1,38 +0,0 @@ -/* - - TSKTrustKitConfig.m - TrustKit - - Copyright 2017 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKTrustKitConfig.h" - -NSString * const TrustKitVersion = @"1.5.0"; - -// General keys -const TSKGlobalConfigurationKey kTSKSwizzleNetworkDelegates = @"TSKSwizzleNetworkDelegates"; -const TSKGlobalConfigurationKey kTSKPinnedDomains = @"TSKPinnedDomains"; - -const TSKGlobalConfigurationKey kTSKIgnorePinningForUserDefinedTrustAnchors = @"TSKIgnorePinningForUserDefinedTrustAnchors"; - -// Keys for each domain within the TSKPinnedDomains entry -const TSKDomainConfigurationKey kTSKPublicKeyHashes = @"TSKPublicKeyHashes"; -const TSKDomainConfigurationKey kTSKEnforcePinning = @"TSKEnforcePinning"; -const TSKDomainConfigurationKey kTSKExcludeSubdomainFromParentPolicy = @"kSKExcludeSubdomainFromParentPolicy"; - -const TSKDomainConfigurationKey kTSKIncludeSubdomains = @"TSKIncludeSubdomains"; -const TSKDomainConfigurationKey kTSKPublicKeyAlgorithms = @"TSKPublicKeyAlgorithms"; -const TSKDomainConfigurationKey kTSKReportUris = @"TSKReportUris"; -const TSKDomainConfigurationKey kTSKDisableDefaultReportUri = @"TSKDisableDefaultReportUri"; -const TSKDomainConfigurationKey kTSKExpirationDate = @"TSKExpirationDate"; -const TSKDomainConfigurationKey kTSKAdditionalTrustAnchors = @"TSKAdditionalTrustAnchors"; - -#pragma mark Public key Algorithms Constants -const TSKSupportedAlgorithm kTSKAlgorithmRsa2048 = @"TSKAlgorithmRsa2048"; -const TSKSupportedAlgorithm kTSKAlgorithmRsa4096 = @"TSKAlgorithmRsa4096"; -const TSKSupportedAlgorithm kTSKAlgorithmEcDsaSecp256r1 = @"TSKAlgorithmEcDsaSecp256r1"; -const TSKSupportedAlgorithm kTSKAlgorithmEcDsaSecp384r1 = @"TSKAlgorithmEcDsaSecp384r1"; diff --git a/vendor/TrustKit/TrustKit.h b/vendor/TrustKit/TrustKit.h deleted file mode 100755 index a43a0384..00000000 --- a/vendor/TrustKit/TrustKit.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - - TrustKit.h - TrustKit - - Copyright 2015 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -@import Foundation; - -#ifndef _TRUSTKIT_ -#define _TRUSTKIT_ - #import "TSKTrustKitConfig.h" - #import "TSKPinningValidatorResult.h" - #import "TSKPinningValidatorCallback.h" - #import "TSKPinningValidator.h" - #import "TSKTrustDecision.h" -#endif /* _TRUSTKIT_ */ - -NS_ASSUME_NONNULL_BEGIN - - -/** - `TrustKit` is the main class for configuring an SSL pinning policy within an App. - - For most Apps, TrustKit should be used as a singleton, where a global SSL pinning policy is - configured for the App. In singleton mode, the policy can be set either: - - * By adding it to the App's _Info.plist_ under the `TSKConfiguration` key, or - * By programmatically supplying it using the `+initSharedInstanceWithConfiguration:` method. - - In singleton mode, TrustKit can only be initialized once so only one of the two techniques - should be used. - - For more complex Apps where multiple SSL pinning policies need to be used independently - (for example within different frameworks), TrustKit can be used in "multi-instance" mode - by leveraging the `-initWithConfiguration:` method described at the end of this page. - - A TrustKit pinning policy is a dictionary which contains some global, App-wide settings - (of type `TSKGlobalConfigurationKey`) as well as domain-specific configuration keys - (of type `TSKDomainConfigurationKey`) to be defined under the `kTSKPinnedDomains` entry. - The following table shows the keys and the types of the corresponding values, and uses - indentation to indicate structure: - - ``` - | Key | Type | - |----------------------------------------------|------------| - | TSKSwizzleNetworkDelegates | Boolean | - | TSKIgnorePinningForUserDefinedTrustAnchors | Boolean | - | TSKPinnedDomains | Dictionary | - | __ | Dictionary | - | ____ TSKPublicKeyHashes | Array | - | ____ TSKPublicKeyAlgorithms | Array | - | ____ TSKIncludeSubdomains | Boolean | - | ____ TSKExcludeSubdomainFromParentPolicy | Boolean | - | ____ TSKEnforcePinning | Boolean | - | ____ TSKReportUris | Array | - | ____ TSKDisableDefaultReportUri | Boolean | - | ____ TSKAdditionalTrustAnchors | Array | - ``` - - When setting the pinning policy programmatically, it has to be supplied to the - `initSharedInstanceWithConfiguration:` method as a dictionary in order to initialize - TrustKit. For example: - - ``` - NSDictionary *trustKitConfig = - @{ - kTSKPinnedDomains : @{ - @"www.datatheorem.com" : @{ - kTSKExpirationDate: @"2017-12-01", - kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048], - kTSKPublicKeyHashes : @[ - @"HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=", - @"0SDf3cRToyZJaMsoS17oF72VMavLxj/N7WBNasNuiR8=" - ], - kTSKEnforcePinning : @NO, - kTSKReportUris : @[@"http://report.datatheorem.com/log_report"], - }, - @"yahoo.com" : @{ - kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096], - kTSKPublicKeyHashes : @[ - @"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=", - @"rFjc3wG7lTZe43zeYTvPq8k4xdDEutCmIhI5dn4oCeE=", - ], - kTSKIncludeSubdomains : @YES - } - }}; - - [TrustKit initSharedInstanceWithConfiguration:trustKitConfig]; - trustKit = [TrustKit sharedInstance]; - ``` - - Similarly, the TrustKit singleton can be initialized in Swift: - - ``` - let trustKitConfig = [ - kTSKSwizzleNetworkDelegates: false, - kTSKPinnedDomains: [ - "yahoo.com": [ - kTSKExpirationDate: "2017-12-01", - kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048], - kTSKPublicKeyHashes: [ - "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=", - "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=" - ],]]] as [String : Any] - - TrustKit.initSharedInstance(withConfiguration:trustKitConfig) - ``` - - After initialization, the `TrustKit` instance's `pinningValidator` should be used to implement - pinning validation within the App's network authentication handlers. - */ -@interface TrustKit : NSObject - - -#pragma mark Usage in Singleton Mode - -/** - Initialize the global TrustKit singleton with the supplied pinning policy. - - @param trustKitConfig A dictionary containing various keys for configuring the SSL pinning policy. - @exception NSException Thrown when the supplied configuration is invalid or TrustKit has - already been initialized. - - */ -+ (void)initSharedInstanceWithConfiguration:(NSDictionary *)trustKitConfig; - - -/** - Retrieve the global TrustKit singleton instance. Raises an exception if `+initSharedInstanceWithConfiguration:` - has not yet been invoked. - - @return the shared TrustKit singleton - */ -+ (instancetype)sharedInstance; - - -#pragma mark Implementing Pinning Validation - - -/** - Retrieve the validator instance conforming to the pinning policy of this TrustKit instance. - - The validator should be used to implement pinning validation within the App's network - authentication handlers. - */ -@property (nonatomic, nonnull) TSKPinningValidator *pinningValidator; - - -#pragma mark Configuring a Validation Callback - - -/** - Register a block to be invoked for every request that is going through TrustKit's pinning - validation mechanism. See `TSKPinningValidatorCallback` for more information. - */ -@property (nonatomic, nullable) TSKPinningValidatorCallback pinningValidatorCallback; - -/** - Queue on which to invoke the `pinningValidatorCallback`; default value is the main queue. - */ -@property (nonatomic, null_resettable) dispatch_queue_t pinningValidatorCallbackQueue; - - -#pragma mark Usage in Multi-Instance Mode - -/** - Initialize a local TrustKit instance with the supplied SSL pinning policy configuration. - - This method is useful in scenarios where the TrustKit singleton cannot be used, for example within - larger Apps that have split some of their functionality into multiple framework/SDK. Each - framework can initialize its own instance of TrustKit and use it for pinning validation independently - of the App's other components. - - @param trustKitConfig A dictionary containing various keys for configuring the SSL pinning policy. - */ -- (instancetype)initWithConfiguration:(NSDictionary *)trustKitConfig; - - - -#pragma mark Other Settings - -/** - Set the global logger. - - This method sets the global logger, used when any `TrustKit` instance needs to display a message to - the developer. - - If a global logger is not set, the default logger will be used, which will only print TrustKit log - messages (using `NSLog()`) when the App is built in Debug mode. If the App was built for Release, the default - logger will not print any messages at all. - */ -+ (void)setLoggerBlock:(void (^)(NSString *))block; - -@end -NS_ASSUME_NONNULL_END diff --git a/vendor/TrustKit/configuration_utils.h b/vendor/TrustKit/configuration_utils.h deleted file mode 100755 index a0bf414b..00000000 --- a/vendor/TrustKit/configuration_utils.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - - configuration_utils.h - TrustKit - - Copyright 2017 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKPinningValidatorCallback.h" - -@import Foundation; - -// Figure out if a specific domain is pinned and retrieve this domain's configuration key; returns nil if no configuration was found -NSString * _Nullable getPinningConfigurationKeyForDomain(NSString * _Nonnull hostname , NSDictionary * _Nonnull domainPinningPolicies); diff --git a/vendor/TrustKit/configuration_utils.m b/vendor/TrustKit/configuration_utils.m deleted file mode 100755 index eadea569..00000000 --- a/vendor/TrustKit/configuration_utils.m +++ /dev/null @@ -1,19 +0,0 @@ -/* - - configuration_utils.m - TrustKit - - Copyright 2017 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "configuration_utils.h" -#import "TSKTrustKitConfig.h" -#import "TSKLog.h" - -NSString * _Nullable getPinningConfigurationKeyForDomain(NSString * _Nonnull hostname , NSDictionary * _Nonnull domainPinningPolicies) -{ - return hostname; -} diff --git a/vendor/TrustKit/parse_configuration.h b/vendor/TrustKit/parse_configuration.h deleted file mode 100755 index a39d1507..00000000 --- a/vendor/TrustKit/parse_configuration.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - - parse_configuration.h - TrustKit - - Copyright 2016 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#ifndef parse_configuration_h -#define parse_configuration_h - -@import Foundation; - -NSDictionary *parseTrustKitConfiguration(NSDictionary *trustKitArguments); - -#endif /* parse_configuration_h */ diff --git a/vendor/TrustKit/parse_configuration.m b/vendor/TrustKit/parse_configuration.m deleted file mode 100755 index 8d348bc1..00000000 --- a/vendor/TrustKit/parse_configuration.m +++ /dev/null @@ -1,285 +0,0 @@ -/* - - parse_configuration.m - TrustKit - - Copyright 2016 The TrustKit Project Authors - Licensed under the MIT license, see associated LICENSE file for terms. - See AUTHORS file for the list of project authors. - - */ - -#import "TSKTrustKitConfig.h" -#import "parse_configuration.h" -#import "Pinning/TSKPublicKeyAlgorithm.h" -#import -#import "configuration_utils.h" - -static SecCertificateRef certificateFromPEM(NSString *pem) -{ - // NOTE: multi-certificate PEM is not supported since this is for individual - // trust anchor certificates. - - // Strip PEM header and footers. We don't support multi-certificate PEM. - NSMutableString *pemMutable = [pem stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet].mutableCopy; - - // Strip PEM header and footer - [pemMutable replaceOccurrencesOfString:@"-----BEGIN CERTIFICATE-----" - withString:@"" - options:(NSStringCompareOptions)(NSAnchoredSearch | NSLiteralSearch) - range:NSMakeRange(0, pemMutable.length)]; - - [pemMutable replaceOccurrencesOfString:@"-----END CERTIFICATE-----" - withString:@"" - options:(NSStringCompareOptions)(NSAnchoredSearch | NSBackwardsSearch | NSLiteralSearch) - range:NSMakeRange(0, pemMutable.length)]; - - NSData *pemData = [[NSData alloc] initWithBase64EncodedString:pemMutable - options:NSDataBase64DecodingIgnoreUnknownCharacters]; - SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef)pemData); - if (!cert) - { - [NSException raise:@"TrustKit configuration invalid" format:@"Failed to parse PEM certificate"]; - } - return cert; -} - - -NSDictionary *parseTrustKitConfiguration(NSDictionary *trustKitArguments) -{ - // Convert settings supplied by the user to a configuration dictionary that can be used by TrustKit - // This includes checking the sanity of the settings and converting public key hashes/pins from an - // NSSArray of NSStrings (as provided by the user) to an NSSet of NSData (as needed by TrustKit) - - NSMutableDictionary *finalConfiguration = [[NSMutableDictionary alloc]init]; - finalConfiguration[kTSKPinnedDomains] = [[NSMutableDictionary alloc]init]; - - - // Retrieve global settings - - // Should we auto-swizzle network delegates - NSNumber *shouldSwizzleNetworkDelegates = trustKitArguments[kTSKSwizzleNetworkDelegates]; - if (shouldSwizzleNetworkDelegates == nil) - { - // Default setting is NO - finalConfiguration[kTSKSwizzleNetworkDelegates] = @(NO); - } - else - { - finalConfiguration[kTSKSwizzleNetworkDelegates] = shouldSwizzleNetworkDelegates; - } - - -#if !TARGET_OS_IPHONE - // OS X only: extract the optional ignorePinningForUserDefinedTrustAnchors setting - NSNumber *shouldIgnorePinningForUserDefinedTrustAnchors = trustKitArguments[kTSKIgnorePinningForUserDefinedTrustAnchors]; - if (shouldIgnorePinningForUserDefinedTrustAnchors == nil) - { - // Default setting is YES - finalConfiguration[kTSKIgnorePinningForUserDefinedTrustAnchors] = @(YES); - } - else - { - finalConfiguration[kTSKIgnorePinningForUserDefinedTrustAnchors] = shouldIgnorePinningForUserDefinedTrustAnchors; - } -#endif - - // Retrieve the pinning policy for each domains - if ((trustKitArguments[kTSKPinnedDomains] == nil) || ([trustKitArguments[kTSKPinnedDomains] count] < 1)) - { - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with no pinned domains. The configuration format has changed: ensure your domain pinning policies are under the TSKPinnedDomains key within TSKConfiguration."]; - } - - - for (NSString *domainName in trustKitArguments[kTSKPinnedDomains]) - { - // Retrieve the supplied arguments for this domain - NSDictionary *domainPinningPolicy = trustKitArguments[kTSKPinnedDomains][domainName]; - NSMutableDictionary *domainFinalConfiguration = [[NSMutableDictionary alloc]init]; - - - // Always start with the optional excludeSubDomain setting; if it set, no other TSKDomainConfigurationKey can be set for this domain - NSNumber *shouldExcludeSubdomain = domainPinningPolicy[kTSKExcludeSubdomainFromParentPolicy]; - if (shouldExcludeSubdomain) - { - // Confirm that no other TSKDomainConfigurationKeys were set for this domain - if ([[domainPinningPolicy allKeys] count] > 1) - { - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with TSKExcludeSubdomainFromParentPolicy for domain %@ but detected additional configuration keys", domainName]; - } - - // Store the whole configuration and continue to the next domain entry - domainFinalConfiguration[kTSKExcludeSubdomainFromParentPolicy] = @(YES); - finalConfiguration[kTSKPinnedDomains][domainName] = [NSDictionary dictionaryWithDictionary:domainFinalConfiguration]; - continue; - } - else - { - // Default setting is NO - domainFinalConfiguration[kTSKExcludeSubdomainFromParentPolicy] = @(NO); - } - - // Default setting is NO - domainFinalConfiguration[kTSKIncludeSubdomains] = @(NO); - - // Extract the optional expiration date setting - NSString *expirationDateStr = domainPinningPolicy[kTSKExpirationDate]; - if (expirationDateStr != nil) - { - // Convert the string in the yyyy-MM-dd format into an actual date - NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; - [dateFormat setDateFormat:@"yyyy-MM-dd"]; - NSDate *expirationDate = [dateFormat dateFromString:expirationDateStr]; - domainFinalConfiguration[kTSKExpirationDate] = expirationDate; - } - - - // Extract the optional enforcePinning setting - NSNumber *shouldEnforcePinning = domainPinningPolicy[kTSKEnforcePinning]; - if (shouldEnforcePinning) - { - domainFinalConfiguration[kTSKEnforcePinning] = shouldEnforcePinning; - } - else - { - // Default setting is YES - domainFinalConfiguration[kTSKEnforcePinning] = @(YES); - } - - - // Extract the optional disableDefaultReportUri setting - NSNumber *shouldDisableDefaultReportUri = domainPinningPolicy[kTSKDisableDefaultReportUri]; - if (shouldDisableDefaultReportUri) - { - domainFinalConfiguration[kTSKDisableDefaultReportUri] = shouldDisableDefaultReportUri; - } - else - { - // Default setting is NO - domainFinalConfiguration[kTSKDisableDefaultReportUri] = @(NO); - } - - // Extract the optional additionalTrustAnchors setting - NSArray *additionalTrustAnchors = domainPinningPolicy[kTSKAdditionalTrustAnchors]; - if (additionalTrustAnchors) - { - CFMutableArrayRef anchorCerts = CFArrayCreateMutable(NULL, (CFIndex)additionalTrustAnchors.count, &kCFTypeArrayCallBacks); - NSInteger certIndex = 0; // used for logging error messages - for (NSString *pem in additionalTrustAnchors) { - SecCertificateRef cert = certificateFromPEM(pem); - if (cert == nil) { - [NSException raise:@"TrustKit configuration invalid" - format:@"Failed to parse PEM-encoded certificate at index %ld for domain %@", (long)certIndex, domainName]; - } - CFArrayAppendValue(anchorCerts, cert); - certIndex++; - } - domainFinalConfiguration[kTSKAdditionalTrustAnchors] = [(__bridge NSMutableArray *)anchorCerts copy]; - } - - // Extract the list of public key algorithms to support and convert them from string to the TSKPublicKeyAlgorithm type - NSArray *publicKeyAlgsStr = domainPinningPolicy[kTSKPublicKeyAlgorithms]; - if (publicKeyAlgsStr == nil) - { - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with an invalid value for %@ for domain %@", kTSKPublicKeyAlgorithms, domainName]; - } - NSMutableArray *publicKeyAlgs = [NSMutableArray array]; - for (NSString *algorithm in publicKeyAlgsStr) - { - if ([kTSKAlgorithmRsa2048 isEqualToString:algorithm]) - { - [publicKeyAlgs addObject:@(TSKPublicKeyAlgorithmRsa2048)]; - } - else if ([kTSKAlgorithmRsa4096 isEqualToString:algorithm]) - { - [publicKeyAlgs addObject:@(TSKPublicKeyAlgorithmRsa4096)]; - } - else if ([kTSKAlgorithmEcDsaSecp256r1 isEqualToString:algorithm]) - { - [publicKeyAlgs addObject:@(TSKPublicKeyAlgorithmEcDsaSecp256r1)]; - } - else if ([kTSKAlgorithmEcDsaSecp384r1 isEqualToString:algorithm]) - { - [publicKeyAlgs addObject:@(TSKPublicKeyAlgorithmEcDsaSecp384r1)]; - } - else - { - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with an invalid value for %@ for domain %@", kTSKPublicKeyAlgorithms, domainName]; - } - } - domainFinalConfiguration[kTSKPublicKeyAlgorithms] = [NSArray arrayWithArray:publicKeyAlgs]; - - - // Extract and convert the report URIs if defined - NSArray *reportUriList = domainPinningPolicy[kTSKReportUris]; - if (reportUriList != nil) - { - NSMutableArray *reportUriListFinal = [NSMutableArray array]; - for (NSString *reportUriStr in reportUriList) - { - NSURL *reportUri = [NSURL URLWithString:reportUriStr]; - if (reportUri == nil) - { - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with an invalid value for %@ for domain %@", kTSKReportUris, domainName]; - } - [reportUriListFinal addObject:reportUri]; - } - - domainFinalConfiguration[kTSKReportUris] = [NSArray arrayWithArray:reportUriListFinal]; - } - - - // Extract and convert the subject public key info hashes - NSArray *serverSslPinsBase64 = domainPinningPolicy[kTSKPublicKeyHashes]; - NSMutableSet *serverSslPinsSet = [NSMutableSet set]; - - for (NSString *pinnedKeyHashBase64 in serverSslPinsBase64) { - NSData *pinnedKeyHash = [[NSData alloc] initWithBase64EncodedString:pinnedKeyHashBase64 options:(NSDataBase64DecodingOptions)0]; - - if ([pinnedKeyHash length] != CC_SHA256_DIGEST_LENGTH) - { - // The subject public key info hash doesn't have a valid size - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with an invalid Pin %@ for domain %@", pinnedKeyHashBase64, domainName]; - } - - [serverSslPinsSet addObject:pinnedKeyHash]; - } - - - NSUInteger requiredNumberOfPins = [domainFinalConfiguration[kTSKEnforcePinning] boolValue] ? 2 : 1; - if([serverSslPinsSet count] < requiredNumberOfPins) - { - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with less than %lu pins (ie. no backup pins) for domain %@. This might brick your App; please review the Getting Started guide in ./docs/getting-started.md", (unsigned long)requiredNumberOfPins, domainName]; - } - - // Save the hashes for this server as an NSSet for quick lookup - domainFinalConfiguration[kTSKPublicKeyHashes] = [NSSet setWithSet:serverSslPinsSet]; - - // Store the whole configuration - finalConfiguration[kTSKPinnedDomains][domainName] = [NSDictionary dictionaryWithDictionary:domainFinalConfiguration]; - } - - // Lastly, ensure that we can find a parent policy for subdomains configured with TSKExcludeSubdomainFromParentPolicy - for (NSString *domainName in finalConfiguration[kTSKPinnedDomains]) - { - if ([finalConfiguration[kTSKPinnedDomains][domainName][kTSKExcludeSubdomainFromParentPolicy] boolValue]) - { - // To force the lookup of a parent domain, we append 'a' to this subdomain so we don't retrieve its policy - NSString *parentDomainConfigKey = getPinningConfigurationKeyForDomain([@"a" stringByAppendingString:domainName], finalConfiguration[kTSKPinnedDomains]); - if (parentDomainConfigKey == nil) - { - [NSException raise:@"TrustKit configuration invalid" - format:@"TrustKit was initialized with TSKExcludeSubdomainFromParentPolicy for domain %@ but could not find a policy for a parent domain", domainName]; - } - } - } - - return [finalConfiguration copy]; -}