1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
/*
Copyright (C) 2019-2025 Selwin van Dijk
This file is part of signalbackup-tools.
signalbackup-tools 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.
signalbackup-tools 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 signalbackup-tools. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef BASE64_H_
#define BASE64_H_
#include <openssl/evp.h>
#include <memory>
#include <cstring>
#include <string>
#include "../logger/logger.h"
#include "../common_bytes.h"
struct Base64
{
public:
inline static std::string bytesToBase64String(unsigned char const *data, size_t size);
inline static std::string bytesToBase64String(std::pair<unsigned char const *, size_t> const &data);
template <typename T>
inline static std::pair<unsigned char*, size_t> base64StringToBytes(T const &str,
typename std::enable_if<std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view>>::type *dummy = nullptr);
};
inline std::string Base64::bytesToBase64String(unsigned char const *data, size_t size)
{
int base64length = ((4 * size / 3) + 3) & ~3;
std::unique_ptr<unsigned char[]> output(new unsigned char[base64length + 1]); // +1 for terminating null
if (EVP_EncodeBlock(output.get(), data, size) != base64length)
{
Logger::error("Failed to base64 encode data");
return std::string();
}
return std::string(reinterpret_cast<char *>(output.get()), base64length);
}
inline std::string Base64::bytesToBase64String(std::pair<unsigned char const *, size_t> const &data)
{
return bytesToBase64String(data.first, data.second);
}
template <typename T>
inline std::pair<unsigned char*, size_t> Base64::base64StringToBytes(T const &str,
typename std::enable_if<std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view>>::type *)
{
int binarylength = str.size() / 4 * 3;
std::unique_ptr<unsigned char[]> output(new unsigned char[binarylength]);
if (EVP_DecodeBlock(output.get(), reinterpret_cast<unsigned const char *>(str.data()), str.size()) == -1)
{
Logger::error("Failed to base64 decode data (size: ", str.size(), "): ", str.data());
return {nullptr, 0};
}
if (str.empty() || str.back() != '=')
return {output.release(), binarylength};
int realsize = binarylength - 1;
if (str.size() >= 2 && str[str.size() - 2] == '=')
realsize = binarylength - 2;
unsigned char *unpaddedoutput = new unsigned char[realsize];
std::memcpy(unpaddedoutput, output.get(), realsize);
return {unpaddedoutput, realsize};
}
#endif
|