Skip to content
35 changes: 12 additions & 23 deletions data/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2698,7 +2698,14 @@ If enabled, you cannot share a key to groups or someone without a public key.`
plugin: 'mail-crypt',
values: setting_types.STRING,
text: `
Defines the elliptic curve to use for key generation.
Defines the elliptic curve to use for key generation. A key pair is generated
for the user, and a key pair is generated for each folder. The folder key is
encrypted using the user key.

This must be set if you wish to use [[link,mail_crypt_folder_keys,folder keys]]
rather than [[link,mail_crypt_global_keys,global keys]]. With global keys
(either RSA or EC keys), all keying material is taken from the global key
settings and no key generation is performed.

Any valid curve supported by the underlying cryptographic library is allowed.

Expand All @@ -2708,27 +2715,9 @@ Example:
crypt_user_key_curve = secp521r1
\`\`\`

This must be set if you wish to use folder keys rather than global keys.

With global keys (either RSA or EC keys), all keying material is taken
from the setting and no key generation is performed.

In folder-keys mode, a key pair is generated for the user, and a
folder-specific key pair is generated. The latter is encrypted by means of
the user's key pair.

For EdDSA, you need to use X448 or X25519, case sensitive.`
},

crypt_global_private_keys: {
plugin: 'mail-crypt',
values: setting_types.NAMED_LIST_FILTER,
seealso: [ 'crypt_private_key_file', 'crypt_private_key_password' ],
text: `
List of private keys to decrypt files. Add [[setting,crypt_private_key_file]]
and optionally [[setting,crypt_private_key_password]] inside each filter.`
},

