diff options
author | Artjoms Rimdjonoks <artjoms.rimdjonoks@zabbix.com> | 2021-12-22 12:37:38 +0300 |
---|---|---|
committer | Artjoms Rimdjonoks <artjoms.rimdjonoks@zabbix.com> | 2021-12-22 12:37:38 +0300 |
commit | 4689dbaa55dc9b8243a5cd5fe172d5a3e4051f05 (patch) | |
tree | 3e96356e0c05e622f4deef72018c1c8173ffed66 | |
parent | 6c5e29c7220ef6206475c1abdfd0f28ec6790fd4 (diff) | |
parent | bae8329129329aefa062be7d5e691427f3d231b7 (diff) |
........S. [ZBX-20377] implemented hmac-sha256 for server for scheduled reports cookies
-rw-r--r-- | ChangeLog.d/bugfix/ZBX-20377 | 1 | ||||
-rw-r--r-- | include/sha256crypt.h | 13 | ||||
-rw-r--r-- | src/libs/zbxcrypto/Makefile.am | 2 | ||||
-rw-r--r-- | src/libs/zbxcrypto/hmac_sha256.c | 68 | ||||
-rw-r--r-- | src/libs/zbxcrypto/hmac_sha256.h | 14 | ||||
-rw-r--r-- | src/libs/zbxcrypto/sha256crypt.c | 21 | ||||
-rw-r--r-- | src/zabbix_server/reporter/report_manager.c | 37 |
7 files changed, 132 insertions, 24 deletions
diff --git a/ChangeLog.d/bugfix/ZBX-20377 b/ChangeLog.d/bugfix/ZBX-20377 new file mode 100644 index 00000000000..5630e5579ab --- /dev/null +++ b/ChangeLog.d/bugfix/ZBX-20377 @@ -0,0 +1 @@ +........S. [ZBX-20377] implemented hmac-sha256 for server for scheduled reports cookies (arimdjonoks) diff --git a/include/sha256crypt.h b/include/sha256crypt.h index 7a1842912e2..8c08f96af6c 100644 --- a/include/sha256crypt.h +++ b/include/sha256crypt.h @@ -20,8 +20,21 @@ #ifndef ZABBIX_SHA256CRYPT_H #define ZABBIX_SHA256CRYPT_H +#include "common.h" + #define ZBX_SHA256_DIGEST_SIZE 32 +/* Structure to save state of computation between the single steps. */ +typedef struct +{ + uint32_t H[8]; + uint32_t total[2]; + uint32_t buflen; + char buffer[128]; /* NB: always correctly aligned for uint32_t. */ +} +sha256_ctx; + void zbx_sha256_hash(const char *in, char *out); +void* zbx_sha256_hash_for_hmac(const void* data, const size_t datalen, void* out, const size_t outlen); #endif /* ZABBIX_SHA256CRYPT_H */ diff --git a/src/libs/zbxcrypto/Makefile.am b/src/libs/zbxcrypto/Makefile.am index 42ff338d829..64dc7ebb133 100644 --- a/src/libs/zbxcrypto/Makefile.am +++ b/src/libs/zbxcrypto/Makefile.am @@ -7,6 +7,8 @@ libzbxcrypto_a_SOURCES = \ md5.c \ sha256crypt.c \ sha512crypt.c \ + hmac_sha256.c \ + hmac_sha256.h \ aes.c \ aes.h \ tls.c \ diff --git a/src/libs/zbxcrypto/hmac_sha256.c b/src/libs/zbxcrypto/hmac_sha256.c new file mode 100644 index 00000000000..54c8e693faf --- /dev/null +++ b/src/libs/zbxcrypto/hmac_sha256.c @@ -0,0 +1,68 @@ +/* +hmac_sha256.c +Originally written by https://github.com/h5p9sl +*/ + +#include "hmac_sha256.h" +#include "sha256crypt.h" + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#define SHA256_BLOCK_SIZE 64 + +static void* H(const void* x, const size_t xlen,const void* y, const size_t ylen, void* out, const size_t outlen); + +size_t hmac_sha256(const void* key, const size_t keylen, const void* data, const size_t datalen, void* out, + const size_t outlen) +{ + uint8_t k[SHA256_BLOCK_SIZE], k_ipad[SHA256_BLOCK_SIZE], k_opad[SHA256_BLOCK_SIZE], + ihash[ZBX_SHA256_DIGEST_SIZE], ohash[ZBX_SHA256_DIGEST_SIZE]; + size_t sz; + int i; + + memset(k, 0, sizeof(k)); + memset(k_ipad, 0x36, SHA256_BLOCK_SIZE); + memset(k_opad, 0x5c, SHA256_BLOCK_SIZE); + + if (keylen > SHA256_BLOCK_SIZE) + { + /* If the key is larger than the hash algorithm's + block size, we must digest it first. + sha256(key, keylen, k, sizeof(k));*/ + zbx_sha256_hash_for_hmac(key, keylen, k, sizeof(k)); + } + else + memcpy(k, key, keylen); + + for (i = 0; i < SHA256_BLOCK_SIZE; i++) + { + k_ipad[i] ^= k[i]; + k_opad[i] ^= k[i]; + } + + /* Perform HMAC algorithm: ( https://tools.ietf.org/html/rfc2104 ) + `H(K XOR opad, H(K XOR ipad, data))` */ + H(k_ipad, sizeof(k_ipad), data, datalen, ihash, sizeof(ihash)); + H(k_opad, sizeof(k_opad), ihash, sizeof(ihash), ohash, sizeof(ohash)); + + sz = (outlen > ZBX_SHA256_DIGEST_SIZE) ? ZBX_SHA256_DIGEST_SIZE : outlen; + memcpy(out, ohash, sz); + + return sz; +} + +static void* H(const void* x, const size_t xlen, const void* y, const size_t ylen, void* out, const size_t outlen) +{ + void* result; + size_t buflen = (xlen + ylen); + uint8_t* buf = (uint8_t*)malloc(buflen); + + memcpy(buf, x, xlen); + memcpy(buf + xlen, y, ylen); + result = zbx_sha256_hash_for_hmac(buf, buflen, out, outlen); + free(buf); + + return result; +} diff --git a/src/libs/zbxcrypto/hmac_sha256.h b/src/libs/zbxcrypto/hmac_sha256.h new file mode 100644 index 00000000000..4a3bf2db905 --- /dev/null +++ b/src/libs/zbxcrypto/hmac_sha256.h @@ -0,0 +1,14 @@ +/* +hmac_sha256.h +Originally written by https://github.com/h5p9sl +*/ + +#ifndef _HMAC_SHA256_H_ +#define _HMAC_SHA256_H_ + +#include <stddef.h> + +size_t hmac_sha256(const void* key, const size_t keylen, const void* data, const size_t datalen, void* out, + const size_t outlen); + +#endif diff --git a/src/libs/zbxcrypto/sha256crypt.c b/src/libs/zbxcrypto/sha256crypt.c index 75059f17b3a..34a5712a853 100644 --- a/src/libs/zbxcrypto/sha256crypt.c +++ b/src/libs/zbxcrypto/sha256crypt.c @@ -308,3 +308,24 @@ void zbx_sha256_hash(const char *in, char *out) sha256_finish_ctx (&ctx, out); } +/* helper functions for sha256 hmac*/ + +typedef struct +{ + uint8_t bytes[ZBX_SHA256_DIGEST_SIZE]; +} SHA256_HASH; + +void* zbx_sha256_hash_for_hmac(const void* data, const size_t datalen, void* out, const size_t outlen) +{ + size_t sz; + sha256_ctx ctx; + SHA256_HASH hash; + + sha256_init_ctx(&ctx); + sha256_process_bytes(data, datalen, &ctx); + sha256_finish_ctx(&ctx, &hash); + + sz = (outlen > ZBX_SHA256_DIGEST_SIZE) ? ZBX_SHA256_DIGEST_SIZE : outlen; + + return memcpy(out, hash.bytes, sz); +} diff --git a/src/zabbix_server/reporter/report_manager.c b/src/zabbix_server/reporter/report_manager.c index 6c76cbb73ad..9472c3196bf 100644 --- a/src/zabbix_server/reporter/report_manager.c +++ b/src/zabbix_server/reporter/report_manager.c @@ -29,7 +29,8 @@ #include "zbxmedia.h" #include "dbcache.h" #include "zbxreport.h" -#include "../../libs/zbxcrypto/aes.h" +#include "../../libs/zbxcrypto/hmac_sha256.h" +#include "sha256crypt.h" #include "../../libs/zbxalgo/vectorimpl.h" #include "zbxalert.h" #include "zbxserver.h" @@ -434,38 +435,26 @@ static char *rm_time_to_urlfield(const struct tm *tm) static char *report_create_cookie(zbx_rm_t *manager, const char *sessionid) { struct zbx_json j; - char *sign = NULL, *cookie = NULL, *sign_esc, *sign_raw; - size_t size, i; - unsigned char *data; - struct AES_ctx ctx; + char *cookie = NULL, *out_str_raw = NULL; + size_t i; + char out_str[ZBX_SHA256_DIGEST_SIZE * 2 + 1]; + uint8_t out[ZBX_SHA256_DIGEST_SIZE]; zbx_json_init(&j, 512); zbx_json_addstring(&j, ZBX_PROTO_TAG_SESSIONID, sessionid, ZBX_JSON_TYPE_STRING); - size = (j.buffer_size / 16 + 1) * 16; - data = zbx_malloc(NULL, size); - memcpy(data, j.buffer, j.buffer_size); - - if (j.buffer_size < size) - memset(data + j.buffer_size, (int)(size - j.buffer_size), size - j.buffer_size); - - AES_init_ctx(&ctx, (unsigned char *)manager->session_key); + hmac_sha256(manager->session_key, strlen(manager->session_key), j.buffer, j.buffer_size, &out, sizeof(out)); + memset(&out_str, 0, sizeof(out_str)); - for (i = 0; i < size / 16; i++) - AES_ECB_encrypt(&ctx, data + i * 16); + for (i = 0; i < sizeof(out); i++) + zbx_snprintf(&out_str[i*2], 3, "%02x", out[i]); - str_base64_encode_dyn((char *)data, &sign, size); - sign_esc = zbx_dyn_escape_string(sign, "/"); - sign_raw = zbx_dsprintf(NULL, "\"%s\"", sign_esc); - - zbx_json_addraw(&j, ZBX_PROTO_TAG_SIGN, sign_raw); + out_str_raw = zbx_dsprintf(NULL, "\"%s\"", out_str); + zbx_json_addraw(&j, ZBX_PROTO_TAG_SIGN, out_str_raw); str_base64_encode_dyn(j.buffer, &cookie, j.buffer_size); - zbx_free(sign_raw); - zbx_free(sign_esc); - zbx_free(sign); - zbx_free(data); zbx_json_clean(&j); + zbx_free(out_str_raw); return cookie; } |