Supporting HTTPS in iOS XMPPFramework - ios

I am developing an Chatting app for iOS platform. I am using XMPP framework downloaded from https://github.com/robbiehanson/XMPPFramework.
Initially server was not having certificates installed, it was a plain HTTP service. But now certificate authentication is required because now certificate is installed and need to support HTTPS protocol. I Tried just implementing following method,
- (void)xmppStream:(XMPPStream *)sender didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler;
But now it is not connecting to that server or certificate validation is not happening.
Any idea apart from above delegate method do we need to set up any other thing ?
To connect to server i am using following method,
- (BOOL)connectWithTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr
Regards,
Bhat

I resolved the above issue by setting the isSecure values as YES.
The following method was not publicly available for other classes in XMPPStream class.
-(void)setIsSecure:(BOOL)flag
By setting the above value am able to connect the port 5223 and SSL handshake works perfectly..
Regards,
Chandrika

Related

How to Bypass SSL check in iOS 11 using Ionic Cordova framework and self signed certificate

In my app I need to call some REST API service calls. The certificate on the target development server where REST API services are deployed is self signed. So when I am running app I am getting error like:
Failed to load resource: The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.10.20:8080” invalid.....which could put your confidential information at risk.
As this server is only for dev/testing purpose so I simply wants to ignore ssl check ... How can I achieve it? I tried following way:
[AppDelegate.m file] but didn't succeeded as below code is not working in iOS 11 ...
#implementation NSURLRequest(DataController)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
#end
I am using ionic 3 & Cordova 7 in my app.
Thanks #peter I have found one more workaround for checking app in ios11 for testing purpose whether API's are getting hit properly or not. You can forcefully change the webview from WKWebView to UIWebview by adding below tag in config.xml
<preference name="CordovaWebViewEngine" value="CDVUIWebViewEngine" />
now add following code in Appdelegate.m file
#implementation NSURLRequest(DataController)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
#end
it worked for me..!
Note:only for dev/testing purpose.not recommended for production deployments
Interestingly, I am just researching the same problem. Looks like in iOS 11 things are a bit more restricted. I am answering here for WKWebView.
In essence you need to do:
place custom auth code to the WKWebView plugin code
load resource directly from Cordova (then WKWebView events gets properly triggered)
disable ATS (NSAppTransportSecurity)
Detail description
What you should do in detail is the following (if you are using WKWebView):
You need to modify CDVWKWebViewEngine.m (plugin code). You need to add there:
- (void)webView:(WKWebView *)webView
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge
*)challenge completionHandler:(void (^)
(NSURLSessionAuthChallengeDisposition
disposition, NSURLCredential *credential))completionHandler {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
completionHandler(NSURLSessionAuthChallengeUseCredential,
[NSURLCredential credentialForTrust:serverTrust]);
}
However, please note - this only works when WKWebView is initialized (i.e. loaded via cordova framework).
So you need to load your application also from that URI where API is. I presume you have local network (self signed certificate), so this should not be a problem. If you will load application locally (i.e. from index.html) then this wont work!
Additionally you need to disable iOS ATS in application *.plist setting file like:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
This is what works for me.
Additional resources:
Very nice testing site for different SSL scenarios (including self signed): https://badssl.com/
Apple forum discussion on this topic: https://forums.developer.apple.com/message/269452#269452
Disclamer: Disabling certificate check should be avoided, use this only if you have a very good reason or other restrictions. You still have communication security, but you have no trust. Hence men in the middle attack is possible! If you decide to go with this option, you should also use certificate pinning to make things more secure.
I recently had a problem associated with an invalid SSL certificate on a server.
In my application, I am using the WKWebView plugin, which has become a requirement to send applications to an App Store. It is in this plug-in that an adjustment needs to be made to ignore invalid SSL certificates, in the file "plugins/cordova-plugin-ionic-webview/src/ios/CDVWKWebViewEngine.m", includes:
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
NSLog(#"Allow all");
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
CFDataRef exceptions = SecTrustCopyExceptions (serverTrust);
SecTrustSetExceptions (serverTrust, exceptions);
CFRelease (exceptions);
completionHandler (NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]);
}
As a result, the application will not take into account invalid SSL certificates.
References of https://developer.apple.com/forums/thread/15610
Remembering that it is not recommended to do this in applications in production, because invalid SSL certificates can compromise the security of the application.

How to create an HTTPS server on IOS using cocoaHTTPServer?

