Skip to content

Commit

Permalink
restore iOS 12, tvOS 12, watchOS 4, macOS 10.13 support
Browse files Browse the repository at this point in the history
  • Loading branch information
aj-dt committed Apr 3, 2023
1 parent e657464 commit 158a2ad
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 37 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ TrustKit
[![Build Status](https://app.bitrise.io/app/fe29405fb90f94ea/status.svg?token=TJ3o4dhSWa--0ZlJT7FV1A)](https://app.bitrise.io/app/fe29405fb90f94ea) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Version Status](https://img.shields.io/cocoapods/v/TrustKit.svg?style=flat)](https://cocoapods.org/pods/TrustKit) [![Platform](https://img.shields.io/cocoapods/p/TrustKit.svg?style=flat)](https://cocoapods.org/pods/TrustKit) [![License MIT](https://img.shields.io/cocoapods/l/TrustKit.svg?style=flat)](https://en.wikipedia.org/wiki/MIT_License)
[![Gitter chat](https://badges.gitter.im/datatheorem/gitter.png)](https://gitter.im/TrustKit/Lobby)

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

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

Expand Down
16 changes: 8 additions & 8 deletions TrustKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1550,18 +1550,18 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)/**";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 14.0;
TVOS_DEPLOYMENT_TARGET = 12.0;
VALID_ARCHS = "$(ARCHS_STANDARD)";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
WATCHOS_DEPLOYMENT_TARGET = 7.0;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Debug;
};
Expand Down Expand Up @@ -1619,18 +1619,18 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)/**";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 14.0;
TVOS_DEPLOYMENT_TARGET = 12.0;
VALIDATE_PRODUCT = YES;
VALID_ARCHS = "$(ARCHS_STANDARD)";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
WATCHOS_DEPLOYMENT_TARGET = 7.0;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Release;
};
Expand Down
10 changes: 4 additions & 6 deletions TrustKit/Pinning/TSKSPKIHashCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -277,19 +277,17 @@ - (SecKeyRef)copyPublicKeyFromCertificate:(SecCertificateRef)certificate
// The certificate chain must be evaluated first in order to be able
// to determine which is the leaf certificate of the chain, and only
// then SecTrustCopyKey can be called
SecTrustResultType trustResult = 0;
NSError *error = NULL;
bool isChainTrusted = evaluateCertificateChainTrust(trust, &error);
(void)isChainTrusted; // Discard the chain trust result, not relevant for copying the public key
status = SecTrustGetTrustResult(trust, &trustResult);
if ((error != NULL) && (status != errSecSuccess))
SecTrustResultType trustResult = 0;
bool chainEvaluationSucceeded = evaluateCertificateChainTrust(trust, &trustResult, &error);
if (!chainEvaluationSucceeded && (trustResult != kSecTrustResultRecoverableTrustFailure))
{
TSKLog(@"Could not evaluate trust for the certificate: %@", [error localizedDescription]);
CFRelease(trust);
return nil;
}

SecKeyRef publicKey = SecTrustCopyKey(trust);
SecKeyRef publicKey = copyKey(trust);
CFRelease(trust);
return publicKey;
}
Expand Down
25 changes: 16 additions & 9 deletions TrustKit/Pinning/pinning_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,17 @@
#ifndef TrustKit_pinning_utils_h
#define TrustKit_pinning_utils_h


/**
Evaluate the certificate chain for the specified trust management object
Evaluate trust for the specified certificate and policies
This function invokes SecTrustEvaluateWithError().
This function invokes SecTrustEvaluateWithError() on iOS12+, macOS14+ and SecTrustEvaluate() otherwise.
@param serverTrust The trust management object to evaluate
@param error An error pointer the method uses to return an error when trust evaluation fails with the certificate chain. Set to nil to ignore the error.
@return A boolean value indicating whether the certificate is trusted according to the certificate chain of the trust object
@param trust The trust management object to evaluate
@param trsustResult On return, points to a result type reflecting the result of this evaluation.
@param error An error pointer the method uses to return an error when trust evaluation fails. Set to nil to ignore the error.
@return A boolean value indicating whether evaluating the trust certificate chain succeeded (note: this does not mean the certificate is trusted, only that evaluation succeeded)
*/

bool evaluateCertificateChainTrust(SecTrustRef serverTrust, NSError **error);

bool evaluateCertificateChainTrust(SecTrustRef serverTrust, SecTrustResultType *trustResult, NSError **error);

/**
Returns a specific certificate from the certificate chain used to evaluate trust.
Expand All @@ -49,4 +47,13 @@ bool evaluateCertificateChainTrust(SecTrustRef serverTrust, NSError **error);
*/
SecCertificateRef getCertificateAtIndex(SecTrustRef serverTrust, CFIndex index);

/**
Returns the public key for a leaf certificate after it has been evaluated.
This function invokes SecTrustCopyKey() on iOS 14+ and SecTrustCopyPublicKey otherwise
@param trust The trust management object to evaluate
@return The leaf certificate's public key, or nil if it the public key could not be extracted
*/
SecKeyRef copyKey(SecTrustRef serverTrust);

#endif
49 changes: 42 additions & 7 deletions TrustKit/Pinning/pinning_utils.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,41 @@
#include <dlfcn.h>
#include "TargetConditionals.h"

bool evaluateCertificateChainTrust(SecTrustRef serverTrust, SecTrustResultType *trustResult, NSError **error) {
bool certificateEvaluationSucceeded = false;

bool evaluateCertificateChainTrust(SecTrustRef serverTrust, NSError **error) {
CFErrorRef errorRef;
bool chainTrusted = SecTrustEvaluateWithError(serverTrust, &errorRef);
if (errorRef != NULL) {
chainTrusted = false;
if (error != NULL) {
if (@available(iOS 12.0, macOS 14.0, tvOS 12.0, watchOS 5.0, *)) {
CFErrorRef errorRef;
certificateEvaluationSucceeded = SecTrustEvaluateWithError(serverTrust, &errorRef);
OSStatus status = SecTrustGetTrustResult(serverTrust, trustResult);
if (status != errSecSuccess)
{
certificateEvaluationSucceeded = false;
NSString *errDescription = [NSString stringWithFormat:@"got status %d", status];
*error = [[NSError alloc] initWithDomain:@"com.datatheorem.trustkit" code:1 userInfo:@{NSLocalizedDescriptionKey:errDescription}];
}
else if (!certificateEvaluationSucceeded && (error != NULL))
{
*error = (__bridge_transfer NSError *)errorRef;
}
}
return chainTrusted;
else
{
// Use pragmas to supress deprecated warnings
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
OSStatus status = SecTrustEvaluate(serverTrust, trustResult);
#pragma clang diagnostic pop
if (status == errSecSuccess) {
certificateEvaluationSucceeded = true;
}
else if (error != NULL){
NSString *errDescription = [NSString stringWithFormat:@"got status %d", status];
*error = [[NSError alloc] initWithDomain:@"com.datatheorem.trustkit" code:2 userInfo:@{NSLocalizedDescriptionKey:errDescription}];
}
}

return certificateEvaluationSucceeded;
}

SecCertificateRef getCertificateAtIndex(SecTrustRef serverTrust, CFIndex index) {
Expand Down Expand Up @@ -51,3 +75,14 @@ SecCertificateRef getCertificateAtIndex(SecTrustRef serverTrust, CFIndex index)
}
return certificate;
}

SecKeyRef copyKey(SecTrustRef serverTrust) {
if (@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)) {
return SecTrustCopyKey(serverTrust);
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return SecTrustCopyPublicKey(serverTrust);
#pragma clang diagnostic pop
}
}
10 changes: 4 additions & 6 deletions TrustKit/Pinning/ssl_pin_verifier.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@ TSKTrustEvaluationResult verifyPublicKeyPin(SecTrustRef serverTrust, NSString *s

NSError *error = NULL;
SecTrustResultType trustResult = 0;
bool isChainTrusted = evaluateCertificateChainTrust(serverTrust, &error);
OSStatus status = SecTrustGetTrustResult(serverTrust, &trustResult);
bool trustResultInvalid = !isChainTrusted && (trustResult == kSecTrustResultInvalid);
bool getResultFailed = status != errSecSuccess;
if (trustResultInvalid || getResultFailed)

bool chainEvaluationSucceeded = evaluateCertificateChainTrust(serverTrust, &trustResult, &error);
if (!chainEvaluationSucceeded && (trustResult == kSecTrustResultInvalid))
{
TSKLog(@"SecTrustEvaluate error for %@: %@", serverHostname, [error localizedDescription]);
CFRelease(serverTrust);
Expand Down Expand Up @@ -106,7 +104,7 @@ TSKTrustEvaluationResult verifyPublicKeyPin(SecTrustRef serverTrust, NSString *s

// Retrieve the OS X host's list of user-defined CA certificates
CFArrayRef userRootCerts;
status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainUser, &userRootCerts);
OSStatus status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainUser, &userRootCerts);
if (status == errSecSuccess)
{
[customRootCerts addObjectsFromArray:(__bridge NSArray *)(userRootCerts)];
Expand Down

0 comments on commit 158a2ad

Please sign in to comment.