1st Jan, 2009

Tutorial: How To Compile OpenSSL for the iPhone

This is a quick tutorial to show you how to minimally compile a version of the openssl and crypto libraries for the iPhone.

Download and Configure OpenSSL

First thing to do is grab the openssl source.  You can get that here.  I’ll be using openssl-0.9.8i for this demo.  Unzip this file (mines on the desktop).  Open up a terminal and go to the unzipped folder and run the default configuration.  The argument passed is where your ‘make install’ will place the compiled libraries. You should replace this with your path.

cd Desktop/openssl-0.9.8i
./config --openssldir=/Users/airpard/Desktop/openssl_arm/

Edit the Makefile

Next thing to do is open up the make file.  This is named “Makefile” in the current directory you should already be in with the terminal.  Here are the list of changes to make:

Find CC= cc and change it to:
CC= /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.0
 
Find -arch i386 in CFLAG and change it to:
-arch armv6
 
Find CFLAG and add to the BEGINNING!!:
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk
 
Find SHARED_LDFLAGS=-arch i386 -dynamiclib and change it to:
SHARED_LDFLAGS=-arch armv6 -dynamiclib

Fix Build Error

If you build it at this point you may have noticed a build error. To fix this open up ui_openssl.c. This is located in openssl-0.9.8i/crypto/ui/ folder. If you have a text editor with line numbers, head down to line 403. Otherwise do a text search to make this change:

static volatile sig_atomic_t intr_signal;
to
static volatile int intr_signal;

Save your changes and you should now be able to build with no errors.

Build Libraries

make
make install

That’s it. You’ll notice that everything was moved to the path provided in step 1 when configuring openssl. Remember to add the include folder to your Xcode project. Also, remember these libraries are only built for the iPhone and will not work in the simulator. You can change all the armv6 references to i386 and build it again if you choose to. Happy Coding!

Examples

Some people had some questions about how to use the libraries in an Xcode project. Here is a simple xcode project including just the linking of the libraries and adding of the header files: openssl_tutorial (v2.2) openssl_tutorial (v3.1)

For the lazy people.  Compiled libraries: compiled_libraries (v2.2)

Responses

Hi,

Thanks for the tutorial. One question – must I build this the same (but change to i386) to make a working lib for the iphone simulator?

How do you make the project contain both a working simulator lib and the actually iphone (arm) lib?

BTW, make seems to compile everything fine and then:

ld: unknown option: -openssldir=/Users/liamjfoy/Viewcurl/libcurl/openssl_arm/
collect2: ld returned 1 exit status
make[2]: *** [link_app.] Error 1
make[1]: *** [openssl] Error 2
make: *** [build_apps] Error 1

Hi Liam — I haven’t messed with openssl in the simulator for awhile, but since openssl is part of OS X you may get away with just building it for the phone (unless they have fixed this simulator bug).

If you are going to build both libraries and wish to run them in both the simulator and iPhone there are a few options. The one I like is to create three targets in Xcode. One being the iPhone application for armv6 architecture. The second target all the same except building for the i386 simulator. And a third target being ‘All’ that builds both targets. This is a of type ‘Aggregate’ under the other tab in the New Target wizard. If you only want to maintain one target you can simply link both libraries in the same target, no harm in doing this but remember to build it in the phone ;p

Liam — In regards to your error. The second line (the config line) uses a double dash. Don’t copy and paste that weird dash in there.

Thanks eric I’ve fixed everything now. I’ll let you know with regards to the first question I asked :) thanks for the tutorial!

Liam

Thanks for the peer coding ;p

Just so you know I’m trying to build libcurl with SSL support for the iPhone. I can build both of them on there own so tonight I’m going to try and make libcurl use the openssl lib your tutorial helped me to create :-) (I see you work for apple! hi apple! haha)

Sounds cool. Let me know how it works out. And Hello to you ;p

Hey eric – I’ve look around for some documentation with regards to using the i386 build of the lib and arm build of the lib in my project. Do you know of any good tutorials :) ?

i’m building ssh for the iphone. i’ve built ssl as per your instructions, and included the libs in the resources for my xcode project. we want to base building ssh off of openssl, rather than the ssl include files and such that come with mac os.

problem is that there are a number of multiple definitions between ssh’s sha2.h and ssl’s sha.h. when i use the mac version, it compiles ok, when i use openssl’s version, i get a lot of conflicts. i assume i want to be using ssh’s definitions, so i need to keep sha2.h intact.

have you seen this issue? i’m on openssl 0.9.8j and openssh 5.1p1.

thanks.

Mickey – You should have no problems if you add the include folder in the downloaded version of openssl to the header search path for the target. I’ve used ssh for multiple projects with no conflicts.

which directory? when i look in the directory include/openssl under the source directory, i see all the include files are links. when i look under the project i set up and compiled according to your instructions, i have a directory openssl_arm/openssl/include. the files sha.h in these 2 directories have 2 completely different sizes. i assume i should be using the original includes?

