Swiftpack.co - Package - datatheorem/TrustKit

TrustKit

Build Status Carthage compatible Version Status Platform License MIT Gitter chat

TrustKit is an open source framework that makes it easy to deploy SSL public key pinning and reporting in any iOS 11+, macOS 10.13+, tvOS 11+ or watchOS 4+ App; it supports both Swift and Objective-C Apps.

If you need SSL pinning/reporting in your Android App. we have also released TrustKit for Android at https://github.com/datatheorem/TrustKit-Android.

Overview

TrustKit provides the following features:

  • Simple API to configure an SSL pinning policy and enforce it within an App. The policy settings are heavily based on the HTTP Public Key Pinning specification.
  • Sane implementation by pinning the certificate's Subject Public Key Info, as opposed to the certificate itself or the public key bits.
  • Reporting mechanism to notify a server about pinning validation failures happening within the App, when an unexpected certificate chain is detected. This is similar to the report-uri directive described in the HPKP specification. The reporting mechanism can also be customized within the App by leveraging pin validation notifications sent by TrustKit.
  • Auto-pinning functionality by swizzling the App's NSURLConnection and NSURLSession delegates in order to automatically add pinning validation to the App's HTTPS connections; this allows deploying TrustKit without even modifying the App's source code.

Getting Started

Sample Usage

Deploying SSL pinning in the App requires initializing TrustKit with a pinning policy (domains, Subject Public Key Info hashes, and additional settings).

The policy can be configured within the App's Info.plist:

Info.plist policy

Alternatively, the pinning policy can be set programmatically:

    NSDictionary *trustKitConfig =
  @{
    kTSKSwizzleNetworkDelegates: @NO,
    kTSKPinnedDomains : @{
            @"www.datatheorem.com" : @{
                    kTSKExpirationDate: @"2017-12-01",
                    kTSKPublicKeyHashes : @[
                            @"HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=",
                            @"0SDf3cRToyZJaMsoS17oF72VMavLxj/N7WBNasNuiR8="
                            ],
                    kTSKEnforcePinning : @NO,
                    kTSKReportUris : @[@"http://report.datatheorem.com/log_report"],
                    },
            @"yahoo.com" : @{
                    kTSKPublicKeyHashes : @[
                            @"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
                            @"rFjc3wG7lTZe43zeYTvPq8k4xdDEutCmIhI5dn4oCeE=",
                            ],
                    kTSKIncludeSubdomains : @YES
                    }
            }};
    
    [TrustKit initSharedInstanceWithConfiguration:trustKitConfig];

The policy can also be set programmatically in Swift Apps:

        let trustKitConfig = [
            kTSKSwizzleNetworkDelegates: false,
            kTSKPinnedDomains: [
                "yahoo.com": [
                    kTSKExpirationDate: "2017-12-01",
                    kTSKPublicKeyHashes: [
                        "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=",
                        "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="
                    ],]]] as [String : Any]
        
        TrustKit.initSharedInstance(withConfiguration:trustKitConfig)

After TrustKit has been initialized, a TSKPinningValidator instance can be retrieved from the TrustKit singleton, and can be used to perform SSL pinning validation in the App's network delegates. For example in an NSURLSessionDelegate:

- (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);
    }
}

For more information, see the Getting Started guide.

Credits

TrustKit is a joint-effort between the mobile teams at Data Theorem and Yahoo. See AUTHORS for details.

License

TrustKit is released under the MIT license. See LICENSE for details.

Github

link
Stars: 1403

Dependencies

Used By

Total: 0

Releases

