Merge pull request #882 from OliverLetterer/derived-certificates
Pinning certificates will now trust all derived certificates.
This commit is contained in:
commit
24dd68fa6e
1 changed files with 101 additions and 70 deletions
|
|
@ -548,30 +548,61 @@ willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challe
|
|||
{
|
||||
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
||||
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
|
||||
|
||||
SecPolicyRef policy = SecPolicyCreateBasicX509();
|
||||
CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust);
|
||||
NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:certificateCount];
|
||||
|
||||
for (CFIndex i = 0; i < certificateCount; i++) {
|
||||
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i);
|
||||
|
||||
if (self.SSLPinningMode == AFSSLPinningModeCertificate) {
|
||||
[trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)];
|
||||
} else if (self.SSLPinningMode == AFSSLPinningModePublicKey) {
|
||||
SecCertificateRef someCertificates[] = {certificate};
|
||||
CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL);
|
||||
|
||||
SecTrustRef trust = NULL;
|
||||
|
||||
OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust);
|
||||
NSAssert(status == noErr, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
|
||||
|
||||
SecTrustResultType result;
|
||||
status = SecTrustEvaluate(trust, &result);
|
||||
NSAssert(status == noErr, @"SecTrustEvaluate error: %ld", (long int)status);
|
||||
|
||||
[trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)];
|
||||
|
||||
CFRelease(trust);
|
||||
CFRelease(certificates);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(policy);
|
||||
|
||||
switch (self.SSLPinningMode) {
|
||||
case AFSSLPinningModePublicKey: {
|
||||
id publicKey = (__bridge_transfer id)SecTrustCopyPublicKey(serverTrust);
|
||||
|
||||
for (id publicKey in trustChain) {
|
||||
if ([[self.class pinnedPublicKeys] containsObject:publicKey]) {
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
|
||||
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
|
||||
} else {
|
||||
[[challenge sender] cancelAuthenticationChallenge:challenge];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[[challenge sender] cancelAuthenticationChallenge:challenge];
|
||||
break;
|
||||
}
|
||||
case AFSSLPinningModeCertificate: {
|
||||
SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
|
||||
NSData *serverCertificateData = (__bridge_transfer NSData *)SecCertificateCopyData(serverCertificate);
|
||||
|
||||
if ([[[self class] pinnedCertificates] containsObject:serverCertificateData]) {
|
||||
for (id serverCertificateData in trustChain) {
|
||||
if ([[self.class pinnedCertificates] containsObject:serverCertificateData]) {
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
|
||||
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
|
||||
} else {
|
||||
[[challenge sender] cancelAuthenticationChallenge:challenge];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[[challenge sender] cancelAuthenticationChallenge:challenge];
|
||||
break;
|
||||
}
|
||||
case AFSSLPinningModeNone: {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue