Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
nabla-c0d3 committed Jul 13, 2017
2 parents f30dc5d + d18c427 commit 5fe1e8d
Show file tree
Hide file tree
Showing 46 changed files with 1,110 additions and 885 deletions.
65 changes: 33 additions & 32 deletions TrustKit/Pinning/TSKSPKIHashCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
sizeof(ecDsaSecp384r1Asn1Header)
};


@interface TSKSPKIHashCache ()

// Dictionnary to cache SPKI hashes instead of having to compute them on every connection
Expand Down Expand Up @@ -142,11 +141,11 @@ - (instancetype)initWithIdentifier:(NSString *)uniqueIdentifier
_keychainQueue = dispatch_queue_create("TSKSPKIKeychainLock", DISPATCH_QUEUE_SERIAL);
// Cleanup the Keychain in case the App previously crashed
NSMutableDictionary * publicKeyGet = [[NSMutableDictionary alloc] init];
[publicKeyGet setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[publicKeyGet setObject:(kTSKKeychainPublicKeyTag) forKey:(__bridge id)kSecAttrApplicationTag];
[publicKeyGet setObject:(__bridge id)(kCFBooleanTrue) forKey:(__bridge id)kSecReturnData];
publicKeyGet[(__bridge id)kSecClass] = (__bridge id)kSecClassKey;
publicKeyGet[(__bridge id)kSecAttrApplicationTag] = kTSKKeychainPublicKeyTag;
publicKeyGet[(__bridge id)kSecReturnData] = @YES;
dispatch_sync(_keychainQueue, ^{
SecItemDelete((__bridge CFDictionaryRef)(publicKeyGet));
SecItemDelete((__bridge CFDictionaryRef)publicKeyGet);
});
#endif
}
Expand Down Expand Up @@ -295,20 +294,22 @@ @implementation TSKSPKIHashCache (Unified)
// Use the unified SecKey API (specifically SecKeyCopyExternalRepresentation())
- (NSData *)getPublicKeyDataFromCertificate_unified:(SecCertificateRef)certificate
{
SecKeyRef publicKey;
SecTrustRef tempTrust;
// Create an X509 trust using the using the certificate
SecTrustRef trust;
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustCreateWithCertificates(certificate, policy, &trust);

// Get a public key reference from the certificate
SecTrustCreateWithCertificates(certificate, policy, &tempTrust);
SecTrustEvaluate(tempTrust, NULL);
publicKey = SecTrustCopyPublicKey(tempTrust);
// Get a public key reference for the certificate from the trust
SecTrustEvaluate(trust, NULL);
SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
CFRelease(policy);
CFRelease(tempTrust);
CFRelease(trust);

// Obtain the public key bytes from the key reference
CFDataRef publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL);
CFRelease(publicKey);
return (NSData *)CFBridgingRelease(publicKeyData);

return (__bridge_transfer NSData *)publicKeyData;
}

@end
Expand All @@ -335,30 +336,30 @@ - (NSData *)getPublicKeyDataFromCertificate_legacy_ios:(SecCertificateRef)certif
CFRelease(tempTrust);


