diff --git a/src/common.c b/src/common.c index e9f9ad2..e53f6cd 100755 --- a/src/common.c +++ b/src/common.c @@ -939,3 +939,43 @@ void add_day_to_time(struct tm *time) } else time->tm_mday = time->tm_mday + 1; } + +void add_bin_list(struct list_head *list, uint8_t *str, size_t len) +{ + bin_list_t *node; + + if (len >= 1024) { + CWMP_LOG(ERROR, "Binary length out of index"); + return; + } + + node = (bin_list_t *)calloc(1, sizeof(*node)); + if (!node) { + CWMP_LOG(ERROR, "Out of memory!"); + return; + } + + INIT_LIST_HEAD(&node->list); + memcpy(node->bin, str, len); + node->len = len; + + list_add_tail(&node->list, list); +} + +void add_str_binlist(struct list_head *list, char *str) +{ + if (str != NULL) { + add_bin_list(list, (uint8_t *)str, strlen(str)); + } +} + +void free_binlist(struct list_head *blist) +{ + bin_list_t *iter = NULL, *node; + + list_for_each_entry_safe(iter, node, blist, list) { + list_del(&iter->list); + FREE(iter); + } +} + diff --git a/src/common.h b/src/common.h index 647ff41..16752b7 100644 --- a/src/common.h +++ b/src/common.h @@ -587,6 +587,12 @@ typedef struct intf_reset_node { struct list_head list; } intf_reset_node; +typedef struct bin_list { + uint8_t bin[1024]; + size_t len; + struct list_head list; +} bin_list_t; + extern struct cwmp *cwmp_main; extern long int flashsize; extern struct FAULT_CPE FAULT_CPE_ARRAY[]; @@ -644,4 +650,8 @@ void check_firewall_restart_state(); void add_day_to_time(struct tm *time); int set_rpc_acs_to_supported(const char *rpc_name); void set_rpc_parameter_key(char *param_key); + +void add_bin_list(struct list_head *list, uint8_t *str, size_t len); +void add_str_binlist(struct list_head *list, char *str); +void free_binlist(struct list_head *list); #endif diff --git a/src/digauth.c b/src/digauth.c index d5ed5f7..6a437d8 100644 --- a/src/digauth.c +++ b/src/digauth.c @@ -20,27 +20,6 @@ #include "ssl_utils.h" #include "common.h" -#ifdef LMBEDTLS -#include -#define MD5_CTX mbedtls_md5_context -#define MD5_INIT(X) { mbedtls_md5_init(X); mbedtls_md5_starts_ret(X); } -#define MD5_UPDATE(X, Y, Z) mbedtls_md5_update_ret(X, (unsigned char *)Y, Z) -#define MD5_FINAL(X, Y) mbedtls_md5_finish_ret(Y, X) -#elif LOPENSSL -#include -#define MD5_CTX MD5_CTX -#define MD5_INIT MD5_Init -#define MD5_UPDATE MD5_Update -#define MD5_FINAL MD5_Final -#else -#include -#include -#define MD5_CTX MD5_CTX -#define MD5_INIT MD5_Init -#define MD5_UPDATE MD5_Update -#define MD5_FINAL MD5_Final -#endif - #ifndef MD5_DIGEST_SIZE #define MD5_DIGEST_SIZE 16 #endif @@ -198,7 +177,7 @@ static void get_digest_ha1(const char *algo, const char *uname, const char *rlm, char *skey, int skey_len) { unsigned char digest[MD5_DIGEST_SIZE]; - MD5_CTX context; + LIST_HEAD(buff_list); if (algo == NULL || uname == NULL || rlm == NULL || psw == NULL || nonce == NULL || cnonce == NULL || skey == NULL) { @@ -214,13 +193,10 @@ static void get_digest_ha1(const char *algo, const char *uname, const char *rlm, } snprintf(a, len, "%s:%s:%s", uname, rlm, psw); + add_str_binlist(&buff_list, a); + FREE(a); - MD5_INIT(&context); - MD5_UPDATE(&context, (unsigned char *)a, strlen(a)); - MD5_FINAL(digest, &context); - - free(a); - a = NULL; + calulate_md5_hash(&buff_list, digest, sizeof(digest)); if (0 == strcasecmp(algo, "md5-sess")) { len = strlen(nonce) + strlen(cnonce) + 3; @@ -230,23 +206,22 @@ static void get_digest_ha1(const char *algo, const char *uname, const char *rlm, return; } + add_bin_list(&buff_list, digest, sizeof(digest)); snprintf(a, len, ":%s:%s", nonce, cnonce); + add_str_binlist(&buff_list, a); + FREE(a); - MD5_INIT(&context); - MD5_UPDATE(&context, (unsigned char *)digest, sizeof(digest)); - MD5_UPDATE(&context, (unsigned char *)a, strlen(a)); - MD5_FINAL(digest, &context); - - free(a); + calulate_md5_hash(&buff_list, digest, sizeof(digest)); } get_hexstring(digest, sizeof(digest), skey, skey_len); + free_binlist(&buff_list); } static void get_digest_ha2(const char *method, const char *uri, char *ha2, int ha2_len) { unsigned char digest[MD5_DIGEST_SIZE]; - MD5_CTX context; + LIST_HEAD(buff_list); if (method == NULL || uri == NULL || ha2 == NULL) { CWMP_LOG(ERROR, "digest_authentication an argument of the function %s is null: %p %p %p", __FUNCTION__, method, uri, ha2); @@ -262,22 +237,20 @@ static void get_digest_ha2(const char *method, const char *uri, char *ha2, int h snprintf(a, len, "%s:%s", method, uri); + add_str_binlist(&buff_list, a); + FREE(a); - MD5_INIT(&context); - MD5_UPDATE(&context, (unsigned char *)a, strlen(a)); - MD5_FINAL(digest, &context); - - free(a); - + calulate_md5_hash(&buff_list, digest, sizeof(digest)); get_hexstring(digest, sizeof(digest), ha2, ha2_len); + free_binlist(&buff_list); } static void get_digest_response(const char *ha1, const char *nonce, const char *nonce_cnt, const char *cnonce, const char *qop, const char *ha2, char *resp, int resp_len) { - MD5_CTX context; unsigned char digest[MD5_DIGEST_SIZE]; + LIST_HEAD(buff_list); if (ha1 == NULL || nonce == NULL || nonce_cnt == NULL || cnonce == NULL || qop == NULL || ha2 == NULL || resp == NULL) { @@ -305,18 +278,18 @@ static void get_digest_response(const char *ha1, const char *nonce, const char * snprintf(b, len, "%s%s:%s:%s:", a, nonce_cnt, cnonce, qop); - free(a); + FREE(a); a = b; } - MD5_INIT(&context); - MD5_UPDATE(&context, (unsigned char *)ha1, MD5_HASH_HEX_LEN); - MD5_UPDATE(&context, (unsigned char *)a, strlen(a)); - MD5_UPDATE(&context, (unsigned char *)ha2, MD5_HASH_HEX_LEN); - MD5_FINAL(digest, &context); + add_bin_list(&buff_list, (uint8_t *)ha1, MD5_HASH_HEX_LEN); + add_str_binlist(&buff_list, a); + add_bin_list(&buff_list, (uint8_t *)ha2, MD5_HASH_HEX_LEN); + FREE(a); - free(a); + calulate_md5_hash(&buff_list, digest, sizeof(digest)); get_hexstring(digest, sizeof(digest), resp, resp_len); + free_binlist(&buff_list); } static void get_nonce(uint32_t time, const char* method, const char *rand, @@ -324,6 +297,7 @@ static void get_nonce(uint32_t time, const char* method, const char *rand, char *nonce, unsigned int nonce_size) { unsigned char ts[4]; + LIST_HEAD(buff_list); if (method == NULL || uri == NULL || rlm == NULL || nonce == NULL) { CWMP_LOG(ERROR, "digest_authentication an argument of the function %s is null: %p %p %p %p", __FUNCTION__, method, uri, rlm, nonce); @@ -358,16 +332,17 @@ static void get_nonce(uint32_t time, const char* method, const char *rand, snprintf(uri_realm, len, ":%s:%s", uri, rlm); - MD5_CTX context; unsigned char digest[MD5_DIGEST_SIZE]; - MD5_INIT(&context); - MD5_UPDATE(&context, (unsigned char *)ts, 4); - MD5_UPDATE(&context, (unsigned char *)meth, strlen(meth)); - if (rand != NULL && rand_size > 0) - MD5_UPDATE(&context, (unsigned char *)rand, rand_size); - MD5_UPDATE(&context, (unsigned char *)uri_realm, strlen(uri_realm)); - MD5_FINAL(digest, &context); + add_bin_list(&buff_list, (uint8_t *)ts, 4); + add_str_binlist(&buff_list, meth); + + if (rand != NULL && rand_size > 0) { + add_bin_list(&buff_list, (uint8_t *)rand, rand_size); + } + + add_str_binlist(&buff_list, uri_realm); + calulate_md5_hash(&buff_list, digest, sizeof(digest)); free(meth); free(uri_realm); @@ -375,6 +350,7 @@ static void get_nonce(uint32_t time, const char* method, const char *rand, get_hexstring(digest, sizeof(digest), nonce, nonce_size); len = nonce_size - strlen(nonce) - 1; strncat(nonce, tshex, len); + free_binlist(&buff_list); } int http_authentication_failure_resp(FILE *fp, const char *http_meth, const char *uri, diff --git a/src/ssl_utils.c b/src/ssl_utils.c index 814d8ed..6248585 100644 --- a/src/ssl_utils.c +++ b/src/ssl_utils.c @@ -12,20 +12,20 @@ #include #endif #ifdef LOPENSSL -#include -#include #include #include #endif #ifdef LWOLFSSL #include -#include +#include +#include #endif #include #include +#include "ssl_utils.h" #include "common.h" #include "log.h" @@ -127,3 +127,69 @@ void message_compute_signature(char *msg_out, char *signature, size_t len) snprintf(&(signature[i * 2]), 3, "%02X", result[i]); } } + + +void calulate_md5_hash(struct list_head *buff_list, uint8_t *output, size_t outlen) +{ + unsigned int bytes = 0; + +#ifdef LMBEDTLS + mbedtls_md_context_t enpctx; + mbedtls_md_context_t *mdctx = &enpctx; + const mbedtls_md_info_t *md; + unsigned char md_value[MBEDTLS_MD_MAX_SIZE]; +#else + EVP_MD_CTX *mdctx; + const EVP_MD *md; + unsigned char md_value[EVP_MAX_MD_SIZE]; +#endif + + if (!buff_list || !output) + return; + +#ifndef LMBEDTLS + // makes all algorithms available to the EVP* routines + OpenSSL_add_all_algorithms(); +#endif + +#ifdef LMBEDTLS + md = mbedtls_md_info_from_string("MD5"); + mbedtls_md_init(mdctx); + mbedtls_md_init_ctx(mdctx, md); +#else + md = EVP_get_digestbyname("MD5"); + mdctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(mdctx, md, NULL); +#endif + + if (md == NULL) + goto end; + + bin_list_t *iter; + list_for_each_entry(iter, buff_list, list) { +#ifdef LMBEDTLS + mbedtls_md_update(mdctx, iter->bin, iter->len); +#else + EVP_DigestUpdate(mdctx, iter->bin, iter->len); +#endif + } + +#ifdef LMBEDTLS + mbedtls_md_finish(mdctx, md_value); + bytes = mbedtls_md_get_size(md); +#else + bytes = 0; + EVP_DigestFinal_ex(mdctx, md_value, &bytes); +#endif + + memcpy(output, &md_value, ((bytes +#include +#endif + +#ifdef LWOLFSSL +#include +#include +#include +#endif + +#ifdef LMBEDTLS +#include +#endif + +#include + char *generate_random_string(size_t size); void message_compute_signature(char *msg_out, char *signature, size_t len); +void calulate_md5_hash(struct list_head *buf_list, uint8_t *output, size_t outlen); #endif