2012-07-23 4 views
6

HTTP 요청을 처리하는 API 코드를 작성 중이며 간단한 호출을 위해 [NSUrlConnection : sendAsynchronousRequest : queue : completionHandler]를 사용하고 있습니다. 핸들러를 사용할 수 있으며 각 호출에 대해 다른 대표와 다른 클래스를 가질 필요도 없습니다.NSUrlConnection sendAsynchronousRequest 및 자체 서명 된 인증서

자체 서명 된 인증서를 수락하는 유일한 방법은 인증서가 적합하다는 두 가지 기능을 구현하는 대리인을 갖는 것입니다. 블록을 사용하는 비동기 메서드로이를 수행 할 수있는 방법이 있습니까?

답변

3

아니요. 그러나 위임 호출이 그다지 어려운 것은 아닙니다. 이것은 당신은 코드를 필요로한다 :

1)이 정적 파일

static CFArrayRef certs; 

이 확인)하여 초기화에서이 작업을 수행 :

// 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]; 
    } 
} 
관련 문제