Security Global Forum

Security Global Forum

Our mission is to provide clients with an online user community of industry peers and IBM experts, to exchange tips and tricks, best practices, and product knowledge. We hope the information you find here helps you maximize the value of your IBM Security solutions.

 View Only

Using custom certificates and hosts file with Android emulator

By Shane Weeden posted Tue May 31, 2016 12:00 AM

  

When writing mobile applications on Android that utilise the OAuth 2.0 capability of IBM Security Access Manager (or in fact any other interaction with WebSEAL from the Android emulator), I typically want to test my application against a virtual ISAM appliance running on my laptop. This allows quick iterative testing, and gives me a completely standalone test environment that doesn’t have to be online (e.g. when I’m flying from Australia to London…)

I always want to use https URL’s for my OAuth authorization and token endpoints, with correct security configuration in place to perform transport-level server certificate validation. Further, I want local hosts file resolution of my endpoints on the Android emulator so that I can use real host names in my application configuration. It took me a little research to figure out how to do these things, and for everyone’s benefit I thought I’d write down and share what I had to do.

Pre-requisite information

This article makes a few base assumptions.

  • You should be familiar with the use of Android Studio, creating and running emulators with Android Virtual Device Manager, and have the adb (Android Debug Bridge) command-line tool available and running.
  • You should be comfortable with ISAM WebSEAL configuration, including updating the configuration file for a WebSEAL reverse proxy instance.
  • You should have access to the openssl command-line tool. Linux and Mac installations typically have this by default.

In these examples I will be using a test appliance that is installed on my local laptop running on VMWare Fusion (the Mac equivalent of VMWare Workstation). The ISAM virtual appliance has two IP addresses – the management IP is 192.168.42.101 (known as hostname isam.myidp.ibm.com) and the WebSEAL ip is 192.168.42.102 (known as www.myidp.ibm.com).

Updating the hosts file on your android emulator

By default a new android virtual device will contain a hosts file (/etc/hosts) that looks like this:

127.0.0.1       localhost
::1             ip6-localhost

My ISAM OAuth test system is called www.myidp.ibm.com, and the WebSEAL instance that I want my Android emulator to communicate with runs in VMWare on my laptop at the address 192.168.42.102, therefore I want to install a hosts file with these three lines of text in it:

127.0.0.1       localhost
::1             ip6-localhost
192.168.42.102  www.myidp.ibm.com

To install this hosts file on my emulator, I created a local text file called “hosts” in my current directory, and then I run this simple shell script when my emulator is starting up:

#!/bin/bash
#
# While the emulator is starting up, run this script to upload a custom hosts file
#
adb remount
while [ $? -ne 0 ]
do
 sleep 1
 echo "Retrying adb remount"
 adb remount
done
adb push hosts /etc/hosts
if [ $? -ne 0 ]
then
 echo "Failed to push hosts file to android device"
else
 echo "Hosts file pushed successfully"
fi
############################################################################

For reasons unknown to me, this script only works once when the emulator starts – if I try to re-run it more than once, I get a read-only filesystem error. In any case, I only need to run it once when the emulator starts, so this is good enough.

To verify that your hosts file is correctly installed, run:

adb shell cat /etc/hosts

You should see the hosts file including the entry for www.myidp.ibm.com.

Creating and installing a custom WebSEAL certificate that works with Android

The previous section (updating the emulator hosts file) takes care of telling Android how to reach your server, however given that you probably don’t have a real paid-for SSL certificate matching your hostname, chances are if you try to use an API from your mobile application that creates a https connection to your server, you will get a stack trace similar to this:

05-31 12:42:51.501: W/System.err(4483): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

To overcome this error we will create a self-signed certificate with a matching hostname, defined with the v3_ca extension. This special extension is important otherwise the Android device will NOT permit the public cert to be installed as a trusted signer. The private key and cert will be installed on WebSEAL as the server certificate, and the public cert will be installed on the Android device as a trusted signer.

Creating the certificate using openssl

Use the following shell script to create a self-signed certificate that contains the v3_ca extension, and has a cn matching the hostname “www.myidp.ibm.com” (change as needed for your own host):

