core: move crypto functions to wee-crypto.c, rename API function string_hash to crypto_hash

v2.8-utf8proc
Sébastien Helleu 2020-03-01 18:02:39 +01:00
parent c4ef3d6c2e
commit 9a6a27ef58
32 changed files with 1094 additions and 1017 deletions

View File

@ -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 string_hash
* api: add function crypto_hash
* 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)

View File

@ -125,6 +125,7 @@ WeeChat "core" is located in following directories:
|    wee-completion.c | Default completions.
|    wee-config-file.c | Configuration file management.
|    wee-config.c | Configuration options for WeeChat core (file weechat.conf).
|    wee-crypto.c | Cryptographic functions.
|    wee-debug.c | Some debug functions.
|    wee-eval.c | Evaluation of expressions with references to internal vars.
|    wee-hashtable.c | Hashtables.
@ -391,6 +392,7 @@ WeeChat "core" is located in following directories:
|       core/ | Root of unit tests for core.
|          test-core-arraylist.cpp | Tests: arraylists.
|          test-core-calc.cpp | Tests: calculation of expressions.
|          test-core-crypto.cpp | Tests: cryptographic functions.
|          test-core-eval.cpp | Tests: evaluation of expressions.
|          test-core-hashtble.cpp | Tests: hashtables.
|          test-core-hdata.cpp | Tests: hdata.

View File

