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:
- I downloaded Certificate from the browser and included it to my Xcode project.
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]];
Exctract identity
[self extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data password:@"myCertificatePasswordHere"];
Send HTTP Request over HTTPS
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:myHTTPsURLHere]; [request setClientCertificateIdentity:identity]; [request startSynchronous];
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!