Android OSP (AOSP) uses several security providers by default for SSL/TLS and cryptographic functionality, through the use of the Java JSSE architecture. In certain cases, AOSP developers or users may want to install alternative security providers into AOSP-based systems. Reasons for installing an alternate provider vary depending on project but may include:
- Desire to use a specific cryptography or SSL/TLS implementation
- Requirement for FIPS 140-2 validated cryptography
- Requirement for CAVP validation cryptography
- Desire to use features lacking in existing providers
- Standardize on one security provider across platforms
This document explains how to install wolfSSL’s JSSE provider (wolfJSSE) into the Android OSP to provide default SSL/TLS functionality for the system and applications. It should act as a supplement to the wolfSSL JSSE Provider User Manual.
Requirements
-
- Android OSP (AOSP) with development environment set up
- Ability to re-compile the OS, along with a working existing build of AOSP
- wolfSSL Library
- wolfSSL JNI Library (includes wolfJSSE provider, aka “wolfJSSE”)
Download AOSP Source Code
Follow Android documentation for downloading and configuring the AOSP source tree:
https://source.android.com/setup/build/downloading
Steps at the above link will walk through setting up the correct development environment, git configuration, and compiling the AOSP code.
Set up and Build Android AOSP
Follow instructions on the Android AOSP developer website to set up the development environment and build the Android AOSP for the first time.
When testing, wolfSSL used the Android emulator that ships and builds with AOSP for demonstration, walkthrough, and testing purposes.
The official Android instructions should be followed for this section, but for reference, these are steps that wolfSSL used to set up and build the Android AOSP on Ubuntu 14.04.6 64-bit:
1. Create local “bin” directory:
$ mkdir ~/bin $ PATH=~/bin:$PATH
2. Download “repo”
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo $ chmod a+x ~/bin/repo
3. Make working directory
$ mkdir WORKING_DIRECTORY $ cd WORKING_DIRECTORY
4. Configure git
$ git config --global user.name "Your Name" $ git config --global user.email "you@example.com"
5. Init “repo”, selecting branch if desired. Here “android-6.0.1_r22” was selected
$ repo init -u https://android.googlesource.com/platform/manifest -b android-6.0.1_r22
6. Sync repo
$ repo sync
7. Clean up directory
$ make clobber
8. Set up build
$ source build/envsetup.sh $ lunch aosp_arm-eng
9. Build AOSP image
$ m
10. Launch emulator
$ emulator
In a separate terminal window, view logcat output
$ adb logcat
Download wolfSSL and wolfSSL JNI Source Code
Download wolfSSL (>= 4.1.0) from the wolfSSL website download page:
https://www.wolfssl.com/download/
wolfSSL JNI does not currently have an officially-released stable version available with JSSE support. Please obtain a pre-release copy with JSSE support from your wolfSSL account representative or email support@wolfssl.com.
Copy wolfSSL and wolfSSL JNI to AOSP Source Tree
wolfSSL JNI ships with a script that copies wolfSSL and wolfSSL JNI files into the Android AOSP source tree in the correct location. To run that script, navigate to the “/scripts/android_aosp” directory:
$ cd /platform/android_aosp $ ./jsse_install.sh [wolfssl_dir] [wolfssljni_dir] [android_aosp]
Where:
[wolfssl_dir] == wolfSSL source directory [wolfssljni_dir] == wolfSSL JNI source directory [android_aosp] == Android AOSP working source tree
This will first copy wolfSSL files from into , then will copy wolfSSL JNI files from into .
After the script completes, double check that the following two directories exist and look like the listings below:
/external/wolfssl Android.mk certs/ CleanSpec.mk COPYING README src/ wolfcrypt/ wolfssl/ /external/wolfssljni Android.mk build.xml COPYING examples/ IDE/ java.sh LICENSING native/ README src/
Note that the Android.mk and CleanSpec.mk files copied into the above directories are copied from the “/scripts/android_aosp/wolfssl” and “/scripts/android_aosp/wolfssljni” directories.
Modify Android.mk Files for Custom wolfSSL Compilation Defines
The following Android.mk files for wolfSSL and wolfSSL JNI in AOSP define a list of preprocessor defines that will be used when compiling these libraries:
/external/wolfssl/Android.mk /external/wolfssljni/Android.mk
Please update the LOCAL_CFLAGS variable in these Android.mk files to match the desired wolfSSL compilation configuration. Both Android.mk LOCAL_CFLAGS need to match exactly for proper runtime behavior.
Add wolfSSL JNI to Android Framework Base
In the following file, add “wolfssljni” to the LOCAL_JAVA_LIBRARIES variable, after “bouncycastle”:
/frameworks/base/Android.mk
The updated LOCAL_JAVA_LIBRARIES should look like this:
LOCAL_JAVA_LIBRARIES := core-libart conscrypt okhttp core-junit bouncycastle wolfssljni ext
Whitelist wolfSSL JNI JAR Classes
At the bottom of the following file, add a section for wolfSSL JNI:
/build/core/tasks/check_boot_jars/package_whitelist.txt
The new section should look like this:
################################################### # wolfssljni.jar com\.wolfssl com\.wolfssl\.provider\.jsse com\.wolfssl\.wolfcrypt
Add wolfSSL JNI to Product Image
There are several different product image makefiles in the Android build system. The “wolfssljni” package needs to be added to the PRODUCT_BOOT_JARS and PRODUCT_PACKAGES variables of the one being used by the given AOSP build.
When testing with the Android emulator, and the “aosp_arm-eng” target (lunch aosp_arm-eng), these were added to the following file:
/build/target/product/core_minimal.mk
Add “wolfssljni” to the bottom of the PRODUCT_PACKAGES variable, ie:
PRODUCT_PACKAGES += \ BackupRestoreConfirmation \ DownloadProvider \ …. wifi-service \ wolfssljni
And, add “wolfssljni” to PRODUCT_BOOT_JARS, after “bouncycastle” and before “ext”, ie:
# The order of PRODUCT_BOOT_JARS matters. PRODUCT_BOOT_JARS := \ core-libart \ conscrypt \ okhttp \ core-junit \ bouncycastle \ wolfssljni \ ext \ framework \ telephony-common \ voip-common \ ims-common \ apache-xml \ org.apache.http.legacy.boot
Register wolfJSSE Provider with Android libcore
Android Java Security providers are registered at the OS level using the following file:
/libcore/luni/src/main/java/java/security/security.properties
Place wolfJSSE as the first security provider, ie:
# # Providers # See also: J2SE doc. "How to Implement a Provider for the JavaTM Cryptography Architecture" # # wolfJSSE SSL/TLS provider security.provider.1=com.wolfssl.provider.jsse.WolfSSLProvider # Android's provider of OpenSSL backed implementations security.provider.2=com.android.org.conscrypt.OpenSSLProvider # Android's stripped down BouncyCastle provider security.provider.3=com.android.org.bouncycastle.jce.provider.BouncyCastleProvider # Remaining Harmony providers security.provider.4=org.apache.harmony.security.provider.crypto.CryptoProvider security.provider.5=com.android.org.conscrypt.JSSEProvider
To register wolfJSSE as the default SSLSocketFactory and SSLServerSocketFactory provider implementations, also change the following two variables:
ssl.SocketFactory.provider=com.wolfssl.provider.jsse.WolfSSLSocketFactory ssl.ServerSocketFactory.provider=com.wolfssl.provider.jsse.WolfSSLServerSocketFactory
Compile wolfSSL Library
Verify that the wolfSSL library can be compiled successfully by AOSP:
$ cd /external/wolfssl $ mm
This command should compile libwolfssl.so, and should complete successfully.
Compile wolfSSL JNI Library
Verify that the wolfSSL JNI library can be compiled successfully by AOSP:
$ cd /external/wolfssljni $ mm
This command should compile libwolfssljni.so and wolfssljni.jar, and should complete successfully.
Re-Compile AOSP Source Tree
After all changes have been made for integration of wolfJSSE into Android OSP, clean and re-compile the image:
$ make installclean $ m
At this stage, provider installation should be complete. Applications utilizing SSL/TLS functionality through the JSSE classes should now default to using wolfJSSE.
Verifying wolfJSSE Has Been Installed as a Security Provider
Applications can verify that wolfJSSE has been installed as a security provider by inspecting the Security.getProviders() result. For example:
import java.security.Provider; import java.security.Security; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; // Get all providers System.out.println(“All Installed Java Providers:”); Provider[] providers = Security.getProviders(); // Print all registered providers for (Provider prov:providers) { System.out.println(prov.getName()); } // Test if wolfJSSE is a Provider System.out.println(“\nInfo about wolfSSL Provider:”); Provider p = Security.getProvider(“wolfJSSE”); if (p != null) { System.out.println(p.toString); System.out.println(p.getInfo()); System.out.println(p.getVersion()); } // Test if wolfJSSE is providing TLS through SSLContext class try { System.out.println(“\nWhat provider is providing TLS?”); SSLContext ctx = SSLContext.getInstance(“TLS”); Provider prov = ctx.getProvider(); System.out.println(“TLS Provider = “ + prov); } catch (NoSuchAlgorithmException e) { // handle exception }
With the above, output similar to the following should be seen:
All Installed Java Providers: wolfJSSE AndroidKeyStoreBCWorkaround AndroidOpenSSL BC Crypto HarmonyJSSE AndroidKeyStore Info about wolfSSL Provider: wolfJSSE version 1.0 wolfSSL JSSE Provider 1.0 What provider is providing TLS? TLS Provider = wolfJSSE version 1.0
Support and Questions
Please contact wolfSSL at support@wolfssl.com for questions or issues related to installing wolfJSSE as a security provider in Android AOSP.