4

I am using ASIHTTPRequest v1.8.1 to make a HTTPS request. The problem is that it doesn't work on iOS 5.0 & 5.0.1, while on 5.1 & 5.1.1 it works fine. The code is quite simple:

__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:RemoteNotiURL]];
[request setPostValue:@"i" forKey:@"plat"];
[request setPostValue:token forKey:@"token"];
[request setValidatesSecureCertificate:NO];

[request setCompletionBlock:^{
    NSLog(@"done");
}];

[request setFailedBlock:^{
    NSLog(@"error = %@", [request error]);

}];

[request startAsynchronous];

RemoteNotiURL is a URL like https://xxx.example.com

The error is:

error = Error Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)" UserInfo=0x18460b0 {NSUnderlyingError=0x1853ab0 "The operation couldn’t be completed. (OSStatus error -9800.)", NSLocalizedDescription=A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)}

What can I do about this?

TiMESPLiNTER
  • 5,741
  • 2
  • 28
  • 64
b_bruce
  • 53
  • 1
  • 4
  • Could be related to this: http://stackoverflow.com/questions/7792949/ios-5-https-asihttprequest-stop-working – JosephH May 09 '12 at 11:04

1 Answers1

13

As @JosephH said the solution involves modifying ASIHTTPRequest.m to change the kCFStreamSSLLevel property of the sslProperties dictionary. In this file look for the comment // Tell CFNetwork not to validate SSL certificates

Under this comment there is an if clause

if (![self validatesSecureCertificate]) {
        // see: http://iphonedevelopment.blogspot.com/2010/05/nsstream-tcp-and-ssl.html

        NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
                                       [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
                                       [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
                                       [NSNumber numberWithBool:NO],  kCFStreamSSLValidatesCertificateChain,
                                       kCFNull,kCFStreamSSLPeerName,
                                       nil];

        CFReadStreamSetProperty((CFReadStreamRef)[self readStream], 
                                kCFStreamPropertySSLSettings, 
                                (CFTypeRef)sslProperties);
        [sslProperties release];
    }

Modify the if clause like so

if (![self validatesSecureCertificate]) {
        // see: http://iphonedevelopment.blogspot.com/2010/05/nsstream-tcp-and-ssl.html

        NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
                                       [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
                                       [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
                                       [NSNumber numberWithBool:NO],  kCFStreamSSLValidatesCertificateChain,
                                       kCFNull,kCFStreamSSLPeerName,
                                       @"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
                                       nil];

        CFReadStreamSetProperty((CFReadStreamRef)[self readStream], 
                                kCFStreamPropertySSLSettings, 
                                (CFTypeRef)sslProperties);
        [sslProperties release];
    }else {
        NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
                                       [NSNumber numberWithBool:NO], kCFStreamSSLAllowsExpiredCertificates,
                                       [NSNumber numberWithBool:NO], kCFStreamSSLAllowsAnyRoot,
                                       [NSNumber numberWithBool:YES],  kCFStreamSSLValidatesCertificateChain,
                                       @"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
                                       nil];

        CFReadStreamSetProperty((CFReadStreamRef)[self readStream], 
                                kCFStreamPropertySSLSettings, 
                                (CFTypeRef)sslProperties);
        [sslProperties release];
    }

This should make requests work again. Both requests which validate SSL certificates and those which don't validate them.

Tested on IOS 5.0.1 and 5.1.1.

Hope this helps.

Ignacio Valdivieso
  • 1,181
  • 8
  • 5