2012-07-23 6 views
6

Ich schreibe einen API-Code, der http-Anfragen ausführt, und ich habe [NSUrlConnection: sendAsynchronousRequest: queue: completionHandler] für die Aufrufe verwendet, da es das Schreiben recht einfach macht Handler, und auch damit ich nicht für jeden Anruf verschiedene Klassen mit verschiedenen Delegierten haben muss.NSUrConnection sendAsynchronousRequest und selbstsignierte Zertifikate

Das Problem, das ich habe, ist, dass es scheint, dass die einzige Möglichkeit, selbst signierte Zertifikate zu akzeptieren, einen Delegaten hat, der einige Funktionen implementiert, die sagen, dass das Zertifikat in Ordnung ist. Gibt es eine Möglichkeit, dies mit der asynchronen Methode zu tun, die Blöcke verwendet?

Antwort

3

Nein, aber die Delegiertenanrufe sind nicht so schwer. Dies ist der Code, den Sie benötigen:

1) eine statische Datei Machen Sie dieses

static CFArrayRef certs; 

2) Tun Sie dies in Ihrem initialize:

// 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) Dann fügen Sie diese Methode:

- (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]; 
    } 
} 
Verwandte Themen