2012-07-23 75 views
6

我正在編寫一些API代碼來執行http請求,並且我一直在使用[NSUrlConnection:sendAsynchronousRequest:queue:completionHandler]進行調用,因爲它使編寫簡單處理程序,也使我不必爲每次調用與不同的代表有不同的班級。NSUrlConnection sendAsynchronousRequest和自簽名證書

我遇到的問題是,似乎接受自簽名證書的唯一方法是讓委託實現一些功能,說明證書沒問題。有沒有辦法使用塊的異步方法來做到這一點?

回答

3

不,但委託電話並不是那麼辛苦。這是代碼,您需要:

1)將此文件靜態

static CFArrayRef certs; 

2)做到這一點在你的初始化:

// I had a crt certificate, needed a der one, so found this site: 
    // http://fixunix.com/openssl/537621-re-der-crt-file-conversion.html 
    // and did this from Terminal: openssl x509 -in crt.crt -outform der -out crt.der 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"<your name>" ofType:@"der"]; 
    assert(path); 
    NSData *data = [NSData dataWithContentsOfFile:path]; 
    assert(data); 

    SecCertificateRef rootcert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data); 
    if(rootcert) { 
     const void *array[1] = { rootcert }; 
     certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks); 
     CFRelease(rootcert); // for completeness, really does not matter 
    } else { 
     NSLog(@"BIG TROUBLE - ROOT CERTIFICATE FAILED!"); 
    } 

3)然後添加這個方法:

- (void)connection:(NSURLConnection *)conn didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
#pragma unused(conn) 
    // NSLog(@"didReceiveAuthenticationChallenge %@ FAILURES=%zd", [[challenge protectionSpace] authenticationMethod], (ssize_t)[challenge previousFailureCount]); 

    /* Setup */ 
    NSURLProtectionSpace *protectionSpace = [challenge protectionSpace]; 
    assert(protectionSpace); 
    SecTrustRef trust      = [protectionSpace serverTrust]; 
    assert(trust); 
    CFRetain(trust);      // Don't know when ARC might release protectionSpace 
    NSURLCredential *credential    = [NSURLCredential credentialForTrust:trust]; 

    BOOL trusted = NO; 
    OSStatus err; 
    SecTrustResultType trustResult = 0; 

    err = SecTrustSetAnchorCertificates(trust, certs); 
    if (err == noErr) { 
     err = SecTrustEvaluate(trust, &trustResult); 
     if(err == noErr) { 
     // http://developer.apple.com/library/mac/#qa/qa1360/_index.html 
      switch(trustResult) { 
      case kSecTrustResultProceed: 
      case kSecTrustResultConfirm: 
      case kSecTrustResultUnspecified: 
       trusted = YES; 
       break; 
      }  
     } 
    } 
    CFRelease(trust); 

    // Return based on whether we decided to trust or not 
    if (trusted) { 
     [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
    } else { 
     NSLog(@"Trust evaluation failed"); 
     [[challenge sender] cancelAuthenticationChallenge:challenge]; 
    } 
}