2013-03-10 288 views
2

我正在開發iOS應用程序。我們擁有帶自簽名ca-cert的自定義證書頒發機構。證書頒發機構也爲用戶和https服務器頒發證書。我想創建iOS應用程序,它可以使用ca證書驗證https服務器,並且還可以使用客戶端證書與https服務器通信。我已經有了使用客戶端證書與https服務器進行通信的代碼,但我需要將ca證書導入系統密鑰環。我想將ca證書硬編碼到應用程序中。我的代碼如下所示:SecTrustSetAnchorCertificates與客戶端證書

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

    bool result=NO; 
    if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) { 
     result= YES; 
    } else if([protectionSpace authenticationMethod] ==  NSURLAuthenticationMethodClientCertificate) { 
     result = YES; 
    } 
    return result; 
} 

- (BOOL)shouldTrustProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
    CFDataRef certDataRef = (__bridge_retained CFDataRef)self.rootCertData; 
    SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef); 

    SecTrustRef serverTrust = protectionSpace.serverTrust; 

    CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert, 1, NULL); 
    SecTrustSetAnchorCertificates(serverTrust, certArrayRef); 

    SecTrustResultType trustResult; 
    SecTrustEvaluate(serverTrust, &trustResult); 

    return trustResult == kSecTrustResultUnspecified; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 

    NSLog(@"Did receive auth challange %@",[challenge debugDescription]); 

    NSURLProtectionSpace *protectionSpace = [challenge protectionSpace]; 

    NSString *authMethod = [protectionSpace authenticationMethod]; 
    if(authMethod == NSURLAuthenticationMethodServerTrust) { 
     NSLog(@"Verifying The Trust"); 

     NSURLCredential* cred=[NSURLCredential credentialForTrust:[protectionSpace serverTrust]]; 
     if ([self shouldTrustProtectionSpace:challenge.protectionSpace]) { 
      [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge]; 
      NSLog(@"OK"); 
     } else { 
      NSLog(@"FAILED"); 
      [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge]; 
     } 

    } 
    if(authMethod == NSURLAuthenticationMethodClientCertificate) { 
     NSLog(@"Trying Certificate"); 
     ..... 

一切都像魅力,直到服務器不需要客戶端證書。在這個時刻,我會收到錯誤此服務器的證書無效,執行不會到達點

NSLog(@"Trying Certificate"); 

當我有.der CA證書加載到系統鑰匙圈,一切正常,即使客戶端證書被髮送到服務器,服務器可以識別用戶。我東西

SecTrustSetAnchorCertificates(serverTrust, certArrayRef); 

影響莫名其妙的信任,因爲當我跳過這個電話,我可以簡單地做:

[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge]; 

沒有任何錯誤,但我無法驗證證書在這種情況下。

我在做什麼錯?

非常感謝, 亞當

回答