Saturday, January 3, 2015

Developing with the latest OpenSSL on Mac OSX Yosemite and XCode 6.1.1

Developing OpenSSL on Mac OSX Yosemite, XCode 6.1.1

Had to write some encryption/decryption code for Mac OSX, and as I intend to use this on multiple platforms, I prefer to use openssl rather than Apple's code for all key generation and enc/dec functions.
Trying to use some sample code using openssl I discovered that Apple stopped supporting and updating OpenSSL a few years ago. If you try to compile code including headers, you will get a warning saying it was deprecated as of OSX Lion.
So I searched for how to update openssl on OSX and found few useful links, so this is the summary of what I needed to do:

1. Check what openssl version is installed in your system:

$ openssl version

with the latest version as of this writing you should get this:

OpenSSL 1.0.1j 15 Oct 2014

If you have a fresh OSX Yosemite (mine is 10.10.1), you most likely will get this response:

OpenSSL 0.9.8za 5 Jun 2014

This version does not contain some of the vulnurability fixes introduced in later versions (including the well-known Heartbleed).
So a quick search on updating openssl will bring you this answer.
On my machine, I had to install brew from scratch (using the instructions at brew.sh) and then following these:

$ brew update
$ brew install openssl
$ brew link --force openssl

I then had to rename old openssl and create a symbolic link to the brew installed one using:

$ sudo mv /usr/bin/openssl /usr/bin/openssl_OLD
$ sudo ln -s /usr/local/Cellar/openssl/1.0.1j_1/bin/openssl /usr/bin/openssl

Note: the 1.0.1j_1 is for the time of writing, it probably will change as openssl new versions introduced.

Now, this updates openssl to the latest for command line use. We now need to make sure the include directories are updated as well, so to check the version you have on your machine, look into /usr/include/openssl/opensslv.h - most likely it will contain the 0.9.8za version (or whatever was there before), so we need to link that directory to the brew installed one:

$ sudo mv /usr/include/openssl /usr/include/openssl_OLD
$ sudo ln -s /usr/local/Cellar/openssl/1.0.1j_1/include/openssl /usr/include/openssl

Now, if you try to create an xcode console app with this code:

#include 
#include 

int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    printf("OpenSSL version is: %s\n", OPENSSL_VERSION_TEXT);
    return 0;
}


You will be disappointed to see that it still, stubbornly, keeps referring to the old openssl...
To find out what happens, hold the command key and click on the to open that header file, and you will see that xcode is actually looking for it under the osx sdk (on my machine it is: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/openssl)

so to fix that, I created a symbolic link inside the sdk folder to the brew installed version as well:

$ sudo mv /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/openssl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/openssl_OLD
$ sudo ln -s /usr/local/Cellar/openssl/1.0.1j_1/include/openssl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/openssl

Now, this should work which can be tested by building the above console app (you may need to first clean it to remove any cached headers).
Note: XCode may contain multiple SDKs (on my machine there is also MacOSX10.9.sdk) - so make sure you update all the ones you use.




And a message from our advertisers:


Toptal provides remote engineers and designers of high quality. I recommend them. Follow this link (full disclosure: this is my affiliate link):
https://www.toptal.com/#engage-honest-computer-engineers-today



5 comments:

  1. Great article. I simply copied the 'openssl' folder from /usr/includes and placed it in the Mac OS X 10.11 SDK includes directory. So, I basically just skipped to your last step, and it worked for me. I am aware that I will be using the older headers and lib, but at least I feel comfortable knowing that the app will work across all apps and their native openssl libs. So I don't have to ship my app with the openssl libs.Thanks!

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. How can I update for mac 10.11?
    Now we do not have the permission in /usr/bin/

    ReplyDelete
    Replies
    1. I am afraid I don't have the time to check this. I will update you if/when I do.

      Delete