Importing CA certificates on Firefox for Android

I recently needed to import a custom certificate authority to Firefox on Android. Unlike several other applications on Android, Firefox uses it's own certificate store. After a bit of digging I found this support question which pointed me in the right direction. This post is going to go over importing CA certificates using either Apache or Python.

Setting up a CA

This post will assume you've already set up a certificate authority, and have a copy of the x509 certificate in PEM format. If you want some information on setting up a certificate authority using OpenSSL, Jamie Nguyen has written some excellent documentation on the topic. For the purpose of this post, I set up a new certificate with the following OpenSSL commands:

openssl genrsa -out ca.key.pem 1024
openssl req -key ca.key.pem -new -x509 -days 7300 \
  -sha256 -extensions v3_ca -out ca.cert.pem

The resulting x509 certificate should look something like the following:

-----BEGIN CERTIFICATE-----
MIICwDCCAimgAwIBAgIJAOTlnWuRt44KMA0GCSqGSIb3DQEBCwUAMHkxCzAJBgNV
BAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMRIwEAYDVQQKDAlBbGljZSBMdGQxKDAm
BgNVBAsMH0FsaWNlIEx0ZCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxGjAYBgNVBAMM
EUFsaWNlIEx0ZCBSb290IENBMB4XDTE4MDkyMTIxMjc0OVoXDTM4MDkxNjIxMjc0
OVoweTELMAkGA1UEBhMCR0IxEDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUFs
aWNlIEx0ZDEoMCYGA1UECwwfQWxpY2UgTHRkIENlcnRpZmljYXRlIEF1dGhvcml0
eTEaMBgGA1UEAwwRQWxpY2UgTHRkIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBALchJKVPPw+oI1OGBpZkb+uT0yP1fOk0Ze9oUwURFkgOS7evkVWw
Jauj+4GOkQ8Rr9YfLxAoPHBhOmjyQYSiYOksbTez7S5AO0h6syfYTJA9N59EAzXN
2vi9olTgOI88ia/vVcg8IZO2YyNdsvZMBMK8AEq9uElX+kCC5kDnUKJdAgMBAAGj
UDBOMB0GA1UdDgQWBBQuaKsUgGmeitcgvQSMdHDeP1cVoTAfBgNVHSMEGDAWgBQu
aKsUgGmeitcgvQSMdHDeP1cVoTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA
A4GBAHv7UERGItJflvA3uiBW7jtmdlgwE17NOI9zxhexFAKnOVVa8Jn5bfPaQSVh
+TisSJ+OlL+k8MzQmauvdaWghnXBo+z3NmeQLyk6YwKBm72+jFBf0z3Xccr3Ozs5
0syMhpMy5WKdKj/BEYKRJ5UXJ6MpWjVvf9EWQUFhmX+MlK0w
-----END CERTIFICATE-----

Importing the certificate with Apache

To import the certificate, it needs to be served from a web server with the application/x-x509-ca-cert MIME type. This can be done by adding configuration similar to the following:

AddType application/x-x509-ca-cert .pem

The AddType directive will tell Apache to serve any files ending in .pem with the application/x-x509-ca-cert MIME type. Once the configuration is in place, restart Apache to pick up the new configuration, and drop the certificate file into the DocumentRoot directory:

$ systemctl restart apache2.service
$ ls /var/www/html/ca.cert.pem
/var/www/html/ca.cert.pem

From here you should be able to load the certificate by opening http://{apache-hostname}/ca.cert.pem in Firefox. If everything goes well you should get a message similar to the following:

Firefox importing a new certficate authority

Importing certificates with Python

If you don't have Apache set up is also possible to use a script similar to the following to serve files with the correct MIME type:

#!/usr/bin/env python3

"""Serve PEM files using the application/x-x509-ca-cert MIME type"""

import http.server
import socketserver


def run_server(ip_address='0.0.0.0', port=8000):
    """Run a web server to serve CA certs"""

    handler = http.server.SimpleHTTPRequestHandler
    handler.extensions_map['.pem'] = 'application/x-x509-ca-cert'

    with socketserver.TCPServer((ip_address, port), handler) as httpd:
        print("serving at port", port)
        httpd.serve_forever()

if __name__ == '__main__':
    run_server()

Note: the script above will listen on port 8000 and serve content from the directory it's being run in.