- SSL Pinning switch case was not being applied if a .cer file was found in the bundle.
- SSL Public Key pinning was broken because we didn't make a call to SecTrustEvaluate before SecTrustCopyPublicKey
This commit is contained in:
Kevin Harwood 2013-04-06 11:30:47 -05:00
Родитель 06a9c63ead
Коммит ebccca44da
1 изменённых файлов: 47 добавлений и 48 удалений

Просмотреть файл

@ -218,7 +218,13 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &allowedTrust);
NSAssert(status == noErr, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
SecTrustResultType result = 0;
status = SecTrustEvaluate(allowedTrust, &result);
NSAssert(status == noErr, @"SecTrustEvaluate error: %ld", (long int)status);
SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust);
NSCParameterAssert(allowedPublicKey);
[publicKeys addObject:(__bridge_transfer id)allowedPublicKey];
CFRelease(allowedTrust);
@ -543,59 +549,52 @@ willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challe
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *certificateData = (__bridge_transfer NSData *)SecCertificateCopyData(certificate);
if ([[[self class] pinnedCertificates] containsObject:certificateData]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
switch (self.SSLPinningMode) {
case AFSSLPinningModePublicKey: {
id publicKey = (__bridge_transfer id)SecTrustCopyPublicKey(serverTrust);
if ([[self.class pinnedPublicKeys] containsObject:publicKey]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[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]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
break;
}
case AFSSLPinningModeNone: {
#ifdef _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_
switch (self.SSLPinningMode) {
case AFSSLPinningModePublicKey: {
id publicKey = (__bridge_transfer id)SecTrustCopyPublicKey(serverTrust);
if ([[self.class pinnedPublicKeys] containsObject:publicKey]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
#else
SecTrustResultType result = 0;
OSStatus status = SecTrustEvaluate(serverTrust, &result);
NSAssert(status == noErr, @"SecTrustEvaluate error: %ld", (long int)status);
if (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
#endif
break;
} else {
[[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]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
break;
}
case AFSSLPinningModeNone: {
#ifdef _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
#else
SecTrustResultType result = 0;
OSStatus status = SecTrustEvaluate(serverTrust, &result);
NSAssert(status == noErr, @"SecTrustEvaluate error: %ld", (long int)status);
if (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
#endif
break;
}
}
}
}
#endif