2
votes

I am very new to Objective C and HTTPs. Please advise me on this matter.

I need my iPhone application to communicate with my server over HTTPs. I created self-signed certificate and when accessing URLs via browsers it works though displays a warning message that the server is untrusted. That's ok.

To send HTTP requests from my iPhone App. over HTTPS I am using ASIHTTPRequest. But I am getting an error message "A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)".

I browsed around Stackoverflow and learned to do it the following way:

  1. I downloaded Certificate from the browser and included it to my Xcode project.
  2. Load certificate to NSData

    NSString* fullFileName = @"myCertificate.cer"; NSString* fileName = [[fullFileName lastPathComponent] stringByDeletingPathExtension]; NSString* extension = [fullFileName pathExtension]; NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:extension]];

  3. Exctract identity

    [self extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data password:@"myCertificatePasswordHere"];

  4. Send HTTP Request over HTTPS

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:myHTTPsURLHere]; [request setClientCertificateIdentity:identity]; [request startSynchronous];

  5. As many people here suggested I also modified ASIHTTPRequest.m and included

[sslProperties setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates]; [sslProperties setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots];

into an IF statement

   if (![self validatesSecureCertificate]) {

     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 {
            NSMutableDictionary *sslProperties = [[NSMutableDictionary 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 setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates]; // Sergey added this line
            [sslProperties setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots]; // Sergey added this line 
            [sslProperties release];
        } 

But it does not help :(. I am still getting an error message:

  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)"

Please advise me how to make ASIHTTPRequest over HTTPs so that Client Certificate gets verified by my server? I do not want to use private api...

Thank you very much!

1
There is an SSL validation error bug in ASIHTTPRequest for iOS version 5.0.1. It's been fixed here github.com/ignaval/asi-http-request/commit/… (thanks to ignaval)user1434183
ASIHTTPRequest is no longer supported by the developer and should not be used. If you want to use a third party framework, use AFNetworking.nickfox

1 Answers

1
votes

There is indeed a bug with ASIHttpRequest and iOS 5. A good fix that worked for me was this one: Fix for self-signed client certificates on iOS 5 (alternate) by james-chalfant