diff --git a/docs/documentation/Classes.html b/docs/documentation/Classes.html new file mode 100644 index 0000000..8b29af2 --- /dev/null +++ b/docs/documentation/Classes.html @@ -0,0 +1,323 @@ + + + + Classes Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Classes

+

The following classes are available globally.

+ +
+
+
+
    +
  • +
    + + + + TSKPinningValidator + +
    +
    +
    +
    +
    +
    +

    TSKPinningValidator is a class for manually verifying a server’s identity against the global 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:

    + +
      +
    • evaluateTrust:forHostname: which evaluates the server’s certificate chain against the global SSL pinning policy.
    • +
    • handleChallenge:completionHandler: a helper method to be used for implementing pinning validation in challenge handler methods within NSURLSession and WKWebView delegates.
    • +
    + + See more +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    @interface TSKPinningValidator : NSObject
    + +
    +
    +

    Swift

    +
    class TSKPinningValidator : NSObject
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + TrustKit + +
    +
    +
    +
    +
    +
    +

    TrustKit is a class for programmatically configuring the global SSL pinning policy within an App.

    + +

    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 TrustKit class described here. Throughout the App’s lifecycle, TrustKit can only be initialized once so only one of the two techniques should be used.

    + +

    A TrustKit pinning policy is a dictionary which contains some global, App-wide settings as well as domain-specific configuration keys. The following table shows the keys and their types, and uses indentation to indicate structure:

    + +
    | Key                                          | Type       |
    +|----------------------------------------------|------------|
    +| `TSKSwizzleNetworkDelegates`                 | Boolean    |
    +| `TSKIgnorePinningForUserDefinedTrustAnchors` | Boolean    |
    +| `TSKPinnedDomains`                           | Dictionary |
    +| __ `<domain-name-to-pin-as-string>`          | Dictionary |
    +| ____ `TSKPublicKeyHashes`                    | Array      |
    +| ____ `TSKPublicKeyAlgorithms`                | Array      |
    +| ____ `TSKIncludeSubdomains`                  | Boolean    |
    +| ____ `TSKEnforcePinning`                     | Boolean    |
    +| ____ `TSKReportUris`                         | Array      |
    +| ____ `kTSKDisableDefaultReportUri`           | Boolean    |
    +
    + +

    When setting the pinning policy programmatically, it has to be supplied to the initializeWithConfiguration: method as a dictionary. For example:

    + +
       NSDictionary *trustKitConfig =
    +   @{
    +     kTSKSwizzleNetworkDelegates: @NO,
    +     kTSKPinnedDomains : @{
    +             @"www.datatheorem.com" : @{
    +                     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 initializeWithConfiguration:trustKitConfig];
    +
    + +

    Similarly, TrustKit can be initialized in Swift:

    + +
        let trustKitConfig = [
    +        kTSKSwizzleNetworkDelegates: false,
    +        kTSKPinnedDomains: [
    +            "yahoo.com": [
    +                kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048],
    +                kTSKPublicKeyHashes: [
    +                    "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=",
    +                    "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="
    +                  ],]]]
    +
    +    TrustKit.initializeWithConfiguration(config)
    +
    + +

    The various configuration keys that can be specified in the policy are described in the Constants section of the documentation.

    + +

    Lastly, once TrustKit has been initialized, kTSKValidationCompletedNotification notifications will be posted every time TrustKit validates the certificate chain of a server; these notifications provide some information about the validation that was done and can be used for example for performance measurement.

    + + See more +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    @interface TrustKit : NSObject
    + +
    +
    +

    Swift

    +
    class TrustKit : NSObject
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/Classes/TSKPinningValidator.html b/docs/documentation/Classes/TSKPinningValidator.html new file mode 100644 index 0000000..f6c26f4 --- /dev/null +++ b/docs/documentation/Classes/TSKPinningValidator.html @@ -0,0 +1,367 @@ + + + + TSKPinningValidator Class Reference + + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

TSKPinningValidator

+
+
+
@interface TSKPinningValidator : NSObject
+ +
+
+

TSKPinningValidator is a class for manually verifying a server’s identity against the global 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:

+ +
    +
  • evaluateTrust:forHostname: which evaluates the server’s certificate chain against the global SSL pinning policy.
  • +
  • handleChallenge:completionHandler: a helper method to be used for implementing pinning validation in challenge handler methods within NSURLSession and WKWebView delegates.
  • +
+ +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    Evaluate the supplied server trust against the global 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 .

    + +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (TSKTrustDecision)evaluateTrust:(SecTrustRef _Nonnull)serverTrust
    +                      forHostname:(NSString *_Nonnull)serverHostname;
    + +
    +
    +

    Swift

    +
    class func evaluateTrust(_ serverTrust: SecTrust, forHostname serverHostname: String) -> TSKTrustDecision
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + 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.

    + +
    +
    + + serverHostname + + +
    +

    The hostname of the server whose identity is being validated.

    + +
    +
    +
    +
    +

    Return Value

    +

    A TSKTrustDecision which describes whether the SSL connection should be allowed or blocked, based on the global pinning policy.

    + +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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 WKNavigationDelegate challenge handler method:

    + +
    - (void)webView:(WKWebView *)webView
    +didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
    +completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
    +NSURLCredential *credential))completionHandler
    +{
    +    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    +    {
    +        [TSKPinningValidator handleChallenge:challenge completionHandler:completionHandler];
    +    }
    +}
    +
    + +

    @exception NSException Thrown when TrustKit has not been initialized with a pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (BOOL)handleChallenge:(NSURLAuthenticationChallenge *_Nonnull)challenge
    +      completionHandler:
    +          (void (^_Nonnull)(NSURLSessionAuthChallengeDisposition,
    +                            NSURLCredential *_Nullable))completionHandler;
    + +
    +
    +

    Swift

    +
    class func handle(_ challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) -> Bool
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + challenge + + +
    +

    The authentication challenge, supplied by the URL loading system to the delegate’s challenge handler method.

    + +
    +
    + + completionHandler + + +
    +

    A block to invoke to respond to the challenge, supplied by the URL loading system to the delegate’s challenge handler method.

    + +
    +
    +
    +
    +

    Return Value

    +

    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).

    + +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/Classes/TrustKit.html b/docs/documentation/Classes/TrustKit.html new file mode 100644 index 0000000..0673ade --- /dev/null +++ b/docs/documentation/Classes/TrustKit.html @@ -0,0 +1,381 @@ + + + + TrustKit Class Reference + + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

TrustKit

+
+
+
@interface TrustKit : NSObject
+ +
+
+

TrustKit is a class for programmatically configuring the global SSL pinning policy within an App.

+ +

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 TrustKit class described here. Throughout the App’s lifecycle, TrustKit can only be initialized once so only one of the two techniques should be used.

+ +

A TrustKit pinning policy is a dictionary which contains some global, App-wide settings as well as domain-specific configuration keys. The following table shows the keys and their types, and uses indentation to indicate structure:

+ +
| Key                                          | Type       |
+|----------------------------------------------|------------|
+| `TSKSwizzleNetworkDelegates`                 | Boolean    |
+| `TSKIgnorePinningForUserDefinedTrustAnchors` | Boolean    |
+| `TSKPinnedDomains`                           | Dictionary |
+| __ `<domain-name-to-pin-as-string>`          | Dictionary |
+| ____ `TSKPublicKeyHashes`                    | Array      |
+| ____ `TSKPublicKeyAlgorithms`                | Array      |
+| ____ `TSKIncludeSubdomains`                  | Boolean    |
+| ____ `TSKEnforcePinning`                     | Boolean    |
+| ____ `TSKReportUris`                         | Array      |
+| ____ `kTSKDisableDefaultReportUri`           | Boolean    |
+
+ +

