1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-26 12:56:37 +02:00

core: merge functions string_hash_binary and string_hash into a single function string_hash

This commit is contained in:
Sébastien Helleu
2020-03-01 16:41:28 +01:00
parent 1ae2591458
commit c4ef3d6c2e
15 changed files with 305 additions and 675 deletions
+73 -94
View File
@@ -66,150 +66,131 @@ int secure_data_encrypted = 0;
/*
* Computes hash of data, as binary buffer.
* Computes hash of data using the given algorithm.
*
* Note: "*hash" must be freed after use.
* 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.
*/
void
secure_hash_binary (const char *data, int length_data, int hash_algo,
char **hash, int *length_hash)
int
secure_hash (const void *data, int data_size, int hash_algo,
void *hash, int *hash_size)
{
gcry_md_hd_t *hd_md;
int hd_md_opened;
int rc, hd_md_opened, algo_size;
unsigned char *ptr_hash;
if (!hash || !length_hash)
return;
rc = 0;
hd_md = NULL;
hd_md_opened = 0;
*hash = NULL;
*length_hash = 0;
if (!data || (length_data < 1))
goto hash_binary_end;
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_binary_end;
goto hash_end;
if (gcry_md_open (hd_md, hash_algo, 0) != 0)
goto hash_binary_end;
goto hash_end;
hd_md_opened = 1;
gcry_md_write (*hd_md, data, length_data);
gcry_md_write (*hd_md, data, data_size);
ptr_hash = gcry_md_read (*hd_md, hash_algo);
if (!ptr_hash)
goto hash_binary_end;
goto hash_end;
*length_hash = gcry_md_get_algo_dlen (hash_algo);
*hash = malloc (*length_hash);
if (!*hash)
{
*length_hash = 0;
goto hash_binary_end;
}
memcpy (*hash, ptr_hash, *length_hash);
algo_size = gcry_md_get_algo_dlen (hash_algo);
memcpy (hash, ptr_hash, algo_size);
if (hash_size)
*hash_size = algo_size;
hash_binary_end:
rc = 1;
hash_end:
if (hd_md)
{
if (hd_md_opened)
gcry_md_close (*hd_md);
free (hd_md);
}
}
/*
* Computes hash of data, as text (string with hexadecimal).
*
* Returns a string with the hash as hexadecimal, NULL if error.
*
* Note: result must be freed after use.
*/
char *
secure_hash (const char *data, int length_data, int hash_algo)
{
char *hash, *result;
int length_hash, i;
const char *hexa = "0123456789abcdef";
hash = NULL;
length_hash = 0;
result = NULL;
secure_hash_binary (data, length_data, hash_algo, &hash, &length_hash);
if (!hash || (length_hash < 1))
goto hash_end;
result = malloc (((length_hash) * 2) + 1);
if (!result)
goto hash_end;
for (i = 0; i < length_hash; i++)
{
result[i * 2] = hexa[(hash[i] & 0xFF) / 16];
result[(i * 2) + 1] = hexa[(hash[i] & 0xFF) % 16];
}
result[(length_hash * 2)] = '\0';
hash_end:
if (hash)
free (hash);
return result;
return rc;
}
/*
* Computes PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2)
* hash of data, as binary buffer.
*
* Returns 1 if OK, 0 if error.
* The hash size depends on the algorithm, common ones are:
*
* Note: if OK, "*hash" must be freed after use.
* 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 char *data, int length_data, int hash_subalgo,
const char *salt, int length_salt, int iterations,
char **hash, int *length_hash)
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;
int rc, algo_size;
rc = 0;
if (!hash || !length_hash)
if (!hash)
goto hash_pbkdf2_end;
*hash = NULL;
*length_hash = 0;
if (hash_size)
*hash_size = 0;
if (!data || (length_data < 1) || !salt || (length_salt < 1)
if (!data || (data_size < 1) || !salt || (salt_size < 1)
|| (iterations < 1))
{
goto hash_pbkdf2_end;
}
*length_hash = gcry_md_get_algo_dlen (hash_subalgo);
*hash = malloc (*length_hash);
if (!*hash)
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)
{
*length_hash = 0;
goto hash_pbkdf2_end;
}
if (gcry_kdf_derive (data, length_data, GCRY_KDF_PBKDF2, hash_subalgo,
salt, length_salt, iterations,
*length_hash, *hash) != 0)
{
free (*hash);
*hash = NULL;
*length_hash = 0;
goto hash_pbkdf2_end;
}
if (hash_size)
*hash_size = algo_size;
rc = 1;
@@ -229,7 +210,7 @@ int
secure_derive_key (const char *salt, const char *passphrase,
unsigned char *key, int length_key)
{
char *buffer, *hash;
char *buffer, hash[512 / 8];
int length, length_hash;
if (!salt || !passphrase || !key || (length_key < 1))
@@ -247,8 +228,7 @@ secure_derive_key (const char *salt, const char *passphrase,
memcpy (buffer + SECURE_SALT_SIZE, passphrase, strlen (passphrase));
/* compute hash of buffer */
secure_hash_binary (buffer, length, GCRY_MD_SHA512, &hash, &length_hash);
if (!hash)
if (!secure_hash (buffer, length, GCRY_MD_SHA512, hash, &length_hash))
{
free (buffer);
return 0;
@@ -258,7 +238,6 @@ secure_derive_key (const char *salt, const char *passphrase,
memcpy (key, hash,
(length_hash > length_key) ? length_key : length_hash);
free (hash);
free (buffer);
return 1;
+5 -6
View File
@@ -55,14 +55,13 @@ extern int secure_cipher[];
extern int secure_data_encrypted;
extern char *secure_decrypt_error[];
extern void secure_hash_binary (const char *data, int length_data,
int hash_algo, char **hash, int *length_hash);
extern char *secure_hash (const char *data, int length_data, int hash_algo);
extern int secure_hash_pbkdf2 (const char *data, int length_data,
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 char *salt, int length_salt,
const void *salt, int salt_size,
int iterations,
char **hash, int *length_hash);
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,
+12 -37
View File
@@ -3444,54 +3444,29 @@ string_get_hash_algo (const char *hash_algo)
}
/*
* Computes hash data, as binary buffer.
*
* Note: "*hash" must be freed after use.
* Computes hash data.
*/
void
string_hash_binary (const char *data, int length_data, const char *hash_algo,
char **hash, int *length_hash)
int
string_hash (const void *data, int data_size, const char *hash_algo,
void *hash, int *hash_size)
{
int algo;
if (!hash || !length_hash)
return;
if (!hash)
return 0;
*hash = NULL;
*length_hash = 0;
if (hash_size)
*hash_size = 0;
if (!data || (length_data < 1) || !hash_algo)
return;
if (!data || (data_size < 1) || !hash_algo)
return 0;
algo = string_get_hash_algo (hash_algo);
if (algo == GCRY_MD_NONE)
return;
return 0;
secure_hash_binary (data, length_data, algo, hash, length_hash);
}
/*
* Computes hash of a buffer, as text (string with hexadecimal).
*
* Returns a string with the hash as hexadecimal, NULL if error.
*
* Note: result must be freed after use.
*/
char *
string_hash (const char *data, int length_data, const char *hash_algo)
{
int algo;
if (!data || (length_data < 1) || !hash_algo)
return NULL;
algo = string_get_hash_algo (hash_algo);
if (algo == GCRY_MD_NONE)
return NULL;
return secure_hash (data, length_data, algo);
return secure_hash (data, data_size, algo, hash, hash_size);
}
/*
+2 -5
View File
@@ -118,11 +118,8 @@ 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 void string_hash_binary (const char *data, int length_data,
const char *hash_algo,
char **hash, int *length_hash);
extern char *string_hash (const char *data, int length_data,
const char *hash_algo);
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,
-1
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_binary = &string_hash_binary;
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;
+2 -5
View File
@@ -187,7 +187,7 @@ char *
relay_websocket_build_handshake (struct t_relay_client *client)
{
const char *sec_websocket_key;
char *key, sec_websocket_accept[128], handshake[1024], *hash;
char *key, sec_websocket_accept[128], handshake[1024], hash[160 / 8];
int length, length_hash;
sec_websocket_key = weechat_hashtable_get (client->http_headers,
@@ -207,9 +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 */
weechat_string_hash_binary (key, strlen (key), "sha1",
&hash, &length_hash);
if (!hash)
if (!weechat_string_hash (key, strlen (key), "sha1", hash, &length_hash))
{
free (key);
return NULL;
@@ -220,7 +218,6 @@ relay_websocket_build_handshake (struct t_relay_client *client)
sec_websocket_accept[0] = '\0';
}
free (hash);
free (key);
/* build the handshake (it will be sent as-is to client) */
+10 -3
View File
@@ -755,7 +755,8 @@ script_repo_sha512sum_file (const char *filename)
{
struct stat st;
FILE *file;
char *data, *hash;
char *data, hash[512 / 8], hash_hexa[((512 / 8) * 2) + 1];
int length_hash;
if (stat (filename, &st) == -1)
return NULL;
@@ -773,11 +774,17 @@ script_repo_sha512sum_file (const char *filename)
}
fclose (file);
hash = weechat_string_hash (data, st.st_size, "sha512");
if (!weechat_string_hash (data, st.st_size, "sha512", hash, &length_hash))
{
free (data);
return NULL;
}
weechat_string_base_encode (16, hash, length_hash, hash_hexa);
weechat_string_tolower (hash_hexa);
free (data);
return hash;
return strdup (hash_hexa);
}
/*
+7 -13
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 "20200229-01"
#define WEECHAT_PLUGIN_API_VERSION "20200301-01"
/* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \
@@ -341,11 +341,8 @@ struct t_weechat_plugin
char *(*string_hex_dump) (const char *data, int data_size,
int bytes_per_line, const char *prefix,
const char *suffix);
void (*string_hash_binary) (const char *data, int length_data,
const char *hash_algo,
char **hash, int *length_hash);
char *(*string_hash) (const char *data, int length_data,
const char *hash_algo);
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,
@@ -1259,13 +1256,10 @@ 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_binary(__data, __length_data, __hash_algo, \
__hash, __length_hash) \
(weechat_plugin->string_hash_binary)(__data, __length_data, \
__hash_algo, \
__hash, __length_hash)
#define weechat_string_hash(__data, __length_data, __hash_algo) \
(weechat_plugin->string_hash)(__data, __length_data, __hash_algo)
#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) \