#!/bin/sh
#
# Uses openssl to generate a self-signed cert that can be used on WebSEAL, and 
# can be installed on Android for CA verification.
#
HOST=www.myidp.ibm.com
PRIVATEKEY=${HOST}_private.pem
PUBLICKEY=${HOST}_public.pem
P12FILE=$HOST.p12
P12PWD=passw0rd
P12LABEL=$HOST
# This creates the public and private keys in PEM format
openssl req -x509 -nodes -days 999 -newkey rsa:2048 \
    -keyout "$PRIVATEKEY" -out "$PUBLICKEY" -reqexts v3_req \
    -extensions v3_ca -subj /C=us/O=ibm/CN=$HOST
# This creates a password-protected pkcs12 file so that the private key 
# can be imported into the ISAM appliance
openssl pkcs12 -export -in "$PUBLICKEY" -inkey "$PRIVATEKEY" \
    -out "$P12FILE" -passout pass:"$P12PWD" -name "$P12LABEL"
############################################################################

On completion, you should have three output files, however these two in particular we will use later:

  • www.myidp.ibm.com.p12 – This is the password-protected pkcs12 file that we can import to the ISAM appliance for use as the WebSEAL listening certificate.
  • www.myidp.ibm.com_public.pem – This is the public certificate that we will install into the Android emulator as a trusted CA.

Configuring WebSEAL to use the self-signed certificate

This step should be quite familiar to ISAM administrators. You can use the administration console (also known as the local management interface or LMI) to open the pdsrv certificate keystore and import the www.myidp.ibm.com.p12 personal certificate. You should see it installed as shown:

Given that I’m all about automation these days, here’s a curl equivalent (assuming your LMI admin password is “admin”) to do this import:

curl -k -v -u "admin:admin" -H "Accept: application/json" \
    --form cert=@www.myidp.ibm.com.p12 \
    --form password=passw0rd \
    --form operation=import https://isam.myidp.ibm.com/isam/ssl_certificates/pdsrv/personal_cert

We will save the deployment of pending changes to the end, so at this stage let’s update the WebSEAL configuration file to ensure that WebSEAL uses our new certificate. Again this can be done with the administration UI, however here’s the command-line equivalent, assuming your WebSEAL instance is called “default”:

curl -k -v -u "admin:admin" -H "Accept: application/json" \
    -H "Content-type: application/json" -X PUT -d "{\"value\":\"www.myidp.ibm.com\"}" \
    https://isam.myidp.ibm.com/wga/reverseproxy/default/configuration/stanza/ssl/entry_name/webseal-cert-keyfile-label

Now is the time to deploy pending changes:

curl -k -v -u "admin:admin" -H "Accept: application/json" \
    -X PUT https://isam.myidp.ibm.com/isam/pending_changes

 And restart your WebSEAL instance (again assuming the instance is “default”):

curl -k -v -u "admin:admin" -H "Accept: application/json" \
    -X PUT -d "{\"operation\":\"restart\"}" https://isam.myidp.ibm.com/wga/reverseproxy/default

This completes the installation of the personal certificate on the ISAM appliance, and the configuration of WebSEAL to use it.

Installing the trusted signer on Android

This step requires your Android emulator to be running. You will also need to set a PIN to unlock the emulator screen before you are allowed to install a user-installed trusted CA cert. The emulator will guide you through this step if you don’t already have PIN-protection enabled. For the purposes of this article, I’ll assume that is already in place. If not, just follow the instructions to set a PIN when prompted.

First push the public certificate file to the sdcard of your android emulator:

adb push www.myidp.ibm.com_public.pem /sdcard/www.myidp.ibm.com_public.pem

Now on the emulator itself, open Settings -> Security. In the Credential Storage section, select Install from SD Card, as shown:

Scroll down and select the www.myidp.ibm.com_public.pem file:

You will be prompted to enter a certificate name:

Press ok and the certificate should now install. To verify that the installation was successful, go into the Trusted Credentials option:

Select the User tab, and verify that the public certificate is present:

You have now completed everything you need to ensure that https connections made from the android virtual device to a hostname defined in a local hosts file can be completed successfully.

Summary

I hope these couple of tips save you some time when working with Android studio, the emulator and https connections to WebSEAL, particularly for interaction with ISAM’s OAuth runtime.

0 comments
4 views

Permalink