When setting the pinning policy programmatically, it has to be supplied to the initializeWithConfiguration: method as a dictionary. For example:

+ +
   NSDictionary *trustKitConfig =
+   @{
+     kTSKSwizzleNetworkDelegates: @NO,
+     kTSKPinnedDomains : @{
+             @"www.datatheorem.com" : @{
+                     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 initializeWithConfiguration:trustKitConfig];
+
+ +

Similarly, TrustKit can be initialized in Swift:

+ +
    let trustKitConfig = [
+        kTSKSwizzleNetworkDelegates: false,
+        kTSKPinnedDomains: [
+            "yahoo.com": [
+                kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048],
+                kTSKPublicKeyHashes: [
+                    "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=",
+                    "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="
+                  ],]]]
+
+    TrustKit.initializeWithConfiguration(config)
+
+ +

The various configuration keys that can be specified in the policy are described in the Constants section of the documentation.

+ +

Lastly, once TrustKit has been initialized, kTSKValidationCompletedNotification notifications will be posted every time TrustKit validates the certificate chain of a server; these notifications provide some information about the validation that was done and can be used for example for performance measurement.

+ +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    Initialize the global SSL pinning policy with the supplied configuration.

    + +

    This method should be called as early as possible in the App’s lifecycle to ensure that the App’s very first SSL connections are validated by TrustKit. Once TrustKit has been initialized, notifications will be posted for any SSL pinning validation performed.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (void)initializeWithConfiguration:(nonnull NSDictionary *)trustKitConfig;
    + +
    +
    +

    Swift

    +
    class func initialize(withConfiguration trustKitConfig: [AnyHashable : Any])
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + trustKitConfig + + +
    +

    A dictionary containing various keys for configuring the global SSL pinning policy.

    + +
    +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + +configuration + +
    +
    +
    +
    +
    +
    +

    Retrieve a copy of the global SSL pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (nullable NSDictionary *)configuration;
    + +
    +
    +

    Swift

    +
    class func configuration() -> [AnyHashable : Any]?
    + +
    +
    +
    +

    Return Value

    +

    A dictionary with a copy of the current TrustKit configuration, or nil if TrustKit has not been initialized.

    + +
    + +
    +
    +
  • +
  • +
    + + + + +setLoggerBlock: + +
    +
    +
    +
    +
    +
    +

    Set the global logger.

    + +

    This method sets the global logger, used when TrustKit needs to display a message to the developer.

    + +

    If a global logger is not set, the default logger will be used, which will 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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (void)setLoggerBlock:(nonnull void (^)(NSString *_Nonnull))block;
    + +
    +
    +

    Swift

    +
    class func setLoggerBlock(_ block: @escaping (String) -> Void)
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/Constants.html b/docs/documentation/Constants.html new file mode 100644 index 0000000..503e600 --- /dev/null +++ b/docs/documentation/Constants.html @@ -0,0 +1,997 @@ + + + + Constants Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Constants

+

The following constants are available globally.

+ +
+
+
+ +
    +
  • +
    + + + + TrustKitVersion + +
    +
    +
    +
    +
    +
    +

    The version of TrustKit, such as 1.4.0.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern NSString *const _Nonnull TrustKitVersion
    + +
    +
    +

    Swift

    +
    let TrustKitVersion: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    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.

    + +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKGlobalConfigurationKey _Nonnull kTSKSwizzleNetworkDelegates
    + +
    +
    +

    Swift

    +
    let kTSKSwizzleNetworkDelegates: String
    + +
    +
    + +
    +
    +
  • +
  • +
    + + + + kTSKPinnedDomains + +
    +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKGlobalConfigurationKey _Nonnull kTSKPinnedDomains
    + +
    +
    +

    Swift

    +
    let kTSKPinnedDomains: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKGlobalConfigurationKey _Nonnull kTSKIgnorePinningForUserDefinedTrustAnchors
    + +
    +
    +

    Swift

    +
    let kTSKIgnorePinningForUserDefinedTrustAnchors: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + kTSKPublicKeyHashes + +
    +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKPublicKeyHashes
    + +
    +
    +

    Swift

    +
    let kTSKPublicKeyHashes: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKPublicKeyAlgorithms
    + +
    +
    +

    Swift

    +
    let kTSKPublicKeyAlgorithms: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + kTSKEnforcePinning + +
    +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKEnforcePinning
    + +
    +
    +

    Swift

    +
    let kTSKEnforcePinning: String
    + +
    +
    + +
    +
    +
  • +
  • +
    + + + + kTSKIncludeSubdomains + +
    +
    +
    +
    +
    +
    +

    A boolean. If set to YES, also pin all the subdomains of the specified domain; default value is NO.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKIncludeSubdomains
    + +
    +
    +

    Swift

    +
    let kTSKIncludeSubdomains: String
    + +
    +
    + +
    +
    +
  • +
  • +
    + + + + kTSKReportUris + +
    +
    +
    +
    +
    +
    +

    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.example.ABC, + app-version:1.0, + app-vendor-id:599F9C00-92DC-4B5C-9464-7971F01F8370, + date-time: 2015-07-10T20:03:14Z, + hostname: mail.example.com, + port: 0, + include-subdomains: true, + noted-hostname: example.com, + validated-certificate-chain: [ + pem1, … pemN + ], + known-pins: [ + pin-sha256=\d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\, + “pin-sha256=“E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\ + ], + validation-result:1 + }

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKReportUris
    + +
    +
    +

    Swift

    +
    let kTSKReportUris: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKDisableDefaultReportUri
    + +
    +
    +

    Swift

    +
    let kTSKDisableDefaultReportUri: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ + +
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    The name of the notification to be posted for every request that is going through TrustKit’s pinning validation mechanism.

    + +

    Once TrustKit has been initialized, notifications will be posted with this name every time TrustKit validates the certificate chain for a server configured in the SSL pinning policy; if the server’s hostname does not have an entry in the pinning policy, no notifications get posted as no pinning validation was performed.

    + +

    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). The notifications provide details about TrustKit’s inner-workings which most Apps should not need to process. Hence, these notifications can be ignored unless the App requires some advanced customization in regards to pinning validation.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const NSString *_Nonnull kTSKValidationCompletedNotification
    + +
    +
    +

    Swift

    +
    static let tskValidationCompleted: NSNotification.Name
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    The time in seconds it took for the SSL pinning validation to be performed.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationDurationNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationDurationNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The TSKPinningValidationResult returned when validating the server’s certificate chain, which represents the result of evaluating the certificate chain against the configured SSL pins for this server.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationResultNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationResultNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The TSKTrustDecision returned when validating the certificate’s chain, which describes whether the connection should be blocked or allowed, based on the TSKPinningValidationResult returned when evaluating the server’s certificate chain and the SSL pining policy configured for this server.

    + +

    For example, the pinning validation could have failed (returning TSKPinningValidationFailed) but the policy might be set to ignore pinning validation failures for this server, thereby returning TSKTrustDecisionShouldAllowConnection.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationDecisionNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationDecisionNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The certificate chain returned by the server as an array of PEM-formatted certificates.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationCertificateChainNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationCertificateChainNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The entry within the SSL pinning configuration that was used as the pinning policy for the server being validated. It will be the same as the kTSKValidationServerHostnameNotificationKey entry unless the server is a subdomain of a domain configured in the pinning policy with kTSKIncludeSubdomains enabled. The corresponding pinning configuration that was used for validation can be retrieved using:

    + +
    NSString *notedHostname = userInfo[kTSKValidationNotedHostnameNotificationKey];
    +NSDictionary *hostnameConfiguration = [TrustKit configuration][kTSKPinnedDomains][notedHostname];
    +
    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationNotedHostnameNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationNotedHostnameNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The hostname of the server SSL pinning validation was performed against.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationServerHostnameNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationServerHostnameNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/Enums.html b/docs/documentation/Enums.html new file mode 100644 index 0000000..95dfb04 --- /dev/null +++ b/docs/documentation/Enums.html @@ -0,0 +1,191 @@ + + + + Enums Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Enums

