OpenSSL + Swift: Everything You Need to Know

Jonathan Cardasis
Hashes and Dashes of Code.

There are little to no tutorials out there outlining how to get started with OpenSSL for macOS and iOS applications without the use of external solutions such as Cocoapods. Here I’m going to focus on how you can include OpenSSL into your project without external build systems. I will be outlining how to build and link for a macOS target, but iOS is very similar.

Tid-Bits of Knowhow

OpenSSL was first released in 1998 under the premise to create a free set of encryption tools for code used on the internet. Since then it has become one of the most well known (and distributed) open-source projects.

OpenSSL is a C based security library focusing on computer network security. Due to the large implementation suite it provides, from SSL and TLS to hash and cipher functions, OpenSSL has trusted implementations of some of the most popular cryptographic functions.

First Timers and OpenSSL (Background)

Integrating OpenSSL’s library into your macOS or iOS app can be…..well…a bit more than tricky when you haven’t used a library like it before.

The first thing to note is that you should never use an untrusted, precompiled version of OpenSSL in your app. Anyone can modify the source of OpenSSL with malicious code and distribute that library. Be sure to only download the library from a trusted source (i.e. https://www.openssl.org/source/) and check the hash of your download.

Static or Dynamic Linking

So we download the source. We need to compile it into a usable library. There are two options we have: a Static Library or a Dynamic Library. Like anything in Computer Science, the answer to “Which should I use?” is It Depends.

Dynamic Libraries (also known as Shared Libraries) are .so files (or .dylib files in macOS). All code relating to the library is this file and it is referenced by your program at run-time. Static Libraries are .a files. Any program using a static library takes a copy of the code from the static library and makes it part of the programs compiled binary — the library becomes part of the code and is one of the first things loaded when starting the application.

Dynamic Libraries have the benefit of reducing duplicate code — if two applications want to reference the same library, they can. And an update to a system dynamic library can allow applications to always use the latest version. Static Libraries, on the other hand, increase the overall size of the binary, however, this also means that code is connected at compile time and there is no additional run-time loading overhead. All the code is just there.

Both have advantages or tradeoffs. In the interest of this guide, I have a business requirement to stay on the same version of OpenSSL for licensing purposes, therefore I am using static linking for the library (as my code will then always use the same version of the code library).

Now to macOS (The Good Stuff) 🔐

File System Structure and git

Create a folder for the OpenSSL libraries and associated file to be located in. I created an OpenSSL folder at the top level of my project directory:

CryptoExample
OpenSSL/
└ .gitkeep
└ CryptoExample/
└ CryptoExample.xcodeproj

I add a .gitkeep file so git will keep this directory, but we will ignore all other files in that directory in our .gitignore:

# gitignore
OpenSSL/*
!OpenSSL/.gitkeep

Building for macOS

For most projects, we can build for the i386 and x86 architectures and then combine those builds into a single library. The below script will download a version of OpenSSL (1.1.0g in this case) from their website and run a SHA256 checksum to confirm the download has not been tampered with:

(Note: run the script from your project directory)

OpenSSL build script for macOS architectures

After running the script the OpenSSL folder will contain the libcrypto.a and the libssl.a libraries as well as the LICENSE file and include directory (which includes all the header files for OpenSSL).

Configuring your Xcode Project

Let’s do this.

This is most likely the reason why you are here. You have your libraries, include headers, but how do you link everything together so you can utilize OpenSSL in your project?!

After running the above shell script your file hierarchy should look something like this:

File Hierarchy

Target Build Settings

  1. Under your target’s Build Settings edit LIBRARY_SEARCH_PATHS to include: $(PROJECT_DIR)/OpenSSL/lib.
  2. Set HEADER_SEARCH_PATHS to include: $(SRCROOT)/OpenSSL/include.

ModuleMap

Now we create a Swift ModuleMap in order to let the compiler know what C files we want to be associated with a custom module. Here we will call the module OpenSSL for simplicity, however, it can be called anything.

1. Create a shim.h file. This is an import header file which imports all OpenSSL files we need to expose.

2. Create a custom module.modulemap :

3. Head back to your target’s Build Settings and edit IMPORT_PATHS to include: $(SRCROOT)/$(TARGET_NAME). This will tell the compiler to look in our project folder for custom module maps.

4. Finally, you can import OpenSSL (we called the module ‘OpenSSL’) into any Swift file requiring it’s usage.

Your final project hierarchy may look like the following:

build_openssl.sh
CryptoExample
└ AppDelegate.swift
└ Assets.xcassets
└ Base.lproj
└ Info.plist
Modules
module.modulemap
shim.h
└ ViewController.swift
CryptoExample.xcodeproj
OpenSSL

Using Swift (and the problems that arise)

Now we can successfully import our OpenSSL module (note that we could have named it anything). Now we run into some issues with Swift which we do not face when using Objective-C.

OpenSSL is written in C and makes use of macros. Swift, by nature, can not access C macros directly. This makes dealing with some C libraries, like OpenSSL a bit tricky. One declaration in the library is X509 which is essentially just a pointer. We can use an OpaquePointer without issue, and I create a typealias for readability.

Take a look at the example below of how direct OpenSSL to Swift language interaction works.

Example.

Alternatives

Swift can make dealing with OpenSSL a bit harder than usual. If you find this to be too daunting, you have the option of wrapping all this logic in Objective-C, or exposing C declarations via Objective-C functions which can be called from Swift.

Let’s say you have the C macro to convert a hex value (e.g. 0xff0000) to an NSColor:

#define UIColorFromRGB(rgbHex, alphaValue) \
[NSColor colorWithRed:((float)((rgbHex >> 16) & 0xFF))/255.0 \
green:((float)((rgbHex >> 8) & 0xFF))/255.0 \
blue:((float)((rgbHex >> 0) & 0xFF))/255.0 \
alpha:alphaValue]

In Objective-C the macro can be wrapped in a function and then imported to Swift:

+ (NSColor *)colorFromMacro:(int)rgb alpha:(float)alpha {
return NSColorFromRGB(rgb, alpha);
}

Licensing

First off, I’m no lawyer. I’m a programmer with an internet connection and the requirement to cover our butts. That being said, it is good to know how and where you can use OpenSSL.

OpenSSL is fairly permissive, allowing you to include the frameworks in your application without much issue. The LICENSE outlines exact usages, but some highlights are:

  1. Your code must include the copyright notice for the code (located in the LICENSE file).
  2. You can not use “OpenSSL” in your product name.
  3. Perhaps the most important: Any redistributions of the framework or advertising materials mentioning the use of OpenSSL must include the following acknowledgment:

“This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)"

Essentially, if you use OpenSSL in your project, you should include this statement in a “Legal” section of your application.

For full details, be sure to consult your LICENSE file included in your OpenSSL folder.

Jonathan Cardasis

Written by

Mac and iOS Developer. iOS Dev @GeneralMotors | AR Craftsman | Swift Enthusiast | jonathancardasis.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade