SF-Mail is an unofficial, security-friendly e-mail client for Sailfish OS with built-in OpenPGP and S/MIME — its goal is to make encrypted e-mail genuinely easy: encrypt, decrypt and sign mail (PGP/MIME, inline PGP and S/MIME), including encrypted attachments. Accounts, folders and messages come from the system mail database (QMF), so the app sits next to the stock mail app and shares its accounts.
SF-Mail = Security Friendly mail. The "SF" is not short for Sailfish — it stands for the goal of making security (PGP and S/MIME) friendly and easy to use.
Tapping a "new mail" notification is delivered to whichever program owns the
D-Bus name com.jolla.email.ui — the QMF notification plugin has that target
compiled in, and the same name also carries mailto: links and "share via
e-mail". Out of the box that is the stock Jolla mail client, with no setting to
change it.
SF-Mail can take that name over, so taps, mailto: and sharing open
in SF-Mail — the app implements the full stock interface, so nothing is silently
dropped. A switch controls this: About → System → "Open mail
notifications in this app", on by default. Switching it off hands everything
back to the client that owned it before SF-Mail was installed — the D-Bus
activation entry points at a small dispatcher that reads this setting on every
activation.
This is a system-wide change, not a per-app preference. Installing the package:
- adds
/etc/sailjail/permissions/EmailUi.permission, which is what allows the sandboxed app to own the name (the sandbox itself stays fully in place); - rewrites
/usr/share/dbus-1/services/com.jolla.email.ui.serviceso a tap also starts SF-Mail when it isn't running. The original is kept next to it ascom.jolla.email.ui.service.sfmail-orig, and a package trigger re-applies the change after ajolla-emailupdate.
Undoing it — turn the switch off, or rpm -e harbour-sfmail, which restores
the original file; either way mail notifications go back to the previous client. The stock client itself is never
modified, removed or disabled; it just no longer receives the tap while SF-Mail is
installed. (If both are running, whichever claimed the name first keeps it.)
If you would rather not have this, simply leave the switch off.
Encryption protects the body, not the envelope. SF-Mail closes two leaks that follow from that — in ways your correspondents will notice.
Blind copies. A single encrypted message names every recipient key in the
clear: OpenPGP writes one key packet per recipient, S/MIME one RecipientInfo per
certificate. Anyone who receives such a message can read that list — so a blind copy
would only be blind in the headers. SF-Mail therefore sends one message per audience:
the open recipients get theirs, every blind copy gets its own, each encrypted only to
the keys that belong in it. No recipient learns of any other, not even how many there
were.
What you will notice:
- Sending to blind copies produces one message per blind recipient in Sent.
- A blind copy needs the recipient's key or certificate, like any other. Without it the message is not sent — SF-Mail never falls back to plain text silently.
- Inline PGP cannot do this (one armoured block, one message) and refuses a blind copy; use PGP/MIME.
Encrypted subject. A subject sent in the clear passes every server on the
way and often says more than the body. PGP/MIME mail therefore carries the real
subject inside the encryption (protected
headers,
as other clients do) and shows ... on the outside. The same mechanism carries the
recipients, so a blind copy still sees whom the message was addressed to.
This applies to PGP/MIME only. Inline PGP and S/MIME send the subject in the clear, because their formats have no agreed place to hide it that the receiving side would find.
The price is real and worth knowing before you use it:
- Clients that do not implement protected headers show
...as the subject, and their replies come back asRe: .... - Server-side search and threading only ever see the placeholder.
- In the message list SF-Mail also shows
...until the message is decrypted; the real subject appears when you open it.
Signed-only mail is unaffected — there is nothing to hide from someone who can read the body anyway.
- Accounts + per-account folder list (swipe left in a mailbox), combined inbox
- Read / delete messages, raw header view with sender checks (active SPF/DMARC via DNS, From↔Return-Path mismatch, optional DNS blacklists — only the sender's IP/domain are ever looked up, nothing of yours)
- HTML mail is drawn in the device theme: the colours a message brings are dropped, so text written for white paper stays readable on a dark screen, and remote images are never loaded (loading one would tell the sender you read it)
- Attachments (plain, PGP and S/MIME) with their size — open with… or save as… to a folder you pick; large attachments download on demand
- Blind copies stay blind — one message per audience, so no recipient can read the others off the encryption; encrypted subjects via protected headers (see above)
- OpenPGP — encrypt (+ optional sign), decrypt by tap (PGP/MIME with a
passphrase dialog, and inline PGP), signature status, PGP/MIME sending
(RFC 3156,
multipart/encrypted) with attachments - Easy key management — create your own RSA-4096 key right in the app (a
strong passphrase is enforced), import / export / details, back up the secret
key, extend the expiry, revoke (a protected revocation certificate is
created for you; revoking is a deliberate two-step with confirmation), and
publish to
keys.openpgp.org. Keyserver lookup never auto-imports — it shows the fingerprint, you decide. When generating a key an equivalentgpgcommand line is shown, so you can see what is being made. - S/MIME (aarch64 only, switch it on under About) — decrypt by tap, sign
and/or encrypt outgoing mail (CMS,
application/pkcs7-mime) with attachments. Signatures are verified against your certificate store, and the result is what you see: valid, valid-but-from-an-authority-you-have-not-trusted, invalid, or not checkable. Certificate management: create your own self-signed RSA-4096 certificate (with theemailProtection/keyEnciphermente-mail attributes), import your own.p12, back it up as a.p12, import a sender's certificate from a signed message — always through a dialog that shows subject, addresses, issuer and fingerprint first. Missing issuer certificates can be fetched on request (over HTTPS); nothing fetched becomes trusted by itself - Crypto type follows the conversation: replies match the received mail (S/MIME → S/MIME, PGP → PGP, plain → plain); for a new message you only choose when both PGP and S/MIME are actually possible for sender and recipients
- 1-tap key import with safety checks — warns about revoked/expired keys, a key already present, a different key already stored for the address, and whether the key matches the sender's address; a block carrying several keys names all of them, because importing takes all of them; never imports without your confirmation
- Recipient fields complete an address after two characters — from the addresses you remembered, from the keys and certificates you hold, and from the address book — next to an address-book picker per recipient and a per-recipient crypto hint (🔑 PGP / 📜 S/MIME / no key)
- Remembered addresses — press and hold the sender block of a message to keep an address, and edit or forget it on a page of its own. Before a second copy is made, the app names the places that already hold the address (address book, PGP key, S/MIME certificate); one already remembered is named as such instead of being offered again
- Send from an alias — the alias addresses configured for an account in the system settings can be picked as the sender, protected headers included
- Localized folder names; the interface follows the device language
- Key hygiene & privacy — the bundled GnuPG agent is hardened so unlocked keys are not kept in memory between operations; passphrases never reach a command line and private keys are never written to disk unprotected; the process is not dumpable, so other programs cannot read its memory; after importing a key file you can have it securely deleted from the device; backups are passphrase-protected and the app reminds you to move them off-device
- Decrypted mail is not kept — attachments you open or hand to another app are
written to a cache and to
~/Downloads/sfmail, and both are emptied when the app starts and when it quits. What stays on the device is the encrypted message - The debug log is off and only records anything while you switch it on under About. It then holds diagnostic output including your account address and attachment file names, is capped in size, and is meant for reporting a problem
- 32 languages, following the device language, falling back to English. Only the German and English texts have been read by a native speaker; the rest are offered as they are. Corrections are welcome — see below
Trust in SF-Mail is a decision made on the device, not one delegated to an authority. The app is built for encrypted mail across trust boundaries — with or without a CA on the other side — so it carries no PKI of its own: identities you create yourself and identities you import stand on the same footing, and each becomes trusted the moment you, having seen its fingerprint, say so. This holds for S/MIME exactly as for PGP: a certificate authority becomes an anchor for everything it signs only when you tick that box in the import dialog, and your own identity is an anchor because you made it. Revocation lists belong to the delegated-trust world and are consequently not consulted — a certificate withdrawn by its authority still verifies here.
The system gpg on the target devices is too old to read modern keyrings
(pubring.kbx + private-keys-v1.d), so the app bundles a maintained GnuPG
2.5 stack (2.5.21, with current libgcrypt/libksba/libassuan) under its own
prefix (/usr/share/harbour-sfmail/gpg/…). OpenPGP is driven through the
GpgME++/QGpgME C++ bindings (gpgme 1.18) in the app's plugin (SFMail.Gpg, QML
singleton Gpg); only S/MIME shells out to gpgsm/OpenSSL. The
app uses its own keyring at ~/.local/share/sfmail/harbour-sfmail/gnupg,
entirely separate from the system keystore. S/MIME uses gpgsm from the same
bundled stack (plus an OpenSSL helper for .p12 handling) with its own store
under ~/.local/share/sfmail/harbour-sfmail/smime.
Requires the Sailfish OS Platform SDK. Build the RPM per target:
# aarch64
mb2 -t SailfishOS-5.0.0.62-aarch64.default build
# armv7hl (SFOS 4.6)
mb2 -t SailfishOS-4.6.0.13-armv7hl.default buildRPMs are written to RPMS/. Install on the device with pkcon install-local <rpm>.
Which release runs where. The aarch64 package needs Sailfish OS 5.1 or newer: it bundles an OpenSSL build for the S/MIME plumbing, and that binary needs the system libraries of 5.1. The armv7hl package is built against 4.6 and carries no OpenSSL, so S/MIME is unavailable there by design; OpenPGP works fully. A device running 5.2 uses the same aarch64 package.
The interface ships in 32 languages under src/translations/. English and
German were written by hand; the others were prepared for this release and have
not yet been read by a native speaker.
If one of them is yours and something reads wrong, please say so — an issue with "this line should say that" is enough, and the security wording matters most: the lines stating whether a signature is valid, whether a certificate authority is trusted, and what deleting a key destroys are a verdict the user acts on, so they have to be as clear and as sharp as the English.
The bundled GnuPG binaries are checked in under stack/stage-modern-aarch64/ and
stack/stage-modern-armv7hl/ so the RPM builds out of the box. To rebuild the GnuPG
stack from the upstream tarballs in stack/src/, see stack/build-stack.sh.
GPL-3.0-or-later — see LICENSE.
The app bundles GnuPG and its libraries (GPL / LGPL) and an OpenSSL build
(Apache 2.0). Their licenses, versions and corresponding upstream source are
documented in THIRD-PARTY-NOTICES.md; the source
tarballs are included under stack/src/, with their SHA-256 digests recorded in
stack/build-stack.sh, which also carries the build-time patches applied to
them.