jgusta / IOSObjCWebSockets

An Obj-C/iOS web socket helper class, with the ability to send and receive data via simple delegate functions, and function calls. I also put together a working configuration for TLS on iOS, taking into account Apple's recent changes to its requirements with regards to TLS. In this example, I connect an iOS app to a NodeJS TLS server.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IOSObjCWebSockets

Class to help with TLS web sockets, and their respective connections between iOS and a basic NodeJS TLS Server.

IMPORTANT RESOURCES

NOTE: I have included my configuration files for this process, one for the main certificate authority, and one for an intermediate certificate authority. Follow the tutorial @ the link above for how to create the certificates correctly. As far as I can tell, you need a certificate authority AND an intermediate certicate authority, to sign your server and client certificates. It does not seem like a self-signed certificate is enough if you want to configure TLS at all to make a secure handshake. It took a lot of tweaking for me to get this part right - any errors that you have, I would first assume that it is with your certificate creation.

IMPORTANT: If you use my configuration files, you need to change the DNS name all the way at the bottom of both files to be the DNS of your server.

RELEVANT OFFICIAL DOCUMENTATION:

  • The Apple documentation for Network package (Network.h) is helpful, it is the basis for the iOS side of the TLS socket.

  • NodeJS docs for TLS server that I use in index.js - https://nodejs.org/api/tls.html#tls_tls_ssl

Client (iOS) Setup

Upon use of this class, an inbound connection (listener) is created, as well as an outbound connection. One is also able to easily send and receive data via a send_data method, and a receive_data delegate method. If you run the project, the ViewController creates and presents a button that you can tap to test sending data. I expect the most difficult part of this process for anyone to be creating the certificates correctly. If you follow the link above exactly for creating certificates, and use my .cnf files, you shouldn't have too many problems to surmount, if any.

To use in your project, copy IOSObjCWebSockets.h into your project directory, and import it. Also, copy IOSObjCWebSockets.m to the same directory as IOSObjCWebSockets.h.

Initialize

The main parts of instantiating are as follows:

1.) Import into the class/controller you want to use it in.

#import "IOSObjCWebSockets.h"

2.) Set your class/controller to be a delegate of IOSObjCWebSocketsDelegate.

@interface YourClass : YourType <IOSObjCWebSocketsDelegate>

3.) Instantiate object.

self.web_socket = [[IOSObjCWebSockets alloc] init];

4.) Set the delegate.

self.web_socket.delegate = self;

5.) Set server IP.

[self.web_socket set_IP:@"your.server.IP"];

6.) Set server port.

[self.web_socket set_port:@"your.server.port"];

7.) Set server name (DNS of server...mutable).

[self.web_socket set_DNS:@"your.server.DNS"];

8.) Set your encryption cipher.

[self.web_socket set_encryption:tls_ciphersuite_ECDHE_RSA_WITH_AES_128_GCM_SHA256]; //used as default cipher, many choices

9.) Start the sockets.

[self.web_socket start];

See ViewController for an example of how to implement.

Wait for networking to setup

Depending on what you are doing, some things that you instantiate in your app may need to be instantiated after networking is setup. You can use this delegate function to know when that is, and execute any necessary setup code. Be aware, this fires for every connection, so if you only want it to fire once you must handle that with your own code.

- (void)finished_setup;

Send data:

You must create a dispatch_data_t object for data_param.

[self.web_socket send_data:your.server.IP port:your.server.port data_param:data_param];

Receive data:

Implement this delegate method in your class/controller, all of the received data gets sent to it.

- (void)receive_data:(NSString*)data_as_string;

I am returning the data as an NSString for ease of logging, you should also be able to convert it to whatever you need from an NSString.

Server (NodeJS) Setup

On the server side, I am using a NodeJS TLS server, there are a few important parts of the server side configuration:

const options = {
  key: [fs.readFileSync('/Users/eamonwhite/ar_pong/corona_pong/certs/root/ca/intermediate/private/server.key.pem')], //This should be your server side certificate
  cert: [fs.readFileSync('/Users/eamonwhite/ar_pong/corona_pong/certs/root/ca/intermediate/certs/server.cert.pem')], //This should be your server side key

  //Note from NodeJS docs: This is necessary only if using client certificate authentication.
  //requestCert: true,

  // This is necessary only if the client uses a self-signed certificate.
  ca: [ fs.readFileSync('/Users/eamonwhite/ar_pong/corona_pong/certs/root/ca/intermediate/certs/ca-chain.cert.pem') ], //This should be your chain file, as created during the process described here https://jamielinux.com/docs/openssl-certificate-authority/introduction.html
  passphrase: 'xxx', //Password, if any, for your certificates - a reason to use the same password for all of your certificates.
  hostname: 'xxx.xxx.xxx' //Must include to make iOS happy, this should be the same as the DNS information included in your certificates per these restrictions https://support.apple.com/en-us/HT210176
};

Final Notes:

I would start out with the above configuration, and tweak it if neccessary - you shouldn't need to reconfigure much, and you can reference the NodeJS documentation mentioned above to help. The main trouble with figuring this out was getting the certificates right (with all the restrictions) so that the connection would even happen. You will also need to create a client certificate for for your iPhone. To get it onto your iPhone, email it to yourself in the form that it is created in, then on your iPhone, open the email with your iPhone's apple mail client (might not work with any other mail client), then tap to download, tap to install. Then follow the instructions for installing the certificate. I commented the code thoroughly. I hope this helps!

About

An Obj-C/iOS web socket helper class, with the ability to send and receive data via simple delegate functions, and function calls. I also put together a working configuration for TLS on iOS, taking into account Apple's recent changes to its requirements with regards to TLS. In this example, I connect an iOS app to a NodeJS TLS server.


Languages

Language:Objective-C 93.7%Language:JavaScript 5.5%Language:C 0.8%