From 3157d1f06e37906fd8821d2d869c40eac0d2b38c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sun, 1 Mar 2020 22:27:56 +0100 Subject: [PATCH] api: add function crypto_hash_pbkdf2 --- ChangeLog.adoc | 2 +- doc/en/weechat_plugin_api.en.adoc | 55 +++++++++++++++++++++++++++ doc/fr/weechat_plugin_api.fr.adoc | 55 +++++++++++++++++++++++++++ doc/it/weechat_plugin_api.it.adoc | 57 +++++++++++++++++++++++++++- doc/ja/weechat_plugin_api.ja.adoc | 55 +++++++++++++++++++++++++++ src/core/wee-crypto.c | 14 ++++--- src/core/wee-crypto.h | 2 +- src/plugins/plugin-api.c | 39 +++++++++++++++++++ src/plugins/plugin-api.h | 5 +++ src/plugins/plugin.c | 1 + src/plugins/weechat-plugin.h | 15 +++++++- tests/unit/core/test-core-crypto.cpp | 4 +- 12 files changed, 293 insertions(+), 11 deletions(-) diff --git a/ChangeLog.adoc b/ChangeLog.adoc index a4cc74d4a..de422cb01 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -22,7 +22,7 @@ New features:: * core: add variable "old_full_name" in buffer, set during buffer renaming (issue #1428) * core: add debug option "-d" in command /eval (issue #1434) - * api: add function crypto_hash + * api: add functions crypto_hash and crypto_hash_pbkdf2 * api: add info "weechat_headless" (issue #1433) * buflist: add pointer "window" in bar item evaluation * relay: reject client with weechat protocol if password or totp is received in init command but not set in WeeChat (issue #1435) diff --git a/doc/en/weechat_plugin_api.en.adoc b/doc/en/weechat_plugin_api.en.adoc index 677a756f6..ad284b573 100644 --- a/doc/en/weechat_plugin_api.en.adoc +++ b/doc/en/weechat_plugin_api.en.adoc @@ -3355,6 +3355,7 @@ Arguments: * _hash_size_: pointer to a variable used to store the size of the hash computed (in bytes) (can be NULL) +[[crypto_hash_algorithms]] Supported hash algorithms: [width="100%",cols="2,2,3,6",options="header"] @@ -3392,6 +3393,60 @@ rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size); [NOTE] This function is not available in scripting API. +==== crypto_hash_pbkdf2 + +_WeeChat ≥ 2.8._ + +Compute PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2) hash +of data. + +Prototype: + +[source,C] +---- +int weechat_crypto_hash_pbkdf2 (const void *data, int data_size, + const char *hash_algo, + const void *salt, int salt_size, + int iterations, + void *hash, int *hash_size); +---- + +Arguments: + +* _data_: the data to hash +* _data_size_: number of bytes to hash in _data_ +* _hash_algo_: hash algorithm used by the key derivation function, see table + in function <> +* _salt_: the salt +* _salt_size_: number of bytes in _salt_ +* _iterations_: number of iterations +* _hash_: pointer to the hash variable, which is used to store the resulting hash + (the buffer must be large enough, according to the algorithm, see table in + function <>) +* _hash_size_: pointer to a variable used to store the size of the hash computed + (in bytes) (can be NULL) + +Return value: + +* 1 if OK, 0 if error + +C example: + +[source,C] +---- +const char *data = "abcdefghijklmnopqrstuvwxyz"; +const char *salt = "12345678901234567890123456789012"; /* 32 bytes */ +char hash[256 / 8]; +int rc, hash_size; +rc = weechat_crypto_hash_pbkdf2 (data, strlen (data), "sha256", salt, strlen (salt), 100000, + hash, &hash_size); +/* rc == 1, hash_size == 32 and hash is a buffer with: + 99 b3 5e 42 53 d1 a7 a8 49 c1 dc 2c e2 53 c2 b6 6d a1 8b dc 6e 78 a7 06 e0 ef 34 db 0a 7a a2 bb */ +---- + +[NOTE] +This function is not available in scripting API. + [[directories]] === Directories diff --git a/doc/fr/weechat_plugin_api.fr.adoc b/doc/fr/weechat_plugin_api.fr.adoc index e0449509f..d7e8e7a3d 100644 --- a/doc/fr/weechat_plugin_api.fr.adoc +++ b/doc/fr/weechat_plugin_api.fr.adoc @@ -3415,6 +3415,7 @@ Paramètres : * _hash_size_ : pointeur vers une variable utiliser pour stocker la longueur du résultat du hachage (en octets) (peut être NULL) +[[crypto_hash_algorithms]] Algorithmes de hachage supportés : [width="100%",cols="2,2,3,6",options="header"] @@ -3452,6 +3453,60 @@ rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size); [NOTE] Cette fonction n'est pas disponible dans l'API script. +==== crypto_hash_pbkdf2 + +_WeeChat ≥ 2.8._ + +Calculer le hachage PBKDF2 (PKCS#5 Passphrase Based Key Derivation Function number 2) +des données. + +Prototype : + +[source,C] +---- +int weechat_crypto_hash_pbkdf2 (const void *data, int data_size, + const char *hash_algo, + const void *salt, int salt_size, + int iterations, + void *hash, int *hash_size); +---- + +Paramètres : + +* _data_ : les données à hacher +* _data_size_ : nombre d'octets à hacher dans _data_ +* _hash_algo_ : algorithme de hachage utilisé dans la fonction de dérivation + de clé, voir le tableau dans la fonction <> +* _salt_ : le sel +* _salt_size_ : nombre d'octets dans _salt_ +* _iterations_ : nombre d'itérations +* _hash_ : pointeur vers la variable de hachage, qui est utilisée pour stocker + le résultat du hachage (le tampon doit être suffisamment grand, selon + l'algorithme, voir le tableau dans la fonction <>) +* _hash_size_ : pointeur vers une variable utiliser pour stocker la longueur + du résultat du hachage (en octets) (peut être NULL) + +Valeur de retour : + +* 1 si OK, 0 si erreur + +Exemple en C : + +[source,C] +---- +const char *data = "abcdefghijklmnopqrstuvwxyz"; +const char *salt = "12345678901234567890123456789012"; /* 32 octets */ +char hash[256 / 8]; +int rc, hash_size; +rc = weechat_crypto_hash_pbkdf2 (data, strlen (data), "sha256", salt, strlen (salt), 100000, + hash, &hash_size); +/* rc == 1, hash_size == 32 et hash est un tampon avec : + 99 b3 5e 42 53 d1 a7 a8 49 c1 dc 2c e2 53 c2 b6 6d a1 8b dc 6e 78 a7 06 e0 ef 34 db 0a 7a a2 bb */ +---- + +[NOTE] +Cette fonction n'est pas disponible dans l'API script. + [[directories]] === Répertoires diff --git a/doc/it/weechat_plugin_api.it.adoc b/doc/it/weechat_plugin_api.it.adoc index 0705b9522..dbd38850b 100644 --- a/doc/it/weechat_plugin_api.it.adoc +++ b/doc/it/weechat_plugin_api.it.adoc @@ -3497,6 +3497,7 @@ Argomenti: * _hash_size_: pointer to a variable used to store the length of the hash computed (in bytes) (can be NULL) +[[crypto_hash_algorithms]] Supported hash algorithms: [width="100%",cols="2,2,3,6",options="header"] @@ -3517,7 +3518,6 @@ Supported hash algorithms: Valore restituito: -// TRANSLATION MISSING * 1 if OK, 0 if error Esempio in C: @@ -3535,6 +3535,61 @@ rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size); [NOTE] Questa funzione non è disponibile nelle API per lo scripting. +// TRANSLATION MISSING +==== crypto_hash_pbkdf2 + +_WeeChat ≥ 2.8._ + +Compute PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2) hash +of data. + +Prototipo: + +[source,C] +---- +int weechat_crypto_hash_pbkdf2 (const void *data, int data_size, + const char *hash_algo, + const void *salt, int salt_size, + int iterations, + void *hash, int *hash_size); +---- + +Argomenti: + +* _data_: the data to hash +* _data_size_: number of bytes to hash in _data_ +* _hash_algo_: hash algorithm used by the key derivation function, see table + in function <> +* _salt_: the salt +* _salt_size_: number of bytes in _salt_ +* _iterations_: number of iterations +* _hash_: pointer to the hash variable, which is used to store the resulting hash + (the buffer must be large enough, according to the algorithm, see table in + function <>) +* _hash_size_: pointer to a variable used to store the size of the hash computed + (in bytes) (can be NULL) + +Valore restituito: + +* 1 if OK, 0 if error + +Esempio in C: + +[source,C] +---- +const char *data = "abcdefghijklmnopqrstuvwxyz"; +const char *salt = "12345678901234567890123456789012"; /* 32 bytes */ +char hash[256 / 8]; +int rc, hash_size; +rc = weechat_crypto_hash_pbkdf2 (data, strlen (data), "sha256", salt, strlen (salt), 100000, + hash, &hash_size); +/* rc == 1, hash_size == 32 and hash is a buffer with: + 99 b3 5e 42 53 d1 a7 a8 49 c1 dc 2c e2 53 c2 b6 6d a1 8b dc 6e 78 a7 06 e0 ef 34 db 0a 7a a2 bb */ +---- + +[NOTE] +Questa funzione non è disponibile nelle API per lo scripting. + [[directories]] === Cartelle diff --git a/doc/ja/weechat_plugin_api.ja.adoc b/doc/ja/weechat_plugin_api.ja.adoc index 887b8ec47..a31f4b15c 100644 --- a/doc/ja/weechat_plugin_api.ja.adoc +++ b/doc/ja/weechat_plugin_api.ja.adoc @@ -3374,6 +3374,7 @@ int weechat_crypto_hash (const void *data, int data_size, const char *hash_algo, * _hash_size_: pointer to a variable used to store the length of the hash computed (in bytes) (can be NULL) +[[crypto_hash_algorithms]] Supported hash algorithms: [width="100%",cols="2,2,3,6",options="header"] @@ -3411,6 +3412,60 @@ rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size); [NOTE] スクリプト API ではこの関数を利用できません。 +==== crypto_hash_pbkdf2 + +_WeeChat バージョン 2.8 以上で利用可。_ + +Compute PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2) hash +of data. + +プロトタイプ: + +[source,C] +---- +int weechat_crypto_hash_pbkdf2 (const void *data, int data_size, + const char *hash_algo, + const void *salt, int salt_size, + int iterations, + void *hash, int *hash_size); +---- + +引数: + +* _data_: the data to hash +* _data_size_: number of bytes to hash in _data_ +* _hash_algo_: hash algorithm used by the key derivation function, see table + in function <> +* _salt_: the salt +* _salt_size_: number of bytes in _salt_ +* _iterations_: number of iterations +* _hash_: pointer to the hash variable, which is used to store the resulting hash + (the buffer must be large enough, according to the algorithm, see table in + function <>) +* _hash_size_: pointer to a variable used to store the size of the hash computed + (in bytes) (can be NULL) + +戻り値: + +* 成功した場合は 1、失敗した場合は 0 + +C 言語での使用例: + +[source,C] +---- +const char *data = "abcdefghijklmnopqrstuvwxyz"; +const char *salt = "12345678901234567890123456789012"; /* 32 bytes */ +char hash[256 / 8]; +int rc, hash_size; +rc = weechat_crypto_hash_pbkdf2 (data, strlen (data), "sha256", salt, strlen (salt), 100000, + hash, &hash_size); +/* rc == 1, hash_size == 32 and hash is a buffer with: + 99 b3 5e 42 53 d1 a7 a8 49 c1 dc 2c e2 53 c2 b6 6d a1 8b dc 6e 78 a7 06 e0 ef 34 db 0a 7a a2 bb */ +---- + +[NOTE] +スクリプト API ではこの関数を利用できません。 + [[directories]] === ディレクトリ diff --git a/src/core/wee-crypto.c b/src/core/wee-crypto.c index 248f73c1d..ea19c04d3 100644 --- a/src/core/wee-crypto.c +++ b/src/core/wee-crypto.c @@ -97,7 +97,9 @@ weecrypto_get_hash_algo (const char *hash_algo) * If hash_size is not NULL, the length of hash is stored in *hash_size * (in bytes). * - * Returns 1 if OK, 0 if error. + * Returns: + * 1: OK + * 0: error */ int @@ -167,11 +169,13 @@ hash_end: * If hash_size is not NULL, the length of hash is stored in *hash_size * (in bytes). * - * Returns 1 if OK, 0 if error. + * Returns: + * 1: OK + * 0: error */ int -weecrypto_hash_pbkdf2 (const void *data, int data_size, int hash_subalgo, +weecrypto_hash_pbkdf2 (const void *data, int data_size, int hash_algo, const void *salt, int salt_size, int iterations, void *hash, int *hash_size) { @@ -191,8 +195,8 @@ weecrypto_hash_pbkdf2 (const void *data, int data_size, int hash_subalgo, goto hash_pbkdf2_end; } - algo_size = gcry_md_get_algo_dlen (hash_subalgo); - if (gcry_kdf_derive (data, data_size, GCRY_KDF_PBKDF2, hash_subalgo, + algo_size = gcry_md_get_algo_dlen (hash_algo); + if (gcry_kdf_derive (data, data_size, GCRY_KDF_PBKDF2, hash_algo, salt, salt_size, iterations, algo_size, hash) != 0) { diff --git a/src/core/wee-crypto.h b/src/core/wee-crypto.h index 9902042af..ccea36fb8 100644 --- a/src/core/wee-crypto.h +++ b/src/core/wee-crypto.h @@ -27,7 +27,7 @@ extern int weecrypto_get_hash_algo (const char *hash_algo); extern int weecrypto_hash (const void *data, int data_size, int hash_algo, void *hash, int *hash_size); extern int weecrypto_hash_pbkdf2 (const void *data, int data_size, - int hash_subalgo, + int hash_algo, const void *salt, int salt_size, int iterations, void *hash, int *hash_size); diff --git a/src/plugins/plugin-api.c b/src/plugins/plugin-api.c index 180d3f814..0d862e251 100644 --- a/src/plugins/plugin-api.c +++ b/src/plugins/plugin-api.c @@ -138,6 +138,10 @@ plugin_api_string_base_decode (int base, const char *from, char *to) /* * Computes hash of data using the given algorithm. + * + * Returns: + * 1: OK + * 0: error */ int @@ -162,6 +166,41 @@ plugin_api_crypto_hash (const void *data, int data_size, const char *hash_algo, return weecrypto_hash (data, data_size, algo, hash, hash_size); } +/* + * Computes PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2) + * hash of data. + * + * Returns: + * 1: OK + * 0: error + */ + +int +plugin_api_crypto_hash_pbkdf2 (const void *data, int data_size, + const char *hash_algo, + const void *salt, int salt_size, + int iterations, + void *hash, int *hash_size) +{ + int algo; + + if (!hash) + return 0; + + if (hash_size) + *hash_size = 0; + + if (!data || (data_size < 1) || !hash_algo || !salt || (salt_size < 1)) + return 0; + + algo = weecrypto_get_hash_algo (hash_algo); + if (algo == GCRY_MD_NONE) + return 0; + + return weecrypto_hash_pbkdf2 (data, data_size, algo, salt, salt_size, + iterations, hash, hash_size); +} + /* * Frees an option. */ diff --git a/src/plugins/plugin-api.h b/src/plugins/plugin-api.h index 7526213a8..e2c78a010 100644 --- a/src/plugins/plugin-api.h +++ b/src/plugins/plugin-api.h @@ -37,6 +37,11 @@ extern int plugin_api_string_base_decode (int base, const char *from, extern int plugin_api_crypto_hash (const void *data, int data_size, const char *hash_algo, void *hash, int *hash_size); +extern int plugin_api_crypto_hash_pbkdf2 (const void *data, int data_size, + const char *hash_algo, + const void *salt, int salt_size, + int iterations, + void *hash, int *hash_size); /* config */ extern void plugin_api_config_file_option_free (struct t_config_option *option); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 597c69417..6497c2739 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -650,6 +650,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv) new_plugin->utf8_strndup = &utf8_strndup; new_plugin->crypto_hash = &plugin_api_crypto_hash; + new_plugin->crypto_hash_pbkdf2 = &plugin_api_crypto_hash_pbkdf2; new_plugin->mkdir_home = &util_mkdir_home; new_plugin->mkdir = &util_mkdir; diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index 1ba368204..ca9f783cf 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -67,7 +67,7 @@ struct timeval; * please change the date with current one; for a second change at same * date, increment the 01, otherwise please keep 01. */ -#define WEECHAT_PLUGIN_API_VERSION "20200301-02" +#define WEECHAT_PLUGIN_API_VERSION "20200301-03" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -375,6 +375,11 @@ struct t_weechat_plugin /* crypto */ int (*crypto_hash) (const void *data, int data_size, const char *hash_algo, void *hash, int *hash_size); + int (*crypto_hash_pbkdf2) (const void *data, int data_size, + const char *hash_algo, + const void *salt, int salt_size, + int iterations, + void *hash, int *hash_size); /* directories/files */ int (*mkdir_home) (const char *directory, int mode); @@ -1316,6 +1321,14 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); __hash, __hash_size) \ (weechat_plugin->crypto_hash)(__data, __data_size, __hash_algo, \ __hash, __hash_size) +#define weechat_crypto_hash_pbkdf2(__data, __data_size, __hash_algo, \ + __salt, __salt_size, __iterations, \ + __hash, __hash_size) \ + (weechat_plugin->crypto_hash_pbkdf2)(__data, __data_size, \ + __hash_algo, \ + __salt, __salt_size, \ + __iterations, \ + __hash, __hash_size) /* directories */ #define weechat_mkdir_home(__directory, __mode) \ diff --git a/tests/unit/core/test-core-crypto.cpp b/tests/unit/core/test-core-crypto.cpp index 92df917f9..9bab485e6 100644 --- a/tests/unit/core/test-core-crypto.cpp +++ b/tests/unit/core/test-core-crypto.cpp @@ -91,7 +91,7 @@ extern "C" #define WEE_CHECK_HASH_PBKDF2(__result_code, __result_hash, \ __data, __data_size, \ - __hash_subalgo, __salt, __salt_size, \ + __hash_algo, __salt, __salt_size, \ __iterations) \ if (__result_hash) \ { \ @@ -105,7 +105,7 @@ extern "C" hash_size = -1; \ LONGS_EQUAL(__result_code, \ weecrypto_hash_pbkdf2 (__data, __data_size, \ - __hash_subalgo, \ + __hash_algo, \ __salt, __salt_size, \ __iterations, \ hash, &hash_size)); \