En iOS, ¿cómo conectarse a un servidor usando https con certificado autofirmado en el servidor?

Estoy desarrollando para iOS 5 y realmente no quiero usar códigos sin ARC, así que elegí implementar esto por mí mismo en lugar de usar AFNetworking. Además, esta podría ser una gran pregunta, así que la dividí en dos partes más pequeñas.

1) Conectarme al servidor usando https en iOS 5. Yo uso los códigos extraídos de "Programación de iOS 5 presionando los límites" aquí. Debido a que estoy desarrollando para iOS 5, no uso los métodos desaprobados en mi proyecto. "RNSecTrustEvaluateAsX509" es un método que reevalúa el certificado como un simple certificado X.509 en lugar de como parte de un protocolo de enlace SSL.

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

    NSURLProtectionSpace *protSpace =  challenge.protectionSpace;
    SecTrustRef trust = protSpace.serverTrust;
    SecTrustResultType result = kSecTrustResultFatalTrustFailure;

    OSStatus status = SecTrustEvaluate(trust, &result);

    if (status == errSecSuccess && result == kSecTrustResultRecoverableTrustFailure) {
        SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, 0);
        CFStringRef subject = SecCertificateCopySubjectSummary(cert);

        NSLog(@"Trying to access %@. Got %@.", protSpace.host,
              (__bridge id)subject);
        CFRange range = CFStringFind(subject, CFSTR("192.168.1.100"), kCFCompareAnchored|kCFCompareBackwards);
        if (range.location != kCFNotFound) {
            NSLog(@"Creating new trust certificate.Ignoring the hostname.");
            status = RNSecTrustEvaluateAsX509(trust, &result);
        }
        CFRelease(subject);
    }

    if (status == errSecSuccess) {
        switch (result) {
            case kSecTrustResultInvalid:
            case kSecTrustResultDeny:
            case kSecTrustResultFatalTrustFailure:
            case kSecTrustResultOtherError:
            case kSecTrustResultRecoverableTrustFailure: {
                NSLog(@"Failing due to result: %lu", result);
                [challenge.sender cancelAuthenticationChallenge:challenge];
            }

                break;
            case kSecTrustResultProceed:
            case kSecTrustResultUnspecified: {
                NSLog(@"Successing with result: %lu", result);
                NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
                [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
            }
                break;
            default:
                NSAssert(NO,@"Unexpected result from trust evaluation: %d", result);
                break;
        }
    }
    else {
        // Something was broken
        NSLog(@"Complete failure with code: %lu", status);
        [challenge.sender cancelAuthenticationChallenge:challenge];
    }

}

Se conecta al servidor, pero siempre aparece un error que dice "No se pudo completar la operación (NSURLErrorDomain error -1012)". Y la consola muestra "Fallo debido al resultado 5", lo que significa que obtengo un kSecTrustResultRecoverableTrustFailure. Sospecho que esto se debe a que estoy usando un certificado autofirmado en el servidor. Esto lleva al segundo problema como abajo.

2) El certificado autofirmado está causando problemas. Así que he añadido estas líneas.

// Self-signed certificates need to be validated manually.
NSArray *anchors = [self serverAnchors];

SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors);
SecTrustSetAnchorCertificatesOnly(trust, YES);

justo antes

OSStatus status = SecTrustEvaluate(trust, &result);

en el método anterior willSendRequestForAuthenticationChallenge. Y también creé un método:

- (NSArray *)serverAnchors
{
    static NSArray *anchors = nil;
    if (!anchors) {
        NSData *caData = [CA_CERTS dataUsingEncoding:NSUTF8StringEncoding];
        SecCertificateRef caRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef) caData);

        anchors = [NSArray arrayWithObjects:(__bridge id)caRef,  nil];

        if (caRef) {
            CFRelease(caRef);   
        }
    }

    return anchors;
}

Definí CA_CERTS como datos de certificado de formato "der", que es un NSString que obtuve del servidor a través de SecCertificateCopyData. Pero sigo recibiendo kSecTrustResultRecoverableTrustFailure. Realmente no sé si estoy haciendo lo correcto aquí. ¿Cómo puedo validar manualmente el certificado autofirmado del servidor con sus propios datos? Más específicamente, ¿cómo obtener sus datos de iOS?

Respuestas a la pregunta(1)

Su respuesta a la pregunta