iphone: secure restfull server "The certificate for this server is invalid - iphone

I am trying to consume secure restful service which gives error
Error = Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “xxx.xxx.xxx.xxx” which could put your confidential information at risk."
working on xCode 4.2, where is the mistake or any step missing.
using following code
RegisterUser.f
#interface RegisterUser : UIViewController<UITextFieldDelegate,
UIScrollViewDelegate, NSURLConnectionDelegate>
RegisterUser.m
- (IBAction)SubmitBtnAction:(id)sender {
NSURL *url = [NSURL URLWithString:#"https://xx.xx.xx.xxx:8223/jaxrs/tunedoorgateway/getCountries"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] >0 && error == nil)
{
NSLog(#"Data = %#", data);
// DO YOUR WORK HERE
}
else if ([data length] == 0 && error == nil)
{
NSLog(#"Nothing was downloaded.");
}
else if (error != nil){
NSLog(#"Error = %#", error);
}
}];
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
NSLog(#"This is canAuthenticateAgainstProtectionSpace");
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
// if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
// if ([trustedHosts containsObject:challenge.protectionSpace.host])
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
NSLog(#"This is didReceiveAuthenticationChallenge");
// [[challenge sender] cancelAuthenticationChallenge:challenge];
}

I feel this might be because of DNS, something like your server is not registered.
Try using this for development:
Create an NSURLRequest+NSURLRequestSSLY.h file and add these lines to it
#import <Foundation/Foundation.h>
#interface NSURLRequest (NSURLRequestSSLY)
+(BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
#end
Create an NSURLRequest+NSURLRequestSSLY.m file and add these lines to it
#import "NSURLRequest+NSURLRequestSSLY.h"
#implementation NSURLRequest (NSURLRequestSSLY)
+(BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host
{
return YES;
}
#end
And don't forget to remove it before publishing as your app might get rejected.

The failure is not in your code. You are using a HTTPS server which does not provide a known certificate. If you have setup the server yourself you have to go and buy a singed certificate from one of the big certification authorities which are trusted by iOS and most other operating systems.
For development purposes you can test your REST service by ignoring the non-trusted certificate. Follow this guide for doing that: http://www.cocoanetics.com/2009/11/ignoring-certificate-errors-on-nsurlrequest/
But for production use I recommend you do not use this method since it will bring a security leak to your application. If you do ignore security you can also just use HTTP instead of HTTPS.

I have tried several way and found out it is related with apple developer centre certificate.
Upgrade your provisioning and try it again. I have tried posting data with iPad, iPhone 5 and 5S but iPhone 4.
When I have update my provisioning and installing on my iPhone 4, works with now issue.

Related

How to Validate SSL certificate

I want to validate SSL certificate in my app and i am using AFNetworking for validating certificate.
For SSL validation i am using openssl,libcrypto.a and libssl.a
My problem is that validation process was complete with NSURLConnection delegate methods, but using AFNetworking its not working.
NSURL *url = [NSURL URLWithString:#"https://www.google.com"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:req];
[operation setCompletionBlockWithSuccess: ^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *stringResponse = [[NSString alloc] initWithData:responseObject
encoding:NSUTF8StringEncoding];
// [self.webView loadHTMLString:stringResponse baseURL:nil];
NSLog(#"Responce-->>%#",stringResponse);
} failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
// [self.webView loadHTMLString:error.localizedDescription baseURL:nil];
NSLog(#"Responce-->>%#",error.localizedDescription);
}];
[operation start];
[operation setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge)
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
// By now, the OS will already have built a SecTrustRef instance for
// the server certificates; we just need to evaluate it
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecTrustResultType res;
OSStatus status = SecTrustEvaluate(serverTrust, &res);
bool verified = FALSE;
if (status == errSecSuccess && ((res == kSecTrustResultProceed) || (res == kSecTrustResultUnspecified)))
{
NSLog(#"iOS certificate chain validation for host %# passed", challenge.protectionSpace.host);
verified = verifyWithOpenSSL(serverTrust);
}
else
{
NSLog(#"iOS certificate chain validation for host %# failed", challenge.protectionSpace.host);
}
if (verified)
{
// If *both* verifications succeeded, then continue with the connection
NSURLCredential *successCredential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[challenge.sender useCredential:successCredential
forAuthenticationChallenge:challenge];
}
else
{
[challenge.sender cancelAuthenticationChallenge:challenge];
}
} else {
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}];
This is a code of AFNetworking for validation, I don't know whether it is wrong or correct.
But this process was completely work with NSURLConnection.
So please help.
AFNetworking 2 makes this really easy. First, add your SSL certificate to your app bundle. The certificate should have a .cer extension. Second, set a securityPolicy for your operation:
operation.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
By default, AFNetworking will validate the remote certificate against the one bundled with your app, ensuring that the domain name is correct, that both were issued with the same keypair, and that the certificate chain is valid.

setDefaultCredential not working for UIWebView in iOS 7 but works fine in earlier iOS versions

I am currently using the following code to set default credentials for UIWebView. This works fine in iOS 6.1 and earlier. However, in iOS 7 Beta 6 it does not work at all.
The web pages that I am trying to load use Windows Authentication. I am able to open them in Safari in iOS 7. However, when I run the below code and then open the URL in a UIWebView, I get an empty white rectangle and nothing ever loads! Like I said, this works perfectly in iOS 6.1 and earlier.
I also tried a second approach that involves using NSURLConnectionDelegate to hand off the credentials. This second approach also works fine in iOS 6.1 and earlier, but is broken in iOS 7.
Does anyone know why this is happening? Similar experiences? Thoughts?
// Authenticate
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"myusername"
password:#"mypassword"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:#"mysite.com"
port:80
protocol:#"http"
realm:nil
authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
I had the same exact issue - an NSURLConnection to a Sharepoint site configured for Windows Authentication was working fine in iOS 6.1. In iOS 7 - regardless of whether I targeted and built the app for 6 or 7 - all authentications would seem to succeed (receiving the proper cookie) but still respond with a 401; all subsequent requests sent with the cookie would receive 401 as well.
I resolved the issue by dumping the didReceiveAuthenticationChallenge delegate protocol in favor of willSendRequestForAuthenticationChallenge. Implementing the 2nd delegate protocol means the first never gets called.
In your delegate, implement this delegate protocol:
- (void)connection:(NSURLConnection *)sender willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] > 0]) {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}else{
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"username" password:#"password" persistence:NSURLPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}
After I implemented this on a whim, my iOS 7 NTLM authentication issues disappeared.
Update: This issue appears to be fixed in iOS 7.0.3
I answered this in the Apple developer forum, but now that iOS7 is out of beta, I'll repost here. Currently Windows Authentication is broken in iOS7. I expect there will be a fix out shortly, but until then you can work around the problem by handling authentication challenges in your UIViewController that contains your UIWebView.
Essentially you
Make an NSURLRequest and NSURLConnection yourself
Handle the connection:didReceiveAuthenticationChallenge:
In the connection:didReceivedResponse manually load your data into the UIWebView
Below I'm loading a PDF, but the process works the same whatever your content type.
//Make sure you implement NSURLConnectionDelegate and NSURLConnectionDataDelegate in your header
#interface MyViewController ()
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#property (strong, nonatomic) NSURLConnection *conn;
#property (strong, nonatomic) NSMutableData *pdfData;
#end
#implementation MyViewController
//... all of your init and other standard UIViewController methods here...
//Method that loads UIWebview. You'll probably call this in viewDidLoad or somewhere similar...
- (void) loadWebView {
//Make Request manually with an NSURLConnection...
NSString *url = //Get your url
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
self.conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
//#pragma mark - NSURLConnectionDelegate
//Handle authentication challenge (NSURLConnectionDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if([challenge previousFailureCount] == 0) {
NSString *username = //Get username
NSString *password = //Get password
//Use credentials to authenticate
NSURLCredential *cred = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
} else {
//Cancel authentication & connection
[[challenge sender] cancelAuthenticationChallenge:challenge];
[self.conn cancel];
self.conn = nil;
}
}
//#pragma mark - NSURLConnectionDataDelegate
//Received response (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//Init data
self.pdfData = [NSMutableData data];
}
//Collect data as it comes in (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.pdfData appendData:data];
}
//Handle connection failure (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
//Clean up...
[self.conn cancel];
self.conn = nil;
self.pdfData = nil;
//TODO: Notify user and offer next step...
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Finally, load data into UIWebview here (I'm loading a PDF)...
[self.webView loadData:self.pdfData MIMEType:#"application/pdf" textEncodingName:#"utf-8" baseURL:nil];
}
#end

need XMPP Framework

I am working on ejabberd setup, i configured the server successfully, But in the client side we need XMPP Framework for this,
I Googled i got the following links
http://deusty.blogspot.in/2008/08/xmppframework-on-iphone.html
http://iphone4developer.blogspot.in/2011/07/how-to-add-xmpp-in-your-ios-project.html
I downloaded the robbiehanson / XMPPFramework but it throws errors, and some links gives me 404 error(they removed)
I downloaded the jabber client from this link (https://github.com/funkyboy/Building-a-Jabber-client-for-iOS) but the xmpp framework files throws errors(those are already deleted) from the app
I got one sample that is iPhoneXMPP sample but it throws error that is "Unable to connect to server. Check xmppStream.hostName" i given my host name in willSecureWithSettings method
Doubts:
1)Please Guide me to download the proper XMPP Framework with out errors
2)How to Configure ejabber client side?
Please guide me
Thanks a lot in advance
I downloaded the robbiehanson/XMPPFramework around 6 months back from this link: https://github.com/robbiehanson/XMPPFramework . I followed the steps that are mentioned in Getting Started section. It didn't throw any error. Just try to follow these steps to setup the xmppframework with your application.
In sample app, I found the function setupStream() that I am calling when I start my application. In this function I am creating an xmppStream and activating different modules that are needed in my application. e.g
xmppStream = [[XMPPStream alloc] init];
// Activate xmpp modules after creating them
[xmppReconnect activate:xmppStream];
[xmppRoster activate:xmppStream];
[xmppvCardTempModule activate:xmppStream];
[xmppvCardAvatarModule activate:xmppStream];
[xmppCapabilities activate:xmppStream];
// Add ourself as a delegate to anything we may be interested in
[xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
[xmppStream setHostName:XMPPHOST];
[xmppStream setHostPort:5222];
// You may need to alter these settings depending on the server you're connecting to
allowSelfSignedCertificates = NO;
allowSSLHostNameMismatch = NO;
After setting the stream, you need to do authentication like this:
- (BOOL)connect:(NSString *)myJID //username registered with server
{
if (![xmppStream isDisconnected]) {
return YES;
}
if (myJID == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
NSError *error = nil;
if (![xmppStream connect:&error])
{
if(DEBUG)
{
NSLog(#"ERROR: Not connected to XMPP Server");
}
DDLogError(#"Error connecting: %#", error);
return NO;
}
return YES;
}
This function will be called by the framework and pass the password here:
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
if(sender == xmppStream)
{
//DDLogVerbose(#"In xmppStream: %#: %#", THIS_FILE, THIS_METHOD);
isXmppConnected = YES;
NSError *error = nil;
if (![[self xmppStream] authenticateWithPassword:password error:&error])
{
DDLogError(#"Error authenticating: %#", error);
}
}
}
Now if user is authenticated, this function will be called:
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
if(sender == xmppStream)
{
[self goOnline];
}
}
goOnline will send user's presence to server:
- (void)goOnline
{
XMPPPresence *presence = [XMPPPresence presence]; // type="available" is implicit
[xmppStream sendElement:presence];
}
Now you can send/receive the message/presence etc.
You will find a nice - complet - tutorial here: http://mobile.tutsplus.com/tutorials/iphone/building-a-jabber-client-for-ios-server-setup/

http media streaming over https by MVMoviePlayerViewController for iphone

I want to implement a function of http media streaming over https by MVMoviePlayerViewController. I try to access https server by NSURLConnection then open media by MVMoviePlayerViewController. I can successfully open the image url by UIWebView through this method under simulator and device and open media url like mp3 and mp4 by MVMoviePlayerViewController under simulator. The strange thing is that I get failed to open media url by MVMoviePlayerViewController under device. The following are error log.
An instance 0x4b4650 of class AVPlayerItem was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
(
Context: 0x0, Property: 0x208c20> Context: 0x0, Property: 0xa8626b0>
The following are some of my code.
-(void)viewDidLoad
{
NSString *stringPath = [NSString stringWithFormat:#"https://xxxxx/xxx.mp4";
NSURL *urlPath = [NSURL URLWithString:[stringPath stringByAddingPercentEscapesUsingEncoding:NSUTF8St ringEncoding]];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:urlPath];
NSURLConnection *httpConnection = [[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self] autorelease];
}
- (BOOL)connection : (NSURLConnection *)connection canAuthenticateAgainstProtectionSpace : (NSURLProtectionSpace *)protectionSpace
{
return YES;
}
- (void)connection : (NSURLConnection *)connection didReceiveAuthenticationChallenge : (NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] > 0)
{
return;
}
NSString *authenticationMethod = challenge.protectionSpace.authenticationMethod;
if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTru st])
{
SecTrustRef secTrustRef = challenge.protectionSpace.serverTrust;
[challenge.sender useCredential:[NSURLCredential credentialForTrust:secTrustRef forAuthenticationChallenge:challenge];
}
else
{
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:#"adminr" password:#"admin" persistence:NSURLCredentialPersistenceForSession];
[challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];
}
}
- (void)connection : (NSURLConnection *)connection didReceiveResponse : (NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
assert([httpResponse isKindOfClass:[NSHTTPURLResponse class]]);
NSLog(#"didReceiveResponse, status code : %d", httpResponse.statusCode);
NSString *stringPath = [NSString stringWithFormat:#"%#", testPath];
NSURL *urlPath = [NSURL URLWithString:[stringPath stringByAddingPercentEscapesUsingEncoding:NSUTF8St ringEncoding]];
if ((httpResponse.statusCode / 100) == 2)
{
MPMoviePlayerViewController *movieViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:urlPath];
[self presentMoviePlayerViewControllerAnimated:movieView Controller];
}
}
STEPS TO REPRODUCE
using NSURLConnection API to connect to an untrusted certification https server.
I will receive didReceiveAuthenticationChallenge (NSURLConnection delegate) and get NSURLAuthenticationMethodServerTrust authenticationMethod. I use SecTrustRef and NSURLCredential to access to untrusted certification https server.
I will receive didReceiveAuthenticationChallenge (NSURLConnection delegate) and use NSURLCredential to set username and password to access to untrusted certification https server.
I all receive didReceiveResponse (NSURLConnection delegate) and get http response statusCode 200 OK.
I try to open https media url by MPMoviePlayerViewController API.

A good solution for user authentication from iPhone app at a PHP server

I have been trying to implement a secure user authentication for an iPhone app. I am pretty much a newbie. I saw many code snippets and suggestions for different ways, and some seemed out dated. In the present scenario, what would be a good option? JSON? ASIHTTPRequest?
Till now, I couldn't find a proper solution for this. I am finding a bit difficult to integrate different ideas and come up with a solution to suit my need. Would be great if someone could share a sample code or at least point me to a solution posted somewhere. Thanks in advance.
Tony
What kind of user authentication does your server have? You could use Basic Auth for authentication, which pretty much means sending the Authorization headers with every request.
ASIHTTPRequest has functionality enabling basic auth and even presenting a login dialog, if you're OK with using that (the project's just been discontinued).
You would obviously need to implement basic authentication on your server as well.
I used this to successfully authenticate a user with a remote PHP server from an iOS app. A bit late, but it may help someone:
-(void)saveNewUserDetails{
[[NSUserDefaults standardUserDefaults] setObject:self.username.text forKey:#"userName"];
[SSKeychain setPassword:self.pwd.text forService:#"MiniCEXReporting" account:self.username.text]; //store securely rather than in NSUserDefaults
[[NSUserDefaults standardUserDefaults] synchronize];
}
-(void) makeConnection{
self.activityIndicator.hidden=NO;
[self.activityIndicator startAnimating];
receivedData=[[NSMutableData alloc] init];
NSString *userString=self.username.text;
postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://someURLhereWithUsernameappended/%#", userString]]];
//for the real thing
//postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://somsis-dev.leeds.ac.uk/api/minicex/%#", self.username.text]]];
[postRequest setHTTPMethod:#"POST"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:postRequest delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if ([challenge previousFailureCount] == 0) {
NSLog(#"received authentication challenge");
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:self.username.text
password:self.pwd.text
persistence:NSURLCredentialPersistenceForSession];
NSLog(#"credential created");
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
NSLog(#"responded to authentication challenge");
}
else {
NSLog(#"authentication failure username -%#- with password -%#-", self.username.text, self.pwd.text);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Authentication Error"
message:#"Please check your username and password"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[self.activityIndicator stopAnimating];
self.activityIndicator.hidden=YES;
}
}