I made a javascript cloud app that runs on a webpage in a webview on my iPad app that communicates via WebSocket connection but it only works when im on my http site and not https or else I get an CFNetwork SSLHandshake failed (-9806) error in Xcode and on the website it says time out during handshake.
Is this because the webserver on the iPad is running on HTTP instead of HTTPS?
JAVASCRIPT CLOUD APP
This part in the cloud is working for HTTP when connecting to the web server on the iPad.
var protocol = "ws";
if (this.useSecureConnection)
protocol = "wss";
var url = protocol+'://localhost:'+this.port+'/service';
this.connection = new WebSocket(url);
Xcode iOS iPad App (Objective-C)
I thought that was the issue so I tried to enable HTTPS but I am not sure what to create for the "sslIdentityAndCertificates" method.
- (BOOL)isSecureServer
{
HTTPLogTrace();
// Override me to create an https server...
return YES;
}
/**
* This method is expected to returns an array appropriate for use in kCFStreamSSLCertificates SSL Settings.
* It should be an array of SecCertificateRefs except for the first element in the array, which is a SecIdentityRef.
**/
- (NSArray *)sslIdentityAndCertificates
{
HTTPLogTrace();
return nil;
}
Some of the other posts I have seen use APIs that are only available on Mac and not iOS.
I tried several combinations of ATS permissions as well. All resulted in HTTPS not allowing for WebSocket connection.
Any help is greatly appreciated! :)

Worklight - overloading NSURLConnection delegate method

I am working on an iOS app that is communicating with a Worklight server thanks to the iOS SDK provided by Worklight.
I would like to integrate the AppConnect SDK (MDM) to the project in order to do some tunneling on communications.
For this, I have to overload an NSURLConnectionDelegate method to add some AppConnect-related certificate configuration to an HTTP request :
- (void) connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
The problem is that NSURLConnections and NSURLRequests are encapsulated by the Worklight iOS library : the method that I use to make calls is
[[WLClient sharedInstance] invokeProcedure:myInvocation withDelegate:self options:serviceOptions];
So I can't see the NSURLConnections and NSURLRequests, and I can't overload the NSURLConnectionDelegate method...
That's why I would like to know : is it possible to overload the HTTP behavior of the Worklight iOS library in this way ? And if it is possible, how can I do it ?
If you need to add header, you can use the options in invokeProcedure.
In case you need more complicated things, I would suggest using NSURLProtocol -> https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLProtocol_Class/index.html

iOS - Simple SSL socket connection

What is the correct way to create a SSL socket connection in iOS?
I've implemented a SSL server in Java by:
creating a SSL certificate with a store password
loading it by setting the system properties "javax.net.ssl.keyStore" and "javax.net.ssl.keyStorePassword"
creating a SSLServerSocket with the SSLServerSocket factory
Now I want to create a client app which opens a socket connection in a thread and communicates over that. What is the proper way to create such a connection and do the communication with my servers certificate?
You can use NSInputStream and NSOutputStream to connect using TLS as per the answer to this question.
EDIT:
Rather than use the SSL settings in that answer, I would suggest this:
NSDictionary *settings = #{
(__bridge NSString *)kCFStreamPropertySocketSecurityLevel:(__bridge NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL
};
This uses the following defaults:
kCFStreamSSLAllowsExpiredCertificates: NO
kCFStreamSSLAllowsAnyRoot: NO
kCFStreamSSLValidatesCertificateChain: YES
If you want to set the security level to use a particular version of SSL or TLS, take a look at the values in CFSocketStream.h.
There is no need to create a certificate if you are making a client app not a server one.
To do it in iOS, there are a number of ways, the simplest is to use AFNetworking library.
Just put the url (https) inside one of its methods, and you are ready.
I used it many times. Just spend 5 mins to read the doc.

MUC implemention on ejabberd server using xmppFramework

I want to know that is it possible to create a chatroom and invite people ? I have setup ejabberd on my mac and implemented chat with single buddy following
this link but i want to implement MUC. I tried demo project of MUC which come with xmppframework available here ,but every time i get error 404 remote server not found. The delegate method
- (void)xmppRoomDidCreate:(XMPPRoom *)sender;
never gets called.
Instead
- (void)handleDidLeaveRoom:(XMPPRoom *)room
this method gets called. Has anyone successfully implemented MUC using localhost as server?If yes then please let me know the XMPP client you are using , because for ejabberd,it says remote server not found.
Did you try with conference.host (presumably conference.localhost) as MUC host ?

Resources