diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2022-08-16 21:25:30 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2022-08-16 21:33:50 +0200 |
commit | 0090695f7d79efa4f50398b55bc59317d1de1d75 (patch) | |
tree | 9c1adbf669c3cdca080bd8aea4cbb9a119bb2d18 /src/core | |
parent | e61441081520bcada6de699229ce9af241302665 (diff) | |
download | weechat-0090695f7d79efa4f50398b55bc59317d1de1d75.zip |
api: add function crypto_hash_file
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/wee-crypto.c | 100 | ||||
-rw-r--r-- | src/core/wee-crypto.h | 2 |
2 files changed, 102 insertions, 0 deletions
diff --git a/src/core/wee-crypto.c b/src/core/wee-crypto.c index 00ee3292c..f99d7aac0 100644 --- a/src/core/wee-crypto.c +++ b/src/core/wee-crypto.c @@ -26,6 +26,7 @@ #include <stdlib.h> #include <stdio.h> #include <stdint.h> +#include <sys/stat.h> #include <time.h> #include <math.h> #include <gcrypt.h> @@ -160,6 +161,105 @@ hash_end: } /* + * Computes hash of file using the given hash 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 (libgcrypt ≥ 1.7.0) + * GCRY_MD_SHA3_256 256 bits == 32 bytes (libgcrypt ≥ 1.7.0) + * GCRY_MD_SHA3_384 384 bits == 48 bytes (libgcrypt ≥ 1.7.0) + * GCRY_MD_SHA3_512 512 bits == 64 bytes (libgcrypt ≥ 1.7.0) + * + * 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: OK + * 0: error + */ + +int +weecrypto_hash_file (const char *filename, int hash_algo, + void *hash, int *hash_size) +{ + gcry_md_hd_t *hd_md; + struct stat st; + FILE *file; + size_t num_read; + int rc, hd_md_opened, algo_size; + unsigned char *ptr_hash; + char buffer[4096]; + + rc = 0; + hd_md = NULL; + hd_md_opened = 0; + file = NULL; + + if (!hash) + goto hash_end; + + if (hash_size) + *hash_size = 0; + + if (!filename || !filename[0] || !hash) + goto hash_end; + + if (stat (filename, &st) == -1) + goto hash_end; + + file = fopen (filename, "r"); + if (!file) + 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; + + while (!feof (file)) + { + num_read = fread (buffer, 1, sizeof (buffer), file); + if (num_read == 0) + break; + gcry_md_write (*hd_md, buffer, num_read); + } + + 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); + } + if (file) + fclose (file); + return rc; +} +/* * Computes PKCS#5 Passphrase Based Key Derivation Function number 2 (PBKDF2) * hash of data. * diff --git a/src/core/wee-crypto.h b/src/core/wee-crypto.h index fd7675b9e..863bccb23 100644 --- a/src/core/wee-crypto.h +++ b/src/core/wee-crypto.h @@ -26,6 +26,8 @@ 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_file (const char *filename, int hash_algo, + void *hash, int *hash_size); extern int weecrypto_hash_pbkdf2 (const void *data, int data_size, int hash_algo, const void *salt, int salt_size, |