+

The following enums are available globally.

+ +
+
+
+
    +
  • +
    + + + + TSKTrustDecision + +
    +
    +
    +
    +
    +
    +

    Possible return values when verifying a server’s identity against the global SSL pinning policy using TSKPinningValidator.

    + + See more +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    enum TSKTrustDecision : NSInteger {}
    + +
    +
    +

    Swift

    +
    enum TSKTrustDecision : Int
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/Enums/TSKTrustDecision.html b/docs/documentation/Enums/TSKTrustDecision.html new file mode 100644 index 0000000..21549f3 --- /dev/null +++ b/docs/documentation/Enums/TSKTrustDecision.html @@ -0,0 +1,270 @@ + + + + TSKTrustDecision Enum Reference + + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

TSKTrustDecision

+
+
+
enum TSKTrustDecision : NSInteger {}
+ +
+
+

Possible return values when verifying a server’s identity against the global SSL pinning policy using TSKPinningValidator.

+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Based on the server’s certificate chain and the global 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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    TSKTrustDecisionShouldAllowConnection
    + +
    +
    +

    Swift

    +
    case shouldAllowConnection = 0
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Based on the server’s certificate chain and the global 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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    TSKTrustDecisionShouldBlockConnection
    + +
    +
    +

    Swift

    +
    case shouldBlockConnection = 1
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    TSKTrustDecisionDomainNotPinned
    + +
    +
    +

    Swift

    +
    case domainNotPinned = 2
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/Type Definitions.html b/docs/documentation/Type Definitions.html new file mode 100644 index 0000000..7b84d8d --- /dev/null +++ b/docs/documentation/Type Definitions.html @@ -0,0 +1,330 @@ + + + + Type Definitions Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Type Definitions

+

The following type definitions are available globally.

+ +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    A global, App-wide configuration key that can be set in the pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    typedef NSString *TSKGlobalConfigurationKey
    + +
    +
    +

    Swift

    +
    typealias TSKGlobalConfigurationKey = NSString
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    A domain-specific configuration key (to defined for a domain under the kTSKPinnedDomains key) that can be set in the pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    typedef NSString *TSKDomainConfigurationKey
    + +
    +
    +

    Swift

    +
    typealias TSKDomainConfigurationKey = NSString
    + +
    +
    + +
    +
    +
  • +