unfortunately, i get the same thing either directory i use. if i then copy the sha.h file from /usr/include/openssl, and substitute it, the problem goes away.

any thoughts? do i have a version incompatibility between openssh and openssl?

another issue you may be able to point me in the right direction. even before i downloaded openssl, openssh compiled just fine for mac os on the command line. ssh runs, no problem.

when in xcode for the iphone, i’m getting undefined symbols, like BN_new().

BN_new() is not defined anywhere in openssh, and sure enough, a nm(1) reveals:

U _BN_new()

for ssh. there are no other libs compiled with ssh except for what is built there.

BN_new() IS defined in openssl, and i have included the library i built following your instructions as a resource in my xcode project, and it shows up as a toolbox.

do you have any idea as to why these are coming up undefined?

thanks again…

Mickey- After you’re done compiling in the output folder there should be a lib and include folder. These are the folders to add to your project. Within the project, select your iPhone target and hit command-i. Find the user header paths. Select the box to always use user header paths. Then add ‘include/openssl’ to the user header paths. Link to the new libraries and that should be all you have to do.

Wow, what a great find — thanks a lot for the tutorial!

I’m also trying to get OpenSSH working with your OpenSSL output. I’m compiling OpenSSH from the command line. I tried to replicate the tricks you used in your OpenSSL method above, but I couldn’t find any mention of i386 (so I wasn’t sure if the armv6 options were required or not). I got the following errors:

1) I got an error where it tried to look for some resolv8_compat.h and nameser8_compat.h files. I fixed that by copying these files from /usr/include

2) It couldn’t find the appropriate libs. I tried copying the output libs from your project to the iPhone SDK lib folder, and then adding an appropriate -L LDFLAG for the iPhone SDK lib folder, but I think the architecture flag isn’t set correctly, since I get a bunch of errors:

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.0 -o ssh ssh.o readconf.o clientloop.o sshtty.o sshconnect.o sshconnect1.o sshconnect2.o mux.o -L. -Lopenbsd-compat/ -L/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk/usr/lib -fstack-protector-all -arch armv6 -lssh -lopenbsd-compat -lcrypto -lz
ld warning: in openbsd-compat//libopenbsd-compat.a, file is not of required architecture
ld warning: in /usr/lib/libcrypto.dylib, missing required architecture arm in file
Undefined symbols:
“_BN_copy”, referenced from:
_key_from_private in libssh.a(key.o)
_key_from_private in libssh.a(key.o)

[......around 50-100 lines.....]

