Skip to content

Commit

Permalink
Add custom anchors to NSURLProtectionSpace's serverTrust property (#7)
Browse files Browse the repository at this point in the history
* Add custom anchors to NSURLProtectionSpace's serverTrust property directly

* v2.1
  • Loading branch information
tburgin authored and russellhancox committed Sep 9, 2016
1 parent b35e5af commit 21b0a06
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 30 deletions.
2 changes: 1 addition & 1 deletion MOLAuthenticatingURLSession.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'MOLAuthenticatingURLSession'
s.version = '2.0'
s.version = '2.1'
s.platform = :osx
s.license = { :type => 'Apache 2.0', :file => 'LICENSE' }
s.homepage = 'https://github.com/google/macops-molauthenticatingurlsession'
Expand Down
35 changes: 6 additions & 29 deletions Source/MOLAuthenticatingURLSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -285,31 +285,12 @@ - (NSURLCredential *)serverCredentialForProtectionSpace:(NSURLProtectionSpace *)

OSStatus err = errSecSuccess;

// A local SecTrustRef to store custom anchors if they exist. SecTrustSetAnchorCertificates in
// combination with SecTrustEvaluate will leak a SecTrustRef if we were to set the anchors on
// protectionSpace.serverTrust. If there are custom anchors serverTrust will be evaluated, if
// there are no custom anchors protectionSpace.serverTrust will be evaluated.
SecTrustRef serverTrust = NULL;

if (self.anchors) {
CFArrayRef policies = NULL;
SecTrustCopyPolicies(protectionSpace.serverTrust, &policies);
int certCount = (int)SecTrustGetCertificateCount(protectionSpace.serverTrust);
NSMutableArray *serverTrustCertRefs = [[NSMutableArray alloc] initWithCapacity:certCount];
for (int i = 0; i < certCount; ++i) {
[serverTrustCertRefs addObject:
(__bridge id)SecTrustGetCertificateAtIndex(protectionSpace.serverTrust, i)];
}

// Create a copy of protectionSpace.serverTrust by grabbing its policies and certificates.
SecTrustCreateWithCertificates((__bridge CFTypeRef)serverTrustCertRefs, policies, &serverTrust);
if (policies) CFRelease(policies);

// Set this array of certs as the anchors to trust.
err = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)self.anchors);
// Set the anchors to be used during evaluation
err = SecTrustSetAnchorCertificates(protectionSpace.serverTrust,
(__bridge CFArrayRef)self.anchors);
if (err != errSecSuccess) {
[self log:@"Server Trust: Could not set anchor certificates: %d", err];
if (serverTrust) CFRelease(serverTrust);
return nil;
}
}
Expand All @@ -323,25 +304,21 @@ - (NSURLCredential *)serverCredentialForProtectionSpace:(NSURLProtectionSpace *)

// Evaluate the server's cert chain.
SecTrustResultType result = kSecTrustResultInvalid;
err = SecTrustEvaluate(serverTrust ?: protectionSpace.serverTrust, &result);
err = SecTrustEvaluate(protectionSpace.serverTrust, &result);
if (err != errSecSuccess) {
[self log:@"Server Trust: Unable to evaluate certificate chain for server: %d", err];
if (serverTrust) CFRelease(serverTrust);
return nil;
}

// Having a trust level "unspecified" by the user is the usual result, described at
// https://developer.apple.com/library/mac/qa/qa1360
if (result != kSecTrustResultProceed && result != kSecTrustResultUnspecified) {
[self log:@"Server Trust: Server isn't trusted. SecTrustResultType: %d", result];
if (serverTrust) CFRelease(serverTrust);
return nil;
}

NSURLCredential *cred = [NSURLCredential
credentialForTrust:serverTrust ?: protectionSpace.serverTrust];
if (serverTrust) CFRelease(serverTrust);
return cred;
// Create and return the credential
return [NSURLCredential credentialForTrust:protectionSpace.serverTrust];
}

/**
Expand Down

0 comments on commit 21b0a06

Please sign in to comment.