Skip to main content

Self-Signed TLS Certificate for Email

Upon setting up an email app on my Android device, I noticed that the self-signed TLS certificate for secure connections needs to include certain configuration options. Otherwise, Android would not accept it as a valid candidate. Here is the short write-up of the process.

Scenario

You have a mail transfer agent (MTA) like postfix for the SMTP protocol to recieve and to send messages. Additionally, you have a mail delivery agent (MDA) like dovecot to maintain the IMAP or POP3 protocol for retrieving of messages from your mail server.

You want to secure the conections to both via TLS and you want to use self-signed certificates as you do not need any trust from browsers, for example. However, you want to use such a certificate on both, your Linux machine as well as on your Android device.

Certificate Management

Firstly, you need to generate a new TLS certificate on your server. After that you can distribute it to your devices for the usage as trusted certificate.

Server

As the first step, you might want to back up previously existing keys and certificates. For dovecot, the configuration options ssl_cert and ssl_key point to the according location. On ArchLinux they exist in 10-ssl.conf. The postfix configuration holds similar paths in main.cf as smtpd_tls_cert_file and smtpd_tls_key_file.

Then, generate a new key and certificate using openssl via the following invocation.

openssl req -x509                                  \
            -newkey rsa:4096                       \
            -sha256                                \
            -days 365                              \
            -nodes                                 \
            -keyout mail.key                       \
            -out mail.crt                          \
            -subj /CN=example.com                  \
            -addext subjectAltName=DNS:example.com \
            -addext basicConstraints=CA:TRUE

We want to use an RSA key of 4096 bits, using SHA256 for hashing. The key is valid for one year and we do not protect the key through a DES passphrase. We order openssl to write the key to mail.key and to write the certificate to mail.crt. In this example, example.com represents our domain. Note that subjectAltName can contain a list of alternatives.

With basicConstraints=CA:TRUE we enable the usage of our key to derive keys further down the key chain. Although we do not intend that, current Android versions require this setting in order to trust according connections.

You can now overwrite the existing key and certificate with the newly generated ones. The restart of dovecot and postfix makes sure that the new TLS certificate is picked up.

Clients

The client configuration varies from client to client. Basically, you want to distribute the certificate to each device in the form expected by each client.

Linux

If you are using getmail on Linux to retrieve email, the accordig setting in your profile configuration is ca_certs. It should point to the generated certificate, retrieved from the server. A similar setting exists with certificate_file for mutt, although mutt also asks whether you trust the new certificate if it cannot find it in the according file.

Android

Firstly, copy the certificate to your Android device. Then, navigate to the encryption settings to add it as a trusted user certificate:

Settings
  -> Security & Location
    -> Advanced
      -> Encryption & Credentials
        -> Install from SD card

After it is included, your email app will be able to use it for secure TLS connections. Note that it is only considered as trusted if basicConstraints=CA:TRUE is set.

Conclusion

The generation of a new certificate is straightforward, but one needs to provide some rather subtile configuration settings in order to use self-signed TLS certificates on Android.

Once done, you are able to securely connect to your email server from both, your Linux machine and Android devices.