“_RSA_new”, referenced from:
_key_new in libssh.a(key.o)
_key_demote in libssh.a(key.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [ssh] Error 1

I tried a bunch of things but couldn’t figure out what the problem is.

I’m using the latest official stable OpenSSH source code (specifically http://mirror.planetunix.net/pub/OpenBSD/OpenSSH/portable/openssh-5.1p1.tar.gz).

If you’re up for putting up a new tutorial, openssh would be a really great one to do!

eric – thanks for the response. that is what i am doing. i did have to pull the sha.h from /usr/include /openssl to get it to compile, but it did. however, i’m getting duplicate symbols on linking. SHA256_Init(() is defined both in sha256.o in openssl, and in sha2.o of ssh. same function name, different function contents. i don’t see how these can coexist. that is why i was wondering if i have versions of the two that aren’t compatible.

by the way, do you mean adding ‘include/openssl’ or the full pathname?

Strat – To build for i386 just run the config as you normally would. So basically you will just do step one of the tutorial. Skip the Makefile edits and just make;make install.

thanks for the post eric. a slightly cleaner option might be to add an entry in Configure per the install instructions. I.e. duplicate the line in Configure that begins with “darwin-i386-cc”. Change occurrences of i386 on the line to armv6, change cc to the toolchain compiler, and add the -isysroot flag. Now doing

./Configure darwin-armv6-cc –prefix=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk/usr

gets you the proper makefile and will install in the toolchain directory.

Marc

Hey, thanks a million for the tutorial and the binaries! You saved me a *lot* of frustration. In return, here’s a tip on how to avoid setting up multiple projects for simulator vs. device:

lipo libcrypto_arm.a libcrypto_i386.a -create -output libcrypto.a

Do the same for libssl.a and bingo, you’ve got universal libraries that will work in either environment!

Hello Guys

I am iPhone developer, I want to build one iPhone application using SSH, As I have downloaded openSSL from above link, I am’t able to use OpenSSL in my project, So can you please provide me any sample of xCode with simple connection with Server or any sample command?

thanks
Jayanti

Thank you very much for the tutorial! I’m trying to recompile some opensource packages for iPhone and this HOWTO is exactly I was looking for! Now I have successfully compiled openssl-0.9.8k for iPhoneOS 3.0 and some other openssl related packages.

But I’m still having problems recompiling ipsec-tools package. It successfully links my precompiled openssl libraries but later make fails with the following error:

Undefined symbols:
“_yywrap”, referenced from:
_yylex in token.o
_input in token.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make[4]: *** [setkey] Error 1
make[3]: *** [all] Error 2
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

Is this bug somehow specific to iPhone platform or I just missed some important flags when configuring? Would someone help please as I have no more ideas where to look for the issue..

What would you charge to get a basic SSH implementation up and working, I want to drop it into my project and send a message of where to connect (with user/pwd/server/etc) and the command I want executed. The class should close the connection and return the output from the command executed.

You are awesome. Just ran through your steps (with a couple of tweaks for GCC 4.2 and SDK 3.1.2) and it worked 100%

Thank you

Just a quick note, if you are trying to build the simulator libraries by replacing the iPhoneOS paths with the simulator, you may encounter a linking error trying to link to crt1.10.6.o

You can run this to fix it:
cd /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/usr/lib
sudo ln -s crt1.10.5.o crt1.10.6.o

Adding headers to your project is not mentioned.

AFAIk there is no GUI tool for that,
you need to add the headers into your project, by editing .xcodeproj by hand.
GCC_PREFIX_HEADER = iPhoneClient_Prefix.pch;
HEADER_SEARCH_PATHS = (
/usr/include/libxml2, /Users/jkekoni/Desktop/openssl_arm/include, );
INFOPLIST_FILE = Info.plist;

Building on i386 emulator however requires
some special spell I do not know.

Just using openssl build on target will not do.
This seems to be happening when trying to link
on i386 on OSX 10.6:


  "_fopen$UNIX2003", referenced from:
      _BIO_new_file in libcrypto.a(bss_file.o)
      _file_ctrl in libcrypto.a(bss_file.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status

The lipo trick does not help in here,
since the problem is in the underlying library.

I do not know a spell to fix this.

Does anyone do?

Ok I have cooked up the spell:

1st compile for arm as described above.
go to install directory.

mv libssl.a libssl-arm.a
mv libcrypto.a libcrypto-arm.a

run configure again.

Find CC= cc and change it to:

CC= /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.0
 

Find CFLAG and add to the BEGINNING!!:

-isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneOS2.2.sdk

(No other changes needed, since target is allready i386.)

make clean
make
make install

go to target directory

mv libssl.a libssl-i386.a
mv libcrypto.a libcrypto-i386.a

lipo libssl-arm.a libssl-i386.a -create -output libssl.a
lipo libcrypto-arm.a libcrypto-i386.a  -create -output libcrypto.a

(NOTE: There may be typing errors above. Check that the paths actually exists.)

Thanks for helpful info.

I created a script to generate a combined library. I placed it at:

http://github.com/shigeyas/build-openssl-iphone

Thanks for the tutorial!

To get openssl-1.0.0 to build, I had to add the no-asm config option (0.9.8n didn’t need it).

Hello,
firstly thanks a lot for your Tutorial. But I have a big problem. I’m new to mac (development) and does not know how to include the library in my source files.
Since I’ve read that libssl is part of the OS, I’ve included the dylib from the System (Add -> Existing Frameworks… -> libssl.dylib)
But what I have to include? I’ve tried libssh.h, but this fails!

@Gabriel – openssl is not included in iOS. This is why I have supplied these steps to add it to your application via static libraries. I’d suggest try downloading the openssl_tutorial and take a look how to include static libraries to your application.

Hei Eric.
Thanks for responding me. iOS…for me is this at the moment something like a black box ;-) First I want to understand how to develop on my Mac ;-)

So,what I have to do if I want to use openssl on the mac plattform

thank you for helping me ;-)

Hi Eric,

Thank you for this tutorial. I’m having trouble building this using Xcode 3.2 SDK.

After making the necessary changes, and typing “make”, I get the following error:

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.0 -I. -I.. -I../include -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch armv6 -O3 -fomit-frame-pointer -DL_ENDIAN -c -o cryptlib.o cryptlib.c
In file included from ../include/openssl/bio.h:67,
from cryptlib.h:74,
from cryptlib.c:117:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/usr/include/stdarg.h:4:25: error: stdarg.h: No such file or directory
make[1]: *** [cryptlib.o] Error 1
make: *** [build_crypto] Error 1

Any idea how I can fix this?

I am using Mac OS X Snow Leopard 10.6.3 on an iMac 27″ with Intel Core i7, Xcode 3.2 SDK.

@Don – Sorry not sure. To be honest I haven’t looked at the openssl libraries since I compiled it for v2.2. My guess is it will take some more tweaks in order to work with v3.2 of iOS and the newest openssl library. Unless you need something in particular on latest versions, I can vouch that the compiled libraries attached to this tutorial do work on the iPad.

Leave a response

Your response:

Categories