+
+
+ + +
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    A key to be used to retrieve data about the pinning validation that occured, from the userInfo dictionary attached to a kTSKValidationCompletedNotification notification.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    typedef NSString *TSKNotificationUserInfoKey
    + +
    +
    +

    Swift

    +
    typealias TSKNotificationUserInfoKey = NSString
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/css/highlight.css b/docs/documentation/css/highlight.css new file mode 100644 index 0000000..d0db0e1 --- /dev/null +++ b/docs/documentation/css/highlight.css @@ -0,0 +1,200 @@ +/* Credit to https://gist.github.com/wataru420/2048287 */ +.highlight { + /* Comment */ + /* Error */ + /* Keyword */ + /* Operator */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Deleted */ + /* Generic.Deleted.Specific */ + /* Generic.Emph */ + /* Generic.Error */ + /* Generic.Heading */ + /* Generic.Inserted */ + /* Generic.Inserted.Specific */ + /* Generic.Output */ + /* Generic.Prompt */ + /* Generic.Strong */ + /* Generic.Subheading */ + /* Generic.Traceback */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Number */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Entity */ + /* Name.Exception */ + /* Name.Function */ + /* Name.Namespace */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Literal.Number.Integer.Long */ } + .highlight .c { + color: #999988; + font-style: italic; } + .highlight .err { + color: #a61717; + background-color: #e3d2d2; } + .highlight .k { + color: #000000; + font-weight: bold; } + .highlight .o { + color: #000000; + font-weight: bold; } + .highlight .cm { + color: #999988; + font-style: italic; } + .highlight .cp { + color: #999999; + font-weight: bold; } + .highlight .c1 { + color: #999988; + font-style: italic; } + .highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; } + .highlight .gd { + color: #000000; + background-color: #ffdddd; } + .highlight .gd .x { + color: #000000; + background-color: #ffaaaa; } + .highlight .ge { + color: #000000; + font-style: italic; } + .highlight .gr { + color: #aa0000; } + .highlight .gh { + color: #999999; } + .highlight .gi { + color: #000000; + background-color: #ddffdd; } + .highlight .gi .x { + color: #000000; + background-color: #aaffaa; } + .highlight .go { + color: #888888; } + .highlight .gp { + color: #555555; } + .highlight .gs { + font-weight: bold; } + .highlight .gu { + color: #aaaaaa; } + .highlight .gt { + color: #aa0000; } + .highlight .kc { + color: #000000; + font-weight: bold; } + .highlight .kd { + color: #000000; + font-weight: bold; } + .highlight .kp { + color: #000000; + font-weight: bold; } + .highlight .kr { + color: #000000; + font-weight: bold; } + .highlight .kt { + color: #445588; } + .highlight .m { + color: #009999; } + .highlight .s { + color: #d14; } + .highlight .na { + color: #008080; } + .highlight .nb { + color: #0086B3; } + .highlight .nc { + color: #445588; + font-weight: bold; } + .highlight .no { + color: #008080; } + .highlight .ni { + color: #800080; } + .highlight .ne { + color: #990000; + font-weight: bold; } + .highlight .nf { + color: #990000; } + .highlight .nn { + color: #555555; } + .highlight .nt { + color: #000080; } + .highlight .nv { + color: #008080; } + .highlight .ow { + color: #000000; + font-weight: bold; } + .highlight .w { + color: #bbbbbb; } + .highlight .mf { + color: #009999; } + .highlight .mh { + color: #009999; } + .highlight .mi { + color: #009999; } + .highlight .mo { + color: #009999; } + .highlight .sb { + color: #d14; } + .highlight .sc { + color: #d14; } + .highlight .sd { + color: #d14; } + .highlight .s2 { + color: #d14; } + .highlight .se { + color: #d14; } + .highlight .sh { + color: #d14; } + .highlight .si { + color: #d14; } + .highlight .sx { + color: #d14; } + .highlight .sr { + color: #009926; } + .highlight .s1 { + color: #d14; } + .highlight .ss { + color: #990073; } + .highlight .bp { + color: #999999; } + .highlight .vc { + color: #008080; } + .highlight .vg { + color: #008080; } + .highlight .vi { + color: #008080; } + .highlight .il { + color: #009999; } diff --git a/docs/documentation/css/jazzy.css b/docs/documentation/css/jazzy.css new file mode 100644 index 0000000..d6d65b7 --- /dev/null +++ b/docs/documentation/css/jazzy.css @@ -0,0 +1,332 @@ +html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { + background: transparent; + border: 0; + margin: 0; + outline: 0; + padding: 0; + vertical-align: baseline; } + +body { + background-color: #f2f2f2; + font-family: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + -webkit-font-smoothing: subpixel-antialiased; + word-wrap: break-word; } + +h1, h2, h3 { + margin-top: 0.8em; + margin-bottom: 0.3em; + font-weight: 100; + color: black; } + +h1 { + font-size: 2.5em; } + +h2 { + font-size: 2em; + border-bottom: 1px solid #e2e2e2; } + +h4 { + font-size: 13px; + line-height: 1.5; + margin-top: 21px; } + +h5 { + font-size: 1.1em; } + +h6 { + font-size: 1.1em; + color: #777; } + +.section-name { + color: gray; + display: block; + font-family: Helvetica; + font-size: 22px; + font-weight: 100; + margin-bottom: 15px; } + +pre, code { + font: 0.95em Menlo, monospace; + color: #777; + word-wrap: normal; } + +p code, li code { + background-color: #eee; + padding: 2px 4px; + border-radius: 4px; } + +a { + color: #0088cc; + text-decoration: none; } + +ul { + padding-left: 15px; } + +li { + line-height: 1.8em; } + +img { + max-width: 100%; } + +blockquote { + margin-left: 0; + padding: 0 10px; + border-left: 4px solid #ccc; } + +.content-wrapper { + margin: 0 auto; + width: 980px; } + +header { + font-size: 0.85em; + line-height: 26px; + background-color: #414141; + position: fixed; + width: 100%; + z-index: 1; } + header img { + padding-right: 6px; + vertical-align: -4px; + height: 16px; } + header a { + color: #fff; } + header p { + float: left; + color: #999; } + header .header-right { + float: right; + margin-left: 16px; } + +#breadcrumbs { + background-color: #f2f2f2; + height: 27px; + padding-top: 17px; + position: fixed; + width: 100%; + z-index: 1; + margin-top: 26px; } + #breadcrumbs #carat { + height: 10px; + margin: 0 5px; } + +.sidebar { + background-color: #f9f9f9; + border: 1px solid #e2e2e2; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + top: 70px; + bottom: 0; + width: 230px; + word-wrap: normal; } + +.nav-groups { + list-style-type: none; + background: #fff; + padding-left: 0; } + +.nav-group-name { + border-bottom: 1px solid #e2e2e2; + font-size: 1.1em; + font-weight: 100; + padding: 15px 0 15px 20px; } + .nav-group-name > a { + color: #333; } + +.nav-group-tasks { + margin-top: 5px; } + +.nav-group-task { + font-size: 0.9em; + list-style-type: none; + white-space: nowrap; } + .nav-group-task a { + color: #888; } + +.main-content { + background-color: #fff; + border: 1px solid #e2e2e2; + margin-left: 246px; + position: absolute; + overflow: hidden; + padding-bottom: 60px; + top: 70px; + width: 734px; } + .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { + margin-bottom: 1em; } + .main-content p { + line-height: 1.8em; } + .main-content section .section:first-child { + margin-top: 0; + padding-top: 0; } + .main-content section .task-group-section .task-group:first-of-type { + padding-top: 10px; } + .main-content section .task-group-section .task-group:first-of-type .section-name { + padding-top: 15px; } + +.section { + padding: 0 25px; } + +.highlight { + background-color: #eee; + padding: 10px 12px; + border: 1px solid #e2e2e2; + border-radius: 4px; + overflow-x: auto; } + +.declaration .highlight { + overflow-x: initial; + padding: 0 40px 40px 0; + margin-bottom: -25px; + background-color: transparent; + border: none; } + +.section-name { + margin: 0; + margin-left: 18px; } + +.task-group-section { + padding-left: 6px; + border-top: 1px solid #e2e2e2; } + +.task-group { + padding-top: 0px; } + +.task-name-container a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.item { + padding-top: 8px; + width: 100%; + list-style-type: none; } + .item a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .item code { + background-color: transparent; + padding: 0; } + .item .token { + padding-left: 3px; + margin-left: 15px; + font-size: 11.9px; } + .item .declaration-note { + font-size: .85em; + color: gray; + font-style: italic; } + +.pointer-container { + border-bottom: 1px solid #e2e2e2; + left: -23px; + padding-bottom: 13px; + position: relative; + width: 110%; } + +.pointer { + background: #f9f9f9; + border-left: 1px solid #e2e2e2; + border-top: 1px solid #e2e2e2; + height: 12px; + left: 21px; + top: -7px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + width: 12px; } + +.height-container { + display: none; + left: -25px; + padding: 0 25px; + position: relative; + width: 100%; + overflow: hidden; } + .height-container .section { + background: #f9f9f9; + border-bottom: 1px solid #e2e2e2; + left: -25px; + position: relative; + width: 100%; + padding-top: 10px; + padding-bottom: 5px; } + +.aside, .language { + padding: 6px 12px; + margin: 12px 0; + border-left: 5px solid #dddddd; + overflow-y: hidden; } + .aside .aside-title, .language .aside-title { + font-size: 9px; + letter-spacing: 2px; + text-transform: uppercase; + padding-bottom: 0; + margin: 0; + color: #aaa; + -webkit-user-select: none; } + .aside p:last-child, .language p:last-child { + margin-bottom: 0; } + +.language { + border-left: 5px solid #cde9f4; } + .language .aside-title { + color: #4b8afb; } + +.aside-warning { + border-left: 5px solid #ff6666; } + .aside-warning .aside-title { + color: #ff0000; } + +.graybox { + border-collapse: collapse; + width: 100%; } + .graybox p { + margin: 0; + word-break: break-word; + min-width: 50px; } + .graybox td { + border: 1px solid #e2e2e2; + padding: 5px 25px 5px 10px; + vertical-align: middle; } + .graybox tr td:first-of-type { + text-align: right; + padding: 7px; + vertical-align: top; + word-break: normal; + width: 40px; } + +.slightly-smaller { + font-size: 0.9em; } + +#footer { + position: absolute; + bottom: 10px; + margin-left: 25px; } + #footer p { + margin: 0; + color: #aaa; + font-size: 0.8em; } + +html.dash header, html.dash #breadcrumbs, html.dash .sidebar { + display: none; } +html.dash .main-content { + width: 980px; + margin-left: 0; + border: none; + width: 100%; + top: 0; + padding-bottom: 0; } +html.dash .height-container { + display: block; } +html.dash .item .token { + margin-left: 0; } +html.dash .content-wrapper { + width: auto; } +html.dash #footer { + position: static; } diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Info.plist b/docs/documentation/docsets/TrustKit.docset/Contents/Info.plist new file mode 100644 index 0000000..fd7ad8a --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleIdentifier + com.jazzy.trustkit + CFBundleName + TrustKit + DocSetPlatformFamily + trustkit + isDashDocset + + dashIndexFilePath + index.html + isJavaScriptEnabled + + DashDocSetFamily + dashtoc + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes.html new file mode 100644 index 0000000..8b29af2 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes.html @@ -0,0 +1,323 @@ + + + + Classes Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Classes

+

The following classes are available globally.

+ +
+
+
+
    +
  • +
    + + + + TSKPinningValidator + +
    +
    +
    +
    +
    +
    +

    TSKPinningValidator is a class for manually verifying a server’s identity against the global 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:

    + +
      +
    • evaluateTrust:forHostname: which evaluates the server’s certificate chain against the global SSL pinning policy.
    • +
    • handleChallenge:completionHandler: a helper method to be used for implementing pinning validation in challenge handler methods within NSURLSession and WKWebView delegates.
    • +
    + + See more +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    @interface TSKPinningValidator : NSObject
    + +
    +
    +

    Swift

    +
    class TSKPinningValidator : NSObject
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + TrustKit + +
    +
    +
    +
    +
    +
    +

    TrustKit is a class for programmatically configuring the global SSL pinning policy within an App.

    + +

    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 TrustKit class described here. Throughout the App’s lifecycle, TrustKit can only be initialized once so only one of the two techniques should be used.

    + +

    A TrustKit pinning policy is a dictionary which contains some global, App-wide settings as well as domain-specific configuration keys. The following table shows the keys and their types, and uses indentation to indicate structure:

    + +
    | Key                                          | Type       |
    +|----------------------------------------------|------------|
    +| `TSKSwizzleNetworkDelegates`                 | Boolean    |
    +| `TSKIgnorePinningForUserDefinedTrustAnchors` | Boolean    |
    +| `TSKPinnedDomains`                           | Dictionary |
    +| __ `<domain-name-to-pin-as-string>`          | Dictionary |
    +| ____ `TSKPublicKeyHashes`                    | Array      |
    +| ____ `TSKPublicKeyAlgorithms`                | Array      |
    +| ____ `TSKIncludeSubdomains`                  | Boolean    |
    +| ____ `TSKEnforcePinning`                     | Boolean    |
    +| ____ `TSKReportUris`                         | Array      |
    +| ____ `kTSKDisableDefaultReportUri`           | Boolean    |
    +
    + +

    When setting the pinning policy programmatically, it has to be supplied to the initializeWithConfiguration: method as a dictionary. For example:

    + +
       NSDictionary *trustKitConfig =
    +   @{
    +     kTSKSwizzleNetworkDelegates: @NO,
    +     kTSKPinnedDomains : @{
    +             @"www.datatheorem.com" : @{
    +                     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 initializeWithConfiguration:trustKitConfig];
    +
    + +

    Similarly, TrustKit can be initialized in Swift:

    + +
        let trustKitConfig = [
    +        kTSKSwizzleNetworkDelegates: false,
    +        kTSKPinnedDomains: [
    +            "yahoo.com": [
    +                kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048],
    +                kTSKPublicKeyHashes: [
    +                    "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=",
    +                    "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="
    +                  ],]]]
    +
    +    TrustKit.initializeWithConfiguration(config)
    +
    + +

    The various configuration keys that can be specified in the policy are described in the Constants section of the documentation.

    + +

    Lastly, once TrustKit has been initialized, kTSKValidationCompletedNotification notifications will be posted every time TrustKit validates the certificate chain of a server; these notifications provide some information about the validation that was done and can be used for example for performance measurement.

    + + See more +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    @interface TrustKit : NSObject
    + +
    +
    +

    Swift

    +
    class TrustKit : NSObject
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes/TSKPinningValidator.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes/TSKPinningValidator.html new file mode 100644 index 0000000..f6c26f4 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes/TSKPinningValidator.html @@ -0,0 +1,367 @@ + + + + TSKPinningValidator Class Reference + + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

TSKPinningValidator

+
+
+
@interface TSKPinningValidator : NSObject
+ +
+
+

TSKPinningValidator is a class for manually verifying a server’s identity against the global 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:

+ +
    +
  • evaluateTrust:forHostname: which evaluates the server’s certificate chain against the global SSL pinning policy.
  • +
  • handleChallenge:completionHandler: a helper method to be used for implementing pinning validation in challenge handler methods within NSURLSession and WKWebView delegates.
  • +
+ +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    Evaluate the supplied server trust against the global 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 .

    + +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (TSKTrustDecision)evaluateTrust:(SecTrustRef _Nonnull)serverTrust
    +                      forHostname:(NSString *_Nonnull)serverHostname;
    + +
    +
    +

    Swift

    +
    class func evaluateTrust(_ serverTrust: SecTrust, forHostname serverHostname: String) -> TSKTrustDecision
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + 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.

    + +
    +
    + + serverHostname + + +
    +

    The hostname of the server whose identity is being validated.

    + +
    +
    +
    +
    +

    Return Value

    +

    A TSKTrustDecision which describes whether the SSL connection should be allowed or blocked, based on the global pinning policy.

    + +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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 WKNavigationDelegate challenge handler method:

    + +
    - (void)webView:(WKWebView *)webView
    +didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
    +completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
    +NSURLCredential *credential))completionHandler
    +{
    +    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    +    {
    +        [TSKPinningValidator handleChallenge:challenge completionHandler:completionHandler];
    +    }
    +}
    +
    + +

    @exception NSException Thrown when TrustKit has not been initialized with a pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (BOOL)handleChallenge:(NSURLAuthenticationChallenge *_Nonnull)challenge
    +      completionHandler:
    +          (void (^_Nonnull)(NSURLSessionAuthChallengeDisposition,
    +                            NSURLCredential *_Nullable))completionHandler;
    + +
    +
    +

    Swift

    +
    class func handle(_ challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) -> Bool
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + challenge + + +
    +

    The authentication challenge, supplied by the URL loading system to the delegate’s challenge handler method.

    + +
    +
    + + completionHandler + + +
    +

    A block to invoke to respond to the challenge, supplied by the URL loading system to the delegate’s challenge handler method.

    + +
    +
    +
    +
    +

    Return Value

    +

    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).

    + +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes/TrustKit.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes/TrustKit.html new file mode 100644 index 0000000..0673ade --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Classes/TrustKit.html @@ -0,0 +1,381 @@ + + + + TrustKit Class Reference + + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