// Extract the actual bytes from the key reference using the Keychain
/// Extract the actual bytes from the key reference using the Keychain
// Prepare the dictionary to add the key
NSMutableDictionary *peerPublicKeyAdd = [[NSMutableDictionary alloc] init];
[peerPublicKeyAdd setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[peerPublicKeyAdd setObject:kTSKKeychainPublicKeyTag forKey:(__bridge id)kSecAttrApplicationTag];
[peerPublicKeyAdd setObject:(__bridge id)(publicKey) forKey:(__bridge id)kSecValueRef];
peerPublicKeyAdd[(__bridge id)kSecClass] = (__bridge id)kSecClassKey;
peerPublicKeyAdd[(__bridge id)kSecAttrApplicationTag] = kTSKKeychainPublicKeyTag;
peerPublicKeyAdd[(__bridge id)kSecValueRef] = (__bridge id)publicKey;

// Avoid issues with background fetching while the device is locked
[peerPublicKeyAdd setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];
peerPublicKeyAdd[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;

// Request the key's data to be returned
[peerPublicKeyAdd setObject:(__bridge id)(kCFBooleanTrue) forKey:(__bridge id)kSecReturnData];
peerPublicKeyAdd[(__bridge id)kSecReturnData] = @YES;

// Prepare the dictionary to retrieve and delete the key
NSMutableDictionary * publicKeyGet = [[NSMutableDictionary alloc] init];
[publicKeyGet setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[publicKeyGet setObject:(kTSKKeychainPublicKeyTag) forKey:(__bridge id)kSecAttrApplicationTag];
[publicKeyGet setObject:(__bridge id)(kCFBooleanTrue) forKey:(__bridge id)kSecReturnData];
publicKeyGet[(__bridge id)kSecClass] = (__bridge id)kSecClassKey;
publicKeyGet[(__bridge id)kSecAttrApplicationTag] = kTSKKeychainPublicKeyTag;
publicKeyGet[(__bridge id)kSecReturnData] = @YES;


// Get the key bytes from the Keychain atomically
dispatch_sync(self.keychainQueue, ^{
resultAdd = SecItemAdd((__bridge CFDictionaryRef) peerPublicKeyAdd, (void *)&publicKeyData);
resultDel = SecItemDelete((__bridge CFDictionaryRef)(publicKeyGet));
resultDel = SecItemDelete((__bridge CFDictionaryRef)publicKeyGet);
});

CFRelease(publicKey);
Expand Down Expand Up @@ -388,9 +389,9 @@ - (NSData *)getPublicKeyDataFromCertificate_legacy_macos:(SecCertificateRef)cert
CFErrorRef error = NULL;

// SecCertificateCopyValues() is macOS only
NSArray *oids = [NSArray arrayWithObject:(__bridge id)(kSecOIDX509V1SubjectPublicKey)];
CFDictionaryRef certificateValues = SecCertificateCopyValues(certificate, (__bridge CFArrayRef)(oids), &error);
if (certificateValues == NULL)
NSArray *oids = @[ (__bridge id)kSecOIDX509V1SubjectPublicKey ];
NSDictionary *certificateValues = (__bridge_transfer NSDictionary *)SecCertificateCopyValues(certificate, (__bridge CFArrayRef)(oids), &error);
if (certificateValues == nil)
{
CFStringRef errorDescription = CFErrorCopyDescription(error);
TSKLog(@"SecCertificateCopyValues() error: %@", errorDescription);
Expand All @@ -399,15 +400,15 @@ - (NSData *)getPublicKeyDataFromCertificate_legacy_macos:(SecCertificateRef)cert
return nil;
}

for (NSString* fieldName in (__bridge NSDictionary *)certificateValues)
for (NSString *fieldName in certificateValues)
{
NSDictionary *fieldDict = CFDictionaryGetValue(certificateValues, (__bridge const void *)(fieldName));
if ([fieldDict[(__bridge __strong id)(kSecPropertyKeyLabel)] isEqualToString:@"Public Key Data"])
NSDictionary *fieldDict = certificateValues[fieldName];
NSString *fieldLabel = fieldDict[(__bridge id)kSecPropertyKeyLabel];
if ([fieldLabel isEqualToString:@"Public Key Data"])
{
publicKeyData = fieldDict[(__bridge __strong id)(kSecPropertyKeyValue)];
publicKeyData = fieldDict[(__bridge id)kSecPropertyKeyValue];
}
}
CFRelease(certificateValues);
return publicKeyData;
}

Expand Down
8 changes: 4 additions & 4 deletions TrustKitDemo/Podfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
platform :ios, '9.0'

target 'TrustKitDemo' do
target 'TrustKitDemo-ObjC' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!

Expand All @@ -11,11 +11,11 @@ target 'TrustKitDemo' do
end


target 'TrustKitDemoInSwift' do
target 'TrustKitDemo-Swift' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
use_frameworks!

# Pods for TrustKitDemo
pod 'TrustKit', :path => '../'

end
end
2 changes: 1 addition & 1 deletion TrustKitDemo/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
TrustKit: 59a0878569585d9b1adb7d76c341426deb57a5b8

PODFILE CHECKSUM: 86e19c8ce4662ee6d0981982609efb580466dfcc
PODFILE CHECKSUM: 4562cd01d4aad1fc62e9d31a2ca43aacdbb72dc9

COCOAPODS: 1.2.1
2 changes: 1 addition & 1 deletion TrustKitDemo/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5fe1e8d

Please sign in to comment.