From 06a9c63eade3ee48f1b6d696d0d4cad13c152da5 Mon Sep 17 00:00:00 2001 From: Kevin Harwood Date: Sat, 6 Apr 2013 11:04:02 -0500 Subject: [PATCH 1/5] Attempting to add the pinning mode as an example. --- .../project.pbxproj | 4 ++++ Example/Classes/AFAppDotNetAPIClient.m | 2 ++ Example/adn.cer | Bin 0 -> 1707 bytes 3 files changed, 6 insertions(+) create mode 100644 Example/adn.cer diff --git a/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj b/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj index d89b181..f3e7dd8 100644 --- a/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj +++ b/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2982AD3217107C0000FFF048 /* adn.cer in Resources */ = {isa = PBXBuildFile; fileRef = 2982AD3117107C0000FFF048 /* adn.cer */; }; F8129C7415910C37009BFE23 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F8129C7215910C37009BFE23 /* AppDelegate.m */; }; F818101615E6A0C600EF93C2 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50ABD6EC159FC2CE001BE42C /* MobileCoreServices.framework */; }; F88812F016C533D6003C8B8C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469E013957DF100DB05C8 /* Security.framework */; }; @@ -40,6 +41,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 2982AD3117107C0000FFF048 /* adn.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = adn.cer; sourceTree = SOURCE_ROOT; }; 50ABD6EC159FC2CE001BE42C /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; F8129C3815910830009BFE23 /* Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = SOURCE_ROOT; }; F8129C7215910C37009BFE23 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; @@ -198,6 +200,7 @@ F8E4696B1395739D00DB05C8 /* Supporting Files */ = { isa = PBXGroup; children = ( + 2982AD3117107C0000FFF048 /* adn.cer */, F8DA09E31396AC040057D0CC /* main.m */, F8129C3815910830009BFE23 /* Prefix.pch */, F8E4696C1395739D00DB05C8 /* iOS-Info.plist */, @@ -319,6 +322,7 @@ F8A847C1161F51A300940F39 /* Default-568h@2x.png in Resources */, F8A847C3161F523E00940F39 /* Default.png in Resources */, F8A847C5161F524200940F39 /* Default@2x.png in Resources */, + 2982AD3217107C0000FFF048 /* adn.cer in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/Classes/AFAppDotNetAPIClient.m b/Example/Classes/AFAppDotNetAPIClient.m index f0bc2f1..7859d90 100644 --- a/Example/Classes/AFAppDotNetAPIClient.m +++ b/Example/Classes/AFAppDotNetAPIClient.m @@ -49,6 +49,8 @@ static NSString * const kAFAppDotNetAPIBaseURLString = @"https://alpha-api.app.n // Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 [self setDefaultHeader:@"Accept" value:@"application/json"]; + [self setDefaultSSLPinningMode:AFSSLPinningModePublicKey]; + return self; } diff --git a/Example/adn.cer b/Example/adn.cer new file mode 100644 index 0000000000000000000000000000000000000000..614e784664114ecc09182da430cae9d8aa05863c GIT binary patch literal 1707 zcmZ`(4Nz276ux(VVPzHF6;J}60*WBZT~R1>9M*MpNpO%K|4SdcZFE8J0sR76W8bPeJ|?VXjD` z5aed7XCehLWQu^5teMp^oQq1c8Pu~-FoCBi0*i`@R7UJFV3*2Zx2mI2BykB9FHA(} zS#v(6aXJe*+Gb!VttLJZg$K*ki_l_qG8+4B#%3Z)LWvl}zs<-#S%(5mCt3XzGA(Uk zO?J-4(&`|jB%o9w&!%nEDw3Ub8tm!_6h?5FA}E91$rz~&#>moCI-TcSNYty;Gf?1| z#sL3V742}SY>W%>aPITp0*ZlWjRCMlpy)2|-V{>5V z!nO*gf5o!QPNp*Rex2)_El{rY8rAGmX*=w{B=~*5C;V96erHR~wvq7XDgUo^$f6 zq13^ofryaLZ@$uZ@Y5e(Uh~ELweubi_KD+;J??I5T32NpIIG>$Elc53YrD9+KYK&> z%Z|Ucw{cam95p8mk9s0LYcDH)yZ5m4RL@)y4Fy67UQIJUaU}$f3T*iyxE!O6H>mJ=|nEz%BKkl9` z!Z*nOa|gWCcNtSj`e_i3ibO(z*gH;-CUl8koCG(jR0t<_0m35z$=C0SnMGh$M-bI!xllugTh%zbz+;I z;p1mjpaXEhk!P_*+vVuOM#U`J~hC9StSFsnXP9SN6Q%fm*>Lg6dDTy&gLRlTlNajeP#obR&`C7{_%z6GDg4WPv~B^ bvS3-y)jPAVR@|7mX=}|R?&vB0ufo3p3#}Ki literal 0 HcmV?d00001 From ebccca44da3591a2611dce46d2a0b32097e224da Mon Sep 17 00:00:00 2001 From: Kevin Harwood Date: Sat, 6 Apr 2013 11:30:47 -0500 Subject: [PATCH 2/5] Fixed SSL Pinning - 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 --- AFNetworking/AFURLConnectionOperation.m | 95 ++++++++++++------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 0d9bac7..0ecbdb8 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -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 From 5b633898b3c035fcc1761eaa10d7263cfa20f1d1 Mon Sep 17 00:00:00 2001 From: Kevin Harwood Date: Sat, 6 Apr 2013 11:33:29 -0500 Subject: [PATCH 3/5] Clean up --- AFNetworking/AFURLConnectionOperation.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 0ecbdb8..f7dd75c 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -222,8 +222,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat status = SecTrustEvaluate(allowedTrust, &result); NSAssert(status == noErr, @"SecTrustEvaluate error: %ld", (long int)status); - SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust); - + SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust); NSCParameterAssert(allowedPublicKey); [publicKeys addObject:(__bridge_transfer id)allowedPublicKey]; From c8e420990efc80a1eba059f9c34fab0023efdcfc Mon Sep 17 00:00:00 2001 From: Kevin Harwood Date: Sat, 6 Apr 2013 15:02:57 -0500 Subject: [PATCH 4/5] Added guard around adding a NULL object to an array --- AFNetworking/AFURLConnectionOperation.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index f7dd75c..7ddc96b 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -224,7 +224,8 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust); NSCParameterAssert(allowedPublicKey); - [publicKeys addObject:(__bridge_transfer id)allowedPublicKey]; + if(allowedPublicKey!=NULL) + [publicKeys addObject:(__bridge_transfer id)allowedPublicKey]; CFRelease(allowedTrust); CFRelease(policy); From 158db930ff0183048e203eabad6ad8c45227e72a Mon Sep 17 00:00:00 2001 From: Kevin Harwood Date: Sat, 6 Apr 2013 15:46:50 -0500 Subject: [PATCH 5/5] Revert "Added guard around adding a NULL object to an array" This reverts commit c8e420990efc80a1eba059f9c34fab0023efdcfc. --- AFNetworking/AFURLConnectionOperation.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 7ddc96b..f7dd75c 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -224,8 +224,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust); NSCParameterAssert(allowedPublicKey); - if(allowedPublicKey!=NULL) - [publicKeys addObject:(__bridge_transfer id)allowedPublicKey]; + [publicKeys addObject:(__bridge_transfer id)allowedPublicKey]; CFRelease(allowedTrust); CFRelease(policy);