Changing OpenSSL library in Android app for HttpClient

Solution 1:

I have compiled libcrypto.so and libssl.so for Android and put the files in a folder jniLibs...

This won't work.

Android utilizes OpenSSL 1.0.0 and provides it in /system. Zygote starts at boot and loads the down level version of OpenSSL (its like init - all Android processes are forked from it).

When your process is forked from Zygote, your 1.0.1 version is never loaded because 1.0.0 is already loaded from Zygote. You never know there's a problem because the down level version provides all the symbols you need (its binary compatible).

You need to write a wrapper shared object. The wrapper shared object must link against the static versions of OpenSSL 1.0.1 (libcrypto.a and libssl.a). Your wrapper must export unique symbols, like My_OpenSSL_add_all_algorithms and My_SSL_load_error_strings. Internally, your shared object can refer to the undecorated names, OpenSSL_add_all_algorithms and SSL_load_error_strings.

So your shared object would look like so (also see GCC's Visibility page):

#if __GNUC__ >= 4
    #define DLL_PUBLIC __attribute__ ((visibility ("default")))
    #define DLL_LOCAL  __attribute__ ((visibility ("hidden")))
#else
    #define DLL_PUBLIC
    #define DLL_LOCAL
#endif

DLL_PUBLIC void My_OpenSSL_add_all_algorithms() {

    return (void)OpenSSL_add_all_algorithms();
}

DLL_PUBLIC void My_SSL_load_error_strings() {

    return (void)SSL_load_error_strings();
}
...

Then, compile with the -fvisibility=hidden flag and link against libcrypto.a and libssl.a. Only the functions marked with DLL_PUBLIC will be exported and callable through JNI.

I don't think the #if __GNUC__ >= 4 is needed because the cross compiler tools provided by Android are GCC 4.0 above. In fact, I think its currently GCC 4.8.


Changing OpenSSL library in Android app for HttpClient

This question is tougher. Once you provide the updated OpenSSL in your shared wrapper, I don't know how you would get Android's HttpClient to use it.

The worse case answer: you might need to fork Android and provide an updated OpenSSL.

A potentially better solution: rip the HttpClient code, put it in your own package, and then be sure you shared object is used by port of the source code.