TrustKit

+
+
+
@interface TrustKit : NSObject
+ +
+
+

TrustKit is a class for programmatically configuring the global SSL pinning policy within an App.

+ +

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 TrustKit class described here. Throughout the App’s lifecycle, TrustKit can only be initialized once so only one of the two techniques should be used.

+ +

A TrustKit pinning policy is a dictionary which contains some global, App-wide settings as well as domain-specific configuration keys. The following table shows the keys and their types, and uses indentation to indicate structure:

+ +
| Key                                          | Type       |
+|----------------------------------------------|------------|
+| `TSKSwizzleNetworkDelegates`                 | Boolean    |
+| `TSKIgnorePinningForUserDefinedTrustAnchors` | Boolean    |
+| `TSKPinnedDomains`                           | Dictionary |
+| __ `<domain-name-to-pin-as-string>`          | Dictionary |
+| ____ `TSKPublicKeyHashes`                    | Array      |
+| ____ `TSKPublicKeyAlgorithms`                | Array      |
+| ____ `TSKIncludeSubdomains`                  | Boolean    |
+| ____ `TSKEnforcePinning`                     | Boolean    |
+| ____ `TSKReportUris`                         | Array      |
+| ____ `kTSKDisableDefaultReportUri`           | Boolean    |
+
+ +

When setting the pinning policy programmatically, it has to be supplied to the initializeWithConfiguration: method as a dictionary. For example:

+ +
   NSDictionary *trustKitConfig =
