Browse Source

Use SecTrust return status code at runtime

The `SecTrust` functions in use within AFSecurityPolicy.h only make use of the return code when `NS_BLOCK_ASSERTIONS` is not defined. The use of NS_BLOCK_ASSERTIONS to silence static analyzer warnings about unused values is convenient, however the larger issue is the failure of `AFPublicKeyForCertificate`, `AFPublicKeyTrustChainForServerTrust` and `AFServerTrustIsValid` to detect a runtime status code that is not `errSecSuccess` and to return early.
Dave Anderson 11 năm trước cách đây
mục cha
commit
0e6eb0c9c2
1 tập tin đã thay đổi với 45 bổ sung25 xóa
  1. 45 25
      AFNetworking/AFSecurityPolicy.m

+ 45 - 25
AFNetworking/AFSecurityPolicy.m

@@ -26,12 +26,14 @@
 static NSData * AFSecKeyGetData(SecKeyRef key) {
     CFDataRef data = NULL;
 
-#if defined(NS_BLOCK_ASSERTIONS)
-    SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data);
-#else
     OSStatus status = SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data);
     NSCAssert(status == errSecSuccess, @"SecItemExport error: %ld", (long int)status);
-#endif
+    if (status != errSecSuccess) {
+        if (data) {
+            CFRelease(data);
+        }
+        return nil;
+    }
 
     NSCParameterAssert(data);
 
@@ -56,21 +58,29 @@ static id AFPublicKeyForCertificate(NSData *certificate) {
 
     SecPolicyRef policy = SecPolicyCreateBasicX509();
     SecTrustRef allowedTrust = NULL;
-#if defined(NS_BLOCK_ASSERTIONS)
-    SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust);
-#else
     OSStatus status = SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust);
     NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
-#endif
+    if (status != errSecSuccess) {
+        if (allowedTrust) {
+            CFRelease(allowedTrust);
+        }
+        CFRelease(policy);
+        CFRelease(tempCertificates);
+        CFRelease(allowedCertificate);
+        return nil;
+    }
 
     SecTrustResultType result = 0;
 
-#if defined(NS_BLOCK_ASSERTIONS)
-    SecTrustEvaluate(allowedTrust, &result);
-#else
     status = SecTrustEvaluate(allowedTrust, &result);
     NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
-#endif
+    if (status != errSecSuccess) {
+        CFRelease(allowedTrust);
+        CFRelease(policy);
+        CFRelease(tempCertificates);
+        CFRelease(allowedCertificate);
+        return nil;
+    }
 
     SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust);
     NSCParameterAssert(allowedPublicKey);
@@ -86,13 +96,11 @@ static id AFPublicKeyForCertificate(NSData *certificate) {
 static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
     SecTrustResultType result = 0;
 
-#if defined(NS_BLOCK_ASSERTIONS)
-    SecTrustEvaluate(serverTrust, &result);
-#else
     OSStatus status = SecTrustEvaluate(serverTrust, &result);
     NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
-#endif
-
+    if (status != errSecSuccess) {
+        return NO;
+    }
     return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
 }
 
@@ -120,19 +128,27 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
 
         SecTrustRef trust = NULL;
 
-#if defined(NS_BLOCK_ASSERTIONS)
-        SecTrustCreateWithCertificates(certificates, policy, &trust);
-
-        SecTrustResultType result;
-        SecTrustEvaluate(trust, &result);
-#else
         OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust);
         NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
+        if (status != errSecSuccess) {
+            if (trust) {
+                CFRelease(trust);
+            }
+            CFRelease(certificates);
+            continue;
+        }
 
+        
         SecTrustResultType result;
         status = SecTrustEvaluate(trust, &result);
         NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
-#endif
+        if (status != errSecSuccess) {
+            if (trust) {
+                CFRelease(trust);
+            }
+            CFRelease(certificates);
+            continue;
+        }
 
         [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)];
 
@@ -206,7 +222,11 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
     if (self.pinnedCertificates) {
         NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]];
         for (NSData *certificate in self.pinnedCertificates) {
-            [mutablePinnedPublicKeys addObject:AFPublicKeyForCertificate(certificate)];
+            id publicKey = AFPublicKeyForCertificate(certificate);
+            if (!publicKey) {
+                continue;
+            }
+            [mutablePinnedPublicKeys addObject:publicKey];
         }
         self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys];
     } else {