]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Core] Add switch_digest(), switch_digest_string() APIs. Add unit-tests.
authorAndrey Volk <andywolk@gmail.com>
Thu, 8 Apr 2021 21:55:52 +0000 (00:55 +0300)
committerAndrey Volk <andywolk@gmail.com>
Sun, 11 Apr 2021 22:03:15 +0000 (01:03 +0300)
src/include/switch_utils.h
src/switch_core.c
src/switch_utils.c
tests/unit/switch_core.c
tests/unit/test_switch_core.2017.vcxproj

index 1c409759083405f32c9088d1185f52b117f3c75e..20655ecd4e374ab5096c760e8bded3ab74fe1e96 100644 (file)
@@ -1460,6 +1460,9 @@ SWITCH_DECLARE(char *)switch_html_strip(const char *str);
 
 SWITCH_DECLARE(unsigned long) switch_getpid(void);
 
+SWITCH_DECLARE(switch_status_t) switch_digest(const char *digest_name, unsigned char **digest, const void *input, switch_size_t inputLen, unsigned int *outputlen);
+SWITCH_DECLARE(switch_status_t) switch_digest_string(const char *digest_name, char **digest_str, const void *input, switch_size_t inputLen, unsigned int *outputlen);
+
 SWITCH_END_EXTERN_C
 #endif
 /* For Emacs:
index 2a27b57ea30bc526dfb223705a006e9a9c33ef51..d4507aa49c26717650b31e4a8ba405116969afa4 100644 (file)
@@ -1945,6 +1945,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
 
        SSL_library_init();
        switch_ssl_init_ssl_locks();
+       OpenSSL_add_all_algorithms();
        switch_curl_init();
 
        switch_core_set_variable("hostname", runtime.hostname);
@@ -3037,6 +3038,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
        switch_curl_destroy();
 
        switch_ssl_destroy_ssl_locks();
+       EVP_cleanup();
 
        switch_scheduler_task_thread_stop();
 
index 5d6b8f2aaf89d29aefe0c6d63a236a218a185b05..0fee81551b2564f65e8dda58bc3ef2f5bfad0bc6 100644 (file)
 #include "gumbo.h"
 #endif
 
+#if defined(HAVE_OPENSSL)
+#include <openssl/evp.h>
+#endif
+
 struct switch_network_node {
        ip_t ip;
        ip_t mask;
@@ -4549,6 +4553,89 @@ SWITCH_DECLARE(unsigned long) switch_getpid(void)
        return (unsigned long)pid;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_digest(const char *digest_name, unsigned char **digest, const void *input, switch_size_t inputLen, unsigned int *outputlen)
+{
+#if defined(HAVE_OPENSSL)
+       EVP_MD_CTX *mdctx;
+       const EVP_MD *md;
+       int size;
+
+       switch_assert(digest);
+
+       if (!digest_name) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Message digest is not set\n");
+               return SWITCH_STATUS_FALSE;
+       }
+
+       md = EVP_get_digestbyname(digest_name);
+
+       if (!md) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown message digest %s\n", digest_name);                    
+               return SWITCH_STATUS_FALSE;
+       }
+
+       size = EVP_MD_size(md);
+       if (!size || !(*digest = malloc(size))) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Zero digest size or can't allocate memory to store results %s\n", digest_name);
+               return SWITCH_STATUS_FALSE;
+       }
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+       mdctx = EVP_MD_CTX_new();
+#else
+       mdctx = EVP_MD_CTX_create();
+#endif
+
+       if (!mdctx) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "EVP_MD_CTX_new error\n");
+               switch_safe_free(*digest);
+               return SWITCH_STATUS_FALSE;
+       }
+
+       EVP_MD_CTX_init(mdctx);
+       EVP_DigestInit_ex(mdctx, md, NULL);
+       EVP_DigestUpdate(mdctx, input, inputLen);
+       EVP_DigestFinal_ex(mdctx, *digest, outputlen);
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+       EVP_MD_CTX_free(mdctx);
+#else
+       EVP_MD_CTX_destroy(mdctx);
+#endif
+
+       return SWITCH_STATUS_SUCCESS;
+#else
+       return SWITCH_STATUS_FALSE;
+#endif
+}
+
+SWITCH_DECLARE(switch_status_t) switch_digest_string(const char *digest_name, char **digest_str, const void *input, switch_size_t inputLen, unsigned int *outputlen)
+{
+       unsigned char *digest = NULL;
+       switch_status_t status;
+       short i = 0, x;
+       uint8_t b;
+
+       status = switch_digest(digest_name, &digest, input, inputLen, outputlen);
+
+       if (status == SWITCH_STATUS_SUCCESS) {
+               if ((*digest_str = malloc(*outputlen * 2 + 1))) {
+                       for (x = i = 0; x < *outputlen; x++) {
+                               b = (digest[x] >> 4) & 15;
+                               (*digest_str)[i++] = b + (b > 9 ? 'a' - 10 : '0');
+                               b = digest[x] & 15;
+                               (*digest_str)[i++] = b + (b > 9 ? 'a' - 10 : '0');
+                       }
+
+                       (*digest_str)[i] = '\0';
+               }
+       }
+
+       switch_safe_free(digest);
+       *outputlen = i;
+
+       return status;
+}
 
 /* For Emacs:
  * Local Variables:
index 9f58969a6f2ba97919048c501daf75bcdbebd9e4..d0d6bacef2d5488b93a9cf27443c59ae06e33ef1 100644 (file)
 
 #include <test/switch_test.h>
 
+#if defined(HAVE_OPENSSL)
+#include <openssl/ssl.h>
+#endif
+
 FST_CORE_BEGIN("./conf")
 {
        FST_SUITE_BEGIN(switch_ivr_originate)
@@ -48,6 +52,52 @@ FST_CORE_BEGIN("./conf")
                }
                FST_TEARDOWN_END()
 
+#ifdef HAVE_OPENSSL
+               FST_TEST_BEGIN(test_md5)
+               {
+                       char *digest_name = "md5";
+                       char *digest_str = NULL;
+                       const char *str = "test data";
+                       unsigned int outputlen;
+
+                       switch_status_t status = switch_digest_string(digest_name, &digest_str, str, strlen(str), &outputlen);
+                       fst_check_int_equals(status, SWITCH_STATUS_SUCCESS);
+                       fst_check_string_equals(digest_str, "eb733a00c0c9d336e65691a37ab54293");
+                       switch_safe_free(digest_str);
+               }
+               FST_TEST_END()
+
+               FST_TEST_BEGIN(test_sha256)
+               {
+                       char *digest_name = "sha256";
+                       char *digest_str = NULL;
+                       const char *str = "test data";
+                       unsigned int outputlen;
+
+                       switch_status_t status = switch_digest_string(digest_name, &digest_str, str, strlen(str), &outputlen);
+                       fst_check_int_equals(status, SWITCH_STATUS_SUCCESS);
+                       fst_check_string_equals(digest_str, "916f0027a575074ce72a331777c3478d6513f786a591bd892da1a577bf2335f9");
+                       switch_safe_free(digest_str);
+               }
+               FST_TEST_END()
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+               FST_TEST_BEGIN(test_sha512_256)
+               {
+                       char *digest_name = "sha512-256";
+                       char *digest_str = NULL;
+                       const char *str = "test data";
+                       unsigned int outputlen;
+
+                       switch_status_t status = switch_digest_string(digest_name, &digest_str, str, strlen(str), &outputlen);
+                       fst_check_int_equals(status, SWITCH_STATUS_SUCCESS);
+                       fst_check_string_equals(digest_str, "9fe875600168548c1954aed4f03974ce06b3e17f03a70980190da2d7ef937a43");
+                       switch_safe_free(digest_str);
+               }
+               FST_TEST_END()
+#endif
+
 #ifndef WIN32
                FST_TEST_BEGIN(test_fork)
                {
index 922fb9b51fcf2bd500ca9b558002dfe6755a70e6..c9e1cd542327afc5e5fe9edb95efdd6604c60d13 100644 (file)
@@ -47,6 +47,7 @@
     <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Import Project="$(SolutionDir)w32\openssl.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">