Skip to content
Permalink
Browse files

Add optional SSL certificate pinning

  • Loading branch information...
dstnbrkr authored and mattt committed Dec 22, 2012
1 parent a146a3b commit 07c9f6c35861de64c3ae4ecb8a5aadd568db06cd
Showing with 37 additions and 0 deletions.
  1. +37 −0 AFNetworking/AFURLConnectionOperation.m
@@ -173,6 +173,24 @@ + (NSThread *)networkRequestThread {
return _networkRequestThread;
}

+ (NSArray *)pinnedCertificates {
static NSArray *_pinnedCertificates = nil;
static dispatch_once_t oncePredicate;

dispatch_once(&oncePredicate, ^{
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];
NSMutableArray *certificates = [NSMutableArray array];
for (NSString *path in paths) {
NSData *certificateData = [NSData dataWithContentsOfFile:path];
[certificates addObject:certificateData];
}
_pinnedCertificates = [[NSArray alloc] initWithArray:certificates];
});

return _pinnedCertificates;
}

- (id)initWithRequest:(NSURLRequest *)urlRequest {
self = [super init];
if (!self) {
@@ -467,6 +485,25 @@ - (void)cancelConnection {

#pragma mark - NSURLConnectionDelegate

#ifdef _AFNETWORKING_PIN_SSL_CERTIFICATES_
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));

NSArray *pinnedCertificates = [[self class] pinnedCertificates];
if ([pinnedCertificates containsObject:remoteCertificateData]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];

This comment has been minimized.

Copy link
@0xced

0xced Dec 26, 2012

Collaborator

Why use cancelAuthenticationChallenge: and not performDefaultHandlingForAuthenticationChallenge: or rejectProtectionSpaceAndContinueWithChallenge: instead?

This comment has been minimized.

Copy link
@dstnbrkr

dstnbrkr Dec 26, 2012

Author Contributor

The intent is for the check to be more strict than the default system check, so authentication should fail outright if the server certificate doesn't match the bundled certificate.

In the case of a compromised CA this check would fail but performDefaultHandlingForAuthenticationChallenge: would allow it to fall back to the system check, which would pass - because the system only checks for a trusted CA.

}
}
}
#endif

- (BOOL)connection:(NSURLConnection *)connection
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{

0 comments on commit 07c9f6c

Please sign in to comment.
You can’t perform that action at this time.