@ -2061,66 +2061,6 @@ char *dump = weechat_string_hex_dump (string, strlen (string), 8, " >> ", NULL);
[NOTE]
This function is not available in scripting API.
==== string_hash
_WeeChat ≥ 2.8._
Compute hash of data.
Prototype:
[source,C]
----
int string_hash (const void *data, int data_size, const char *hash_algo, void *hash, int *hash_size);
----
Arguments:
* _data_: the data to hash
* _data_size_: number of bytes to hash in _data_
* _hash_algo_: the hash algorithm, see table below
* _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 below)
* _hash_size_: pointer to a variable used to store the size of the hash computed
(in bytes) (can be NULL)
Supported hash algorithms:
[width="100%",cols="2,2,3,6",options="header"]
|===
| Value | Algorithm | Hash size | Notes
| `+crc32+` | CRC32 | 4 bytes (32 bits) | Not a hash algorithm in the cryptographic sense.
| `+md5+` | MD5 | 16 bytes (128 bits) | *Weak*, not recommended for cryptography usage.
| `+sha1+` | SHA-1 | 20 bytes (160 bits) | *Weak*, not recommended for cryptography usage.
| `+sha224+` | SHA-224 | 28 bytes (224 bits) |
| `+sha256+` | SHA-256 | 32 bytes (256 bits) |
| `+sha384+` | SHA-384 | 48 bytes (384 bits) |
| `+sha512+` | SHA-512 | 64 bytes (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 bytes (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 bytes (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 bytes (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 bytes (512 bits) |
|===
Return value:
* 1 if OK, 0 if error
C example:
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_string_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 and hash is a buffer with:
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
This function is not available in scripting API.
==== string_is_command_char
_WeeChat ≥ 0.3.2._
@ -3386,6 +3326,72 @@ free (string);
[NOTE]
This function is not available in scripting API.
[[crypto]]
=== Cryptography
Some cryptographic functions.
==== crypto_hash
_WeeChat ≥ 2.8._
Compute hash of data.
Prototype:
[source,C]
----
int weechat_crypto_hash (const void *data, int data_size, const char *hash_algo,
void *hash, int *hash_size);
----
Arguments:
* _data_: the data to hash
* _data_size_: number of bytes to hash in _data_
* _hash_algo_: the hash algorithm, see table below
* _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 below)
* _hash_size_: pointer to a variable used to store the size of the hash computed
(in bytes) (can be NULL)
Supported hash algorithms:
[width="100%",cols="2,2,3,6",options="header"]
|===
| Value | Algorithm | Hash size | Notes
| `+crc32+` | CRC32 | 4 bytes (32 bits) | Not a hash algorithm in the cryptographic sense.
| `+md5+` | MD5 | 16 bytes (128 bits) | *Weak*, not recommended for cryptography usage.
| `+sha1+` | SHA-1 | 20 bytes (160 bits) | *Weak*, not recommended for cryptography usage.
| `+sha224+` | SHA-224 | 28 bytes (224 bits) |
| `+sha256+` | SHA-256 | 32 bytes (256 bits) |
| `+sha384+` | SHA-384 | 48 bytes (384 bits) |
| `+sha512+` | SHA-512 | 64 bytes (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 bytes (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 bytes (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 bytes (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 bytes (512 bits) |
|===
Return value:
* 1 if OK, 0 if error
C example:
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 and hash is a buffer with:
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
This function is not available in scripting API.
[[directories]]
=== Directories

View File

@ -127,6 +127,7 @@ Le cœur de WeeChat est situé dans les répertoires suivants :
|    wee-completion.c | Complétions par défaut.
|    wee-config-file.c | Gestion des fichiers de configuration.
|    wee-config.c | Options de configuration du cœur de WeeChat (fichier weechat.conf).
|    wee-crypto.c | Fonctions de cryptographie.
|    wee-debug.c | Quelques fonctions de debug.
|    wee-eval.c | Évaluation d'expressions avec des références à des variables internes.
|    wee-hashtable.c | Tables de hachage.
@ -393,6 +394,7 @@ Le cœur de WeeChat est situé dans les répertoires suivants :
|       core/ | Racine des tests unitaires pour le cœur.
|          test-core-arraylist.cpp | Tests : listes avec tableau (« arraylists »).
|          test-core-calc.cpp | Tests : calcul d'expressions.
|          test-core-crypto.cpp | Tests : fonctions cryptographiques.
|          test-core-eval.cpp | Tests : évaluation d'expressions.
|          test-core-hashtble.cpp | Tests : tables de hachage.
|          test-core-hdata.cpp | Tests : hdata.

View File

@ -2099,67 +2099,6 @@ char *dump = weechat_string_hex_dump (string, strlen (string), 8, " >> ", NULL);
[NOTE]
Cette fonction n'est pas disponible dans l'API script.
==== string_hash
_WeeChat ≥ 2.8._
Calculer le hachage des données.
Prototype :
[source,C]
----
int string_hash (const void *data, int data_size, const char *hash_algo, void *hash, int *hash_size);
----
Paramètres :
* _data_ : les données à hacher
* _data_size_ : nombre d'octets à hacher dans _data_
* _hash_algo_ : l'algorithme de hachage, voir le tableau ci-dessous
* _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 ci-dessous)
* _hash_size_ : pointeur vers une variable utiliser pour stocker la longueur
du résultat du hachage (en octets) (peut être NULL)
Algorithmes de hachage supportés :
[width="100%",cols="2,2,3,6",options="header"]
|===
| Valeur | Algorithme | Taille du haché | Notes
| `+crc32+` | CRC32 | 4 octets (32 bits) | Pas un algorithme de hachage au sens cryptographique.
| `+md5+` | MD5 | 16 octets (128 bits) | *Faible*, non recommandé pour un usage cryptographique.
| `+sha1+` | SHA-1 | 20 octets (160 bits) | *Faible*, non recommandé pour un usage cryptographique.
| `+sha224+` | SHA-224 | 28 octets (224 bits) |
| `+sha256+` | SHA-256 | 32 octets (256 bits) |
| `+sha384+` | SHA-384 | 48 octets (384 bits) |
| `+sha512+` | SHA-512 | 64 octets (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 octets (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 octets (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 octets (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 octets (512 bits) |
|===
Valeur de retour :
* 1 si OK, 0 si erreur
Exemple en C :
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_string_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 et hash est un tampon avec :
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
Cette fonction n'est pas disponible dans l'API script.
==== string_is_command_char
_WeeChat ≥ 0.3.2._
@ -3446,6 +3385,73 @@ free (str);
[NOTE]
Cette fonction n'est pas disponible dans l'API script.
[[crypto]]
=== Cryptographie
Fonctions de cryptographie.
==== crypto_hash
_WeeChat ≥ 2.8._
Calculer le hachage des données.
Prototype :
[source,C]
----
int weechat_crypto_hash (const void *data, int data_size, const char *hash_algo,
void *hash, int *hash_size);
----
Paramètres :
* _data_ : les données à hacher
* _data_size_ : nombre d'octets à hacher dans _data_
* _hash_algo_ : l'algorithme de hachage, voir le tableau ci-dessous
* _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 ci-dessous)
* _hash_size_ : pointeur vers une variable utiliser pour stocker la longueur
du résultat du hachage (en octets) (peut être NULL)
Algorithmes de hachage supportés :
[width="100%",cols="2,2,3,6",options="header"]
|===
| Valeur | Algorithme | Taille du haché | Notes
| `+crc32+` | CRC32 | 4 octets (32 bits) | Pas un algorithme de hachage au sens cryptographique.
| `+md5+` | MD5 | 16 octets (128 bits) | *Faible*, non recommandé pour un usage cryptographique.
| `+sha1+` | SHA-1 | 20 octets (160 bits) | *Faible*, non recommandé pour un usage cryptographique.
| `+sha224+` | SHA-224 | 28 octets (224 bits) |
| `+sha256+` | SHA-256 | 32 octets (256 bits) |
| `+sha384+` | SHA-384 | 48 octets (384 bits) |
| `+sha512+` | SHA-512 | 64 octets (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 octets (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 octets (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 octets (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 octets (512 bits) |
|===
Valeur de retour :
* 1 si OK, 0 si erreur
Exemple en C :
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 et hash est un tampon avec :
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
Cette fonction n'est pas disponible dans l'API script.
[[directories]]
=== Répertoires

View File

@ -2152,68 +2152,6 @@ char *dump = weechat_string_hex_dump (string, strlen (string), 8, " >> ", NULL);
[NOTE]
Questa funzione non è disponibile nelle API per lo scripting.
// TRANSLATION MISSING
==== string_hash
_WeeChat ≥ 2.8._
Compute hash of data.
Prototipo:
[source,C]
----
int string_hash (const void *data, int data_size, const char *hash_algo, void *hash, int *hash_size);
----
Argomenti:
* _data_: the data to hash
* _data_size_: number of bytes to hash in _data_
* _hash_algo_: the hash algorithm, see table below
* _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 below)
* _hash_size_: pointer to a variable used to store the length of the hash computed
(in bytes) (can be NULL)
Supported hash algorithms:
[width="100%",cols="2,2,3,6",options="header"]
|===
| Value | Algorithm | Hash size | Notes
| `+crc32+` | CRC32 | 4 bytes (32 bits) | Not a hash algorithm in the cryptographic sense.
| `+md5+` | MD5 | 16 bytes (128 bits) | *Weak*, not recommended for cryptography usage.
| `+sha1+` | SHA-1 | 20 bytes (160 bits) | *Weak*, not recommended for cryptography usage.
| `+sha224+` | SHA-224 | 28 bytes (224 bits) |
| `+sha256+` | SHA-256 | 32 bytes (256 bits) |
| `+sha384+` | SHA-384 | 48 bytes (384 bits) |
| `+sha512+` | SHA-512 | 64 bytes (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 bytes (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 bytes (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 bytes (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 bytes (512 bits) |
|===
Valore restituito:
// TRANSLATION MISSING
* 1 if OK, 0 if error
Esempio in C:
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_string_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 and hash is a buffer with:
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
Questa funzione non è disponibile nelle API per lo scripting.
==== string_is_command_char
_WeeChat ≥ 0.3.2._
@ -3528,6 +3466,75 @@ free (string);
[NOTE]
Questa funzione non è disponibile nelle API per lo scripting.
// TRANSLATION MISSING
[[crypto]]
=== Cryptography
Some cryptographic functions.
// TRANSLATION MISSING
==== crypto_hash
_WeeChat ≥ 2.8._
Compute hash of data.
Prototipo:
[source,C]
----
int weechat_crypto_hash (const void *data, int data_size, const char *hash_algo,
void *hash, int *hash_size);
----
Argomenti:
* _data_: the data to hash
* _data_size_: number of bytes to hash in _data_
* _hash_algo_: the hash algorithm, see table below
* _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 below)
* _hash_size_: pointer to a variable used to store the length of the hash computed
(in bytes) (can be NULL)
Supported hash algorithms:
[width="100%",cols="2,2,3,6",options="header"]
|===
| Value | Algorithm | Hash size | Notes
| `+crc32+` | CRC32 | 4 bytes (32 bits) | Not a hash algorithm in the cryptographic sense.
| `+md5+` | MD5 | 16 bytes (128 bits) | *Weak*, not recommended for cryptography usage.
| `+sha1+` | SHA-1 | 20 bytes (160 bits) | *Weak*, not recommended for cryptography usage.
| `+sha224+` | SHA-224 | 28 bytes (224 bits) |
| `+sha256+` | SHA-256 | 32 bytes (256 bits) |
| `+sha384+` | SHA-384 | 48 bytes (384 bits) |
| `+sha512+` | SHA-512 | 64 bytes (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 bytes (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 bytes (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 bytes (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 bytes (512 bits) |
|===
Valore restituito:
// TRANSLATION MISSING
* 1 if OK, 0 if error
Esempio in C:
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 and hash is a buffer with:
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
Questa funzione non è disponibile nelle API per lo scripting.
[[directories]]
=== Cartelle

View File

@ -132,6 +132,8 @@ WeeChat "core" は以下のディレクトリに配置されています:
|    wee-completion.c | デフォルト補完
|    wee-config-file.c | 設定ファイル管理
|    wee-config.c | WeeChat コアの設定オプション (weechat.conf ファイル)
// TRANSLATION MISSING
|    wee-crypto.c | Cryptographic functions.
|    wee-debug.c | デバッグ用関数
|    wee-eval.c | 内部変数へのリファレンスを含む式を評価
|    wee-hashtable.c | ハッシュテーブル
@ -400,6 +402,8 @@ WeeChat "core" は以下のディレクトリに配置されています:
|          test-core-arraylist.cpp | テスト: 配列リスト
// TRANSLATION MISSING
|          test-core-calc.cpp | Tests: calculation of expressions.
// TRANSLATION MISSING
|          test-core-crypto.cpp | Tests: cryptographic functions.
|          test-core-eval.cpp | テスト: 式の評価
|          test-core-hashtble.cpp | テスト: ハッシュテーブル
|          test-core-hdata.cpp | テスト: hdata

View File

@ -2074,67 +2074,6 @@ char *dump = weechat_string_hex_dump (string, strlen (string), 8, " >> ", NULL);
[NOTE]
スクリプト API ではこの関数を利用できません。
// TRANSLATION MISSING
==== string_hash
_WeeChat バージョン 2.8 以上で利用可。_
Compute hash of data.
プロトタイプ:
[source,C]
----
int string_hash (const void *data, int data_size, const char *hash_algo, void *hash, int *hash_size);
----
引数:
* _data_: the data to hash
* _data_size_: number of bytes to hash in _data_
* _hash_algo_: the hash algorithm, see table below
* _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 below)
* _hash_size_: pointer to a variable used to store the length of the hash computed
(in bytes) (can be NULL)
Supported hash algorithms:
[width="100%",cols="2,2,3,6",options="header"]
|===
| Value | Algorithm | Hash size | Notes
| `+crc32+` | CRC32 | 4 bytes (32 bits) | Not a hash algorithm in the cryptographic sense.
| `+md5+` | MD5 | 16 bytes (128 bits) | *Weak*, not recommended for cryptography usage.
| `+sha1+` | SHA-1 | 20 bytes (160 bits) | *Weak*, not recommended for cryptography usage.
| `+sha224+` | SHA-224 | 28 bytes (224 bits) |
| `+sha256+` | SHA-256 | 32 bytes (256 bits) |
| `+sha384+` | SHA-384 | 48 bytes (384 bits) |
| `+sha512+` | SHA-512 | 64 bytes (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 bytes (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 bytes (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 bytes (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 bytes (512 bits) |
|===
戻り値:
* 成功した場合は 1、失敗した場合は 0
C 言語での使用例:
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_string_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 and hash is a buffer with:
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
スクリプト API ではこの関数を利用できません。
==== string_is_command_char
_WeeChat バージョン 0.3.2 以上で利用可。_
@ -3404,6 +3343,74 @@ free (string);
[NOTE]
スクリプト API ではこの関数を利用できません。
// TRANSLATION MISSING
[[crypto]]
=== Cryptography
Some cryptographic functions.
// TRANSLATION MISSING
==== crypto_hash
_WeeChat バージョン 2.8 以上で利用可。_
Compute hash of data.
プロトタイプ:
[source,C]
----
int weechat_crypto_hash (const void *data, int data_size, const char *hash_algo,
void *hash, int *hash_size);
----
引数:
* _data_: the data to hash
* _data_size_: number of bytes to hash in _data_
* _hash_algo_: the hash algorithm, see table below
* _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 below)
* _hash_size_: pointer to a variable used to store the length of the hash computed
(in bytes) (can be NULL)
Supported hash algorithms:
[width="100%",cols="2,2,3,6",options="header"]
|===
| Value | Algorithm | Hash size | Notes
| `+crc32+` | CRC32 | 4 bytes (32 bits) | Not a hash algorithm in the cryptographic sense.
| `+md5+` | MD5 | 16 bytes (128 bits) | *Weak*, not recommended for cryptography usage.
| `+sha1+` | SHA-1 | 20 bytes (160 bits) | *Weak*, not recommended for cryptography usage.
| `+sha224+` | SHA-224 | 28 bytes (224 bits) |
| `+sha256+` | SHA-256 | 32 bytes (256 bits) |
| `+sha384+` | SHA-384 | 48 bytes (384 bits) |
| `+sha512+` | SHA-512 | 64 bytes (512 bits) |
| `+sha3-224+` | SHA3-224 | 28 bytes (224 bits) |
| `+sha3-256+` | SHA3-256 | 32 bytes (256 bits) |
| `+sha3-384+` | SHA3-384 | 48 bytes (384 bits) |
| `+sha3-512+` | SHA3-512 | 64 bytes (512 bits) |
|===
戻り値:
* 成功した場合は 1、失敗した場合は 0
C 言語での使用例:
[source,C]
----
const char *data = "abcdefghijklmnopqrstuvwxyz";
char hash[256 / 8];
int rc, hash_size;
rc = weechat_crypto_hash (data, strlen (data), "sha256", hash, &hash_size);
/* rc == 1, hash_size == 32 and hash is a buffer with:
71 c4 80 df 93 d6 ae 2f 1e fa d1 44 7c 66 c9 52 5e 31 62 18 cf 51 fc 8d 9e d8 32 f2 da f1 8b 73 */
----
[NOTE]
スクリプト API ではこの関数を利用できません。
[[directories]]
=== ディレクトリ

View File

@ -51,6 +51,8 @@
./src/core/wee-config-file.c
./src/core/wee-config-file.h
./src/core/wee-config.h
./src/core/wee-crypto.c
./src/core/wee-crypto.h
./src/core/wee-debug.c
./src/core/wee-debug.h
./src/core/wee-eval.c

View File

@ -52,6 +52,8 @@ SET(WEECHAT_SOURCES
./src/core/wee-config-file.c
./src/core/wee-config-file.h
./src/core/wee-config.h
./src/core/wee-crypto.c
./src/core/wee-crypto.h
./src/core/wee-debug.c
./src/core/wee-debug.h
./src/core/wee-eval.c

View File

@ -28,6 +28,7 @@ set(LIB_CORE_SRC
wee-completion.c wee-completion.h
wee-config.c wee-config.h
wee-config-file.c wee-config-file.h
wee-crypto.c wee-crypto.h
wee-debug.c wee-debug.h
wee-eval.c wee-eval.h
wee-hashtable.c wee-hashtable.h

View File

@ -37,6 +37,8 @@ lib_weechat_core_a_SOURCES = weechat.c \
wee-config.h \
wee-config-file.c \
wee-config-file.h \
wee-crypto.c \
wee-crypto.h \
wee-debug.c \
wee-debug.h \
wee-eval.c \

402
src/core/wee-crypto.c Normal file
View File

@ -0,0 +1,402 @@
/*
* wee-crypto.c - cryptographic functions
*
* Copyright (C) 2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* WeeChat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <math.h>
#include <gcrypt.h>
#include "weechat.h"
#include "wee-crypto.h"
#include "wee-config-file.h"
#include "wee-hashtable.h"
#include "wee-string.h"
#include "../plugins/plugin.h"
char *weecrypto_hash_algo_string[] = {
"crc32",
"md5",
"sha1",
"sha224", "sha256", "sha384", "sha512",
"sha3-224", "sha3-256", "sha3-384", "sha3-512",
NULL,
};
int weecrypto_hash_algo[] = {
GCRY_MD_CRC32,
GCRY_MD_MD5,
GCRY_MD_SHA1,
GCRY_MD_SHA224, GCRY_MD_SHA256, GCRY_MD_SHA384, GCRY_MD_SHA512,
GCRY_MD_SHA3_224, GCRY_MD_SHA3_256, GCRY_MD_SHA3_384, GCRY_MD_SHA3_512,
};
/*
* Returns the hash algorithm with the name, or GCRY_MD_NONE if not found.
*/
int
weecrypto_get_hash_algo (const char *hash_algo)
{
int i;
if (!hash_algo)
return GCRY_MD_NONE;
for (i = 0; weecrypto_hash_algo_string[i]; i++)
{
if (strcmp (weecrypto_hash_algo_string[i], hash_algo) == 0)
return weecrypto_hash_algo[i];
}
return GCRY_MD_NONE;
}
/*
* Computes hash of data using the given algorithm.
*
* The hash size depends on the algorithm, common ones are:
*
* GCRY_MD_CRC32 32 bits == 4 bytes
* GCRY_MD_MD5 128 bits == 16 bytes
* GCRY_MD_SHA1 160 bits == 20 bytes
* GCRY_MD_SHA224 224 bits == 28 bytes
* GCRY_MD_SHA256 256 bits == 32 bytes
* GCRY_MD_SHA384 384 bits == 48 bytes
* GCRY_MD_SHA512 512 bits == 64 bytes
* GCRY_MD_SHA3_224 224 bits == 28 bytes
* GCRY_MD_SHA3_256 256 bits == 32 bytes
* GCRY_MD_SHA3_384 384 bits == 48 bytes
* GCRY_MD_SHA3_512 512 bits == 64 bytes
*
* The result hash is stored in "hash" (the buffer must be large enough).
*
* If hash_size is not NULL, the length of hash is stored in *hash_size
* (in bytes).
*
* Returns 1 if OK, 0 if error.
*/
int
weecrypto_hash (const void *data, int data_size, int hash_algo,
void *hash, int *hash_size)
{
gcry_md_hd_t *hd_md;
int rc, hd_md_opened, algo_size;
unsigned char *ptr_hash;
rc = 0;
hd_md = NULL;
hd_md_opened = 0;
if (!hash)
goto hash_end;
if (hash_size)
*hash_size = 0;
if (!data || (data_size < 1))
goto hash_end;
hd_md = malloc (sizeof (gcry_md_hd_t));
if (!hd_md)
goto hash_end;
if (gcry_md_open (hd_md, hash_algo, 0) != 0)
goto hash_end;
hd_md_opened = 1;
gcry_md_write (*hd_md, data, data_size);
ptr_hash = gcry_md_read (*hd_md, hash_algo);
if (!ptr_hash)
goto hash_end;
algo_size = gcry_md_get_algo_dlen (hash_algo);
memcpy (hash, ptr_hash, algo_size);
if (hash_size)
*hash_size = algo_size;
rc = 1;
hash_end:
if (hd_md)
{
if (hd_md_opened)
gcry_md_close (*hd_md);
free (hd_md);
}
return rc;
}
/*
* Computes PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2)
* hash of data.
*
* The hash size depends on the algorithm, common ones are:
*
* GCRY_MD_SHA1 160 bits == 20 bytes
* GCRY_MD_SHA256 256 bits == 32 bytes
* GCRY_MD_SHA512 512 bits == 64 bytes
*
* The result hash is stored in "hash" (the buffer must be large enough).
*
* If hash_size is not NULL, the length of hash is stored in *hash_size
* (in bytes).
*
* Returns 1 if OK, 0 if error.
*/
int
weecrypto_hash_pbkdf2 (const void *data, int data_size, int hash_subalgo,
const void *salt, int salt_size, int iterations,
void *hash, int *hash_size)
{
int rc, algo_size;
rc = 0;
if (!hash)
goto hash_pbkdf2_end;
if (hash_size)
*hash_size = 0;
if (!data || (data_size < 1) || !salt || (salt_size < 1)
|| (iterations < 1))
{
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,
salt, salt_size, iterations,
algo_size, hash) != 0)
{
goto hash_pbkdf2_end;
}
if (hash_size)
*hash_size = algo_size;
rc = 1;
hash_pbkdf2_end:
return rc;
}
/*
* Generates a Time-based One-Time Password (TOTP), as described
* in the RFC 6238.
*
* Returns:
* 1: OK
* 0: error
*/
int
weecrypto_totp_generate_internal (const char *secret, int length_secret,
uint64_t moving_factor, int digits,
char *result)
{
gcry_md_hd_t hd_md;
uint64_t moving_factor_swapped;
unsigned char *ptr_hash;
char hash[20];
int offset, length;
unsigned long bin_code;
if (gcry_md_open (&hd_md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC) != 0)
return 0;
if (gcry_md_setkey (hd_md, secret, length_secret) != 0)
{
gcry_md_close (hd_md);
return 0;
}
moving_factor_swapped = (moving_factor >> 56)
| ((moving_factor << 40) & 0x00FF000000000000)
| ((moving_factor << 24) & 0x0000FF0000000000)
| ((moving_factor << 8) & 0x000000FF00000000)
| ((moving_factor >> 8) & 0x00000000FF000000)
| ((moving_factor >> 24) & 0x0000000000FF0000)
| ((moving_factor >> 40) & 0x000000000000FF00)
| (moving_factor << 56);
gcry_md_write (hd_md,
&moving_factor_swapped, sizeof (moving_factor_swapped));
ptr_hash = gcry_md_read (hd_md, GCRY_MD_SHA1);
if (!ptr_hash)
{
gcry_md_close (hd_md);
return 0;
}
memcpy (hash, ptr_hash, sizeof (hash));
gcry_md_close (hd_md);
offset = hash[19] & 0xf;
bin_code = (hash[offset] & 0x7f) << 24
| (hash[offset+1] & 0xff) << 16
| (hash[offset+2] & 0xff) << 8
| (hash[offset+3] & 0xff);
bin_code %= (unsigned long)(pow (10, digits));
length = snprintf (result, digits + 1, "%.*lu", digits, bin_code);
if (length != digits)
return 0;
return 1;
}
/*
* Generates a Time-based One-Time Password (TOTP), as described
* in the RFC 6238.
*
* Returns the password as string, NULL if error.
*
* Note: result must be freed after use.
*/
char *
weecrypto_totp_generate (const char *secret_base32, time_t totp_time,
int digits)
{
char *result, *secret;
int length_secret, rc;
uint64_t moving_factor;
secret = NULL;
result = NULL;
if (!secret_base32 || !secret_base32[0]
|| (digits < WEECRYPTO_TOTP_MIN_DIGITS)
|| (digits > WEECRYPTO_TOTP_MAX_DIGITS))
{
goto error;
}
secret = malloc ((strlen (secret_base32) * 4) + 16 + 1);
if (!secret)
goto error;
length_secret = string_base32_decode (secret_base32, secret);
if (length_secret < 0)
goto error;
result = malloc (digits + 1);
if (!result)
goto error;
if (totp_time == 0)
totp_time = time (NULL);
moving_factor = totp_time / 30;
rc = weecrypto_totp_generate_internal (secret, length_secret,
moving_factor, digits, result);
if (!rc)
goto error;
free (secret);
return result;
error:
if (secret)
free (secret);
if (result)
free (result);
return NULL;
}
/*
* Validates a Time-based One-Time Password (TOTP).
*
* Returns:
* 1: OTP is OK
* 0: OTP is invalid
*/
int
weecrypto_totp_validate (const char *secret_base32, time_t totp_time,
int window, const char *otp)
{
char *secret, str_otp[16];
int length_secret, digits, rc, otp_ok;
uint64_t i, moving_factor;
secret = NULL;
if (!secret_base32 || !secret_base32[0] || (window < 0) || !otp || !otp[0])
goto error;
digits = strlen (otp);
if ((digits < WEECRYPTO_TOTP_MIN_DIGITS)
|| (digits > WEECRYPTO_TOTP_MAX_DIGITS))
{
goto error;
}
secret = malloc (strlen (secret_base32) + 1);
if (!secret)
goto error;
length_secret = string_base32_decode (secret_base32, secret);
if (length_secret < 0)
goto error;
if (totp_time == 0)
totp_time = time (NULL);
moving_factor = totp_time / 30;
otp_ok = 0;
for (i = moving_factor - window; i <= moving_factor + window; i++)
{
rc = weecrypto_totp_generate_internal (secret, length_secret,
i, digits, str_otp);
if (rc && (strcmp (str_otp, otp) == 0))
{
otp_ok = 1;
break;
}
}
free (secret);
return otp_ok;
error:
if (secret)
free (secret);
return 0;
}

39
src/core/wee-crypto.h Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* WeeChat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_CRYPTO_H
#define WEECHAT_CRYPTO_H
#define WEECRYPTO_TOTP_MIN_DIGITS 4
#define WEECRYPTO_TOTP_MAX_DIGITS 10
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,
const void *salt, int salt_size,
int iterations,
void *hash, int *hash_size);
extern char *weecrypto_totp_generate (const char *secret, time_t totp_time,
int digits);
extern int weecrypto_totp_validate (const char *secret, time_t totp_time,
int window, const char *otp);
#endif /* WEECHAT_CRYPTO_H */

View File

@ -25,13 +25,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <math.h>
#include <gcrypt.h>
#include "weechat.h"
#include "wee-config-file.h"
#include "wee-crypto.h"
#include "wee-hashtable.h"
#include "wee-secure.h"
#include "wee-secure-config.h"
@ -65,139 +63,6 @@ char *secure_decrypt_error[] = { "memory", "buffer", "key", "cipher", "setkey",
int secure_data_encrypted = 0;
/*
* Computes hash of data using the given algorithm.
*
* The hash size depends on the algorithm, common ones are:
*
* GCRY_MD_CRC32 32 bits == 4 bytes
* GCRY_MD_MD5 128 bits == 16 bytes
* GCRY_MD_SHA1 160 bits == 20 bytes
* GCRY_MD_SHA224 224 bits == 28 bytes
* GCRY_MD_SHA256 256 bits == 32 bytes
* GCRY_MD_SHA384 384 bits == 48 bytes
* GCRY_MD_SHA512 512 bits == 64 bytes
* GCRY_MD_SHA3_224 224 bits == 28 bytes
* GCRY_MD_SHA3_256 256 bits == 32 bytes
* GCRY_MD_SHA3_384 384 bits == 48 bytes
* GCRY_MD_SHA3_512 512 bits == 64 bytes
*
* The result hash is stored in "hash" (the buffer must be large enough).
*
* If hash_size is not NULL, the length of hash is stored in *hash_size
* (in bytes).
*
* Returns 1 if OK, 0 if error.
*/
int
secure_hash (const void *data, int data_size, int hash_algo,
void *hash, int *hash_size)
{
gcry_md_hd_t *hd_md;
int rc, hd_md_opened, algo_size;
unsigned char *ptr_hash;
rc = 0;
hd_md = NULL;
hd_md_opened = 0;
if (!hash)
goto hash_end;
if (hash_size)
*hash_size = 0;
if (!data || (data_size < 1))
goto hash_end;
hd_md = malloc (sizeof (gcry_md_hd_t));
if (!hd_md)
goto hash_end;
if (gcry_md_open (hd_md, hash_algo, 0) != 0)
goto hash_end;
hd_md_opened = 1;
gcry_md_write (*hd_md, data, data_size);
ptr_hash = gcry_md_read (*hd_md, hash_algo);
if (!ptr_hash)
goto hash_end;
algo_size = gcry_md_get_algo_dlen (hash_algo);
memcpy (hash, ptr_hash, algo_size);
if (hash_size)
*hash_size = algo_size;
rc = 1;
hash_end:
if (hd_md)
{
if (hd_md_opened)
gcry_md_close (*hd_md);
free (hd_md);
}
return rc;
}
/*
* Computes PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2)
* hash of data, as binary buffer.
*
* The hash size depends on the algorithm, common ones are:
*
* GCRY_MD_SHA1 160 bits == 20 bytes
* GCRY_MD_SHA256 256 bits == 32 bytes
* GCRY_MD_SHA512 512 bits == 64 bytes
*
* The result hash is stored in "hash" (the buffer must be large enough).
*
* If hash_size is not NULL, the length of hash is stored in *hash_size
* (in bytes).
*
* Returns 1 if OK, 0 if error.
*/
int
secure_hash_pbkdf2 (const void *data, int data_size, int hash_subalgo,
const void *salt, int salt_size, int iterations,
void *hash, int *hash_size)
{
int rc, algo_size;
rc = 0;
if (!hash)
goto hash_pbkdf2_end;
if (hash_size)
*hash_size = 0;
if (!data || (data_size < 1) || !salt || (salt_size < 1)
|| (iterations < 1))
{
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,
salt, salt_size, iterations,
algo_size, hash) != 0)
{
goto hash_pbkdf2_end;
}
if (hash_size)
*hash_size = algo_size;
rc = 1;
hash_pbkdf2_end:
return rc;
}
/*
* Derives a key from salt + passphrase (using a hash).
*
@ -228,7 +93,7 @@ secure_derive_key (const char *salt, const char *passphrase,
memcpy (buffer + SECURE_SALT_SIZE, passphrase, strlen (passphrase));
/* compute hash of buffer */
if (!secure_hash (buffer, length, GCRY_MD_SHA512, hash, &length_hash))
if (!weecrypto_hash (buffer, length, GCRY_MD_SHA512, hash, &length_hash))
{
free (buffer);
return 0;
@ -628,195 +493,6 @@ secure_decrypt_data_not_decrypted (const char *passphrase)
return num_ok;
}
/*
* Generates a Time-based One-Time Password (TOTP), as described
* in the RFC 6238.
*
* Returns:
* 1: OK
* 0: error
*/
int
secure_totp_generate_internal (const char *secret, int length_secret,
uint64_t moving_factor, int digits,
char *result)
{
gcry_md_hd_t hd_md;
uint64_t moving_factor_swapped;
unsigned char *ptr_hash;
char hash[20];
int offset, length;
unsigned long bin_code;
if (gcry_md_open (&hd_md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC) != 0)
return 0;
if (gcry_md_setkey (hd_md, secret, length_secret) != 0)
{
gcry_md_close (hd_md);
return 0;
}
moving_factor_swapped = (moving_factor >> 56)
| ((moving_factor << 40) & 0x00FF000000000000)
| ((moving_factor << 24) & 0x0000FF0000000000)
| ((moving_factor << 8) & 0x000000FF00000000)
| ((moving_factor >> 8) & 0x00000000FF000000)
| ((moving_factor >> 24) & 0x0000000000FF0000)
| ((moving_factor >> 40) & 0x000000000000FF00)
| (moving_factor << 56);
gcry_md_write (hd_md,
&moving_factor_swapped, sizeof (moving_factor_swapped));
ptr_hash = gcry_md_read (hd_md, GCRY_MD_SHA1);
if (!ptr_hash)
{
gcry_md_close (hd_md);
return 0;
}
memcpy (hash, ptr_hash, sizeof (hash));
gcry_md_close (hd_md);
offset = hash[19] & 0xf;
bin_code = (hash[offset] & 0x7f) << 24
| (hash[offset+1] & 0xff) << 16
| (hash[offset+2] & 0xff) << 8
| (hash[offset+3] & 0xff);
bin_code %= (unsigned long)(pow (10, digits));
length = snprintf (result, digits + 1, "%.*lu", digits, bin_code);
if (length != digits)
return 0;
return 1;
}
/*
* Generates a Time-based One-Time Password (TOTP), as described
* in the RFC 6238.
*
* Returns the password as string, NULL if error.
*
* Note: result must be freed after use.
*/
char *
secure_totp_generate (const char *secret_base32, time_t totp_time, int digits)
{
char *result, *secret;
int length_secret, rc;
uint64_t moving_factor;
secret = NULL;
result = NULL;
if (!secret_base32 || !secret_base32[0]
|| (digits < SECURE_TOTP_MIN_DIGITS)
|| (digits > SECURE_TOTP_MAX_DIGITS))
{
goto error;
}
secret = malloc ((strlen (secret_base32) * 4) + 16 + 1);
if (!secret)
goto error;
length_secret = string_base32_decode (secret_base32, secret);
if (length_secret < 0)
goto error;
result = malloc (digits + 1);
if (!result)
goto error;
if (totp_time == 0)
totp_time = time (NULL);
moving_factor = totp_time / 30;
rc = secure_totp_generate_internal (secret, length_secret,
moving_factor, digits, result);
if (!rc)
goto error;
free (secret);
return result;
error:
if (secret)
free (secret);
if (result)
free (result);
return NULL;
}
/*
* Validates a Time-based One-Time Password (TOTP).
*
* Returns:
* 1: OTP is OK
* 0: OTP is invalid
*/
int
secure_totp_validate (const char *secret_base32, time_t totp_time, int window,
const char *otp)
{
char *secret, str_otp[16];
int length_secret, digits, rc, otp_ok;
uint64_t i, moving_factor;
secret = NULL;
if (!secret_base32 || !secret_base32[0] || (window < 0) || !otp || !otp[0])
goto error;
digits = strlen (otp);
if ((digits < SECURE_TOTP_MIN_DIGITS) || (digits > SECURE_TOTP_MAX_DIGITS))
goto error;
secret = malloc (strlen (secret_base32) + 1);
if (!secret)
goto error;
length_secret = string_base32_decode (secret_base32, secret);
if (length_secret < 0)
goto error;
if (totp_time == 0)
totp_time = time (NULL);
moving_factor = totp_time / 30;
otp_ok = 0;
for (i = moving_factor - window; i <= moving_factor + window; i++)
{
rc = secure_totp_generate_internal (secret, length_secret,
i, digits, str_otp);
if (rc && (strcmp (str_otp, otp) == 0))
{
otp_ok = 1;
break;
}
}
free (secret);
return otp_ok;
error:
if (secret)
free (secret);
return 0;
}
/*
* Initializes secured data.
*

View File

@ -27,8 +27,6 @@
#define SECURE_SALT_DEFAULT "WeeChat!"
#define SECURE_DATA_PASSPHRASE_FLAG "__passphrase__"
#define SECURE_SALT_SIZE 8
#define SECURE_TOTP_MIN_DIGITS 4
#define SECURE_TOTP_MAX_DIGITS 10
enum t_secure_config_hash_algo
{
@ -55,13 +53,6 @@ extern int secure_cipher[];
extern int secure_data_encrypted;
extern char *secure_decrypt_error[];
extern int secure_hash (const void *data, int data_size, int hash_algo,
void *hash, int *hash_size);
extern int secure_hash_pbkdf2 (const void *data, int data_size,
int hash_subalgo,
const void *salt, int salt_size,
int iterations,
void *hash, int *hash_size);
extern int secure_encrypt_data (const char *data, int length_data,
int hash_algo, int cipher,
const char *passphrase, char **encrypted,
@ -71,10 +62,6 @@ extern int secure_decrypt_data (const char *buffer, int length_buffer,
const char *passphrase, char **decrypted,
int *length_decrypted);
extern int secure_decrypt_data_not_decrypted (const char *passphrase);
extern char *secure_totp_generate (const char *secret, time_t totp_time,
int digits);
extern int secure_totp_validate (const char *secret, time_t totp_time,
int window, const char *otp);
extern int secure_init ();
extern void secure_end ();

View File

@ -53,7 +53,6 @@
#include "wee-config.h"
#include "wee-eval.h"
#include "wee-hashtable.h"
#include "wee-secure.h"
#include "wee-utf8.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
@ -65,22 +64,6 @@
((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : \
c - '0')
char *string_hash_algo_string[] = {
"crc32",
"md5",
"sha1",
"sha224", "sha256", "sha384", "sha512",
"sha3-224", "sha3-256", "sha3-384", "sha3-512",
NULL,
};
int string_hash_algo[] = {
GCRY_MD_CRC32,
GCRY_MD_MD5,
GCRY_MD_SHA1,
GCRY_MD_SHA224, GCRY_MD_SHA256, GCRY_MD_SHA384, GCRY_MD_SHA512,
GCRY_MD_SHA3_224, GCRY_MD_SHA3_256, GCRY_MD_SHA3_384, GCRY_MD_SHA3_512,
};
struct t_hashtable *string_hashtable_shared = NULL;
@ -3422,53 +3405,6 @@ end:
return buf;
}
/*
* Returns the hash algorithm with the name, or GCRY_MD_NONE if not found.
*/
int
string_get_hash_algo (const char *hash_algo)
{
int i;
if (!hash_algo)
return GCRY_MD_NONE;
for (i = 0; string_hash_algo_string[i]; i++)
{
if (strcmp (string_hash_algo_string[i], hash_algo) == 0)
return string_hash_algo[i];
}
return GCRY_MD_NONE;
}
/*
* Computes hash data.
*/
int
string_hash (const void *data, int data_size, const char *hash_algo,
void *hash, int *hash_size)
{
int algo;
if (!hash)
return 0;
if (hash_size)
*hash_size = 0;
if (!data || (data_size < 1) || !hash_algo)
return 0;
algo = string_get_hash_algo (hash_algo);
if (algo == GCRY_MD_NONE)
return 0;
return secure_hash (data, data_size, algo, hash, hash_size);
}
/*
* Checks if a string is a command.
*

View File

@ -118,8 +118,6 @@ extern int string_base64_decode (const char *from, char *to);
extern char *string_hex_dump (const char *data, int data_size,
int bytes_per_line,
const char *prefix, const char *suffix);
extern int string_hash (const void *data, int data_size,
const char *hash_algo, void *hash, int *hash_size);
extern int string_is_command_char (const char *string);
extern const char *string_input_for_buffer (const char *string);
extern char *string_replace_with_callback (const char *string,

View File

@ -31,10 +31,10 @@
#include "../core/weechat.h"
#include "../core/wee-config.h"
#include "../core/wee-crypto.h"
#include "../core/wee-hook.h"
#include "../core/wee-infolist.h"
#include "../core/wee-proxy.h"
#include "../core/wee-secure.h"
#include "../core/wee-string.h"
#include "../core/wee-url.h"
#include "../core/wee-util.h"
@ -780,7 +780,7 @@ plugin_api_info_totp_generate_cb (const void *pointer, void *data,
digits = number;
}
totp = secure_totp_generate (ptr_secret, totp_time, digits);
totp = weecrypto_totp_generate (ptr_secret, totp_time, digits);
if (!totp)
goto error;
@ -853,7 +853,7 @@ plugin_api_info_totp_validate_cb (const void *pointer, void *data,
window = number;
}
rc = secure_totp_validate (ptr_secret, totp_time, window, ptr_otp);
rc = weecrypto_totp_validate (ptr_secret, totp_time, window, ptr_otp);
snprintf (value, sizeof (value), "%d", rc);

View File

@ -25,9 +25,11 @@
#include <stdlib.h>
#include <string.h>
#include <gcrypt.h>
#include "../core/weechat.h"
#include "../core/wee-config.h"
#include "../core/wee-crypto.h"
#include "../core/wee-hashtable.h"
#include "../core/wee-hook.h"
#include "../core/wee-infolist.h"
@ -134,6 +136,32 @@ plugin_api_string_base_decode (int base, const char *from, char *to)
return -1;
}
/*
* Computes hash of data using the given algorithm.
*/
int
plugin_api_crypto_hash (const void *data, int data_size, const char *hash_algo,
void *hash, int *hash_size)
{
int algo;
if (!hash)
return 0;
if (hash_size)
*hash_size = 0;
if (!data || (data_size < 1) || !hash_algo)
return 0;
algo = weecrypto_get_hash_algo (hash_algo);
if (algo == GCRY_MD_NONE)
return 0;
return weecrypto_hash (data, data_size, algo, hash, hash_size);
}
/*
* Frees an option.
*/

View File

@ -33,6 +33,11 @@ extern int plugin_api_string_base_encode (int base, const char *from,
extern int plugin_api_string_base_decode (int base, const char *from,
char *to);
/* crypto */
extern int plugin_api_crypto_hash (const void *data, int data_size,
const char *hash_algo,
void *hash, int *hash_size);
/* config */
extern void plugin_api_config_file_option_free (struct t_config_option *option);
extern struct t_config_option *plugin_api_config_get (const char *option_name);

View File

@ -623,7 +623,6 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
new_plugin->string_base_encode = &plugin_api_string_base_encode;
new_plugin->string_base_decode = &plugin_api_string_base_decode;
new_plugin->string_hex_dump = &string_hex_dump;
new_plugin->string_hash = &string_hash;
new_plugin->string_is_command_char = &string_is_command_char;
new_plugin->string_input_for_buffer = &string_input_for_buffer;
new_plugin->string_eval_expression = &eval_expression;
@ -650,6 +649,8 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
new_plugin->utf8_pos = &utf8_pos;
new_plugin->utf8_strndup = &utf8_strndup;
new_plugin->crypto_hash = &plugin_api_crypto_hash;
new_plugin->mkdir_home = &util_mkdir_home;
new_plugin->mkdir = &util_mkdir;
new_plugin->mkdir_parents = &util_mkdir_parents;

View File

@ -207,7 +207,7 @@ relay_websocket_build_handshake (struct t_relay_client *client)
snprintf (key, length, "%s%s", sec_websocket_key, WEBSOCKET_GUID);
/* compute 160-bit SHA1 on the key and encode it with base64 */
if (!weechat_string_hash (key, strlen (key), "sha1", hash, &length_hash))
if (!weechat_crypto_hash (key, strlen (key), "sha1", hash, &length_hash))
{
free (key);
return NULL;

View File

@ -774,7 +774,7 @@ script_repo_sha512sum_file (const char *filename)
}
fclose (file);
if (!weechat_string_hash (data, st.st_size, "sha512", hash, &length_hash))
if (!weechat_crypto_hash (data, st.st_size, "sha512", hash, &length_hash))
{
free (data);
return NULL;

View File

@ -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-01"
#define WEECHAT_PLUGIN_API_VERSION "20200301-02"
/* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \
@ -341,8 +341,6 @@ struct t_weechat_plugin
char *(*string_hex_dump) (const char *data, int data_size,
int bytes_per_line, const char *prefix,
const char *suffix);
int (*string_hash) (const void *data, int data_size,
const char *hash_algo, void *hash, int *hash_size);
int (*string_is_command_char) (const char *string);
const char *(*string_input_for_buffer) (const char *string);
char *(*string_eval_expression )(const char *expr,
@ -374,6 +372,10 @@ struct t_weechat_plugin
int (*utf8_pos) (const char *string, int real_pos);
char *(*utf8_strndup) (const char *string, int length);
/* crypto */
int (*crypto_hash) (const void *data, int data_size,
const char *hash_algo, void *hash, int *hash_size);
/* directories/files */
int (*mkdir_home) (const char *directory, int mode);
int (*mkdir) (const char *directory, int mode);
@ -1256,10 +1258,6 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
(weechat_plugin->string_hex_dump)(__data, __data_size, \
__bytes_per_line, __prefix, \
__suffix)
#define weechat_string_hash(__data, __data_size, __hash_algo, \
__hash, __hash_size) \
(weechat_plugin->string_hash)(__data, __data_size, __hash_algo, \
__hash, __hash_size)
#define weechat_string_is_command_char(__string) \
(weechat_plugin->string_is_command_char)(__string)
#define weechat_string_input_for_buffer(__string) \
@ -1313,6 +1311,12 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
#define weechat_utf8_strndup(__string, __length) \
(weechat_plugin->utf8_strndup)(__string, __length)
/* crypto */
#define weechat_crypto_hash(__data, __data_size, __hash_algo, \
__hash, __hash_size) \
(weechat_plugin->crypto_hash)(__data, __data_size, __hash_algo, \
__hash, __hash_size)
/* directories */
#define weechat_mkdir_home(__directory, __mode) \
(weechat_plugin->mkdir_home)(__directory, __mode)

View File

@ -27,6 +27,7 @@ set(LIB_WEECHAT_UNIT_TESTS_CORE_SRC
unit/test-plugins.cpp
unit/core/test-core-arraylist.cpp
unit/core/test-core-calc.cpp
unit/core/test-core-crypto.cpp
unit/core/test-core-eval.cpp
unit/core/test-core-hashtable.cpp
unit/core/test-core-hdata.cpp
@ -38,7 +39,6 @@ set(LIB_WEECHAT_UNIT_TESTS_CORE_SRC
unit/core/test-core-url.cpp
unit/core/test-core-utf8.cpp
unit/core/test-core-util.cpp
unit/core/test-core.h
unit/gui/test-gui-color.cpp
unit/gui/test-gui-line.cpp
unit/gui/test-gui-nick.cpp

View File

@ -24,6 +24,7 @@ noinst_LIBRARIES = lib_weechat_unit_tests_core.a
lib_weechat_unit_tests_core_a_SOURCES = unit/test-plugins.cpp \
unit/core/test-core-arraylist.cpp \
unit/core/test-core-calc.cpp \
unit/core/test-core-crypto.cpp \
unit/core/test-core-eval.cpp \
unit/core/test-core-hashtable.cpp \
unit/core/test-core-hdata.cpp \
@ -35,7 +36,6 @@ lib_weechat_unit_tests_core_a_SOURCES = unit/test-plugins.cpp \
unit/core/test-core-url.cpp \
unit/core/test-core-utf8.cpp \
unit/core/test-core-util.cpp \
unit/core/test-core.h \
unit/gui/test-gui-color.cpp \
unit/gui/test-gui-line.cpp \
unit/gui/test-gui-nick.cpp \

View File

@ -62,6 +62,7 @@ extern "C"
IMPORT_TEST_GROUP(Plugins);
IMPORT_TEST_GROUP(CoreArraylist);
IMPORT_TEST_GROUP(CoreCalc);
IMPORT_TEST_GROUP(CoreCrypto);
IMPORT_TEST_GROUP(CoreEval);
IMPORT_TEST_GROUP(CoreHashtable);
IMPORT_TEST_GROUP(CoreHdata);

View File

@ -0,0 +1,311 @@
/*
* test-core-crypto.cpp - test cryptographic functions
*
* Copyright (C) 2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* WeeChat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#include "CppUTest/TestHarness.h"
extern "C"
{
#include <string.h>
#include <gcrypt.h>
#include "src/core/wee-crypto.h"
#include "src/core/wee-string.h"
#define DATA_HASH "this is a test of hash function"
#define DATA_HASH_CRC32 "ef26fe3e"
#define DATA_HASH_MD5 "1197d121af621ac6a63cb8ef6b5dfa30"
#define DATA_HASH_SHA1 "799d818061175b400dc5aaeb14b8d32cdef32ff0"
#define DATA_HASH_SHA224 "637d21f3ba3f4e9fa9fb889dc990b31a658cb37b4aefb5144" \
"70b016d"
#define DATA_HASH_SHA256 "b9a4c3393dfac4330736684510378851e581c68add8eca841" \
"10c31a33e694676"
#define DATA_HASH_SHA384 "42853280be9b8409eed265f272bd580e2fbd448b7c7e236c7" \
"f37dafec7906d51d982dc84ec70a4733eca49d86ac19455"
#define DATA_HASH_SHA512 "4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe0" \
"58255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a" \
"1e6b8ae6e"
#define DATA_HASH_SHA3_224 "26432a3a4ea998790be43386b1de417f88be43146a4af98" \
"2a9627d10"
#define DATA_HASH_SHA3_256 "226e3830306711cf653c1661765c304b37038e7457c35dd" \
"14fca0f6a8ba1d2e3"
#define DATA_HASH_SHA3_384 "77bc16f89c102efc783ddeccc71862fe919b66e1aaa88bd" \
"2ba5f0bbe604fcb86c68f0e401d5d553597366cdd400595ba"
#define DATA_HASH_SHA3_512 "31dfb5fc8f30ac7007acddc4fce562d408706833d0d2af2" \
"e5f61a179099592927ff7d100e278406c7f98d42575001e26e153b135c21f7ef5b00c8" \
"cef93ca048d"
#define DATA_HASH_SALT "this is a salt of 32 bytes xxxxx"
#define DATA_HASH_PBKDF2_SHA1_1000 "85ce23c8873830df8f0a96aa82ae7d7635dad12" \
"7"
#define DATA_HASH_PBKDF2_SHA1_100000 "f2c2a079007523df3a5a5c7b578073dff06ba" \
"49f"
#define DATA_HASH_PBKDF2_SHA256_1000 "0eb0a795537a8c37a2d7d7e50a076e07c9a8e" \
"e9aa281669381af99fad198997c"
#define DATA_HASH_PBKDF2_SHA256_100000 "b243ef60f9d9e7a6315f874053802cfb3b7" \
"b5a3502d47cf7fd76b3ee5661fcff"
#define DATA_HASH_PBKDF2_SHA512_1000 "03d8e9e86f3bbe20b88a600a5aa15f8cfbee0" \
"a402af301e1714c25467a32489c773c71eddf5aa39f42823ecc54c9e9b015517b5f3c0" \
"19bae9463a2d8fe527882"
#define DATA_HASH_PBKDF2_SHA512_100000 "286cca5521b00a7398530fbf11a570401a8" \
"0c901f1584cb493fcb75c49e5c30613c331ce318b34615a08be2fdcb9a3b4d3e9a5b62" \
"e119db6941010533cdf73d3"
#define TOTP_SECRET "secretpasswordbase32"
#define WEE_CHECK_HASH(__result_code, __result_hash, \
__data, __data_size, __hash_algo) \
if (__result_hash) \
{ \
hash_size_expected = string_base16_decode (__result_hash, \
hash_expected); \
} \
else \
{ \
hash_size_expected = 0; \
} \
hash_size = -1; \
LONGS_EQUAL(__result_code, \
weecrypto_hash (__data, __data_size, __hash_algo, \
hash, &hash_size)); \
if (__result_hash) \
{ \
MEMCMP_EQUAL(hash_expected, hash, hash_size); \
} \
LONGS_EQUAL(hash_size_expected, hash_size);
#define WEE_CHECK_HASH_PBKDF2(__result_code, __result_hash, \
__data, __data_size, \
__hash_subalgo, __salt, __salt_size, \
__iterations) \
if (__result_hash) \
{ \
hash_size_expected = string_base16_decode (__result_hash, \
hash_expected); \
} \
else \
{ \
hash_size_expected = 0; \
} \
hash_size = -1; \
LONGS_EQUAL(__result_code, \
weecrypto_hash_pbkdf2 (__data, __data_size, \
__hash_subalgo, \
__salt, __salt_size, \
__iterations, \
hash, &hash_size)); \
if (__result_hash) \
{ \
MEMCMP_EQUAL(hash_expected, hash, hash_size); \
} \
LONGS_EQUAL(hash_size_expected, hash_size);
#define WEE_CHECK_TOTP_GENERATE(__result, __secret, __time, __digits) \
totp = weecrypto_totp_generate (__secret, __time, __digits); \
if (__result == NULL) \
{ \
POINTERS_EQUAL(NULL, totp); \
} \
else \
{ \
STRCMP_EQUAL(__result, totp); \
} \
if (totp) \
free (totp);
#define WEE_CHECK_TOTP_VALIDATE(__result, __secret, __time, __window, \
__otp) \
LONGS_EQUAL(__result, weecrypto_totp_validate (__secret, __time, \
__window, __otp));
}
TEST_GROUP(CoreCrypto)
{
};
/*
* Tests functions:
* weecrypto_hash
*/
TEST(CoreCrypto, Hash)
{
const char *data = DATA_HASH;
char hash_expected[4096], hash[4096];
int data_size, hash_size_expected, hash_size;
data_size = strlen (data);
WEE_CHECK_HASH(0, NULL, NULL, 0, 0);
WEE_CHECK_HASH(0, NULL, "test", 0, 0);
WEE_CHECK_HASH(1, DATA_HASH_CRC32, data, data_size, GCRY_MD_CRC32);
WEE_CHECK_HASH(1, DATA_HASH_MD5, data, data_size, GCRY_MD_MD5);
WEE_CHECK_HASH(1, DATA_HASH_SHA1, data, data_size, GCRY_MD_SHA1);
WEE_CHECK_HASH(1, DATA_HASH_SHA224, data, data_size, GCRY_MD_SHA224);
WEE_CHECK_HASH(1, DATA_HASH_SHA256, data, data_size, GCRY_MD_SHA256);
WEE_CHECK_HASH(1, DATA_HASH_SHA384, data, data_size, GCRY_MD_SHA384);
WEE_CHECK_HASH(1, DATA_HASH_SHA512, data, data_size, GCRY_MD_SHA512);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_224, data, data_size, GCRY_MD_SHA3_224);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_256, data, data_size, GCRY_MD_SHA3_256);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_384, data, data_size, GCRY_MD_SHA3_384);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_512, data, data_size, GCRY_MD_SHA3_512);
}
/*
* Tests functions:
* weecrypto_hash_pbkdf2
*/
TEST(CoreCrypto, HashPbkdf2)
{
const char *data = DATA_HASH, *salt = DATA_HASH_SALT;
char hash_expected[4096], hash[4096];
int data_size, salt_size, hash_size_expected, hash_size;
data_size = strlen (data);
salt_size = strlen (salt);
WEE_CHECK_HASH_PBKDF2(0, NULL, NULL, 0, 0, NULL, 0, 0);
WEE_CHECK_HASH_PBKDF2(0, NULL, "test", 0, 0, NULL, 0, 0);
WEE_CHECK_HASH_PBKDF2(0, NULL, "test", 4, GCRY_MD_SHA1, "salt", 4, 0);
/* SHA1 */
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA1_1000,
data, data_size,
GCRY_MD_SHA1,
DATA_HASH_SALT, salt_size,
1000);
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA1_100000,
data, data_size,
GCRY_MD_SHA1,
DATA_HASH_SALT, salt_size,
100000);
/* SHA256 */
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA256_1000,
data, data_size,
GCRY_MD_SHA256,
DATA_HASH_SALT, salt_size,
1000);
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA256_100000,
data, data_size,
GCRY_MD_SHA256,
DATA_HASH_SALT, salt_size,
100000);
/* SHA512 */
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA512_1000,
data, data_size,
GCRY_MD_SHA512,
DATA_HASH_SALT, salt_size,
1000);
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA512_100000,
data, data_size,
GCRY_MD_SHA512,
DATA_HASH_SALT, salt_size,
100000);
}
/*
* Tests functions:
* weecrypto_totp_generate
*/
TEST(CoreCrypto, TotpGenerate)
{
char *totp;
/* invalid secret */
WEE_CHECK_TOTP_GENERATE(NULL, NULL, 0, 6);
WEE_CHECK_TOTP_GENERATE(NULL, "", 0, 6);
WEE_CHECK_TOTP_GENERATE(NULL, "not_in_base32_0189", 0, 6);
/* invalid number of digits (must be between 4 and 10) */
WEE_CHECK_TOTP_GENERATE(NULL, TOTP_SECRET, 0, 3);
WEE_CHECK_TOTP_GENERATE(NULL, TOTP_SECRET, 0, 11);
/* TOTP with 6 digits */
WEE_CHECK_TOTP_GENERATE("065486", TOTP_SECRET, 1540624066, 6);
WEE_CHECK_TOTP_GENERATE("640073", TOTP_SECRET, 1540624085, 6);
WEE_CHECK_TOTP_GENERATE("725645", TOTP_SECRET, 1540624110, 6);
/* TOTP with 7 digits */
WEE_CHECK_TOTP_GENERATE("0065486", TOTP_SECRET, 1540624066, 7);
WEE_CHECK_TOTP_GENERATE("6640073", TOTP_SECRET, 1540624085, 7);
WEE_CHECK_TOTP_GENERATE("4725645", TOTP_SECRET, 1540624110, 7);
/* TOTP with 8 digits */
WEE_CHECK_TOTP_GENERATE("40065486", TOTP_SECRET, 1540624066, 8);
WEE_CHECK_TOTP_GENERATE("16640073", TOTP_SECRET, 1540624085, 8);
WEE_CHECK_TOTP_GENERATE("94725645", TOTP_SECRET, 1540624110, 8);
}
/*
* Tests functions:
* weecrypto_totp_validate
*/
TEST(CoreCrypto, TotpValidate)
{
/* invalid secret */
WEE_CHECK_TOTP_VALIDATE(0, NULL, 0, 0, "123456");
WEE_CHECK_TOTP_VALIDATE(0, "", 0, 0, "123456");
WEE_CHECK_TOTP_VALIDATE(0, "not_in_base32_0189", 0, 0, "123456");
/* invalid window (must be ≥ 0) */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 0, -1, "123456");
/* invalid OTP */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 0, 0, NULL);
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 0, 0, "");
/* validation error (wrong OTP) */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "065486");
/* TOTP with 6 digits */
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624066, 0, "065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624085, 0, "640073");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 0, "725645");
/* TOTP with 7 digits */
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624066, 0, "0065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624085, 0, "6640073");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 0, "4725645");
/* TOTP with 7 digits */
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624066, 0, "40065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624085, 0, "16640073");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 0, "94725645");
/* TOTP with 6 digits, using window */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 2, "065486");
/* TOTP with 7 digits, using window */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "0065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "0065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 2, "0065486");
/* TOTP with 8 digits, using window */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "40065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "40065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 2, "40065486");
}

View File

@ -25,7 +25,6 @@ extern "C"
{
#include <string.h>
#include <gcrypt.h>
#include "tests/unit/core/test-core.h"
#include "src/core/wee-secure.h"
#include "src/core/wee-string.h"
@ -33,71 +32,6 @@ extern "C"
#define SECURE_PASSWORD "this_is_a_secret_password"
#define TOTP_SECRET "secretpasswordbase32"
#define WEE_CHECK_HASH(__result_code, __result_hash, \
__data, __data_size, __hash_algo) \
if (__result_hash) \
{ \
hash_size_expected = string_base16_decode (__result_hash, \
hash_expected); \
} \
else \
{ \
hash_size_expected = 0; \
} \
hash_size = -1; \
LONGS_EQUAL(__result_code, \
secure_hash (__data, __data_size, __hash_algo, \
hash, &hash_size)); \
if (__result_hash) \
{ \
MEMCMP_EQUAL(hash_expected, hash, hash_size); \
} \
LONGS_EQUAL(hash_size_expected, hash_size);
#define WEE_CHECK_HASH_PBKDF2(__result_code, __result_hash, \
__data, __data_size, \
__hash_subalgo, __salt, __salt_size, \
__iterations) \
if (__result_hash) \
{ \
hash_size_expected = string_base16_decode (__result_hash, \
hash_expected); \
} \
else \
{ \
hash_size_expected = 0; \
} \
hash_size = -1; \
LONGS_EQUAL(__result_code, \
secure_hash_pbkdf2 (__data, __data_size, \
__hash_subalgo, \
__salt, __salt_size, \
__iterations, \
hash, &hash_size)); \
if (__result_hash) \
{ \
MEMCMP_EQUAL(hash_expected, hash, hash_size); \
} \
LONGS_EQUAL(hash_size_expected, hash_size);
#define WEE_CHECK_TOTP_GENERATE(__result, __secret, __time, __digits) \
totp = secure_totp_generate (__secret, __time, __digits); \
if (__result == NULL) \
{ \
POINTERS_EQUAL(NULL, totp); \
} \
else \
{ \
STRCMP_EQUAL(__result, totp); \
} \
if (totp) \
free (totp);
#define WEE_CHECK_TOTP_VALIDATE(__result, __secret, __time, __window, \
__otp) \
LONGS_EQUAL(__result, secure_totp_validate (__secret, __time, \
__window, __otp));
extern int secure_derive_key (const char *salt, const char *passphrase,
unsigned char *key, int length_key);
}
@ -106,90 +40,6 @@ TEST_GROUP(CoreSecure)
{
};
/*
* Tests functions:
* secure_hash
*/
TEST(CoreSecure, Hash)
{
const char *data = DATA_HASH;
char hash_expected[4096], hash[4096];
int data_size, hash_size_expected, hash_size;
data_size = strlen (data);
WEE_CHECK_HASH(0, NULL, NULL, 0, 0);
WEE_CHECK_HASH(0, NULL, "test", 0, 0);
WEE_CHECK_HASH(1, DATA_HASH_CRC32, data, data_size, GCRY_MD_CRC32);
WEE_CHECK_HASH(1, DATA_HASH_MD5, data, data_size, GCRY_MD_MD5);
WEE_CHECK_HASH(1, DATA_HASH_SHA1, data, data_size, GCRY_MD_SHA1);
WEE_CHECK_HASH(1, DATA_HASH_SHA224, data, data_size, GCRY_MD_SHA224);
WEE_CHECK_HASH(1, DATA_HASH_SHA256, data, data_size, GCRY_MD_SHA256);
WEE_CHECK_HASH(1, DATA_HASH_SHA384, data, data_size, GCRY_MD_SHA384);
WEE_CHECK_HASH(1, DATA_HASH_SHA512, data, data_size, GCRY_MD_SHA512);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_224, data, data_size, GCRY_MD_SHA3_224);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_256, data, data_size, GCRY_MD_SHA3_256);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_384, data, data_size, GCRY_MD_SHA3_384);
WEE_CHECK_HASH(1, DATA_HASH_SHA3_512, data, data_size, GCRY_MD_SHA3_512);
}
/*
* Tests functions:
* secure_hash_pbkdf2
*/
TEST(CoreSecure, HashPbkdf2)
{
const char *data = DATA_HASH, *salt = DATA_HASH_SALT;
char hash_expected[4096], hash[4096];
int data_size, salt_size, hash_size_expected, hash_size;
data_size = strlen (data);
salt_size = strlen (salt);
WEE_CHECK_HASH_PBKDF2(0, NULL, NULL, 0, 0, NULL, 0, 0);
WEE_CHECK_HASH_PBKDF2(0, NULL, "test", 0, 0, NULL, 0, 0);
WEE_CHECK_HASH_PBKDF2(0, NULL, "test", 4, GCRY_MD_SHA1, "salt", 4, 0);
/* SHA1 */
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA1_1000,
data, data_size,
GCRY_MD_SHA1,
DATA_HASH_SALT, salt_size,
1000);
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA1_100000,
data, data_size,
GCRY_MD_SHA1,
DATA_HASH_SALT, salt_size,
100000);
/* SHA256 */
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA256_1000,
data, data_size,
GCRY_MD_SHA256,
DATA_HASH_SALT, salt_size,
1000);
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA256_100000,
data, data_size,
GCRY_MD_SHA256,
DATA_HASH_SALT, salt_size,
100000);
/* SHA512 */
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA512_1000,
data, data_size,
GCRY_MD_SHA512,
DATA_HASH_SALT, salt_size,
1000);
WEE_CHECK_HASH_PBKDF2(1, DATA_HASH_PBKDF2_SHA512_100000,
data, data_size,
GCRY_MD_SHA512,
DATA_HASH_SALT, salt_size,
100000);
}
/*
* Tests functions:
* secure_derive_key
@ -288,91 +138,3 @@ TEST(CoreSecure, EncryptDecryptData)
}
}
}
/*
* Tests functions:
* secure_totp_generate
*/
TEST(CoreSecure, TotpGenerate)
{
char *totp;
/* invalid secret */
WEE_CHECK_TOTP_GENERATE(NULL, NULL, 0, 6);
WEE_CHECK_TOTP_GENERATE(NULL, "", 0, 6);
WEE_CHECK_TOTP_GENERATE(NULL, "not_in_base32_0189", 0, 6);
/* invalid number of digits (must be between 4 and 10) */
WEE_CHECK_TOTP_GENERATE(NULL, TOTP_SECRET, 0, 3);
WEE_CHECK_TOTP_GENERATE(NULL, TOTP_SECRET, 0, 11);
/* TOTP with 6 digits */
WEE_CHECK_TOTP_GENERATE("065486", TOTP_SECRET, 1540624066, 6);
WEE_CHECK_TOTP_GENERATE("640073", TOTP_SECRET, 1540624085, 6);
WEE_CHECK_TOTP_GENERATE("725645", TOTP_SECRET, 1540624110, 6);
/* TOTP with 7 digits */
WEE_CHECK_TOTP_GENERATE("0065486", TOTP_SECRET, 1540624066, 7);
WEE_CHECK_TOTP_GENERATE("6640073", TOTP_SECRET, 1540624085, 7);
WEE_CHECK_TOTP_GENERATE("4725645", TOTP_SECRET, 1540624110, 7);
/* TOTP with 8 digits */
WEE_CHECK_TOTP_GENERATE("40065486", TOTP_SECRET, 1540624066, 8);
WEE_CHECK_TOTP_GENERATE("16640073", TOTP_SECRET, 1540624085, 8);
WEE_CHECK_TOTP_GENERATE("94725645", TOTP_SECRET, 1540624110, 8);
}
/*
* Tests functions:
* secure_totp_validate
*/
TEST(CoreSecure, TotpValidate)
{
/* invalid secret */
WEE_CHECK_TOTP_VALIDATE(0, NULL, 0, 0, "123456");
WEE_CHECK_TOTP_VALIDATE(0, "", 0, 0, "123456");
WEE_CHECK_TOTP_VALIDATE(0, "not_in_base32_0189", 0, 0, "123456");
/* invalid window (must be ≥ 0) */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 0, -1, "123456");
/* invalid OTP */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 0, 0, NULL);
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 0, 0, "");
/* validation error (wrong OTP) */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "065486");
/* TOTP with 6 digits */
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624066, 0, "065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624085, 0, "640073");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 0, "725645");
/* TOTP with 7 digits */
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624066, 0, "0065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624085, 0, "6640073");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 0, "4725645");
/* TOTP with 7 digits */
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624066, 0, "40065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624085, 0, "16640073");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 0, "94725645");
/* TOTP with 6 digits, using window */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 2, "065486");
/* TOTP with 7 digits, using window */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "0065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "0065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 2, "0065486");
/* TOTP with 8 digits, using window */
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 0, "40065486");
WEE_CHECK_TOTP_VALIDATE(0, TOTP_SECRET, 1540624110, 1, "40065486");
WEE_CHECK_TOTP_VALIDATE(1, TOTP_SECRET, 1540624110, 2, "40065486");
}

