Importing PKCS #12 client certificates in Firefox on Android

Root access is required. Tested on Fennec 68.11.0esr from F-Droid.

First, get root shell on your device.

$ adb shell
$ su

Go to the firefox app directory (the name depends on the actual firefox build you use, it may be org.mozilla.firefox or org.mozilla.fennec or something else, in my case it's org.mozilla.fennec_fdroid) and find out the name of your profile directory:

# cd /data/data/org.mozilla.fennec_fdroid/files/mozilla
# ls
j9yaq6p7.default profiles.ini

My profile directory is j9yaq6p7.default. Let's list the contents:

# cd j9yaq6p7.default
# ls -l
total 4652
-rw------- 1 u0_a222 u0_a222    776 2020-08-29 14:05 SiteSecurityServiceState.txt
-rw------- 1 u0_a222 u0_a222   1748 2020-08-29 14:06 addonStartup.json.lz4
-rw------- 1 u0_a222 u0_a222     45 2020-08-29 13:56 addons.json
-rw------- 1 u0_a222 u0_a222 943114 2020-08-29 14:00 blocklist.xml
-rw-rw---- 1 u0_a222 u0_a222 434176 2020-08-29 14:12 browser.db
-rw------- 1 u0_a222 u0_a222  32768 2020-08-29 14:13 browser.db-shm
-rw------- 1 u0_a222 u0_a222 432632 2020-08-29 14:13 browser.db-wal
-rw------- 1 u0_a222 u0_a222 229376 2020-08-29 13:57 cert9.db
-rw------- 1 u0_a222 u0_a222    202 2020-08-29 14:06 compatibility.ini
-rw------- 1 u0_a222 u0_a222 131072 2020-08-29 13:53 cookies.sqlite
-rw------- 1 u0_a222 u0_a222  32768 2020-08-29 14:06 cookies.sqlite-shm
-rw------- 1 u0_a222 u0_a222      0 2020-08-29 14:06 cookies.sqlite-wal
drwx------ 2 u0_a222 u0_a222   4096 2020-08-29 13:53 datareporting
drwx------ 2 u0_a222 u0_a222   4096 2020-08-29 13:53 extensions
-rw------- 1 u0_a222 u0_a222   3889 2020-08-29 14:02 extensions.json
-rw------- 1 u0_a222 u0_a222 196608 2020-08-29 13:56 formhistory.sqlite
-rw------- 1 u0_a222 u0_a222 294912 2020-08-29 14:06 key4.db
lrwxrwxrwx 1 u0_a222 u0_a222     18 2020-08-29 14:06 lock -> 127.0.0.1:+11770
drwx------ 2 u0_a222 u0_a222   4096 2020-08-29 13:53 manifests
-rw------- 1 u0_a222 u0_a222  98304 2020-08-29 13:53 permissions.sqlite
-rw------- 1 u0_a222 u0_a222    493 2020-08-29 13:53 pkcs11.txt
-rw------- 1 u0_a222 u0_a222   4032 2020-08-29 14:06 prefs.js
-rw------- 1 u0_a222 u0_a222  63355 2020-08-29 13:58 revocations.txt
drwx------ 3 u0_a222 u0_a222   4096 2020-08-29 14:06 safebrowsing
-rw------- 1 u0_a222 u0_a222  11981 2020-08-29 14:06 search.json.mozlz4
-rw------- 1 u0_a222 u0_a222     90 2020-08-29 14:06 sessionCheckpoints.json
-rw------- 1 u0_a222 u0_a222   8127 2020-08-29 14:11 sessionstore.bak
-rw------- 1 u0_a222 u0_a222   8609 2020-08-29 14:13 sessionstore.js
-rw------- 1 u0_a222 u0_a222 524288 2020-08-29 13:59 signons.sqlite
-rw------- 1 u0_a222 u0_a222  32768 2020-08-29 14:06 signons.sqlite-shm
-rw------- 1 u0_a222 u0_a222 688664 2020-08-29 13:59 signons.sqlite-wal
drwx------ 2 u0_a222 u0_a222   4096 2020-08-29 14:07 startupCache
drwx------ 3 u0_a222 u0_a222   4096 2020-08-29 13:53 storage
-rw------- 1 u0_a222 u0_a222    512 2020-08-29 13:53 storage.sqlite
-rw------- 1 u0_a222 u0_a222     27 2020-08-29 13:53 times.json
-rw------- 1 u0_a222 u0_a222  32768 2020-08-29 13:53 webappsstore.sqlite
-rw------- 1 u0_a222 u0_a222  32768 2020-08-29 14:06 webappsstore.sqlite-shm
-rw------- 1 u0_a222 u0_a222 295160 2020-08-29 13:57 webappsstore.sqlite-wal

Now copy key4.db and cert9.db to /sdcard to be able to adb pull them:

# cp key4.db cert9.db /sdcard
# cd /sdcard

Users who can use adb root can skip this step and just pull it directly from the profile directory but it's not my case.

Now exit the adb shell and copy the databases to a separate directory on your computer:

$ mkdir tmp && cd tmp
$ adb pull /sdcard/key4.db .
$ adb pull /sdcard/cert9.db .

Use pk12util to import keys and certs from a PKCS #12 file:

$ pk12util -i /path/to/my-cert.p12 -d sql:/path/to/tmp/

Copy modified files back to the device:

$ adb push key4.db /sdcard
$ adb push cert9.db /sdcard

Get adb root shell again:

$ adb shell
$ su

Stop the firefox process on the device, then copy the databases to the firefox profile directory and remove them from /sdcard:

# cp /sdcard/key4.db /sdcard/cert9.db /data/data/org.mozilla.fennec_fdroid/files/mozilla/j9yaq6p7.default/
# rm /sdcard/key4.db /sdcard/cert9.db

Fix the permissions:

# cd /data/data/org.mozilla.fennec_fdroid/files/mozilla/j9yaq6p7.default
# chmod 600 key4.db cert9.db
# chown u0_a222:u0_a222 key4.db cert9.db

It's done. Exit the shell and launch firefox to test it.

If you have any comments, contact me by email.