Skip to content

Commit

Permalink
Enforce 2-pin minimum configuration; fixes issue #13
Browse files Browse the repository at this point in the history
  • Loading branch information
nabla-c0d3 committed Jul 4, 2015
1 parent 7032f9d commit 7a8b422
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 102 deletions.
11 changes: 8 additions & 3 deletions TrustKit/TrustKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,13 @@ static OSStatus replaced_SSLHandshake(SSLContextRef context)
}


// Extract and convert the public key hashes
// Extract and convert the subject public key info hashes
NSArray *serverSslPinsBase64 = domainTrustKitArguments[kTSKPublicKeyHashes];
if ([serverSslPinsBase64 count] < 2)
{
[NSException raise:@"TrustKit configuration invalid"
format:@"TrustKit was initialized with less than two pins (ie. no backup pins) for domain %@", domainName];
}

NSMutableArray *serverSslPinsData = [[NSMutableArray alloc] init];

Expand All @@ -277,14 +282,14 @@ static OSStatus replaced_SSLHandshake(SSLContextRef context)

if ([pinnedKeyHash length] != CC_SHA256_DIGEST_LENGTH)
{
// The public key hash doesn't have a valid size
// The subject public key info hash doesn't have a valid size
[NSException raise:@"TrustKit configuration invalid" format:@"TrustKit was initialized with an invalid Pin %@ for domain %@", pinnedKeyHashBase64, domainName];
}

[serverSslPinsData addObject:pinnedKeyHash];
}

// Save the public key hashes for this server as an NSSet for quick lookup
// Save the hashes for this server as an NSSet for quick lookup
domainFinalConfiguration[kTSKPublicKeyHashes] = [NSSet setWithArray:serverSslPinsData];

// Store the whole configuration
Expand Down
99 changes: 58 additions & 41 deletions TrustKitTests/TSKPinConfigurationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ - (void)tearDown

- (void)testGetConfigurationPinningEnabled
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"www.good.com" : @{
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"www.good.com" : @{
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="]}});

NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"www.good.com", trustKitConfig);
XCTAssert([serverConfigKey isEqualToString:@"www.good.com"], @"Did not receive a configuration for a pinned domain");
Expand All @@ -48,10 +50,12 @@ - (void)testGetConfigurationPinningEnabled

- (void)testGetConfigurationPinningDisabled
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});

// Ensure www.datatheorem.com gets no configuration
NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"www.datatheorem.com", trustKitConfig);
Expand All @@ -61,11 +65,13 @@ - (void)testGetConfigurationPinningDisabled

- (void)testIncludeSubdomainsEnabled
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});

// Ensure www.good.com gets the configuration set for good.com as includeSubdomains is enabled
NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"www.good.com", trustKitConfig);
Expand All @@ -75,11 +81,13 @@ - (void)testIncludeSubdomainsEnabled

- (void)testIncludeSubdomainsEnabledSameDomain
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});

// Ensure good.com gets the configuration set for good.com as includeSubdomains is enabled
NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"good.com", trustKitConfig);
Expand All @@ -89,11 +97,13 @@ - (void)testIncludeSubdomainsEnabledSameDomain

- (void)testIncludeSubdomainsEnabledSubSubDomain
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"www.good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"www.good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});

NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"sub.www.good.com.www.good.com", trustKitConfig);
XCTAssert([serverConfigKey isEqualToString:@"www.good.com"], @"IncludeSubdomains did not work");
Expand All @@ -102,11 +112,13 @@ - (void)testIncludeSubdomainsEnabledSubSubDomain

- (void)testIncludeSubdomainsEnabledNotSubdomain
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});

// Corner case to ensure two different domains with similar strings don't get returned as subdomains
NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"good.com.otherdomain.com", trustKitConfig);
Expand All @@ -116,11 +128,13 @@ - (void)testIncludeSubdomainsEnabledNotSubdomain

- (void)testIncludeSubdomainsDisabled
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @NO,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @NO,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]}});

// Ensure www.good.com does not get the configuration set for good.com
NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"www.good.com", trustKitConfig);
Expand All @@ -130,15 +144,18 @@ - (void)testIncludeSubdomainsDisabled

- (void)testIncludeSubdomainsEnabledAndSpecificConfiguration
{
NSDictionary *trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]},
@"www.good.com": @{
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048],
kTSKPublicKeyHashes : @[@"iQMk4onrJJz/nwW1wCUR0Ycsh3omhbM+PqMEwNof/K0="
]}});
NSDictionary *trustKitConfig;
trustKitConfig = parseTrustKitArguments(@{@"good.com" : @{
kTSKIncludeSubdomains : @YES,
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa4096],
kTSKPublicKeyHashes : @[@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="
]},
@"www.good.com": @{
kTSKPublicKeyAlgorithms : @[kTSKAlgorithmRsa2048],
kTSKPublicKeyHashes : @[@"iQMk4onrJJz/nwW1wCUR0Ycsh3omhbM+PqMEwNof/K0=",
@"iQMk4onrJJz/nwW1wCUR0Ycsh3omhbM+PqMEwNof/K0="
]}});

// Ensure the configuration specific to www.good.com takes precedence over the more general config for good.com
NSString *serverConfigKey = getPinningConfigurationKeyForDomain(@"www.good.com", trustKitConfig);
Expand Down
Loading

0 comments on commit 7a8b422

Please sign in to comment.