Installing a JSSE Provider in Android OSP | wolfSSL Documentation

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.