From 5551119d29080cdfc09f891a1d6d4c12f31e7738 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 26 Oct 2024 12:54:29 +0000 Subject: [PATCH] util: Move base64 functions into a separate file Signed-off-by: Michael Tremer --- Makefile.am | 2 + src/libpakfire/base64.c | 188 ++++++++++++++++++++++++ src/libpakfire/include/pakfire/base64.h | 35 +++++ src/libpakfire/include/pakfire/util.h | 7 - src/libpakfire/key.c | 1 + src/libpakfire/util.c | 167 --------------------- tests/libpakfire/util.c | 1 + 7 files changed, 227 insertions(+), 174 deletions(-) create mode 100644 src/libpakfire/base64.c create mode 100644 src/libpakfire/include/pakfire/base64.h diff --git a/Makefile.am b/Makefile.am index ece8a3c48..f93ce0973 100644 --- a/Makefile.am +++ b/Makefile.am @@ -186,6 +186,7 @@ lib_LTLIBRARIES += \ libpakfire_la_SOURCES = \ src/libpakfire/arch.c \ src/libpakfire/archive.c \ + src/libpakfire/base64.c \ src/libpakfire/build.c \ src/libpakfire/buildservice.c \ src/libpakfire/cgroup.c \ @@ -238,6 +239,7 @@ libpakfire_la_SOURCES = \ pkginclude_HEADERS += \ src/libpakfire/include/pakfire/arch.h \ src/libpakfire/include/pakfire/archive.h \ + src/libpakfire/include/pakfire/base64.h \ src/libpakfire/include/pakfire/build.h \ src/libpakfire/include/pakfire/buildservice.h \ src/libpakfire/include/pakfire/cgroup.h \ diff --git a/src/libpakfire/base64.c b/src/libpakfire/base64.c new file mode 100644 index 000000000..78f8eb05a --- /dev/null +++ b/src/libpakfire/base64.c @@ -0,0 +1,188 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2024 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU 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 General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +// OpenSSL +#include +#include +#include + +#include +#include +#include + +#define OPENSSL_ERROR_MAX 1024 + +int pakfire_b64encode(struct pakfire_ctx* ctx, char** output, + const void* buffer, const size_t length) { + char error[OPENSSL_ERROR_MAX]; + BIO* b64 = NULL; + BIO* bio = NULL; + const char* p = NULL; + int r; + + // Initialize the base64 encoder + b64 = BIO_new(BIO_f_base64()); + if (!b64) { + ERR_error_string_n(ERR_get_error(), error, sizeof(error)); + + ERROR(ctx, "Could not initialize the base64 encoder: %s\n", error); + r = 1; + goto ERROR; + } + + // Initialize a memory buffer + bio = BIO_new(BIO_s_mem()); + if (!bio) { + ERR_error_string_n(ERR_get_error(), error, sizeof(error)); + + ERROR(ctx, "Could not initialize memory buffer: %s\n", error); + r = 1; + goto ERROR; + } + + // Connect both things + bio = BIO_push(b64, bio); + + // Disable line breaks and a trailing newline + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); + + // Write the input + r = BIO_write(bio, buffer, length); + if (r < 1) { + ERR_error_string_n(ERR_get_error(), error, sizeof(error)); + + ERROR(ctx, "%s\n", error); + r = 1; + goto ERROR; + } + + // Flush + BIO_flush(bio); + + // Fetch a pointer to the output and determine its length + const size_t l = BIO_get_mem_data(bio, &p); + + // Copy the output to the heap + *output = strndup(p, l); + if (!*output) { + ERROR(ctx, "Could not copy base64 encoded string to heap: %m\n"); + r = 1; + goto ERROR; + } + + // Success + r = 0; + +ERROR: + if (bio) + BIO_free_all(bio); + + return r; +} + +int pakfire_b64decode(struct pakfire_ctx* ctx, void** output, size_t* length, + const char* buffer) { + char error[OPENSSL_ERROR_MAX]; + char chunk[1024]; + BIO* b64 = NULL; + BIO* bio = NULL; + char* p = NULL; + int r; + + // Reset length + *length = 0; + + // Initialize the base64 decoder + b64 = BIO_new(BIO_f_base64()); + if (!b64) { + ERR_error_string_n(ERR_get_error(), error, sizeof(error)); + + ERROR(ctx, "Could not initialize the base64 decoder: %s\n", error); + r = 1; + goto ERROR; + } + + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + + // Initialize a memory buffer + bio = BIO_new_mem_buf(buffer, strlen(buffer)); + if (!bio) { + ERR_error_string_n(ERR_get_error(), error, sizeof(error)); + + ERROR(ctx, "Could not initialize memory buffer: %s\n", error); + r = 1; + goto ERROR; + } + + // Connect both things + bio = BIO_push(b64, bio); + + for (;;) { + // Read a chunk of data + ssize_t bytes_read = BIO_read(bio, chunk, sizeof(chunk)); + + // Handle any errors + if (bytes_read < 0) { + ERR_error_string_n(ERR_get_error(), error, sizeof(error)); + + ERROR(ctx, "Could not read data: %s\n", error); + r = -EINVAL; + goto ERROR; + + // Break if no more data could be read + } else if (bytes_read == 0) { + break; + + // Handle the chunk + } else { + // Update total length of data + *length += bytes_read; + + // Allocate an output buffer + p = pakfire_realloc(p, *length); + if (!p) { + ERROR(ctx, "Could not allocate buffer: %m\n"); + r = -errno; + goto ERROR; + } + + // Copy the chunk + memcpy(p + *length - bytes_read, chunk, bytes_read); + } + } + + // Set output pointer + *output = p; + + // Success! + r = 0; + + goto CLEANUP; + +ERROR: + if (p) + free(p); + +CLEANUP: + if (bio) + BIO_free_all(bio); + + return r; +} diff --git a/src/libpakfire/include/pakfire/base64.h b/src/libpakfire/include/pakfire/base64.h new file mode 100644 index 000000000..91b236e44 --- /dev/null +++ b/src/libpakfire/include/pakfire/base64.h @@ -0,0 +1,35 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2024 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU 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 General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef PAKFIRE_BASE64_H +#define PAKFIRE_BASE64_H + +#ifdef PAKFIRE_PRIVATE + +#include + +int pakfire_b64encode( + struct pakfire_ctx* ctx, char** output, const void* buffer, const size_t length); + +int pakfire_b64decode( + struct pakfire_ctx* ctx, void** output, size_t* length, const char* buffer); + +#endif /* PAKFIRE_PRIVATE */ +#endif /* PAKFIRE_BASE64_H */ diff --git a/src/libpakfire/include/pakfire/util.h b/src/libpakfire/include/pakfire/util.h index e30675ba4..26b753ae9 100644 --- a/src/libpakfire/include/pakfire/util.h +++ b/src/libpakfire/include/pakfire/util.h @@ -98,13 +98,6 @@ int pakfire_rlimit_reset_nofile(struct pakfire_ctx* ctx); int pakfire_compile_regex(struct pakfire_ctx* ctx, pcre2_code** regex, const char* pattern); -// Base64 - -int pakfire_b64encode(struct pakfire_ctx* ctx, char** output, - const void* buffer, const size_t length); -int pakfire_b64decode(struct pakfire_ctx* ctx, void** output, size_t* length, - const char* buffer); - // Copy int pakfire_copy(struct pakfire_ctx* ctx, FILE* src, FILE* dst); diff --git a/src/libpakfire/key.c b/src/libpakfire/key.c index 788790bbd..b5423681e 100644 --- a/src/libpakfire/key.c +++ b/src/libpakfire/key.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/src/libpakfire/util.c b/src/libpakfire/util.c index 2d9dbb50b..29af43106 100644 --- a/src/libpakfire/util.c +++ b/src/libpakfire/util.c @@ -36,11 +36,6 @@ #include #include -// OpenSSL -#include -#include -#include - #define PCRE2_CODE_UNIT_WIDTH 8 #include @@ -621,168 +616,6 @@ int pakfire_compile_regex(struct pakfire_ctx* ctx, pcre2_code** regex, const cha return 0; } -// Base64 - -#define OPENSSL_ERROR_MAX 1024 - -int pakfire_b64encode(struct pakfire_ctx* ctx, char** output, - const void* buffer, const size_t length) { - char error[OPENSSL_ERROR_MAX]; - BIO* b64 = NULL; - BIO* bio = NULL; - const char* p = NULL; - int r; - - // Initialize the base64 encoder - b64 = BIO_new(BIO_f_base64()); - if (!b64) { - ERR_error_string_n(ERR_get_error(), error, sizeof(error)); - - ERROR(ctx, "Could not initialize the base64 encoder: %s\n", error); - r = 1; - goto ERROR; - } - - // Initialize a memory buffer - bio = BIO_new(BIO_s_mem()); - if (!bio) { - ERR_error_string_n(ERR_get_error(), error, sizeof(error)); - - ERROR(ctx, "Could not initialize memory buffer: %s\n", error); - r = 1; - goto ERROR; - } - - // Connect both things - bio = BIO_push(b64, bio); - - // Disable line breaks and a trailing newline - BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - - // Write the input - r = BIO_write(bio, buffer, length); - if (r < 1) { - ERR_error_string_n(ERR_get_error(), error, sizeof(error)); - - ERROR(ctx, "%s\n", error); - r = 1; - goto ERROR; - } - - // Flush - BIO_flush(bio); - - // Fetch a pointer to the output and determine its length - const size_t l = BIO_get_mem_data(bio, &p); - - // Copy the output to the heap - *output = strndup(p, l); - if (!*output) { - ERROR(ctx, "Could not copy base64 encoded string to heap: %m\n"); - r = 1; - goto ERROR; - } - - // Success - r = 0; - -ERROR: - if (bio) - BIO_free_all(bio); - - return r; -} - -int pakfire_b64decode(struct pakfire_ctx* ctx, void** output, size_t* length, - const char* buffer) { - char error[OPENSSL_ERROR_MAX]; - char chunk[1024]; - BIO* b64 = NULL; - BIO* bio = NULL; - char* p = NULL; - int r; - - // Reset length - *length = 0; - - // Initialize the base64 decoder - b64 = BIO_new(BIO_f_base64()); - if (!b64) { - ERR_error_string_n(ERR_get_error(), error, sizeof(error)); - - ERROR(ctx, "Could not initialize the base64 decoder: %s\n", error); - r = 1; - goto ERROR; - } - - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - - // Initialize a memory buffer - bio = BIO_new_mem_buf(buffer, strlen(buffer)); - if (!bio) { - ERR_error_string_n(ERR_get_error(), error, sizeof(error)); - - ERROR(ctx, "Could not initialize memory buffer: %s\n", error); - r = 1; - goto ERROR; - } - - // Connect both things - bio = BIO_push(b64, bio); - - for (;;) { - // Read a chunk of data - ssize_t bytes_read = BIO_read(bio, chunk, sizeof(chunk)); - - // Handle any errors - if (bytes_read < 0) { - ERR_error_string_n(ERR_get_error(), error, sizeof(error)); - - ERROR(ctx, "Could not read data: %s\n", error); - r = -EINVAL; - goto ERROR; - - // Break if no more data could be read - } else if (bytes_read == 0) { - break; - - // Handle the chunk - } else { - // Update total length of data - *length += bytes_read; - - // Allocate an output buffer - p = pakfire_realloc(p, *length); - if (!p) { - ERROR(ctx, "Could not allocate buffer: %m\n"); - r = -errno; - goto ERROR; - } - - // Copy the chunk - memcpy(p + *length - bytes_read, chunk, bytes_read); - } - } - - // Set output pointer - *output = p; - - // Success! - r = 0; - - goto CLEANUP; - -ERROR: - if (p) - free(p); - -CLEANUP: - if (bio) - BIO_free_all(bio); - - return r; -} - // Copy int pakfire_copy(struct pakfire_ctx* ctx, FILE* src, FILE* dst) { diff --git a/tests/libpakfire/util.c b/tests/libpakfire/util.c index 534252c57..81da4cf67 100644 --- a/tests/libpakfire/util.c +++ b/tests/libpakfire/util.c @@ -18,6 +18,7 @@ # # #############################################################################*/ +#include #include #include -- 2.39.5