2011-10-26 9 views
5

के साथ देता है मेरा एप्लिकेशन स्वयं हस्ताक्षरित प्रमाणपत्र के लिए सर्वर ट्रस्ट प्रमाणपत्र का मूल्यांकन करने का प्रयास करता है।SecTrustEvaluate हमेशा kSecTrustResultRecoverableTrustFailure को SecPolicyCreateSSL

if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) { 
     // create trust from protection space 
     SecTrustRef trustRef; 
     int trustCertificateCount = SecTrustGetCertificateCount(challenge.protectionSpace.serverTrust); 

     NSMutableArray* trustCertificates = [[NSMutableArray alloc] initWithCapacity:trustCertificateCount]; 
     for (int i = 0; i < trustCertificateCount; i++) { 
      SecCertificateRef trustCertificate = SecTrustGetCertificateAtIndex(challenge.protectionSpace.serverTrust, i); 
      [trustCertificates addObject:(id) trustCertificate]; 
     }    

     // set evaluation policy 
     SecPolicyRef policyRef; 
     // policyRef = SecPolicyCreateBasicX509(); this is working 
     policyRef = SecPolicyCreateSSL(NO, (CFStringRef)    
     SecTrustCreateWithCertificates((CFArrayRef) trustCertificates, policyRef, &trustRef); 

     [trustCertificates release]; 

     // load known certificates from keychain and set as anchor certificates 
     NSMutableDictionary* secItemCopyCertificatesParams = [[NSMutableDictionary alloc] init];  
     [secItemCopyCertificatesParams setObject:(id)kSecClassCertificate forKey:(id)kSecClass]; 
     [secItemCopyCertificatesParams setObject:@"Server_Cert_Label" forKey:(id)kSecAttrLabel]; 
     [secItemCopyCertificatesParams setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnRef]; 
     [secItemCopyCertificatesParams setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit]; 

     CFArrayRef certificates; 
     certificates = nil; 
     SecItemCopyMatching((CFDictionaryRef) secItemCopyCertificatesParams, (CFTypeRef*) &certificates); 

     if (certificates != nil && CFGetTypeID(certificates) == CFArrayGetTypeID()) { 
      SecTrustSetAnchorCertificates(trustRef, certificates); 
      SecTrustSetAnchorCertificatesOnly(trustRef, NO); 
     } 

     SecTrustResultType result; 
     OSStatus trustEvalStatus = SecTrustEvaluate(trustRef, &result); 
     if (trustEvalStatus == errSecSuccess) { 
      if (result == kSecTrustResultConfirm || result == kSecTrustResultProceed || result == kSecTrustResultUnspecified) { 
       // evaluation OK 
       [challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
      } else { 
       // evaluation failed 
       // ask user to add certificate to keychain 
     } else { 
      // evaluation failed - cancel authentication 
      [[challenge sender] cancelAuthenticationChallenge:challenge]; 
     } 
} 

मैं पहले से ही इस में उल्लेख की तरह एक्सटेंशन जोड़कर स्व-हस्ताक्षरित प्रमाणपत्र में परिवर्तन किए हैं अनुसंधान के एक बहुत बाद: यह SecPolicyCreateBasicX509 के साथ ठीक काम कर रहा है लेकिन SecPolicyCreateSSL

यहाँ के लिए काम नहीं कर रहा मेरी कोड है पोस्ट: Unable to trust a self signed certificate on iphone

क्या किसी के पास कोई अन्य संकेत है जो यहां गायब हो सकता है?

उत्तर

6

बहुत सारे परीक्षण के बाद मैंने इस समस्या का समाधान किया है। निम्नलिखित बदल दिया गया है।

  • नीति मूल्यांकन के लिए नीति को सेट किया गया है। इसका मतलब है कि प्रमाण पत्र क्लाइंट प्रमाणीकरण के लिए चेक किया गया है। जाहिर है सर्वर प्रमाण पत्र में यह नहीं होगा! इसे YES पर सेट करना वास्तव में जांच करेगा कि extendedKeyUsage सर्वर प्रमाणपत्र के लिए serverAuth पर सेट है।

  • SecTrustSetAnchorCertificates और SecTrustSetAnchorCertificatesOnly हमेशा मूल्यांकन से पहले बुलाया जाना चाहिए और न केवल अगर आप अपना एंकर प्रमाणपत्र प्रदान कर रहे हैं। आपको इसे खाली सरणी के साथ कॉल करने की आवश्यकता है, अन्यथा एंकर प्रमाणपत्रों को ज्ञात सिस्टम का मूल्यांकन मूल्यांकन के लिए नहीं किया जाता है। एमडीएम से भरोसेमंद रूट प्रमाण पत्र भी स्थापित कर रहे हैं।

    if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) { 
        // create trust from protection space 
        SecTrustRef trustRef; 
        int trustCertificateCount = SecTrustGetCertificateCount(challenge.protectionSpace.serverTrust); 
    
        NSMutableArray* trustCertificates = [[NSMutableArray alloc] initWithCapacity:trustCertificateCount]; 
        for (int i = 0; i < trustCertificateCount; i++) { 
         SecCertificateRef trustCertificate = SecTrustGetCertificateAtIndex(challenge.protectionSpace.serverTrust, i); 
         [trustCertificates addObject:(id) trustCertificate]; 
        }    
    
        // set evaluation policy 
        SecPolicyRef policyRef; 
        // set to YES to verify certificate extendedKeyUsage is set to serverAuth 
        policyRef = SecPolicyCreateSSL(YES, (CFStringRef) challenge.protectionSpace.host); 
        SecTrustCreateWithCertificates((CFArrayRef) trustCertificates, policyRef, &trustRef); 
    
        [trustCertificates release]; 
    
        // load known certificates from keychain and set as anchor certificates 
        NSMutableDictionary* secItemCopyCertificatesParams = [[NSMutableDictionary alloc] init];  
        [secItemCopyCertificatesParams setObject:(id)kSecClassCertificate forKey:(id)kSecClass]; 
        [secItemCopyCertificatesParams setObject:@"Server_Cert_Label" forKey:(id)kSecAttrLabel]; 
        [secItemCopyCertificatesParams setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnRef]; 
        [secItemCopyCertificatesParams setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit]; 
    
        CFArrayRef certificates; 
        certificates = nil; 
        SecItemCopyMatching((CFDictionaryRef) secItemCopyCertificatesParams, (CFTypeRef*) &certificates); 
    
        if (certificates != nil && CFGetTypeID(certificates) == CFArrayGetTypeID()) { 
         SecTrustSetAnchorCertificates(trustRef, certificates); 
         SecTrustSetAnchorCertificatesOnly(trustRef, NO); 
        } else { 
         // set empty array as own anchor certificate so system anchos certificates are used too! 
         SecTrustSetAnchorCertificates(trustRef, (CFArrayRef) [NSArray array]); 
         SecTrustSetAnchorCertificatesOnly(trustRef, NO); 
        } 
    
        SecTrustResultType result; 
        OSStatus trustEvalStatus = SecTrustEvaluate(trustRef, &result); 
        if (trustEvalStatus == errSecSuccess) { 
         if (result == kSecTrustResultConfirm || result == kSecTrustResultProceed || result == kSecTrustResultUnspecified) { 
          // evaluation OK 
          [challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
         } 
         else { 
          // evaluation failed 
          // ask user to add certificate to keychain 
         } 
        } 
        else { 
         // evaluation failed - cancel authentication 
         [[challenge sender] cancelAuthenticationChallenge:challenge]; 
        } 
    } 
    

    आशा इस किसी की मदद करेंगे:

यहाँ एक काम नमूना पहले कोड पर आधारित है।

+0

'kSecTrustResultConfirm' को आईओएस 7 से हटा दिया गया है। –

3

यह जा सर्वर प्रमाणपत्र समस्या ....

चेक here, मैं अपने kSecTrustResultRecoverableTrustFailure समस्या हल हो सकता है, विशेष रूप से सर्वर कुंजी पीढ़ी में, openssl कॉन्फ़िग फ़ाइल में subjectAltName = DNS:example.com जोड़ने ...

हैं आप इसे उत्पन्न करने के लिए openssl का उपयोग नहीं कर रहे हैं, मुझे खेद है, लेकिन मैं आपकी मदद कर सकता हूं .. वैसे भी अगर आप openssl का उपयोग करना चाहते हैं, here उन कुंजी को उत्पन्न करने के लिए एक अच्छा ट्यूटोरियल है और फिर अपने रूट प्रमाणपत्र प्राधिकरण के साथ साइन इन करें।

 
    [ server ] 
    basicConstraints = critical,CA:FALSE 
    keyUsage = digitalSignature, keyEncipherment, dataEncipherment 
    extendedKeyUsage = serverAuth 
    nsCertType = server 
    subjectAltName = IP:10.0.1.5,DNS:office.totendev.com 

आशा है कि यह मदद करता है:

इस ट्यूटोरियल से, मैं सिर्फ करने के लिए अपने openssl सर्वर कॉन्फ़िग फ़ाइल बदल गया है!

संबंधित मुद्दे