+   @{
+     kTSKSwizzleNetworkDelegates: @NO,
+     kTSKPinnedDomains : @{
+             @"www.datatheorem.com" : @{
+                     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 initializeWithConfiguration:trustKitConfig];
+
+ +

Similarly, TrustKit can be initialized in Swift:

+ +
    let trustKitConfig = [
+        kTSKSwizzleNetworkDelegates: false,
+        kTSKPinnedDomains: [
+            "yahoo.com": [
+                kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048],
+                kTSKPublicKeyHashes: [
+                    "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=",
+                    "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="
+                  ],]]]
+
+    TrustKit.initializeWithConfiguration(config)
+
+ +

The various configuration keys that can be specified in the policy are described in the Constants section of the documentation.

+ +

Lastly, once TrustKit has been initialized, kTSKValidationCompletedNotification notifications will be posted every time TrustKit validates the certificate chain of a server; these notifications provide some information about the validation that was done and can be used for example for performance measurement.

+ +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    Initialize the global SSL pinning policy with the supplied configuration.

    + +

    This method should be called as early as possible in the App’s lifecycle to ensure that the App’s very first SSL connections are validated by TrustKit. Once TrustKit has been initialized, notifications will be posted for any SSL pinning validation performed.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (void)initializeWithConfiguration:(nonnull NSDictionary *)trustKitConfig;
    + +
    +
    +

    Swift

    +
    class func initialize(withConfiguration trustKitConfig: [AnyHashable : Any])
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + trustKitConfig + + +
    +

    A dictionary containing various keys for configuring the global SSL pinning policy.

    + +
    +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + +configuration + +
    +
    +
    +
    +
    +
    +

    Retrieve a copy of the global SSL pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (nullable NSDictionary *)configuration;
    + +
    +
    +

    Swift

    +
    class func configuration() -> [AnyHashable : Any]?
    + +
    +
    +
    +

    Return Value

    +

    A dictionary with a copy of the current TrustKit configuration, or nil if TrustKit has not been initialized.

    + +
    + +
    +
    +
  • +
  • +
    + + + + +setLoggerBlock: + +
    +
    +
    +
    +
    +
    +

    Set the global logger.

    + +

    This method sets the global logger, used when TrustKit needs to display a message to the developer.

    + +

    If a global logger is not set, the default logger will be used, which will 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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    + (void)setLoggerBlock:(nonnull void (^)(NSString *_Nonnull))block;
    + +
    +
    +

    Swift

    +
    class func setLoggerBlock(_ block: @escaping (String) -> Void)
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Constants.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Constants.html new file mode 100644 index 0000000..503e600 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Constants.html @@ -0,0 +1,997 @@ + + + + Constants Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Constants

+

The following constants are available globally.

+ +
+
+
+ +
    +
  • +
    + + + + TrustKitVersion + +
    +
    +
    +
    +
    +
    +

    The version of TrustKit, such as 1.4.0.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern NSString *const _Nonnull TrustKitVersion
    + +
    +
    +

    Swift

    +
    let TrustKitVersion: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    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.

    + +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKGlobalConfigurationKey _Nonnull kTSKSwizzleNetworkDelegates
    + +
    +
    +

    Swift

    +
    let kTSKSwizzleNetworkDelegates: String
    + +
    +
    + +
    +
    +
  • +
  • +
    + + + + kTSKPinnedDomains + +
    +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKGlobalConfigurationKey _Nonnull kTSKPinnedDomains
    + +
    +
    +

    Swift

    +
    let kTSKPinnedDomains: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKGlobalConfigurationKey _Nonnull kTSKIgnorePinningForUserDefinedTrustAnchors
    + +
    +
    +

    Swift

    +
    let kTSKIgnorePinningForUserDefinedTrustAnchors: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + kTSKPublicKeyHashes + +
    +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKPublicKeyHashes
    + +
    +
    +

    Swift

    +
    let kTSKPublicKeyHashes: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKPublicKeyAlgorithms
    + +
    +
    +

    Swift

    +
    let kTSKPublicKeyAlgorithms: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • +
    + + + + kTSKEnforcePinning + +
    +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKEnforcePinning
    + +
    +
    +

    Swift

    +
    let kTSKEnforcePinning: String
    + +
    +
    + +
    +
    +
  • +
  • +
    + + + + kTSKIncludeSubdomains + +
    +
    +
    +
    +
    +
    +

    A boolean. If set to YES, also pin all the subdomains of the specified domain; default value is NO.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKIncludeSubdomains
    + +
    +
    +

    Swift

    +
    let kTSKIncludeSubdomains: String
    + +
    +
    + +
    +
    +
  • +
  • +
    + + + + kTSKReportUris + +
    +
    +
    +
    +
    +
    +

    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.example.ABC, + app-version:1.0, + app-vendor-id:599F9C00-92DC-4B5C-9464-7971F01F8370, + date-time: 2015-07-10T20:03:14Z, + hostname: mail.example.com, + port: 0, + include-subdomains: true, + noted-hostname: example.com, + validated-certificate-chain: [ + pem1, … pemN + ], + known-pins: [ + pin-sha256=\d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\, + “pin-sha256=“E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\ + ], + validation-result:1 + }

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKReportUris
    + +
    +
    +

    Swift

    +
    let kTSKReportUris: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKDomainConfigurationKey _Nonnull kTSKDisableDefaultReportUri
    + +
    +
    +

    Swift

    +
    let kTSKDisableDefaultReportUri: String
    + +
    +
    + +
    +
    +
  • +
+
+
+ + +
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    The name of the notification to be posted for every request that is going through TrustKit’s pinning validation mechanism.

    + +

    Once TrustKit has been initialized, notifications will be posted with this name every time TrustKit validates the certificate chain for a server configured in the SSL pinning policy; if the server’s hostname does not have an entry in the pinning policy, no notifications get posted as no pinning validation was performed.

    + +

    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). The notifications provide details about TrustKit’s inner-workings which most Apps should not need to process. Hence, these notifications can be ignored unless the App requires some advanced customization in regards to pinning validation.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const NSString *_Nonnull kTSKValidationCompletedNotification
    + +
    +
    +

    Swift

    +
    static let tskValidationCompleted: NSNotification.Name
    + +
    +
    + +
    +
    +
  • +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    The time in seconds it took for the SSL pinning validation to be performed.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationDurationNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationDurationNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The TSKPinningValidationResult returned when validating the server’s certificate chain, which represents the result of evaluating the certificate chain against the configured SSL pins for this server.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationResultNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationResultNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The TSKTrustDecision returned when validating the certificate’s chain, which describes whether the connection should be blocked or allowed, based on the TSKPinningValidationResult returned when evaluating the server’s certificate chain and the SSL pining policy configured for this server.

    + +

    For example, the pinning validation could have failed (returning TSKPinningValidationFailed) but the policy might be set to ignore pinning validation failures for this server, thereby returning TSKTrustDecisionShouldAllowConnection.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationDecisionNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationDecisionNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The certificate chain returned by the server as an array of PEM-formatted certificates.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationCertificateChainNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationCertificateChainNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The entry within the SSL pinning configuration that was used as the pinning policy for the server being validated. It will be the same as the kTSKValidationServerHostnameNotificationKey entry unless the server is a subdomain of a domain configured in the pinning policy with kTSKIncludeSubdomains enabled. The corresponding pinning configuration that was used for validation can be retrieved using:

    + +
    NSString *notedHostname = userInfo[kTSKValidationNotedHostnameNotificationKey];
    +NSDictionary *hostnameConfiguration = [TrustKit configuration][kTSKPinnedDomains][notedHostname];
    +
    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationNotedHostnameNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationNotedHostnameNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    The hostname of the server SSL pinning validation was performed against.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    extern const TSKNotificationUserInfoKey _Nonnull kTSKValidationServerHostnameNotificationKey
    + +
    +
    +

    Swift

    +
    let kTSKValidationServerHostnameNotificationKey: String
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Enums.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Enums.html new file mode 100644 index 0000000..95dfb04 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Enums.html @@ -0,0 +1,191 @@ + + + + Enums Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Enums

+

The following enums are available globally.

+ +
+
+
+
    +
  • +
    + + + + TSKTrustDecision + +
    +
    +
    +
    +
    +
    +

    Possible return values when verifying a server’s identity against the global SSL pinning policy using TSKPinningValidator.

    + + See more +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    enum TSKTrustDecision : NSInteger {}
    + +
    +
    +

    Swift

    +
    enum TSKTrustDecision : Int
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Enums/TSKTrustDecision.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Enums/TSKTrustDecision.html new file mode 100644 index 0000000..21549f3 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Enums/TSKTrustDecision.html @@ -0,0 +1,270 @@ + + + + TSKTrustDecision Enum Reference + + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

TSKTrustDecision

+
+
+
enum TSKTrustDecision : NSInteger {}
+ +
+
+

Possible return values when verifying a server’s identity against the global SSL pinning policy using TSKPinningValidator.

