Search code examples
ioslinuxsslapp-transport-security

Secure communication between iOS app and Raspberry Pi


I want to create secure communication channel between my RPI and iOS 11 mobile application in local environment. My RPI is running a python API code and my iOS mobile app creates different API calls to the RPI. For secure connection I’m using certificates signed by my private Certificate Authority. All certificates and signing requests were created using “OpenSSL” Linux command line tool.

As I mentioned earlier, devices are communicating in local network over default .local domain which is configured by avahi service on linux device, and bonjour (zeroconf) service on iOS device. In the beginning I had some issues with loading certificates in mobile app and after I’ve done some research I’ve found that I must have “NSAllowsLocalNetworking” flag enabled inside xCode IDE. With the “NS” flag enabled SSL certificate pinning was successful and secure communication was established.

What I don’t know and I would like to find out are two things:

  1. Is there any restriction from Apple side with publishing application to the app store when the “NSAllowsLocalNetworking” flag was enabled?
  2. Besides using certificates, what other options do I have in terms of secure communication between iOS mobile app and RPI?

Solution

  • You are using the correct approach. Using a self signed certificate with certificate pinning is the right approach will allow you to trust the connection, as long as you have protected the key used to generate the cert.

    In fact, it is recommended by Apple:

    Note: Although ATS is unenforced for connection to local hosts, Apple strongly recommends using Transport Layer Security (TLS) for any local connection, along with the use of a self-signed certificate to validate the local IP address.

    Apple created the NSAllowsLocalNetworking specifically for scenarios such as this. As of current Apple documentation, use of this flag will not trigger the need to provide Apple with justification for disabling ATS. One additional thing to note is that this flag is only supported on iOS10 and later.

    If you need to support older versions, Apple offers a way to do this to support older versions. Basically, you set both the NSAllowsArbitraryLoads flag to true, as well as the NSAllowsLocalNetworking flag. Basically, iOS9 only understand, so iOS 9 devices disable ATS altogether. iOS 10+ understands, both NSAllowsArbitraryLoads and NSAllowsLocalNetworking, so it has logic built in to let NSAllowsLocalNetworking override NSAllowsArbitraryLoads, and leaves ATS protections on for the rest of the app, while allowing local network connections to go through. Apple covers that on their documentation page under the header "Supporting Older Operating Systems".