diff --git a/src/trees-plugin.c b/src/trees-plugin.c index 238d03ff20fe36d640acc80ff811fcd4483f0563..7d0ec3a269c728e500ae844e83feabc9ea0157b2 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 3074ad3c839b1087d685ee0d8c018acbeb421915..c6fd36e26191d3d4045510b767b5febdf5279433 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);