This is a very common feature for email clients - Thunderbird and K-9 Mail support it. It should not be difficult to implement because it’s already built in the SSL library. On Android the built-in certificate store may be used.
Today I’ve configured mandatory client certificates with my Dovecot IMAP server and was going to do it with my Postfix SMTP server too. Unfortunately I have to disable this feature because Delta Chat doesn’t support it.
async-native-tls allows setting client certificate with identity method so it should be doable.
Could you provide links to the documentation you used to configure the server or examples of configuration? Maybe client TLS certificates are somehow useful for chatmail servers, but at least I want to be able to setup a testing server to check that client certificates actually work.
It’s not easy as it requires some weird manipulations with OpenSSL tool, and I’ve only done it for Dovecot, not Postfix. I’ll write a tutorial for both, but I need some time.
ca-crt-with-crl.pem – this file goes to server (Postfix and Dovecot).
pki/issued/client1.crt – client certificate file
pki/private/client1.key – client private key file
You may also create PKCS #12 (ext .p12) file that combines client certificate and private key. This is how they may be imported into Thunderbird. Also it looks like this is the easiest way to have them in async-native-tls (Identity in async_native_tls - Rust).
On Android 14 you go into settings, “Security and privacy”, then “More security and privacy”, then “Encryption and credentials”, then “Install a certificate”, then “VPN and app user certificate”. This apparently allows to install certificates that can then be used in apps such as Conversations XMPP client to “Login with certificate” from the main screen.
In K-9 Mail 6.804 during account configuration you first type in your login and password, then get “Configuration found” popup once autoconfig is fetched and after clicking “EDIT CONFIGURATION” can select Client certificate in advanced settings. Field displays None and nothing happens when I click it even though it has a down arrow, probably because I have no client certificates installed yet.
Looking into Android APIs. It has an android.security.KeyChain object. After importing it with import android.security.KeyChain it is possible to directly call static method KeyChain.choosePrivateKeyAlias that will launch an activity where user can select previously imported key and will call the provided callback with some string called “alias” or null. This alias can then be used to request the private key using KeyChain.getPrivateKey and request the chain with KeyChain.getCertificateChain.
PrivateKey implements java.security.Key interface with a getEncoded() method that will return the key encoded to PKCS #8 (should be checked by calling getFormat()). So it seems we get the private key in PKCS #8 from Android.
KeyChain.getCertificateChain returns an array of X509Certificate which has a method getEncoded() that returns DER. I don’t see an easy way to get a PEM file for the whole chain from this.