From 30f019cddefd705028653ad84def5e9cf19de426 Mon Sep 17 00:00:00 2001 From: gc87 Date: Mon, 28 Feb 2022 18:21:02 +0800 Subject: [PATCH] Add base64 codec --- CMakeLists.txt | 1 + include/neu_base64.h | 34 +++++++++++++++++++++++++++++ include/neuron.h | 1 + src/utils/base64.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 8 +++++++ tests/base64_test.cc | 25 ++++++++++++++++++++++ 6 files changed, 120 insertions(+) create mode 100644 include/neu_base64.h create mode 100644 src/utils/base64.c create mode 100644 tests/base64_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index b4711230..abbc84d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,7 @@ set(NEURON_BASE_SOURCES src/utils/neu_jwt.c src/utils/uuid4.c src/utils/file.c + src/utils/base64.c src/config.c) if(USE_NNG_MQTT) diff --git a/include/neu_base64.h b/include/neu_base64.h new file mode 100644 index 00000000..6b9ba37c --- /dev/null +++ b/include/neu_base64.h @@ -0,0 +1,34 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2021 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +#ifndef __NEU_BASE64_H__ +#define __NEU_BASE64_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +char * neu_encode64(const unsigned char *input, int length); +unsigned char *neu_decode64(int *length, const char *input); + +#ifdef __cplusplus +} +#endif + +#endif // __NEU_BASE64_H__ diff --git a/include/neuron.h b/include/neuron.h index 271a12c0..f9f196f8 100644 --- a/include/neuron.h +++ b/include/neuron.h @@ -25,6 +25,7 @@ extern "C" { #endif #include "neu_adapter.h" +#include "neu_base64.h" #include "neu_file.h" #include "neu_license.h" #include "neu_list.h" diff --git a/src/utils/base64.c b/src/utils/base64.c new file mode 100644 index 00000000..5fd858c8 --- /dev/null +++ b/src/utils/base64.c @@ -0,0 +1,51 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2021 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +#include +#include + +#include + +#include "neuron.h" + +char *neu_encode64(const unsigned char *input, int length) +{ + const int pl = 4 * ((length + 2) / 3); + unsigned char *output = calloc(pl + 1, 1); + const int ol = EVP_EncodeBlock(output, input, length); + if (ol != pl) { + log_error("Encode predicted %d but we got %d\n", pl, ol); + } + + return (char *) output; +} + +unsigned char *neu_decode64(int *length, const char *input) +{ + size_t len = strlen(input); + const int pl = 3 * len / 4; + unsigned char *output = calloc(pl, 1); + const int ol = EVP_DecodeBlock(output, (const unsigned char *) input, len); + if (pl != ol) { + log_error("Decode predicted %d but we got %d\n", pl, ol); + } + + *length = ol; + return output; +} \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c63c73df..e95b3c4f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -166,6 +166,13 @@ target_include_directories(jwt_test PRIVATE ${CMAKE_SOURCE_DIR}/src/utils) target_link_libraries(jwt_test neuron-base gtest_main gtest yaml jansson ssl crypto jwt) +add_executable(base64_test base64_test.cc ${CMAKE_SOURCE_DIR}/src/utils/base64.c) +target_include_directories(base64_test PRIVATE + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/include +) +target_link_libraries(base64_test neuron-base gtest_main gtest crypto) + include(GoogleTest) gtest_discover_tests(data_val_test) gtest_discover_tests(modbus_point_test) @@ -186,3 +193,4 @@ gtest_discover_tests(mqtt_test) gtest_discover_tests(jwt_test) gtest_discover_tests(json_persistence_test) gtest_discover_tests(persistence_test) +gtest_discover_tests(base64_test) diff --git a/tests/base64_test.cc b/tests/base64_test.cc new file mode 100644 index 00000000..694b5786 --- /dev/null +++ b/tests/base64_test.cc @@ -0,0 +1,25 @@ +#include + +#include "neu_base64.h" + +TEST(Base64Test, neu_encode64_test) +{ + const char *input = "hello world!"; + size_t len = strlen(input); + char * b64 = neu_encode64((unsigned char *) input, len); + EXPECT_STREQ(b64, "aGVsbG8gd29ybGQh"); + free(b64); +} + +TEST(Base64Test, neu_decode64_test) +{ + int len = 0; + const char * input = "aGVsbG8gd29ybGQh"; + const char * output = "hello world!"; + char temp[100] = { '\0' }; + unsigned char *data = neu_decode64(&len, input); + memcpy(temp, data, len); + free(data); + EXPECT_STREQ(temp, output); + EXPECT_EQ(len, strlen(output)); +} \ No newline at end of file