mirror of
https://github.com/weechat/weechat.git
synced 2026-07-01 15:26:37 +02:00
core: add algorithms sha512-224, sha512-256, sha3-*, blake2b-* and blake2s-*` in option sec.crypt.hash_algo (closes #2008)
This commit is contained in:
+28
-8
@@ -6109,7 +6109,7 @@ COMMAND_CALLBACK(save)
|
||||
|
||||
COMMAND_CALLBACK(secure)
|
||||
{
|
||||
int passphrase_was_set, count_encrypted;
|
||||
int passphrase_was_set, count_encrypted, rc;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
@@ -6140,7 +6140,33 @@ COMMAND_CALLBACK(secure)
|
||||
gui_chat_printf (NULL, _("All encrypted data has been deleted"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
if (secure_decrypt_data_not_decrypted (argv_eol[2]) > 0)
|
||||
rc = secure_decrypt_data_not_decrypted (argv_eol[2]);
|
||||
if (rc == -2)
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("%sFailed to decrypt data: hash algorithm \"%s\" is not "
|
||||
"available (ligbcrypt version is too old?)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
config_file_option_string (secure_config_crypt_hash_algo));
|
||||
}
|
||||
else if (rc == -3)
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("%sFailed to decrypt data: cipher \"%s\" is not "
|
||||
"available (ligbcrypt version is too old?)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
config_file_option_string (secure_config_crypt_cipher));
|
||||
}
|
||||
else if ((rc == -1) || (rc == 0))
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sFailed to decrypt data: wrong passphrase?"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("Encrypted data has been successfully decrypted"));
|
||||
@@ -6148,12 +6174,6 @@ COMMAND_CALLBACK(secure)
|
||||
free (secure_passphrase);
|
||||
secure_passphrase = strdup (argv_eol[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sFailed to decrypt data (wrong passphrase?)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
|
||||
}
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,18 @@ int weecrypto_hash_algo[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
char *weecrypto_cipher_string[] = {
|
||||
"aes128",
|
||||
"aes192",
|
||||
"aes256",
|
||||
NULL,
|
||||
};
|
||||
int weecrypto_cipher[] = {
|
||||
GCRY_CIPHER_AES128,
|
||||
GCRY_CIPHER_AES192,
|
||||
GCRY_CIPHER_AES256,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns the hash algorithm with the name, or GCRY_MD_NONE if not found.
|
||||
@@ -120,6 +132,27 @@ weecrypto_get_hash_algo (const char *hash_algo)
|
||||
return GCRY_MD_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the cipher with the name, or GCRY_CIPHER_NONE if not found.
|
||||
*/
|
||||
|
||||
int
|
||||
weecrypto_get_cipher (const char *cipher)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!cipher)
|
||||
return GCRY_CIPHER_NONE;
|
||||
|
||||
for (i = 0; weecrypto_cipher_string[i]; i++)
|
||||
{
|
||||
if (strcmp (weecrypto_cipher_string[i], cipher) == 0)
|
||||
return weecrypto_cipher[i];
|
||||
}
|
||||
|
||||
return GCRY_CIPHER_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes hash of data using the given hash algorithm.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define WEECRYPTO_TOTP_MAX_DIGITS 10
|
||||
|
||||
extern int weecrypto_get_hash_algo (const char *hash_algo);
|
||||
extern int weecrypto_get_cipher (const char *cipher);
|
||||
extern int weecrypto_hash (const void *data, int data_size, int hash_algo,
|
||||
void *hash, int *hash_size);
|
||||
extern int weecrypto_hash_file (const char *filename, int hash_algo,
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.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-buffer.h"
|
||||
@@ -85,7 +87,8 @@ secure_buffer_display_data (void *data,
|
||||
void
|
||||
secure_buffer_display ()
|
||||
{
|
||||
int line, count, count_encrypted;
|
||||
int line, count, count_encrypted, hash_algo;
|
||||
char str_supported[1024];
|
||||
|
||||
if (!secure_buffer)
|
||||
return;
|
||||
@@ -99,10 +102,22 @@ secure_buffer_display ()
|
||||
|
||||
line = 0;
|
||||
|
||||
str_supported[0] = '\0';
|
||||
hash_algo = weecrypto_get_hash_algo (
|
||||
config_file_option_string (secure_config_crypt_hash_algo));
|
||||
if (hash_algo == GCRY_MD_NONE)
|
||||
{
|
||||
snprintf (str_supported, sizeof (str_supported),
|
||||
" (%s)",
|
||||
/* TRANSLATORS: "hash algorithm not supported" */
|
||||
_("not supported"));
|
||||
}
|
||||
|
||||
gui_chat_printf_y (secure_buffer, line++,
|
||||
"Hash algo: %s Cipher: %s Salt: %s",
|
||||
secure_hash_algo_string[CONFIG_ENUM(secure_config_crypt_hash_algo)],
|
||||
secure_cipher_string[CONFIG_ENUM(secure_config_crypt_cipher)],
|
||||
"Hash algo: %s%s Cipher: %s Salt: %s",
|
||||
config_file_option_string (secure_config_crypt_hash_algo),
|
||||
str_supported,
|
||||
config_file_option_string (secure_config_crypt_cipher),
|
||||
(CONFIG_BOOLEAN(secure_config_crypt_salt)) ? _("on") : _("off"));
|
||||
|
||||
/* display passphrase */
|
||||
|
||||
+126
-12
@@ -26,9 +26,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.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"
|
||||
@@ -48,6 +50,8 @@ struct t_config_option *secure_config_crypt_hash_algo = NULL;
|
||||
struct t_config_option *secure_config_crypt_passphrase_command = NULL;
|
||||
struct t_config_option *secure_config_crypt_salt = NULL;
|
||||
|
||||
int secure_config_loading = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Gets passphrase from user and puts it in variable "secure_passphrase".
|
||||
@@ -172,6 +176,39 @@ secure_config_reload_cb (const void *pointer, void *data,
|
||||
return config_file_reload (config_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for changes on some options "weechat.crypt.*" (that can not be
|
||||
* changed if there are encrypted data.
|
||||
*/
|
||||
|
||||
int
|
||||
secure_config_check_crypt_option_cb (const void *pointer, void *data,
|
||||
struct t_config_option *option,
|
||||
const char *value)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) value;
|
||||
|
||||
/* any value allowed while reading config */
|
||||
if (secure_config_loading)
|
||||
return 1;
|
||||
|
||||
/* no encrypted data => changes allowed */
|
||||
if (secure_hashtable_data_encrypted->items_count == 0)
|
||||
return 1;
|
||||
|
||||
gui_chat_printf (NULL,
|
||||
_("%sOption %s.%s.%s can not be changed because there "
|
||||
"are still encrypted data"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
option->config_file->name,
|
||||
option->section->name,
|
||||
option->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads a data option in secured data configuration file.
|
||||
*/
|
||||
@@ -183,7 +220,7 @@ secure_config_data_read_cb (const void *pointer, void *data,
|
||||
const char *option_name, const char *value)
|
||||
{
|
||||
char *buffer, *decrypted, str_error[1024];
|
||||
int length_buffer, length_decrypted, rc;
|
||||
int length_buffer, length_decrypted, rc, hash_algo, cipher;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
@@ -237,6 +274,38 @@ secure_config_data_read_cb (const void *pointer, void *data,
|
||||
return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
|
||||
}
|
||||
|
||||
/* get hash algorithm */
|
||||
hash_algo = weecrypto_get_hash_algo (
|
||||
config_file_option_string (secure_config_crypt_hash_algo));
|
||||
if (hash_algo == GCRY_MD_NONE)
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("%sFailed to decrypt data \"%s\": hash algorithm \"%s\" is not "
|
||||
"available (ligbcrypt version is too old?)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
option_name,
|
||||
config_file_option_string (secure_config_crypt_hash_algo));
|
||||
hashtable_set (secure_hashtable_data_encrypted, option_name, value);
|
||||
return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
|
||||
}
|
||||
|
||||
/* get cipher */
|
||||
cipher = weecrypto_get_cipher (
|
||||
config_file_option_string (secure_config_crypt_cipher));
|
||||
if (cipher == GCRY_CIPHER_NONE)
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("%sFailed to decrypt data \"%s\": cipher \"%s\" is not "
|
||||
"available (ligbcrypt version is too old?)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
option_name,
|
||||
config_file_option_string (secure_config_crypt_cipher));
|
||||
hashtable_set (secure_hashtable_data_encrypted, option_name, value);
|
||||
return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
|
||||
}
|
||||
|
||||
/* decrypt data */
|
||||
buffer = malloc (strlen (value) + 1);
|
||||
if (!buffer)
|
||||
@@ -250,8 +319,8 @@ secure_config_data_read_cb (const void *pointer, void *data,
|
||||
rc = secure_decrypt_data (
|
||||
buffer,
|
||||
length_buffer,
|
||||
secure_hash_algo[CONFIG_ENUM(secure_config_crypt_hash_algo)],
|
||||
secure_cipher[CONFIG_ENUM(secure_config_crypt_cipher)],
|
||||
hash_algo,
|
||||
cipher,
|
||||
secure_passphrase,
|
||||
&decrypted,
|
||||
&length_decrypted);
|
||||
@@ -311,13 +380,41 @@ secure_config_data_write_map_cb (void *data,
|
||||
{
|
||||
struct t_config_file *config_file;
|
||||
char *buffer, *buffer_base16;
|
||||
int length_buffer, rc;
|
||||
int length_buffer, rc, hash_algo, cipher;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) hashtable;
|
||||
|
||||
config_file = (struct t_config_file *)data;
|
||||
|
||||
hash_algo = weecrypto_get_hash_algo (
|
||||
config_file_option_string (secure_config_crypt_hash_algo));
|
||||
if (hash_algo == GCRY_MD_NONE)
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("%sFailed to encrypt data \"%s\": hash algorithm \"%s\" is not "
|
||||
"available (ligbcrypt version is too old?)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
key,
|
||||
config_file_option_string (secure_config_crypt_hash_algo));
|
||||
return;
|
||||
}
|
||||
|
||||
cipher = weecrypto_get_cipher (
|
||||
config_file_option_string (secure_config_crypt_cipher));
|
||||
if (cipher == GCRY_CIPHER_NONE)
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("%sFailed to encrypt data \"%s\": cipher \"%s\" is not "
|
||||
"available (ligbcrypt version is too old?)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
key,
|
||||
config_file_option_string (secure_config_crypt_cipher));
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = NULL;
|
||||
length_buffer = 0;
|
||||
|
||||
@@ -326,8 +423,8 @@ secure_config_data_write_map_cb (void *data,
|
||||
/* encrypt password using passphrase */
|
||||
rc = secure_encrypt_data (
|
||||
value, strlen (value) + 1,
|
||||
secure_hash_algo[CONFIG_ENUM(secure_config_crypt_hash_algo)],
|
||||
secure_cipher[CONFIG_ENUM(secure_config_crypt_cipher)],
|
||||
hash_algo,
|
||||
cipher,
|
||||
secure_passphrase,
|
||||
&buffer,
|
||||
&length_buffer);
|
||||
@@ -352,7 +449,7 @@ secure_config_data_write_map_cb (void *data,
|
||||
else
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sError encrypting data \"%s\" (%d)"),
|
||||
_("%sFailed to encrypt data \"%s\" (%d)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
key, rc);
|
||||
}
|
||||
@@ -469,13 +566,26 @@ secure_config_init_options ()
|
||||
N_("cipher used to crypt data (the number after algorithm is the "
|
||||
"size of the key in bits)"),
|
||||
"aes128|aes192|aes256", 0, 0, "aes256", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
&secure_config_check_crypt_option_cb, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
secure_config_crypt_hash_algo = config_file_new_option (
|
||||
secure_config_file, secure_config_section_crypt,
|
||||
"hash_algo", "enum",
|
||||
N_("hash algorithm used to check the decrypted data"),
|
||||
"sha224|sha256|sha384|sha512", 0, 0, "sha256", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
N_("hash algorithm used to check the decrypted data; "
|
||||
"some of them require a specific libgcrypt version: "
|
||||
"sha3-*: libgcrypt >= 1.7.0, "
|
||||
"blake2*: libgcrypt >= 1.8.0, "
|
||||
"sha512-*: libgcrypt >= 1.9.4"),
|
||||
"sha224|sha256|sha384|sha512"
|
||||
"|sha512-224|sha512-256"
|
||||
"|sha3-224|sha3-256|sha3-384|sha3-512"
|
||||
"|blake2b-160|blake2b-256|blake2b-384|blake2b-512"
|
||||
"|blake2s-128|blake2s-160|blake2s-224|blake2s-256",
|
||||
0, 0, "sha256", NULL, 0,
|
||||
&secure_config_check_crypt_option_cb, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
secure_config_crypt_passphrase_command = config_file_new_option (
|
||||
secure_config_file, secure_config_section_crypt,
|
||||
"passphrase_command", "string",
|
||||
@@ -500,7 +610,9 @@ secure_config_init_options ()
|
||||
"then you can turn off this option to have always same content "
|
||||
"in file"),
|
||||
NULL, 0, 0, "on", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
&secure_config_check_crypt_option_cb, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* data */
|
||||
@@ -532,7 +644,9 @@ secure_config_read ()
|
||||
|
||||
secure_data_encrypted = 0;
|
||||
|
||||
secure_config_loading = 1;
|
||||
rc = config_file_read (secure_config_file);
|
||||
secure_config_loading = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
+19
-17
@@ -46,17 +46,6 @@ struct t_hashtable *secure_hashtable_data = NULL;
|
||||
/* data still encrypted (if passphrase not set) */
|
||||
struct t_hashtable *secure_hashtable_data_encrypted = NULL;
|
||||
|
||||
/* hash algorithms */
|
||||
char *secure_hash_algo_string[] = { "sha224", "sha256", "sha384", "sha512",
|
||||
NULL };
|
||||
int secure_hash_algo[] = { GCRY_MD_SHA224, GCRY_MD_SHA256, GCRY_MD_SHA384,
|
||||
GCRY_MD_SHA512 };
|
||||
|
||||
/* ciphers */
|
||||
char *secure_cipher_string[] = { "aes128", "aes192", "aes256", NULL };
|
||||
int secure_cipher[] = { GCRY_CIPHER_AES128, GCRY_CIPHER_AES192,
|
||||
GCRY_CIPHER_AES256 };
|
||||
|
||||
char *secure_decrypt_error[] = { "memory", "buffer", "key", "cipher", "setkey",
|
||||
"decrypt", "hash", "hash mismatch" };
|
||||
|
||||
@@ -427,8 +416,10 @@ decrypt_end:
|
||||
* secured data configuration file (because no passphrase was given).
|
||||
*
|
||||
* Returns:
|
||||
* > 0: number of decrypted data
|
||||
* 0: error decrypting data
|
||||
* >= 0: number of decrypted data
|
||||
* -1: error decrypting data (bad passphrase)
|
||||
* -2: unsupported hash algorithm
|
||||
* -3: unsupported cipher
|
||||
*/
|
||||
|
||||
int
|
||||
@@ -436,11 +427,22 @@ secure_decrypt_data_not_decrypted (const char *passphrase)
|
||||
{
|
||||
char **keys, *buffer, *decrypted;
|
||||
const char *value;
|
||||
int num_ok, num_keys, i, length_buffer, length_decrypted, rc;
|
||||
int num_ok, num_keys, i, hash_algo, cipher, rc;
|
||||
int length_buffer, length_decrypted;
|
||||
|
||||
/* we need a passphrase to decrypt data! */
|
||||
if (!passphrase || !passphrase[0])
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
hash_algo = weecrypto_get_hash_algo (
|
||||
config_file_option_string (secure_config_crypt_hash_algo));
|
||||
if (hash_algo == GCRY_MD_NONE)
|
||||
return -2;
|
||||
|
||||
cipher = weecrypto_get_cipher (
|
||||
config_file_option_string (secure_config_crypt_cipher));
|
||||
if (cipher == GCRY_CIPHER_NONE)
|
||||
return -3;
|
||||
|
||||
num_ok = 0;
|
||||
|
||||
@@ -469,8 +471,8 @@ secure_decrypt_data_not_decrypted (const char *passphrase)
|
||||
rc = secure_decrypt_data (
|
||||
buffer,
|
||||
length_buffer,
|
||||
secure_hash_algo[CONFIG_ENUM(secure_config_crypt_hash_algo)],
|
||||
secure_cipher[CONFIG_ENUM(secure_config_crypt_cipher)],
|
||||
hash_algo,
|
||||
cipher,
|
||||
passphrase,
|
||||
&decrypted,
|
||||
&length_decrypted);
|
||||
|
||||
@@ -28,28 +28,9 @@
|
||||
#define SECURE_DATA_PASSPHRASE_FLAG "__passphrase__"
|
||||
#define SECURE_SALT_SIZE 8
|
||||
|
||||
enum t_secure_config_hash_algo
|
||||
{
|
||||
SECURE_CONFIG_HASH_SHA224 = 0,
|
||||
SECURE_CONFIG_HASH_SHA256,
|
||||
SECURE_CONFIG_HASH_SHA384,
|
||||
SECURE_CONFIG_HASH_SHA512,
|
||||
};
|
||||
|
||||
enum t_secure_config_cipher
|
||||
{
|
||||
SECURE_CONFIG_CIPHER_AES128 = 0,
|
||||
SECURE_CONFIG_CIPHER_AES192,
|
||||
SECURE_CONFIG_CIPHER_AES256,
|
||||
};
|
||||
|
||||
extern char *secure_passphrase;
|
||||
extern struct t_hashtable *secure_hashtable_data;
|
||||
extern struct t_hashtable *secure_hashtable_data_encrypted;
|
||||
extern char *secure_hash_algo_string[];
|
||||
extern int secure_hash_algo[];
|
||||
extern char *secure_cipher_string[];
|
||||
extern int secure_cipher[];
|
||||
extern int secure_data_encrypted;
|
||||
extern char *secure_decrypt_error[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user