View File

@ -32,7 +32,6 @@ extern "C"
#include <string.h>
#include <regex.h>
#include "tests/tests.h"
#include "tests/unit/core/test-core.h"
#include "src/core/weechat.h"
#include "src/core/wee-string.h"
#include "src/core/wee-hashtable.h"
@ -108,27 +107,6 @@ extern "C"
STRCMP_EQUAL(__result, str); \
free (str);
#define WEE_CHECK_HASH(__result_code, __result_hash, \
__data, __data_size, __hash_algo) \
if (__result_hash) \
{ \
hash_size_expected = string_base16_decode (__result_hash, \
hash_expected); \
} \
else \
{ \
hash_size_expected = 0; \
} \
hash_size = -1; \
LONGS_EQUAL(__result_code, \
string_hash (__data, __data_size, __hash_algo, \
hash, &hash_size)); \
if (__result_hash) \
{ \
MEMCMP_EQUAL(hash_expected, hash, hash_size); \
} \
LONGS_EQUAL(hash_size_expected, hash_size);
extern struct t_hashtable *string_hashtable_shared;
TEST_GROUP(CoreString)
@ -1932,37 +1910,6 @@ TEST(CoreString, Hex_dump)
str);
}
/*
* Tests functions:
* string_hash
*/
TEST(CoreString, Hash)
{
const char *data = DATA_HASH;
char hash_expected[4096], hash[4096];
int data_size, hash_size_expected, hash_size;
data_size = strlen (data);
WEE_CHECK_HASH(0, NULL, NULL, 0, NULL);
WEE_CHECK_HASH(0, NULL, DATA_HASH, 0, NULL);
WEE_CHECK_HASH(0, NULL, DATA_HASH, data_size, NULL);
WEE_CHECK_HASH(0, NULL, DATA_HASH, data_size, "not_an_algo");
WEE_CHECK_HASH(1, DATA_HASH_CRC32, data, data_size, "crc32");
WEE_CHECK_HASH(1, DATA_HASH_MD5, data, data_size, "md5");
WEE_CHECK_HASH(1, DATA_HASH_SHA1, data, data_size, "sha1");
WEE_CHECK_HASH(1, DATA_HASH_SHA224, data, data_size, "sha224");
WEE_CHECK_HASH(1, DATA_HASH_SHA256, data, data_size, "sha256");
WEE_CHECK_HASH(1, DATA_HASH_SHA384, data, data_size, "sha384");
WEE_CHECK_HASH(1, DATA_HASH_SHA512, data, data_size, "sha512");
WEE_CHECK_HASH(1, DATA_HASH_SHA3_224, data, data_size, "sha3-224");
WEE_CHECK_HASH(1, DATA_HASH_SHA3_256, data, data_size, "sha3-256");
WEE_CHECK_HASH(1, DATA_HASH_SHA3_384, data, data_size, "sha3-384");
WEE_CHECK_HASH(1, DATA_HASH_SHA3_512, data, data_size, "sha3-512");
}
/*
* Tests functions:
* string_is_command_char

View File

@ -1,61 +0,0 @@
/*
* Copyright (C) 2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* WeeChat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_TEST_UNIT_CORE_H
#define WEECHAT_TEST_UNIT_CORE_H
#define DATA_HASH "this is a test of hash function"
#define DATA_HASH_CRC32 "ef26fe3e"
#define DATA_HASH_MD5 "1197d121af621ac6a63cb8ef6b5dfa30"
#define DATA_HASH_SHA1 "799d818061175b400dc5aaeb14b8d32cdef32ff0"
#define DATA_HASH_SHA224 "637d21f3ba3f4e9fa9fb889dc990b31a658cb37b4aefb5144" \
"70b016d"
#define DATA_HASH_SHA256 "b9a4c3393dfac4330736684510378851e581c68add8eca841" \
"10c31a33e694676"
#define DATA_HASH_SHA384 "42853280be9b8409eed265f272bd580e2fbd448b7c7e236c7" \
"f37dafec7906d51d982dc84ec70a4733eca49d86ac19455"
#define DATA_HASH_SHA512 "4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe0" \
"58255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a" \
"1e6b8ae6e"
#define DATA_HASH_SHA3_224 "26432a3a4ea998790be43386b1de417f88be43146a4af98" \
"2a9627d10"
#define DATA_HASH_SHA3_256 "226e3830306711cf653c1661765c304b37038e7457c35dd" \
"14fca0f6a8ba1d2e3"
#define DATA_HASH_SHA3_384 "77bc16f89c102efc783ddeccc71862fe919b66e1aaa88bd" \
"2ba5f0bbe604fcb86c68f0e401d5d553597366cdd400595ba"
#define DATA_HASH_SHA3_512 "31dfb5fc8f30ac7007acddc4fce562d408706833d0d2af2" \
"e5f61a179099592927ff7d100e278406c7f98d42575001e26e153b135c21f7ef5b00c8" \
"cef93ca048d"
#define DATA_HASH_SALT "this is a salt of 32 bytes xxxxx"
#define DATA_HASH_PBKDF2_SHA1_1000 "85ce23c8873830df8f0a96aa82ae7d7635dad12" \
"7"
#define DATA_HASH_PBKDF2_SHA1_100000 "f2c2a079007523df3a5a5c7b578073dff06ba" \
"49f"
#define DATA_HASH_PBKDF2_SHA256_1000 "0eb0a795537a8c37a2d7d7e50a076e07c9a8e" \
"e9aa281669381af99fad198997c"
#define DATA_HASH_PBKDF2_SHA256_100000 "b243ef60f9d9e7a6315f874053802cfb3b7" \
"b5a3502d47cf7fd76b3ee5661fcff"
#define DATA_HASH_PBKDF2_SHA512_1000 "03d8e9e86f3bbe20b88a600a5aa15f8cfbee0" \
"a402af301e1714c25467a32489c773c71eddf5aa39f42823ecc54c9e9b015517b5f3c0" \
"19bae9463a2d8fe527882"
#define DATA_HASH_PBKDF2_SHA512_100000 "286cca5521b00a7398530fbf11a570401a8" \
"0c901f1584cb493fcb75c49e5c30613c331ce318b34615a08be2fdcb9a3b4d3e9a5b62" \
"e119db6941010533cdf73d3"
#endif /* WEECHAT_TEST_UNIT_CORE_H */