+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Based on the server’s certificate chain and the global 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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    TSKTrustDecisionShouldAllowConnection
    + +
    +
    +

    Swift

    +
    case shouldAllowConnection = 0
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Based on the server’s certificate chain and the global 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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    TSKTrustDecisionShouldBlockConnection
    + +
    +
    +

    Swift

    +
    case shouldBlockConnection = 1
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    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.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    TSKTrustDecisionDomainNotPinned
    + +
    +
    +

    Swift

    +
    case domainNotPinned = 2
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Type Definitions.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Type Definitions.html new file mode 100644 index 0000000..7b84d8d --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/Type Definitions.html @@ -0,0 +1,330 @@ + + + + Type Definitions Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+

Type Definitions

+

The following type definitions are available globally.

+ +
+
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    A global, App-wide configuration key that can be set in the pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    typedef NSString *TSKGlobalConfigurationKey
    + +
    +
    +

    Swift

    +
    typealias TSKGlobalConfigurationKey = NSString
    + +
    +
    + +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    A domain-specific configuration key (to defined for a domain under the kTSKPinnedDomains key) that can be set in the pinning policy.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    typedef NSString *TSKDomainConfigurationKey
    + +
    +
    +

    Swift

    +
    typealias TSKDomainConfigurationKey = NSString
    + +
    +
    + +
    +
    +
  • +
