datatheorem / trustkit Goto Github PK
View Code? Open in Web Editor NEWEasy SSL pinning validation and reporting for iOS, macOS, tvOS and watchOS.
License: MIT License
Easy SSL pinning validation and reporting for iOS, macOS, tvOS and watchOS.
License: MIT License
Hey,
In our app we use a library called CocoaAsyncSocket and we want to use your library to perform certificate pinning on our TLS secured TCP connection (I couldn't find a way to properly do it in CocoaAsyncSocket's docs).
Is it possible to do that?
Thanks,
Elad
Hi, I have a question. What is the hash key that I have to put in kTSKPublicKeyHashes
?
I saw the demo project. The hash key for www.datatheorem.com
is lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=
.
Where do you get this key from?
I have tried to get that same hash. But I cannot find the same key as the demo project.
My steps are.
datatheorem.com.cer
openssl dgst -sha256 -binary datatheorem.com.cer | openssl enc -base64
odZp83ypLYnJApPwyjU5jnQDGxwJI4UTtdKXzVkuTvI=
which it is not the same as in demo project.Thank you.
We could easily add support for OS X Apps as SecureTransport is exactly the same on this platform. Let's look at this eventually.
This is the error when pinning fails.
(lldb) po error
Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://evolve.cipherhealth.com/api/orchid/authentication, NSErrorFailingURLStringKey=https://evolve.cipherhealth.com/api/orchid/authentication, NSLocalizedDescription=cancelled}
So there's no specific way to report back to the user that there's a security failure.
Random crashes occur in my app only when Trustkit is enabled. I think that the problem can be caused by one of the methods inside the reporting_utils.m class.
This section of the code can be the problem:
// Get the data and transfer ownership to ARC
// Explicitly calling CFRelease() at the end of this function can crash the test suite
NSData *certificateData = (NSData *)CFBridgingRelease(SecCertificateCopyData(certificate));
Add Comment
Thanks!
I am building an ios target with "Deployment Target" = 8.1
I am using Trust kit as a pod (pod 'TrustKit') and I see the following link warnings:
(null): Object file (/Users/X/Documents/Projects/Y/Pods/TrustKit/TrustKit/Dependencies/domain_registry/ios/libassert_lib.a(assert.o)) was built for newer iOS version (9.0) than being linked (8.1)
(null): Object file (/Users/X/Documents/Projects/Y/Pods/TrustKit/TrustKit/Dependencies/domain_registry/ios/libdomain_registry_lib.a(registry_search.o)) was built for newer iOS version (9.0) than being linked (8.1)
(null): Object file (/Users/X/Documents/Projects/Y/Pods/TrustKit/TrustKit/Dependencies/domain_registry/ios/libdomain_registry_lib.a(trie_search.o)) was built for newer iOS version (9.0) than being linked (8.1)
(null): Object file (/Users/X/Documents/Projects/Y/Pods/TrustKit/TrustKit/Dependencies/domain_registry/ios/libinit_registry_tables_lib.a(init_registry_tables.o)) was built for newer iOS version (9.0) than being linked (8.1)
I think, security related software is going to gain more trust if neither the compiler nor the static analysis reports any issues that might lead to exploits.
I would also recommend using -wError
and -wPedantic
to avoid such issues.
For example, https://gist.github.com/dodikk/15d8df5f7a16d0f26204
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/trie_search.c:67:24: warning: no previous prototype for function 'FindNodeInRange' [-Wmissing-prototypes]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/registry_search.c:256:25: warning: implicit conversion changes signedness: 'int' to 'size_t' (aka 'unsigned long') [-Wsign-conversion]
$ carthage update
*** Checking out TrustKit at "3a9d1ada34b0d48bbf7e190582ca44de80e9b03f"
*** xcodebuild output can be found in /var/folders/5k/mvb95qrx6mvdjyx66kxvlqpr0000gp/T/carthage-xcodebuild.dJefcO.log
*** Building scheme "TrustKit OS X" in TrustKit.xcodeproj
2016-10-04 11:50:53.437 xcodebuild[3439:239621] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ZLXCodeLine.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:53.438 xcodebuild[3439:239621] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/XCoverage.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:53.439 xcodebuild[3439:239621] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/RealmBrowser.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:53.441 xcodebuild[3439:239621] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/FuzzyAutocomplete.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:53.442 xcodebuild[3439:239621] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ColorSenseRainbow.xcplugin' not present in DVTPlugInCompatibilityUUIDs
*** Building scheme "TrustKit tvOS" in TrustKit.xcodeproj
2016-10-04 11:50:56.504 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ZLXCodeLine.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.505 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/XCoverage.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.506 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/RealmBrowser.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.507 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/FuzzyAutocomplete.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.509 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ColorSenseRainbow.xcplugin' not present in DVTPlugInCompatibilityUUIDs
** BUILD FAILED **
The following build commands failed:
CompileC /Users/adodatko/Library/Developer/Xcode/DerivedData/TrustKit-ezecneeiogldkbgkmmakfxdvekrb/Build/Intermediates/TrustKit.build/Release-appletvos/TrustKit\ tvOS.build/Objects-normal/arm64/public_key_utils.o TrustKit/Pinning/public_key_utils.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/trie_search.c:67:24: warning: no previous prototype for function 'FindNodeInRange' [-Wmissing-prototypes]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/trie_search.c:100:13: warning: no previous prototype for function 'FindLeafNodeInRange' [-Wmissing-prototypes]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/registry_search.c:47:12: warning: implicit conversion changes signedness: 'long' to 'size_t' (aka 'unsigned long') [-Wsign-conversion]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/registry_search.c:53:41: warning: implicit conversion changes signedness: 'const char' to 'unsigned char' [-Wsign-conversion]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/registry_search.c:256:25: warning: implicit conversion changes signedness: 'long' to 'size_t' (aka 'unsigned long') [-Wsign-conversion]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/assert.c:23:6: warning: no previous prototype for function 'DefaultAssertHandler' [-Wmissing-prototypes]
ld: warning: directory not found for option '-L/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/osx'
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/trie_search.c:67:24: warning: no previous prototype for function 'FindNodeInRange' [-Wmissing-prototypes]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Dependencies/domain_registry/private/trie_search.c:100:13: warning: no previous prototype for function 'FindLeafNodeInRange' [-Wmissing-prototypes]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Pinning/public_key_utils.m:73:31: error: implicit declaration of function 'SecKeyCopyExternalRepresentation' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
/tmp/1/Carthage/Checkouts/TrustKit/TrustKit/Pinning/public_key_utils.m:73:15: warning: incompatible integer to pointer conversion initializing 'CFDataRef' (aka 'const struct __CFData *') with an expression of type 'int' [-Wint-conversion]
A shell task failed with exit code 65:
2016-10-04 11:50:56.504 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ZLXCodeLine.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.505 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/XCoverage.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.506 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/RealmBrowser.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.507 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/FuzzyAutocomplete.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2016-10-04 11:50:56.509 xcodebuild[3517:239809] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ColorSenseRainbow.xcplugin' not present in DVTPlugInCompatibilityUUIDs
** BUILD FAILED **
The following build commands failed:
CompileC /Users/adodatko/Library/Developer/Xcode/DerivedData/TrustKit-ezecneeiogldkbgkmmakfxdvekrb/Build/Intermediates/TrustKit.build/Release-appletvos/TrustKit\ tvOS.build/Objects-normal/arm64/public_key_utils.o TrustKit/Pinning/public_key_utils.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
I want to enable certificate pinning against multiple Amazon S3 buckets, I've configured TrustKit in the AppDelegate, sample Xcode project attached: TrustKitWithAmazonS3.zip
On launching the app an exception is raised: Terminating app due to uncaught exception 'TrustKit configuration invalid', reason: 'TrustKit was initialized with includeSubdomains for a domain suffix s3.amazonaws.com'
Why is it considered a domain suffix (if it's not a bug), and what is the correct way to configure certificate pinning for subdomains of s3.amazonaws.com
?
What I've tried so far:
s3.amazonaws.com
: raises exception*.s3.amazonaws.com
: doesn't raise exception but certificate pinning fails on subdomainsCN=s3.amazonaws.com
: no effectCN=*.s3.amazonaws.com
: no effectCertificates obtained using openssl s_client -showcerts -connect s3.amazonaws.com:443
Output from the get_pin_from_certificate.py
script to obtain the Public Key Hashes:
$ ./get_pin_from_certificate.py s3-amazonaws.pem
CERTIFICATE INFO
----------------
subject= /C=US/ST=Washington/L=Seattle/O=Amazon.com Inc./CN=s3.amazonaws.com
issuer= /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Baltimore CA-2 G2
SHA1 Fingerprint=65:B0:62:58:C9:E6:5C:07:A5:6A:39:DB:88:7A:EA:0F:3F:14:42:75
TRUSTKIT CONFIGURATION
----------------------
kTSKPublicKeyHashes: @[@"tfR4WIM3cjezQdf3yh/px0abP/kN6KbYruem43CT1t8="] // You will also need to configure a backup pin
kTSKPublicKeyAlgorithms: @[@"TSKAlgorithmRsa2048"]
$ ./get_pin_from_certificate.py star-s3-amazonaws.pem
CERTIFICATE INFO
----------------
subject= /C=US/ST=Washington/L=Seattle/O=Amazon.com Inc./CN=*.s3.amazonaws.com
issuer= /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Baltimore CA-2 G2
SHA1 Fingerprint=3B:E4:04:74:1F:F3:01:E3:03:0D:B7:7F:C7:79:60:84:16:D6:56:B9
TRUSTKIT CONFIGURATION
----------------------
kTSKPublicKeyHashes: @[@"tzsid6cLOVtz0NnqTUDQU/CmN/bSC5vUQRUj6p7JBF0="] // You will also need to configure a backup pin
kTSKPublicKeyAlgorithms: @[@"TSKAlgorithmRsa2048"]
$ ./get_pin_from_certificate.py s3-amazonaws_intermediate_ca.pem
CERTIFICATE INFO
----------------
subject= /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Baltimore CA-2 G2
issuer= /C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root
SHA1 Fingerprint=A9:D5:30:02:E9:7E:00:E0:43:24:4F:3D:17:0D:6F:4C:41:41:04:FD
TRUSTKIT CONFIGURATION
----------------------
kTSKPublicKeyHashes: @[@"56higu/MFWb/c2b0avLE5oN2ECS2C43RvzSUgx/2xIE="] // You will also need to configure a backup pin
kTSKPublicKeyAlgorithms: @[@"TSKAlgorithmRsa2048"]
Hi,
I went through the sample code base, I use pod file as dependency. I observe
In Xcode 7, TrustKit works like charm.
In Xcode 6, Trustkit build failed with Parse issue of about 28 errors in same category.
Example:
Class name: reporting_utils.m
Issue type: Parse issue
Issue Description: Expected '>' in the below line
NSArray<NSString *> *convertTrustToPemArray(SecTrustRef serverTrust)
Since i need to support from iOS 7.1, when i try to build the application in Xcode 6.4, i got the above build failed error message.
Please advice on this to proceed further to fix the issue
Hey,
I want to enable pinning for all our domain, but disable it for a specific subdomain. So I tried it with something like that:
let trustConfig: [String : Any] = [
kTSKSwizzleNetworkDelegates:true,
kTSKPinnedDomains: [
"mydomain.com" :[
kTSKEnforcePinning: true,
kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048],
kTSKPublicKeyHashes:
[],
kTSKIncludeSubdomains: true
],
"dontpin.mydomain.com" :[
kTSKEnforcePinning: false,
kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048],
kTSKPublicKeyHashes:
[]
]
]
]
Is this the only way? I had to set kTSKPublicKeyAlgorithms
and `kTSKPublicKeyHashes' although I want to disable pinning as they mandatory.
Thanks,
Omer
Crashed: com.apple.NSURLConnectionLoader: EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x0000000000000000
Thread : Crashed: com.apple.NSURLConnectionLoader
0 libsystem_platform.dylib 0x0000000195f51300 _platform_memmove + 176
1 libsystem_coretls.dylib 0x0000000195e62634 SSLAddSessionData + 204
2 libsystem_coretls.dylib 0x0000000195e62634 SSLAddSessionData + 204
3 libsystem_coretls.dylib 0x0000000195e675d0 SSLAdvanceHandshake + 1156
4 libsystem_coretls.dylib 0x0000000195e67b68 SSLProcessHandshakeRecordInner + 212
5 libsystem_coretls.dylib 0x0000000195e682bc SSLProcessHandshakeRecord + 896
6 libsystem_coretls.dylib 0x0000000195e6b5b4 tls_handshake_process + 148
7 Security 0x00000001882603d8 SSLHandshakeProceed + 136
8 Security 0x0000000188260774 SSLHandshake + 160
9 Boxer 0x00000001005af6fc replaced_SSLHandshake (TrustKit.m:127)
10 CFNetwork 0x00000001833da3c8 SocketStream::_PerformSecurityHandshake_NoLock() + 1140
11 CFNetwork 0x00000001833b2b98 SocketStream::socketCallback(__CFSocket*, unsigned long, __CFData const*, void const*) + 152
12 CFNetwork 0x00000001833b2abc SocketStream::_SocketCallBack_stream(__CFSocket*, unsigned long, __CFData const*, void const*, void*) + 88
13 CoreFoundation 0x0000000183a4327c __CFSocketPerformV0 + 668
14 CoreFoundation 0x0000000183a3ff8c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
15 CoreFoundation 0x0000000183a3f230 __CFRunLoopDoSources0 + 264
16 CoreFoundation 0x0000000183a3d2e0 __CFRunLoopRun + 712
17 CoreFoundation 0x0000000183968f74 CFRunLoopRunSpecific + 396
18 CFNetwork 0x0000000183447098 +[NSURLConnection(Loader) _resourceLoadLoop:] + 440
19 Foundation 0x0000000184989db8 __NSThread__main__ + 1072
20 libsystem_pthread.dylib 0x0000000195f5bdb8 _pthread_body + 164
21 libsystem_pthread.dylib 0x0000000195f5bd14 _pthread_body
More info: http://crashes.to/s/b3a1c5c65b6
I tried following to generate a pin but only the second method gave me a pin that worked:
./get_pin_from_server.sh tribesocial.com
and
openssl x509 -inform der -in ~/Downloads/tribesocial.com.cer -out tribesocial.com.pem
./get_pin_from_pem_certificate.sh tribesocial.com.pem
Hi,
We are trying to use TrustKit 1.1.3 and since this Open source and there 2 dependencies(fishhook and domain_registery).
Could I get the versions of the dependencies?(fishhook and domain_registery).
Thanks in advance
I can verify that it does go through the configuration process and attempt to hook into the SSLHandshake method, however it never appears to call the replaced_SSLHandshake method. Perhaps fishhook doesn't quite work correctly on iOS 9? I went and downloaded the current version of fishhook.c as of today, and it makes no difference.
Perhaps that method is now lazy loaded? facebook/fishhook#10
As TrustKit does not have any UI component and already works on iOS and macOS, porting it to the other platforms should be easy.
Hi, It's a really good library and specially it is very easy to implement in our code.
I have a query. I implemented it in my app and then tried to trash network traffic by Charles. Now according to pinning it should not be trash. But i am able to trash some webservices.
I am not able to trash 2-3 webservices but rest i can trash by Charles. I am using ASIHTTP library. I am not sure will it vary on different webservices ?
The HPKP spec requires two pins to be configured minimum (including a backup pin); TrustKit should enforce that when validating the pinning policy.
Using a dictionary to store the configuration make it difficult to understand what information is stored in the configuration.
I would like to crash my App when a proxy is used. Is this possible with TrustKit?
Hi,
I have a development certificate that uses RSA1024, which is not currently supported by trustkit, however i need to add this to our current application.
Is it possible for you guys to tell me how do you guys get the ASN1 headers from the certificates, so i can add this to the script and the trustkit, if it brings value to you guys i could potentially fork and merge back the changes. Let me know regards
Regards
Running the demo project, the URL that is expected to validate with the provided pins - doesn't.
2015-11-05 11:56:01.992 TrustKitDemo[55132:5260362] === TrustKit: Error: default SSL validation failed for www.datatheorem.com: {
TrustEvaluationDate = "2015-11-05 00:56:01 +0000";
TrustResultDetails = (
{
ValidLeaf = 0;
},
{
},
{
}
);
TrustResultValue = 5;
}
2015-11-05 11:56:01.993 TrustKitDemo[55132:5260362] === TrustKit: Pin validation failed for www.datatheorem.com
2015-11-05 11:56:01.993 TrustKitDemo[55132:5260636] === TrustKit: Pin failure report for www.datatheorem.com was not sent due to rate-limiting
2015-11-05 11:56:01.993 TrustKitDemo[55132:5260362] Received error Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://www.datatheorem.com/, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://www.datatheorem.com/}
The hashes used in the demo app:
@"www.datatheorem.com" : @{
kTSKEnforcePinning:@YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048],
// Valid SPKI hashes to demonstrate success
kTSKPublicKeyHashes : @[
@"HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=", // CA key
@"HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=" // CA key
]
}
The hash from get_pin_from_server.sh
:
HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=
Is this just my machine? I do have some custom CAs installed.
This would help with troubleshooting errors.
I want to use TrustKit along with RestKit and I need to support SSL pinning for multiple domains that are unknown during TrustKit initialization process (same certificate, different URLs based on tenant ID). Domain is determined dynamically based on user's input tenant ID. Is it possible to define generic pinning URL or to append new URLs in order to support multi-tenant architectures?
Another question is related to pinning validation failure case. How can I handle this error if using RestKit ?
Hello
After updating to 1.3 I have some random issues with delegate callbacks not happening.
The network connection object is created, configured, resumed and the console prints:
2016-05-28 17:17:26.884 App[10023:1911837] === TrustKit: SSL Pin found for {domain}
2016-05-28 17:17:26.885 App[10023:1911837] === TrustKit: Pin validation succeeded for {domain}
And then nothing happens. No error callback, no success either, My app just remains in the loading state forever, confusing users.
I did clean/build and emptied derived data folder. No change. Downgrading to 1.2.5 seems to fix the problem. I use NSURLSession with AFNetworking.
On another note, the console prints:
TSKPublicKeyAlgorithms = (
0
);
On launch, instead of the algorithms I specified in the config, like: kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048],
I don't know if that's an error, but it seems odd to me.
Edit: It seems it does not affect iPads. I don't really see any patterns to it. Observed on (different) iPhones with iOS 9.3.1 (and Simulator). If I remove TrustKit entirely it goes away, and as I said it also does not happen on 1.2.5.
I noticed a copy paste issue inside +[TSKNSURLSessionDelegateProxy swizzleNSURLSessionConstructors]
.
The code was:
// Figure out NSURLSession's "real" class
NSString *NSURLSessionClass;
if (NSClassFromString(@"NSURLSession") != nil)
{
// iOS 8+
NSURLSessionClass = @"NSURLSession";
}
else if (NSClassFromString(@"NSURLSession") != nil)
{
// Pre iOS 8, for some reason hooking NSURLSession doesn't work. We need to use the real/private class __NSCFURLSession
NSURLSessionClass = @"__NSCFURLSession";
}
else
{
TSKLog(@"ERROR: Could not find NSURLSession's class");
return;
}
I've submitted a pull request for what I believe the fix should be:
// Figure out NSURLSession's "real" class
NSString *NSURLSessionClass;
if (NSClassFromString(@"NSURLSession") != nil)
{
// iOS 8+
NSURLSessionClass = @"NSURLSession";
}
else if (NSClassFromString(@"__NSCFURLSession") != nil)
{
// Pre iOS 8, for some reason hooking NSURLSession doesn't work. We need to use the real/private class __NSCFURLSession
NSURLSessionClass = @"__NSCFURLSession";
}
else
{
TSKLog(@"ERROR: Could not find NSURLSession's class");
return;
}
$ xcodebuild -target TrustKit_Static -configuration Release -sdk iphonesimulator
...
...
...
Check dependencies
No architectures to compile for (ARCHS=i386 x86_64, VALID_ARCHS=armv7 arm64).
** BUILD FAILED **
Chrome does not perform pinning validation when the certificate chain chains up to a private trust anchor, for good reasons:
"We deem this acceptable because the proxy or MITM can only be effective if the client machine has already been configured to trust the proxy’s issuing certificate — that is, the client is already under the control of the person who controls the proxy (e.g. the enterprise’s IT administrator). If the client does not trust the private trust anchor, the proxy’s attempt to mediate the connection will fail as it should."
This is needed to allow corporate proxies, firewalls, etc. to proxy/MiTM the connections. We should add a setting to allow this ie. disabling pinning validation for private CAs.
This can only be implemented on OS X, using SecTrustSettingsCopyCertificates()
. On iOS this API is not available and the feature can't be implemented at all.
If you use this library to pin third party certificates (servers you do not own) to protect API keys and user data, will the app be bricked when the certificates from those sites eventually expire? Looking to understand if TrustKit is an approach that would avoid such pinning behavior. This would be for an app that has to support iOS 7.1.2 and up.
$ sh get_pin_from_server.sh www.datatheorem.com
----------------------------
Top Intermediate Certificate
----------------------------
subject= /C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
issuer= /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/[email protected]
SHA1 Fingerprint=1F:A4:90:D1:D4:95:79:42:CD:23:54:5F:6E:82:3D:00:00:79:6E:A2
--------------------------
TrustKit Pin Configuration
--------------------------
kTSKPublicKeyHashes: @[@"HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY="]
kTSKPublicKeyAlgorithms: @[kTSKAlgorithmRsa2048]
The Pin Configuration returned won't work as TrustKit requires at least 2 hashes:
*** Terminating app due to uncaught exception 'TrustKit configuration invalid', reason: 'TrustKit was initialized with less than two pins (ie. no backup pins) for domain www.datatheorem.com'
How do we go about getting a backup hash, and shouldn't the scripts provide it?
We are getting NUMEROUS instances of TrustKit crashing and it seems to be when it sends reports:
http://crashes.to/s/9168aa90a10
I'm ammending my Issue because I see that there is a kTSKDisableDefaultReportUri which I should have set to NO. So apparently any failed request is being sent to your server also. This hits my point below from the original Issue
Why would you crash the app if it fails to save the Report? Wouldn't it make sense to just not send the report if it can't save it? I'm not sure why our real world users are unable to save the report to their device but We're getting like 30 crashes from 20 different users as a result...
On devices with specific time settings, the time in the pinning failure reports contains unexpected unicode characters (such as 2016-11-06T2\u5348\u524d2:52:28Z
) due to a bug in NSDateFormatter ( http://stackoverflow.com/questions/29374181/nsdateformatter-hh-returning-am-pm-on-ios-8-device ).
Let's set the locale so the time string that's returned in the reports is consistent regardless of the device's settings.
I have some certificates that use public key algorithms that aren’t supported by TrustKit. Specifically, Yahoo has 3 certs that fail pin generation: one future-proof SHA384 and two older SHA1. Ideally TrustKit can support these formats as well (and then might as support SHA512 and SHA224).
It looks like they can be supported by adding the appropriate asn1 headers, and patching the python pin generator.
Is there any reason why these other algorithms can not or should not be supported by TrustKit?
Could the whole pinning process here be intercepted and manipulated using ssl-kill-switch2?
https://github.com/nabla-c0d3/ssl-kill-switch2
Anything you guys can do to protect against that?
When connecting to the same server multiple times (just like during the tests), the SSL connection may use session resumption instead of going through the full SSL handshake. If that happens, TrustKit will not be invoked (which is fine as the certificate is already trusted) so the tests will return unexpected results.
More details here: https://developer.apple.com/library/ios/qa/qa1727/_index.html
To fix this we need to move as many tests as possible to the offline / in-memory tests and reduce the set of online tests to the minimum.
One App has been seeing the following intermittent crash:
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[_NSXPCDistantObject methodSignatureForSelector:]: No protocol has been set on connection <NSXPCConnection: 0x15dc25f50> connection to service named com.apple.nsurlsessiond'
There's very little information available on the Internet regarding this crash but the developer posted it on the Apple Developer Forum at https://forums.developer.apple.com/thread/45651 and got an answer:
... I forgot to loop back here to post an update; sorry.
AFAICT this crash is caused by NSURLSession’s background session support. This passes work to its daemon (nsurlsessiond) using NSXPCConnection (not part of the iOS SDK, but public API on OS X, so you can read up about it there). NSXPCConnection has the notion of interrupted connections, that is, the IPC connection between the client and the server has torn but can be re-established. NSURLSession’s background session support, like all NSXPCConnection clients, must handle these interruptions as a matter of course.
Alas, there’s a bug in the way it does that. This bug is a race condition that manifest itself as this crash. We hope to fix this in a future OS release but I can’t share any concrete details.
TrustKit uses background sessions to upload pin failure reports. According to the reporter, they have been seeing this crash more often after upgrading TrustKit from 1.1.3 to 1.2.0, but are unable to reproduce it.
Looking at the changes ( 1.1.3...1.2.0 ), there are only two commits with changes to how the reports get uploaded:
Without a clear way to reproduce this and as it is a bug in iOS (ie. not a bug in TrustKit), this will be a tough one to fix.
I have tried this on both iOS 9.3 Simulator + device iOS 10. Installed via pods, latest version (i.e. pod 'TrustKit'
).
I also tried adding breakpoints in the Trust Kit pin validation routines and they are never hit and as you'll see below, no logs either.
Just to see what happens, I left the default programmatic config in for my domain, with another domain's hashes (yahoo.com's hashes):
NSDictionary *trustKitConfig =
@{
kTSKSwizzleNetworkDelegates: @YES,
kTSKPinnedDomains : @{
@"MYDOMAIN" : @{
kTSKIncludeSubdomains:@YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"rFjc3wG7lTZe43zeYTvPq8k4xdDEutCmIhI5dn4oCeE="
],
kTSKEnforcePinning : @YES,
}
}};
[TrustKit initializeWithConfiguration:trustKitConfig];
When I run the app, it actually connects to the domain anyway, despite pinning enforced, and the logs show this:
2016-07-06 20:37:23.451972 TK-Example[2792:869181] === TrustKit: Configuration passed via explicit call to initializeWithConfiguration:
2016-07-06 20:37:23.453288 TK-Example[2792:869181] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
2016-07-06 20:37:23.453385 TK-Example[2792:869181] === TrustKit: Loaded 0 SPKI cache entries from the filesystem
2016-07-06 20:37:23.507451 TK-Example[2792:869181] === TrustKit: Successfully initialized with configuration {
TSKPinnedDomains = {
"MYDOMAIN" = {
TSKDisableDefaultReportUri = 0;
TSKEnforcePinning = 1;
TSKIncludeSubdomains = 1;
TSKPublicKeyAlgorithms = (
1
);
TSKPublicKeyHashes = "{(\n <ac58dcdf 01bb9536 5ee37cde 613bcfab c938c5d0 c4bad0a6 22123976 7e2809e1>,\n <4d012d74 c6e6c058 185227cc e0b0c5fb 1804b5dd 33ebd98f 1a6929d3 5e1de996>\n)}";
};
};
TSKSwizzleNetworkDelegates = 1;
}
2016-07-06 20:37:23.968416 TK-Example[2792:869243] Response: <NSHTTPURLResponse: 0x17002e920> { URL: https://MYDOMAIN/ } { status code: 200, headers {
"Cache-Control" = "public, max-age=0";
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Type" = "text/html; charset=utf-8";
Date = "Wed, 06 Jul 2016 19:37:23 GMT";
Etag = "W/\"44a5-ScJW2rB+srCBlitpEpvKUA\"";
"Keep-Alive" = "timeout=5, max=100";
Server = "Apache/2.4.18 (Ubuntu)";
"Strict-Transport-Security" = "max-age=63072000; includeSubDomains";
"Transfer-Encoding" = Identity;
Vary = "Accept-Encoding";
Via = "1.1 MYDOMAIN";
"X-Powered-By" = Express;
} }
Any ideas what I might be doing wrong? Will try the Info.plist
config route when I get the chance to see if I observe the same behaviour.
Hi. I have a question. Can I set kTSKPinnedDomains
with wildcard domain? For example, *.test.com
iOS 10 has some useful new APIs:
SecKeyCopyExternalRepresentation()
. Using this API, TrustKit would no longer need to leverage the Keychain in order to get the public key bytes.SecKeyCopyAttributes()
, thereby removing the need for the developer to specify the key algorithm in the TrustKit policy.Would be nice to have some control over console messages from TrustKit. Now it's only check for DEBUG. But some configurable property is highly appreciated.
I used TrustKit to pin certificates to my TCP over TLS connection as described in #76
I want to test it out.
I replaced some characters in the pinned public key and it rejected the connection, I replaced the pinned hostname and it rejected the connection.
Now I want to do some manual security tests on the app, so I looked at Zap but it only supports proxying http connections and I got a plain old TCP connection.
Do you know how can I do something like that?
Is there another, simpler way to get the same level of test Zap provides?
How would you go about testing something like that?
I know it's not an issue with the library, but it might be something others find useful, and may be a starting point for adding testing strategies to the documentation.
Hello,
I use TrustKit in a framework project to add SSL pinning for external application.
I decide to add all the public key algorithms for the default configuration, because I only have the hashes and not the algorithms for the configuration.
So first point, is TrustKit able to find the good algorithm in the list for a specific hash?
If yes, there is a bug. The first algorithm is taken but not the following.
I provide you the modified unit test to show you my issue:
ssl-pinning-integration-test.txt.zip
Here is the certificate fingerprint
CERTIFICATE INFO
----------------
subject= /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
issuer= /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
SHA1 Fingerprint=AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4
TRUSTKIT CONFIGURATION
----------------------
kTSKPublicKeyHashes: @[@"grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME="] // You will also need to configure a backup pin
kTSKPublicKeyAlgorithms: @[@"TSKAlgorithmRsa4096"]
What happens to pinning after a certificate has been extended? Does the info in TrustKit have to be updated or does the public key stay the same? Does it matter if you extend the certificate at the CA or just request a new one with the same old CSR?
Hi, this looks like a very nice library.
I'm trying to use it with self-signed certificates (CA, Intermediate CA and EE) in an iOS app.
I'm getting "NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)"
Reading these few lines, make me think that you need certificates signed by an authority trusted by iOS.
static OSStatus replaced_SSLHandshake(SSLContextRef context)
{
OSStatus result = original_SSLHandshake(context);
if ((result == noErr) && (_isTrustKitInitialized))
{
Please confirm.
Hello. Great kit, love the simplicity.
But, is there a way we could introduce an on/off option for the default logging? I use it in apps while developing them, and it takes up quite a lot of space in the system log, which is not really necessary when nothing is wrong and you're not debugging anything. An option to turn this off would be great.
I'd PR it if I had any clue how to properly implement such an option without breaking anything.
Edit: Looked at the source. Seems it only logs in Debug mode. I don't know if this is me doing something wrong or if this is intended behavior.
You've got 4 months of hotness built up and we want to use it!
Doesn't appear to be any breaking changes, I could be wrong about that.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.