From d91b930a2aec5d7bf77fbf2655af9a0c9ed96a38 Mon Sep 17 00:00:00 2001 From: David Goulet <dgoulet@ev0ke.net> Date: Tue, 10 Apr 2018 12:43:40 -0400 Subject: [PATCH] Support trees_pwhash_algo database entry This value is fetched from the database and used to decide with libsodium pwhash algorithm must be used for the account. Untested for now but any future commit will fix issues if any. Fixes #12 Signed-off-by: David Goulet <dgoulet@ev0ke.net> --- src/trees-plugin.c | 13 +++++++++++-- src/trees-plugin.h | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/trees-plugin.c b/src/trees-plugin.c index 238d03f..7d0ec3a 100644 --- a/src/trees-plugin.c +++ b/src/trees-plugin.c @@ -135,7 +135,7 @@ static int trees_get_private_key(struct mail_user *user, struct trees_user *suser) { - int have_salt; + int have_salt; int pwhash_alg; unsigned long long opslimit, memlimit; unsigned char pw_salt[crypto_pwhash_SALTBYTES]; unsigned char sk_nonce[crypto_secretbox_NONCEBYTES]; @@ -186,12 +186,21 @@ trees_get_private_key(struct mail_user *user, goto end; } + /* Get the pwhash value from database and then map it. After this, the + * pwhash_alg should be used with libsodium API. */ + pwhash_alg = trees_get_integer_setting(user, "trees_pwhash_algo"); + pwhash_alg = trees_pluging_pwhash_map(pwhash_alg); + if (pwhash_alg == -1) { + i_error("[trees] Unknown pwhash algorithm value: %d.", pwhash_alg); + goto error; + } + /* Derive key from password to open the secretbox containing the private * key of the user. */ if (crypto_pwhash(sk, sizeof(sk), password, strlen(password), pw_salt, opslimit, (size_t) memlimit, - crypto_pwhash_ALG_DEFAULT) < 0) { + pwhash_alg) < 0) { user->error = p_strdup_printf(user->pool, "Unable to derive private key for user %s.", user->username); diff --git a/src/trees-plugin.h b/src/trees-plugin.h index 3074ad3..c6fd36e 100644 --- a/src/trees-plugin.h +++ b/src/trees-plugin.h @@ -23,6 +23,24 @@ #ifndef TREES_PLUGIN_H #define TREES_PLUGIN_H +/* Map pwhash libsodium hash values internally so we can match them to the + * database field pwhash_algo. We do this because we don't want to rely on + * libsodium ABI for which they happily remove things. */ +static inline int +trees_pluging_pwhash_map(int value) +{ + switch (value) { + case 0: + /* argon2i, libsodium <= 1.0.14. */ + return crypto_pwhash_ALG_ARGON2I13; + case 1: + /* argon2id, libsodium >= 1.0.15 */ + return crypto_pwhash_ALG_ARGON2ID13; + default: + return -1; + } +} + void trees_plugin_init(struct module *module); void trees_plugin_deinit(void); -- GitLab