+
+
+ + +
+
+ +
    +
  • + +
    +
    +
    +
    +
    +

    A key to be used to retrieve data about the pinning validation that occured, from the userInfo dictionary attached to a kTSKValidationCompletedNotification notification.

    + +
    +
    +

    Declaration

    +
    +

    Objective-C

    +
    typedef NSString *TSKNotificationUserInfoKey
    + +
    +
    +

    Swift

    +
    typealias TSKNotificationUserInfoKey = NSString
    + +
    +
    + +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/css/highlight.css b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/css/highlight.css new file mode 100644 index 0000000..d0db0e1 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/css/highlight.css @@ -0,0 +1,200 @@ +/* Credit to https://gist.github.com/wataru420/2048287 */ +.highlight { + /* Comment */ + /* Error */ + /* Keyword */ + /* Operator */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Deleted */ + /* Generic.Deleted.Specific */ + /* Generic.Emph */ + /* Generic.Error */ + /* Generic.Heading */ + /* Generic.Inserted */ + /* Generic.Inserted.Specific */ + /* Generic.Output */ + /* Generic.Prompt */ + /* Generic.Strong */ + /* Generic.Subheading */ + /* Generic.Traceback */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Number */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Entity */ + /* Name.Exception */ + /* Name.Function */ + /* Name.Namespace */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Literal.Number.Integer.Long */ } + .highlight .c { + color: #999988; + font-style: italic; } + .highlight .err { + color: #a61717; + background-color: #e3d2d2; } + .highlight .k { + color: #000000; + font-weight: bold; } + .highlight .o { + color: #000000; + font-weight: bold; } + .highlight .cm { + color: #999988; + font-style: italic; } + .highlight .cp { + color: #999999; + font-weight: bold; } + .highlight .c1 { + color: #999988; + font-style: italic; } + .highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; } + .highlight .gd { + color: #000000; + background-color: #ffdddd; } + .highlight .gd .x { + color: #000000; + background-color: #ffaaaa; } + .highlight .ge { + color: #000000; + font-style: italic; } + .highlight .gr { + color: #aa0000; } + .highlight .gh { + color: #999999; } + .highlight .gi { + color: #000000; + background-color: #ddffdd; } + .highlight .gi .x { + color: #000000; + background-color: #aaffaa; } + .highlight .go { + color: #888888; } + .highlight .gp { + color: #555555; } + .highlight .gs { + font-weight: bold; } + .highlight .gu { + color: #aaaaaa; } + .highlight .gt { + color: #aa0000; } + .highlight .kc { + color: #000000; + font-weight: bold; } + .highlight .kd { + color: #000000; + font-weight: bold; } + .highlight .kp { + color: #000000; + font-weight: bold; } + .highlight .kr { + color: #000000; + font-weight: bold; } + .highlight .kt { + color: #445588; } + .highlight .m { + color: #009999; } + .highlight .s { + color: #d14; } + .highlight .na { + color: #008080; } + .highlight .nb { + color: #0086B3; } + .highlight .nc { + color: #445588; + font-weight: bold; } + .highlight .no { + color: #008080; } + .highlight .ni { + color: #800080; } + .highlight .ne { + color: #990000; + font-weight: bold; } + .highlight .nf { + color: #990000; } + .highlight .nn { + color: #555555; } + .highlight .nt { + color: #000080; } + .highlight .nv { + color: #008080; } + .highlight .ow { + color: #000000; + font-weight: bold; } + .highlight .w { + color: #bbbbbb; } + .highlight .mf { + color: #009999; } + .highlight .mh { + color: #009999; } + .highlight .mi { + color: #009999; } + .highlight .mo { + color: #009999; } + .highlight .sb { + color: #d14; } + .highlight .sc { + color: #d14; } + .highlight .sd { + color: #d14; } + .highlight .s2 { + color: #d14; } + .highlight .se { + color: #d14; } + .highlight .sh { + color: #d14; } + .highlight .si { + color: #d14; } + .highlight .sx { + color: #d14; } + .highlight .sr { + color: #009926; } + .highlight .s1 { + color: #d14; } + .highlight .ss { + color: #990073; } + .highlight .bp { + color: #999999; } + .highlight .vc { + color: #008080; } + .highlight .vg { + color: #008080; } + .highlight .vi { + color: #008080; } + .highlight .il { + color: #009999; } diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/css/jazzy.css b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/css/jazzy.css new file mode 100644 index 0000000..d6d65b7 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/css/jazzy.css @@ -0,0 +1,332 @@ +html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { + background: transparent; + border: 0; + margin: 0; + outline: 0; + padding: 0; + vertical-align: baseline; } + +body { + background-color: #f2f2f2; + font-family: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + -webkit-font-smoothing: subpixel-antialiased; + word-wrap: break-word; } + +h1, h2, h3 { + margin-top: 0.8em; + margin-bottom: 0.3em; + font-weight: 100; + color: black; } + +h1 { + font-size: 2.5em; } + +h2 { + font-size: 2em; + border-bottom: 1px solid #e2e2e2; } + +h4 { + font-size: 13px; + line-height: 1.5; + margin-top: 21px; } + +h5 { + font-size: 1.1em; } + +h6 { + font-size: 1.1em; + color: #777; } + +.section-name { + color: gray; + display: block; + font-family: Helvetica; + font-size: 22px; + font-weight: 100; + margin-bottom: 15px; } + +pre, code { + font: 0.95em Menlo, monospace; + color: #777; + word-wrap: normal; } + +p code, li code { + background-color: #eee; + padding: 2px 4px; + border-radius: 4px; } + +a { + color: #0088cc; + text-decoration: none; } + +ul { + padding-left: 15px; } + +li { + line-height: 1.8em; } + +img { + max-width: 100%; } + +blockquote { + margin-left: 0; + padding: 0 10px; + border-left: 4px solid #ccc; } + +.content-wrapper { + margin: 0 auto; + width: 980px; } + +header { + font-size: 0.85em; + line-height: 26px; + background-color: #414141; + position: fixed; + width: 100%; + z-index: 1; } + header img { + padding-right: 6px; + vertical-align: -4px; + height: 16px; } + header a { + color: #fff; } + header p { + float: left; + color: #999; } + header .header-right { + float: right; + margin-left: 16px; } + +#breadcrumbs { + background-color: #f2f2f2; + height: 27px; + padding-top: 17px; + position: fixed; + width: 100%; + z-index: 1; + margin-top: 26px; } + #breadcrumbs #carat { + height: 10px; + margin: 0 5px; } + +.sidebar { + background-color: #f9f9f9; + border: 1px solid #e2e2e2; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + top: 70px; + bottom: 0; + width: 230px; + word-wrap: normal; } + +.nav-groups { + list-style-type: none; + background: #fff; + padding-left: 0; } + +.nav-group-name { + border-bottom: 1px solid #e2e2e2; + font-size: 1.1em; + font-weight: 100; + padding: 15px 0 15px 20px; } + .nav-group-name > a { + color: #333; } + +.nav-group-tasks { + margin-top: 5px; } + +.nav-group-task { + font-size: 0.9em; + list-style-type: none; + white-space: nowrap; } + .nav-group-task a { + color: #888; } + +.main-content { + background-color: #fff; + border: 1px solid #e2e2e2; + margin-left: 246px; + position: absolute; + overflow: hidden; + padding-bottom: 60px; + top: 70px; + width: 734px; } + .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { + margin-bottom: 1em; } + .main-content p { + line-height: 1.8em; } + .main-content section .section:first-child { + margin-top: 0; + padding-top: 0; } + .main-content section .task-group-section .task-group:first-of-type { + padding-top: 10px; } + .main-content section .task-group-section .task-group:first-of-type .section-name { + padding-top: 15px; } + +.section { + padding: 0 25px; } + +.highlight { + background-color: #eee; + padding: 10px 12px; + border: 1px solid #e2e2e2; + border-radius: 4px; + overflow-x: auto; } + +.declaration .highlight { + overflow-x: initial; + padding: 0 40px 40px 0; + margin-bottom: -25px; + background-color: transparent; + border: none; } + +.section-name { + margin: 0; + margin-left: 18px; } + +.task-group-section { + padding-left: 6px; + border-top: 1px solid #e2e2e2; } + +.task-group { + padding-top: 0px; } + +.task-name-container a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.item { + padding-top: 8px; + width: 100%; + list-style-type: none; } + .item a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .item code { + background-color: transparent; + padding: 0; } + .item .token { + padding-left: 3px; + margin-left: 15px; + font-size: 11.9px; } + .item .declaration-note { + font-size: .85em; + color: gray; + font-style: italic; } + +.pointer-container { + border-bottom: 1px solid #e2e2e2; + left: -23px; + padding-bottom: 13px; + position: relative; + width: 110%; } + +.pointer { + background: #f9f9f9; + border-left: 1px solid #e2e2e2; + border-top: 1px solid #e2e2e2; + height: 12px; + left: 21px; + top: -7px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + width: 12px; } + +.height-container { + display: none; + left: -25px; + padding: 0 25px; + position: relative; + width: 100%; + overflow: hidden; } + .height-container .section { + background: #f9f9f9; + border-bottom: 1px solid #e2e2e2; + left: -25px; + position: relative; + width: 100%; + padding-top: 10px; + padding-bottom: 5px; } + +.aside, .language { + padding: 6px 12px; + margin: 12px 0; + border-left: 5px solid #dddddd; + overflow-y: hidden; } + .aside .aside-title, .language .aside-title { + font-size: 9px; + letter-spacing: 2px; + text-transform: uppercase; + padding-bottom: 0; + margin: 0; + color: #aaa; + -webkit-user-select: none; } + .aside p:last-child, .language p:last-child { + margin-bottom: 0; } + +.language { + border-left: 5px solid #cde9f4; } + .language .aside-title { + color: #4b8afb; } + +.aside-warning { + border-left: 5px solid #ff6666; } + .aside-warning .aside-title { + color: #ff0000; } + +.graybox { + border-collapse: collapse; + width: 100%; } + .graybox p { + margin: 0; + word-break: break-word; + min-width: 50px; } + .graybox td { + border: 1px solid #e2e2e2; + padding: 5px 25px 5px 10px; + vertical-align: middle; } + .graybox tr td:first-of-type { + text-align: right; + padding: 7px; + vertical-align: top; + word-break: normal; + width: 40px; } + +.slightly-smaller { + font-size: 0.9em; } + +#footer { + position: absolute; + bottom: 10px; + margin-left: 25px; } + #footer p { + margin: 0; + color: #aaa; + font-size: 0.8em; } + +html.dash header, html.dash #breadcrumbs, html.dash .sidebar { + display: none; } +html.dash .main-content { + width: 980px; + margin-left: 0; + border: none; + width: 100%; + top: 0; + padding-bottom: 0; } +html.dash .height-container { + display: block; } +html.dash .item .token { + margin-left: 0; } +html.dash .content-wrapper { + width: auto; } +html.dash #footer { + position: static; } diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/carat.png b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/carat.png new file mode 100755 index 0000000..29d2f7f Binary files /dev/null and b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/carat.png differ diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/dash.png b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/dash.png new file mode 100755 index 0000000..6f694c7 Binary files /dev/null and b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/dash.png differ diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/gh.png b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/gh.png new file mode 100755 index 0000000..628da97 Binary files /dev/null and b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/img/gh.png differ diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/index.html b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/index.html new file mode 100644 index 0000000..d4483e6 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/index.html @@ -0,0 +1,168 @@ + + + + TrustKit Reference + + + + + + + + + +
+
+

TrustKit Docs

+

View on GitHub

+
+
+
+ +
+
+ +
+
+
+ +

TrustKit Documentation

+ +

TrustKit is an open source framework that makes it easy to deploy SSL public key +pinning in any iOS, macOS, tvOS or watchOS App.

+ +

This is the API documentation for TrustKit. For an overview of the framework and +a more general guide to using it, see the project’s page at +https://datatheorem.github.io/TrustKit .

+ +

TrustKit requires iOS 7.0, macOS 10.9, tvOS 10.0 or watchOS 3.0 as the minimum +deployment target.

+ +

Two classes are available enabling SSL pinning in an App:

+ +
    +
  • TrustKit, for programmatically configuring the global SSL pinning policy within an +App.
  • +
  • TSKPinningValidator, for manually validating a certificate chain against the App’s +configured pinning policy.
  • +
+ +
+
+ +
+
+ + + diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/js/jazzy.js b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/js/jazzy.js new file mode 100755 index 0000000..4ff9455 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/js/jazzy.js @@ -0,0 +1,40 @@ +window.jazzy = {'docset': false} +if (typeof window.dash != 'undefined') { + document.documentElement.className += ' dash' + window.jazzy.docset = true +} +if (navigator.userAgent.match(/xcode/i)) { + document.documentElement.className += ' xcode' + window.jazzy.docset = true +} + +// On doc load, toggle the URL hash discussion if present +$(document).ready(function() { + if (!window.jazzy.docset) { + var linkToHash = $('a[href="' + window.location.hash +'"]'); + linkToHash.trigger("click"); + } +}); + +// On token click, toggle its discussion and animate token.marginLeft +$(".token").click(function(event) { + if (window.jazzy.docset) { + return; + } + var link = $(this); + var animationDuration = 300; + var tokenOffset = "15px"; + var original = link.css('marginLeft') == tokenOffset; + link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); + $content = link.parent().parent().next(); + $content.slideToggle(animationDuration); + + // Keeps the document from jumping to the hash. + var href = $(this).attr('href'); + if (history.pushState) { + history.pushState({}, '', href); + } else { + location.hash = href; + } + event.preventDefault(); +}); diff --git a/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/js/jquery.min.js b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/js/jquery.min.js new file mode 100755 index 0000000..ab28a24 --- /dev/null +++ b/docs/documentation/docsets/TrustKit.docset/Contents/Resources/Documents/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; +if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:k.htmlSerialize?[0,"",""]:[1,"X
","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("