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.