crypt_global_public_key_file: {
plugin: 'mail-crypt',
values: setting_types.FILE,
Expand Down Expand Up @@ -2796,11 +2785,11 @@ regardless of this setting.`
plugin: 'mail-crypt',
values: setting_types.STRING,
seealso: [
'crypt_global_private_keys',
'crypt_global_private_key',
'crypt_user_key_encryption_key',
],
text: `
Name of the private key inside [[setting,crypt_global_private_keys]] or
Name of the private key inside [[setting,crypt_global_private_key]] or
[[setting,crypt_user_key_encryption_key]].`
},

Expand All @@ -2809,15 +2798,15 @@ Name of the private key inside [[setting,crypt_global_private_keys]] or
values: setting_types.FILE,
seealso: [
'[[link,mail_crypt_converting_ec_key_to_pkey]]',
'crypt_global_private_keys',
'crypt_global_private_key',
'crypt_user_key_encryption_key',
],
text: `
Private key in [[link,mail_crypt_converting_ec_key_to_pkey]]. The PEM key may
additionally be base64-encoded into a single line, which can make it easier to
store into userdb extra fields.

Used inside [[setting,crypt_global_private_keys]] and
Used inside [[setting,crypt_global_private_key]] and
[[setting,crypt_user_key_encryption_key]] lists.`
},

Expand Down
184 changes: 92 additions & 92 deletions docs/core/plugins/mail_crypt.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ dovecotlinks:
mail_crypt_global_keys:
hash: global-keys
text: "Mail Crypt Plugin: Global Keys"
mail_crypt_folder_keys:
hash: folder-keys
text: "Mail Crypt Plugin: Folder Keys"
mail_crypt_ec_key:
hash: elliptic-curve-ec-key
text: "Mail Crypt Plugin: Elliptic Curve (EC) Keys"
mail_crypt_supported_sym_algorithms:
hash: supported-symmetric-algorithms
text: "Mail Crypt Plugin: Supported symmetric algorithms"
Expand Down Expand Up @@ -86,10 +92,6 @@ encryption with care and backup encryption keys!
This page assumes you are using configuring mail encryption from scratch with
a recent version of Dovecot.

## Settings

<SettingsComponent plugin="mail-crypt" />

### Supported symmetric algorithms

While mail crypt plugin does not support setting encryption algorithm,
Expand Down Expand Up @@ -131,97 +133,11 @@ List of known algorithms that Dovecot supports as of writing.

<sup>3</sup> Requires recent enough OpenSSL.

### Dynamic Settings

Per-user settings may be returned by [[link,userdb_extra_fields]].
To provide [[setting,crypt_global_private_key]] or
[[setting,crypt_global_public_key_file]] as a single line userdb attribute you
can base64 encode the original PEM key contents. For example:

```sh
cat ecprivkey.pem | base64 -w0
```

All configured keys must be in
[[link,mail_crypt_converting_ec_key_to_pkey,PEM]] format.

## Modes Of Operation

Mail crypt plugin can operate using **either** global keys or folder keys.
Using both is not supported.

### Folder Keys Mode

In this mode, for the user a key pair is generated. Then for each folder a key
pair is generated. This folder is encrypted using the user's key pair. A user
can have more than one key pair but only one can be active.

* [[setting,crypt_user_key_curve]] must be set.
* [[setting,mail_attribute]] must be set, as is is used to store the keys.

#### Unencrypted User Keys

In this version of the folder keys mode, each user's private key is stored
unencrypted on the server.

Example config for folder keys with Maildir:

```[dovecot.conf]
mail_plugins {
mail_crypt = yes
}
mail_attribute {
dict file {
path = %{home}/Maildir/dovecot-attributes
}
}

crypt_user_key_curve = secp521r1
```

#### Encrypted User Keys

In this version of the folder keys mode, the users private key is stored
encrypted on the server.

Example config for mandatory encrypted folder keys with Maildir:

```[dovecot.conf]
mail_plugins {
mail_crypt = yes
}
mail_attribute {
dict file {
path = %{home}/Maildir/dovecot-attributes
}
}

crypt_user_key_curve = secp521r1
crypt_user_key_require_encrypted = yes
```

The password that is used to decrypt the users master/private key, must be
provided via password query:

```[dovecot.conf]
passdb sql {
query = SELECT email as user, password, '%{password | sha256}' AS userdb_crypt_user_key_password \
FROM virtual_users \
WHERE email='%{user}'
}
```

#### Choosing Encryption Password

DO NOT use passwords directly. It can contain `%` which is interpreted as
variable expansion and can cause errors. Also, it might be visible in
debug logging. Suggested approaches are base64 encoding, hex encoding
or hashing the password. With hashing, you get the extra benefit that
password won't be directly visible in logs.

Another issue that you must consider when using user's password is that
when the password changes, **you must re-encrypt the user private key**.

### Global keys

In this mode, all keying material is taken from the settings:
Expand Down Expand Up @@ -318,7 +234,7 @@ Note that ED25519 keys are not suitable for X25519.
#### RSA key

::: warning
Use of RSA keys is discouraged, please use [[setting,crypt_user_key_curve]]
Use of RSA keys is discouraged, please use [[link,mail_crypt_ec_key,EC keys]]
instead.
:::

Expand Down Expand Up @@ -359,6 +275,85 @@ crypt_global_private_key main {
}
```

### Folder Keys

In this mode, a key pair is generated for the user. Then for each folder a key
pair is generated. This folder is encrypted using the user key. A user
can have more than one key pair for reading, but only one can be active for
writing.

* [[setting,crypt_user_key_curve]] must be set.
* [[setting,mail_attribute]] must be set, as it is used to store the keys.

#### Unencrypted User Keys

In this version of the folder keys mode, each user's private key is stored
unencrypted on the server.

Example config for folder keys with Maildir:

```[dovecot.conf]
mail_plugins {
mail_crypt = yes
}
mail_attribute {
dict file {
path = %{home}/Maildir/dovecot-attributes
}
}

crypt_user_key_curve = secp521r1
```

#### Encrypted User Keys

In this version of the folder keys mode, the user's private key is stored
encrypted on the server.

Example config for mandatory encrypted folder keys with Maildir:

```[dovecot.conf]
mail_plugins {
mail_crypt = yes
}
mail_attribute {
dict file {
path = %{home}/Maildir/dovecot-attributes
}
}

crypt_user_key_curve = secp521r1
crypt_user_key_require_encrypted = yes
```

The password that is used to decrypt the user's private key must be
provided via the [[setting,crypt_user_key_password]] setting. See below.

#### Choosing Encryption Password

It is recommended to use a hash of the user's plaintext login password as the
encryption key password instead of the plaintext password directly. This way
the plaintext password is less likely to become visible accidentally, such as
in debug logs. Also using a strong hash makes the key more resistant against
brute force attacks.

Another issue that you must consider when using the login password is that
when the password changes, **you must re-encrypt the user private key**.

Instead of using the login password, another possibility could be to store the
encryption password in a separate database (e.g. SQL or LDAP).

Example config where the user's login password is used as the encryption key
password:

```[dovecot.conf]
passdb sql {
query = SELECT email as user, password, '%{password | hash("pbkdf2")}' AS userdb_crypt_user_key_password \
FROM virtual_users \
WHERE email='%{user}'
}
```

## Base64-encoded Keys

Mail-crypt plugin can read keys that are base64 encoded. This is intended
Expand Down Expand Up @@ -424,6 +419,11 @@ share the key to groups or someone with no public key.

You can use [`decrypt.py`][https://github.com/dovecot/tools/blob/main/dcrypt-decrypt.py] to decrypt encrypted files.

## Settings

<SettingsComponent plugin="mail-crypt" />


## `fs-crypt`

`fs-crypt` is a [[link,fs,lib-fs wrapper]] that can encrypt and decrypt files.
Expand All @@ -438,7 +438,7 @@ combined. Please make sure that compression is always applied before
encryption. See [[plugin,fs-compress]] for an example and more details about
compression.

## `fs-crypt` settings
### `fs-crypt` settings

See [[link,mail_crypt_settings]] for generic mail-crypt settings.

Expand Down