1.7.0 - 2020-09-13 12:31:43

  • Fixed crash when encountering an invalid domain name (#210).
  • Fixed crash when encountering an unsupported public key algorithm (#211).
  • Fixed support for Carthage and the Swift Package Manager (#222).
  • Added "Dynamic" and "Static" products to the Swift Package Manager configuration to allow choosing the linking style (#234).
  • Dropped support for iOS 10, macOS 10.12, tvOS 10 and watchOS 3 (#232).

1.6.5 - 2020-03-20 01:40:20

  • Bug fix for supporting the Swift package manager (#220).

1.6.4 - 2019-12-25 15:41:17

  • Added support for the Swift package manager (#214).

1.6.3 - 2019-11-06 00:12:05

  • Fixed minor security warnings (#213, #212).

1.6.2 - 2019-08-04 03:10:06

  • Fixed handling of overlapping pin sets when using kTSKIncludeSubdomains (#200).
  • Enabled Modules in the CocoaPods spec file so that TrustKit can be packaged in a static Swift library (#205).

1.6.1 - 2019-02-17 22:55:14

  • Fixed a bug with the kTSKExcludeSubdomainFromParentPolicy setting (#187).
  • Fixed static analysis warnings in Xcode 10.

1.6.0 - 2018-09-26 04:59:04

  • Dropped support for iOS 8 and iOS 9.
  • Fixed build errors on iOS 12 (#172) and when using Objective-C++ (#160)
  • Added support for SSL reporting from app extensions (#168)
  • The TSKPublicKeyAlgorithms configuration key is now deprecated; the algorithm of the public key to pin no longer needs to be provided in the TrustKit configuration.
  • The TSKAdditionalTrustAnchors configuration key is now deprecated because its intended functionality no longer works on iOS (#154).
  • Fixed the expiration date logic to always use the UTC time zone (#166)

1.5.3 - 2018-02-20 23:52:11

  • Fixed issue with TSKIncludeSubdomains applying the pinning policy to the wrong domains when parsing the TrustKit configuration (#156).

1.5.2 - 2017-11-28 01:57:11

  • Fixed header name conflict with other SDKs such as Mopub (#150).
  • Fixed TSKSPKIHashCache's API by requiring the identifier to not be nil (#147).

1.5.1 - 2017-07-29 02:16:10

  • Fixed umbrella header and project targets for linking without CocoaPods.
  • Fixed a bug when using kTSKIncludeSubdomains with domains that have a TLD with the same length.
  • Fixed a crash when using a pinning validation callback to read the server's trust.
  • Fixed a crash when enabling kTSKSwizzleNetworkDelegates for connection delegates swizzling.

1.5.0 - 2017-07-13 14:02:44

  • Implemented major changes to support the usage of multiple instances of TrustKit, instead of being forced to use a singleton.
    • This is useful for larger Apps that have split some of their functionality into multiple frameworks/SDKs. Each framework can initialize its own instance of TrustKit and use it for pinning validation independently of the App's other components. See the -initWithConfig: method for more information.
    • The singleton approach should still be used by most Apps as it is simpler. A few minor code changes are required for Apps migrating from previous versions, detailed at the end of this page.
  • Pinning validation notifications have been removed and replaced by a callback that can be set in order to receive information about any pinning validation performed by TrustKit. See the pinningValidatorCallback property of the TrustKit class for more information.
  • The default value for the kTSKSwizzleNetworkDelegates setting has been changed to NO.
  • Support for iOS 7 and macOS 10.9 has been dropped.

Migrating from 1.4.2

For initializing TrustKit, switch from:

[TrustKit initializeWithConfiguration:trustKitConfig];

to:

[TrustKit initSharedInstanceWithConfiguration:trustKitConfig];

For any code using the TSKPinningValidator class, switch from:

[TSKPinningValidator handleChallenge:challenge completionHandler:completionHandler];

to:

[TrustKit.sharedInstance.pinningValidator handleChallenge:challenge completionHandler:completionHandler];

1.4.2 - 2017-03-01 19:59:05

  • New TSKExcludeSubdomainFromParentPolicy domain configuration key. If set to YES, TrustKit will not pin this specific domain if TSKIncludeSubdomains was set for this domain’s parent domain. This allows excluding specific subdomains from a pinning policy that was applied to a parent domain.
  • Switched from the build number (CFBundleVersion) to the release version number (CFBundleShortVersionString) for the app-version field within reports.
  • Various bug fixes:
    • Switch from the deprecated OSSpinLock to os_unfair_lock when running on an iOS 10+ / macOS 10.12+ device.
    • Fixed serialization warning during initialization.
    • Added support for newer gTLDs (such as .team).

1.4.1 - 2017-01-28 03:17:36

  • Added support for secp384r1 certificates (kTSKAlgorithmEcDsaSecp384r1).
  • Added the ability to specify an expiration date for a domain's pinning policy (kTSKExpirationDate). This will help prevent connectivity issues in Apps which do not get updates to their pins, such as when the user disables App updates.
  • A backup pin is no longer required when pinning validation is not enforced (ie. when kTSKEnforcePinning is set to NO).
  • Fixed a bug causing random unicode characters to be displayed in the date-time field of pinning failure reports sent by devices with non-standard time settings.
  • Improved the documentation and switched to jazzy for generating it.

1.4.0 - 2016-09-12 05:31:17

  • Added support for watchOS 3.0 and tvOS 10.0.
  • New utility method [TrustKit setLoggerBlock:] for overriding and customizing TrustKit's logging functionality.
  • New helper method [TSKPinningValidator handleChallenge:completionHandler:] to make it easy to implement pinning validation in NSURLSession and WKWebView delegates.
  • On iOS 10 devices, public keys are extracted from certificates using the new SecKey APIs, instead of leveraging the device's Keychain. This significantly simplifies and speeds up pinning validation.
  • On macOS, the vendor identifier sent along with reports is now randomly generated, instead of being derived from the computer's MAC address and the App's bundle ID; this removes IOKit as a dependency.
  • Replaced all pre-compiled libraries within the project (domain-registry-provider, OCMock) with the corresponding source code.

1.3.2 - 2016-06-21 21:11:34

  • Fixed validation error when enabling multiple public key algorithms (kTSKAlgorithm) for a single domain.

1.3.1 - 2016-06-08 23:08:45

  • Added two extra fields to the pinning failure reports:
    • "trustkit-version": the version number of the TrustKit library embedded within the App.
    • "enforce-pinning": whether TrustKit was configured to block the connection.
  • Fixed a rare crash triggered when sending a report and due to a SecTrustRef object being unexpectedly released.
  • A TrustKit configuration must now contain two different pins for each domain (including a backup pin).
  • A TrustKit configuration must now specify a value for the kTSKSwizzleNetworkDelegates setting, which controls whether the App's network delegates should be swizzled to automatically add SSL pinning validation. See the Getting Started guide for more information.

1.3.0 - 2016-05-25 01:24:08

  • Added NSNotifications (posted under the kTSKValidationCompletedNotification name) to allow Apps to be notified when TrustKit performed an SSL pinning validation for a connection. These notifications can be used for performance measurement or to act upon any pinning validation performed by TrustKit (for example to customize the reporting mechanism). More information is available in the documentation.
  • Various improvements to the test suite.

1.2.5 - 2016-02-29 22:00:53

  • Fixed TSKPinningValidator to reject invalid certificate chains when TrustKit is configured to not enforce pinning.
  • Improved performance and reliability by persisting the Subject Public Key Info cache to the filesystem across App restarts. This will reduce TrustKit's reliance on the Keychain to extract SPKIs from certificates, thereby speeding up the pinning validation process and also mitigating random Keychain errors (such as https://github.com/DinosaurDad/Keychain-34018).

1.2.4 - 2016-02-09 01:15:28

  • Fixed linker warnings caused by the pre-compiled domain_registry libraries.

1.2.3 - 2015-12-23 22:27:50

  • Switched from _Nonnull annotations to NS_ASSUME_NONNULL audited regions, in order to make TrustKit compatible with older versions of Xcode (6.3 and 6.4).

1.2.2 - 2015-12-20 10:10:02

  • Pinning failure reports from OS X Apps will now send a vendor identifier (just like on iOS) generated using a hash of the computer's MAC address and the App's bundle ID.
  • To avoid issues with locked devices and Apps running in the background, reports and certificates are now created using a data protection class set to AccessibleAfterFirstUnlock.
  • Added a new error code to detect Keychain failures when trying to extract the public key from a certificate on iOS.
  • Added a new "app-platform" field to pinning failure reports, which can be set to IOS or OSX.

1.2.1 - 2015-11-28 00:44:08

  • Removed an exception that would be thrown when trying to send a pin failure report while the device had no disk space left.
  • Fixed various issues affecting the stability of the project's test suite.

1.2.0 - 2015-10-21 01:32:59

  • Complete re-write of the hooking strategy to automatically add SSL pinning to the App's connections. TrustKit now swizzles NSURLSession and NSURLConnection delegates to add pinning validation to the delegate's authentication handler methods; for developers who want to call into TrustKit manually, this behavior can be disabled using the TSKSwizzleNetworkDelegates setting. This change was made due to the previous hooking strategy (targeting SecureTransport) not working on iOS 9.
  • The pinning policy format has slightly changed, in order to add new global settings: TSKSwizzleNetworkDelegates, TSKIgnorePinningForUserDefinedTrustAnchors, TSKPinnedDomains. If you have an existing pinning policy for TrustKit 1.1.3, all you need to do is put it under the TSKPinnedDomains key.
  • Greatly simplified the TSKPinningValidator API to make it easy to write authentication handlers that enforce the App's SSL pinning policy. Sample code describing how to do it is available in the documentation.
  • Updated Xcode project settings: stricter warnings, enabled bitcode, separate iOS and OS X build schemes.
  • Pinning failure reports now also send the IDFV in order to simplify the troubleshooting of errors, by being able to detect a single, malfunctioning device.

1.1.3 - 2015-08-25 17:05:45

  • Updated fishhook.
  • Fixed Xcode scheme for statically linking TrustKit, which was missing one file.

1.1.2 - 2015-08-02 20:11:30

  • Internal refactoring for integrating with Travis CI.
  • Added support for building TrustKit with the OS X 10.9 SDK.

1.1.1 - 2015-07-14 18:55:58

  • A pinning policy can no longer pin a domain suffix (such as org, net or less obvious suffixes like appspot.com) with TSKIncludeSubdomains enabled.
  • Fixed a typo preventing builds in Release mode.

1.1.0 - 2015-07-11 00:18:56

  • New TSKIgnorePinningForUserDefinedTrustAnchors configuration setting to skip pinning validation if the server's certificate chain terminates at a user-defined trust anchor. This is useful for allowing SSL connections through corporate proxies or firewalls. Only available on OS X.
  • The pinning policy can now be configured through the App's Info.plist even on iOS 7 and OS X 10.9.
  • Pin failure reports now also contain the result for the server's certificate chain evaluation in the validation-result field, in order to help troubleshoot pin validation failures.
  • A pinning policy is now required to provide two SSL pins minimum per domain, as specified in RFC 7469.
  • Renamed TSKPinVerifier to TSKPinningValidator. Also, the class will now send reports when pin validation failures occur.
  • If kTSKEnforcePinning is set to NO, no SSL connections will be blocked at all. In previous versions, SSL connections where the evaluation of the certificate chain failed (ie. "standard" certificate validation) would be blocked regardless of kTSKEnforcePinning.
  • Uploads of pin failure reports are now rate-limited to one per day, per domain and per type of failure. This will significantly reduce the amount of identical reports that get sent.

1.0.1 - 2015-06-23 02:37:36

  • Fixed a bug when using kTSKIncludeSubdomains, where two unrelated domains would be interpreted as subdomains of each other.

1.0.0 - 2015-06-23 02:32:23

Initial release.