Initial commit
Base project structure
This commit is contained in:
commit
db5dfcaa85
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build/
|
48
CMakeLists.txt
Normal file
48
CMakeLists.txt
Normal file
@ -0,0 +1,48 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(CubbitTestProject)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
# Download and unpack googletest at configure time
|
||||
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
|
||||
if(result)
|
||||
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
|
||||
endif()
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
|
||||
if(result)
|
||||
message(FATAL_ERROR "Build step for googletest failed: ${result}")
|
||||
endif()
|
||||
|
||||
# Prevent overriding the parent project's compiler/linker
|
||||
# settings on Windows
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
# Add googletest directly to our build. This defines
|
||||
# the gtest and gtest_main targets.
|
||||
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
|
||||
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
|
||||
EXCLUDE_FROM_ALL)
|
||||
|
||||
# The gtest/gtest_main targets carry header search path
|
||||
# dependencies automatically when using CMake 2.8.11 or
|
||||
# later. Otherwise we have to add them here ourselves.
|
||||
if (CMAKE_VERSION VERSION_LESS 2.8.11)
|
||||
include_directories("${gtest_SOURCE_DIR}/include")
|
||||
endif()
|
||||
|
||||
# Now simply link against gtest or gtest_main as needed. Eg
|
||||
#add_executable(example example.cpp)
|
||||
#target_link_libraries(example gtest_main)
|
||||
#add_test(NAME example_test COMMAND example)
|
||||
|
||||
enable_testing()
|
||||
include_directories(src)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(test)
|
||||
#add_subdirectory(lib/googletest)
|
15
CMakeLists.txt.in
Normal file
15
CMakeLists.txt.in
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 2.8.2)
|
||||
|
||||
project(googletest-download NONE)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG master
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
)
|
64
scripts/aes256.sh
Executable file
64
scripts/aes256.sh
Executable file
@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
usage() {
|
||||
echo "Usage: $0 [-h] [-e | -d] [-b] -k key -i iv"
|
||||
echo "Reads from stdin and encrypts or decripts to stdout."
|
||||
echo "key and iv must be provided as arguments."
|
||||
echo " -h print this summary"
|
||||
echo " -e encode mode (default)"
|
||||
echo " -d decode mode"
|
||||
echo " -k key specify 32 bytes encryption key"
|
||||
echo " -k iv specify 16 bytes initialization vector"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
#defaults
|
||||
OPENSSL_ENC=-e
|
||||
|
||||
optstring=":edbk:i:h"
|
||||
while getopts ${optstring} arg; do
|
||||
case ${arg} in
|
||||
e)
|
||||
#encode
|
||||
OPENSSL_ENC=-e
|
||||
;;
|
||||
d)
|
||||
#decode
|
||||
OPENSSL_ENC=-d
|
||||
;;
|
||||
b)
|
||||
#base64
|
||||
OPENSSL_BASE64=-a
|
||||
;;
|
||||
k)
|
||||
#encryption key
|
||||
if [[ "${#OPTARG}" != 32 ]]; then
|
||||
echo Please insert a 32 bytes key
|
||||
exit 1
|
||||
fi
|
||||
OPENSSL_KEY=$(echo -n ${OPTARG} | xxd -u -c 32 -ps)
|
||||
;;
|
||||
i)
|
||||
#initialization vector
|
||||
if [[ "${#OPTARG}" != 16 ]]; then
|
||||
echo Please insert a 16 bytes initialization vector
|
||||
exit 1
|
||||
fi
|
||||
OPENSSL_IV=$(echo -n ${OPTARG} | xxd -u -c 32 -ps)
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo Invalid option: -${OPTARG}.
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -z $OPENSSL_KEY ]] && echo Please insert a 32 bytes key && exit 1
|
||||
[[ -z $OPENSSL_IV ]] && echo Please insert a 16 bytes initialization vector && exit 1
|
||||
|
||||
while read line; do
|
||||
echo -n $line | openssl enc -aes-256-cbc $OPENSSL_ENC $OPENSSL_BASE64 -K $OPENSSL_KEY -iv $OPENSSL_IV
|
||||
done
|
10
src/CMakeLists.txt
Normal file
10
src/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
set(SOURCES main.cpp crypto.cpp utils.cpp)
|
||||
|
||||
add_executable(horcrux ${SOURCES})
|
||||
add_library(${CMAKE_PROJECT_NAME}_lib STATIC ${SOURCES})
|
||||
|
||||
find_package(OpenSSL 1.1 REQUIRED)
|
||||
message("Found OpenSSL Version ${OPENSSL_VERSION}")
|
||||
|
||||
target_link_libraries(horcrux OpenSSL::Crypto)
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}_lib OpenSSL::Crypto)
|
69
src/crypto.cpp
Normal file
69
src/crypto.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
class EvpCipherCtx {
|
||||
EVP_CIPHER_CTX *ptr;
|
||||
|
||||
public:
|
||||
EvpCipherCtx(){
|
||||
ptr = EVP_CIPHER_CTX_new();
|
||||
}
|
||||
|
||||
~EvpCipherCtx(){
|
||||
EVP_CIPHER_CTX_free(ptr);
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX* get(){
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int AES256::encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& input, const size_t input_len,
|
||||
std::vector<unsigned char>& output, size_t& output_len)
|
||||
{
|
||||
//auto ctx = std::unique_ptr<EVP_CIPHER_CTX>(EVP_CIPHER_CTX_new());
|
||||
EvpCipherCtx ctx;
|
||||
if (EVP_EncryptInit(ctx.get(), EVP_aes_256_cbc(),
|
||||
(key.data()), (iv.data())) == 0){
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
int len;
|
||||
output.reserve(input.size() + block_len);
|
||||
if (1 != EVP_EncryptUpdate(ctx.get(),
|
||||
(output.data()), &len, (input.data()), input.size())){
|
||||
throw std::exception();
|
||||
}
|
||||
output_len = len;
|
||||
if (1 != EVP_EncryptFinal_ex(ctx.get(), (output.data()) + len, &len)){
|
||||
throw std::exception();
|
||||
}
|
||||
output_len += len;
|
||||
output.resize(output_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AES256::encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
|
||||
std::istream input, const size_t input_len,
|
||||
std::ostream output, size_t& output_len){
|
||||
|
||||
auto inbuf = std::vector<unsigned char>(input_len);
|
||||
auto outbuf = std::vector<unsigned char>(input_len + 16);
|
||||
input.read(reinterpret_cast<char*>(inbuf.data()), input_len);
|
||||
|
||||
encrypt(key, iv, inbuf, input_len, outbuf, output_len);
|
||||
|
||||
output.write(reinterpret_cast<char*>(outbuf.data()), output_len);
|
||||
|
||||
return 0;
|
||||
}
|
19
src/crypto.h
Normal file
19
src/crypto.h
Normal file
@ -0,0 +1,19 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
|
||||
class AES256 {
|
||||
|
||||
unsigned char key[256];
|
||||
unsigned char iv[128];
|
||||
const size_t block_len = 16;
|
||||
|
||||
public:
|
||||
int encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& input, const size_t input_len,
|
||||
std::vector<unsigned char>& output, size_t& output_len);
|
||||
|
||||
int encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
|
||||
std::istream input, const size_t input_len,
|
||||
std::ostream output, size_t& output_len);
|
||||
};
|
69
src/main.cpp
Normal file
69
src/main.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include <string>
|
||||
|
||||
enum RetErr {
|
||||
kOk = 0,
|
||||
kUnknownMode,
|
||||
};
|
||||
|
||||
enum HorcruxMode {
|
||||
kCreate,
|
||||
kLoad
|
||||
};
|
||||
|
||||
|
||||
struct HorcruxOptions {
|
||||
HorcruxMode mode;
|
||||
unsigned int count;
|
||||
std::string key;
|
||||
std::string input;
|
||||
std::string output;
|
||||
};
|
||||
|
||||
//RetErr parse_create_options(std::vector<std::string>& arguments, HorcruxOptions& opt){
|
||||
// opt.mode = kCreate;
|
||||
//}
|
||||
//RetErr parse_load_options(std::vector<std::string>& arguments, HorcruxOptions& opt){
|
||||
// opt.mode = kLoad;
|
||||
//}
|
||||
//
|
||||
//ret_err parse_options(int argc, const char *args[]){
|
||||
// const std::vector<const std:string> arguments;
|
||||
// for (int i = 1; i < argc, ++i){
|
||||
// arguments.push_back(args[i]);
|
||||
// }
|
||||
// horcrux_options options;
|
||||
// if (argc < 1)
|
||||
// return -EINVAL;
|
||||
// const std::string mode(args[1]);
|
||||
// if (mode == "create"){
|
||||
// options.horcrux_mode = horcrux_create;
|
||||
// } else if (mode == "load"){
|
||||
// options.horcrux_mode = horcrux_load;
|
||||
// } else {
|
||||
// return kUnknownMode;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//RetErr horcrux_create(HorcruxOptions& options){
|
||||
//
|
||||
//
|
||||
//}
|
||||
|
||||
|
||||
int main(const int argc, const char *argv[]) {
|
||||
HorcruxOptions options;
|
||||
// RetErr ret = parse_arguments(argc, argv);
|
||||
// switch (options.mode){
|
||||
// case kCreate:
|
||||
// ret = horcrux_create(options);
|
||||
// break;
|
||||
// case kLoad:
|
||||
// ret = horcrux_load(options);
|
||||
// break;
|
||||
// default:
|
||||
// std::cout << "Error: Unknown Mode" << std::endl;
|
||||
// break;
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
41
src/utils.cpp
Normal file
41
src/utils.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include <boost/archive/iterators/binary_from_base64.hpp>
|
||||
#include <boost/archive/iterators/base64_from_binary.hpp>
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
std::string utils::to_base64(const std::vector<unsigned char>& binary)
|
||||
{
|
||||
using namespace boost::archive::iterators;
|
||||
using It = base64_from_binary<transform_width<std::vector<unsigned char>::const_iterator, 6, 8>>;
|
||||
auto base64 = std::string(It(binary.begin()), It(binary.end()));
|
||||
// Add padding.
|
||||
return base64.append((3 - binary.size() % 3) % 3, '=');
|
||||
}
|
||||
|
||||
std::vector<unsigned char> utils::from_base64(const std::string& base64)
|
||||
{
|
||||
using namespace boost::archive::iterators;
|
||||
using It = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
|
||||
auto binary = std::vector<unsigned char>(It(base64.begin()), It(base64.end()));
|
||||
// Remove padding.
|
||||
auto length = base64.size();
|
||||
if(binary.size() > 2 && base64[length - 1] == '=' && base64[length - 2] == '=')
|
||||
{
|
||||
binary.erase(binary.end() - 2, binary.end());
|
||||
}
|
||||
else if(binary.size() > 1 && base64[length - 1] == '=')
|
||||
{
|
||||
binary.erase(binary.end() - 1, binary.end());
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> utils::generate_random(const size_t size){
|
||||
std::vector<unsigned char> res(size);
|
||||
if(!RAND_bytes(res.data(), size)){
|
||||
throw std::exception();
|
||||
}
|
||||
return res;
|
||||
}
|
10
src/utils.h
Normal file
10
src/utils.h
Normal file
@ -0,0 +1,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace utils {
|
||||
|
||||
std::string to_base64(const std::vector<unsigned char>& binary);
|
||||
std::vector<unsigned char> from_base64(const std::string& base64);
|
||||
std::vector<unsigned char> generate_random(const size_t buf_len);
|
||||
|
||||
}
|
7
test/CMakeLists.txt
Normal file
7
test/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
set(BINARY ${CMAKE_PROJECT_NAME}_test)
|
||||
|
||||
add_executable(${BINARY} main.cpp crypto-test.cpp utils-test.cpp)
|
||||
|
||||
add_test(NAME test COMMAND ${BINARY})
|
||||
|
||||
target_link_libraries(${BINARY} PUBLIC ${CMAKE_PROJECT_NAME}_lib gtest)
|
43
test/crypto-test.cpp
Normal file
43
test/crypto-test.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include <string>
|
||||
#include "gtest/gtest.h"
|
||||
#include "utils.h"
|
||||
#include "crypto.h"
|
||||
|
||||
typedef std::basic_string<unsigned char> ustring;
|
||||
|
||||
|
||||
std::vector<std::byte> string_to_bytes(const std::string& str){
|
||||
std::vector<std::byte> out;
|
||||
transform(str.begin(), str.end(), std::back_inserter(out), [](auto c){return static_cast<std::byte>(c);});
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/* test command:
|
||||
echo "ditemi perche' se la mucca fa mu il merlo non fa me" |
|
||||
scripts/aes256.sh -k 0123456789ABCDEF0123456789ABCDEF -i 0123456789ABCDEF |
|
||||
xxd -i
|
||||
*/
|
||||
const std::string test1_str = "ditemi perche' se la mucca fa mu il merlo non fa me";
|
||||
const std::string test1_key = "0123456789ABCDEF0123456789ABCDEF";
|
||||
const std::string test1_iv = "0123456789ABCDEF";
|
||||
const std::vector<unsigned char> test1_enc {
|
||||
0x4c, 0x17, 0x6e, 0x6d, 0xd2, 0x83, 0x51, 0x52, 0xfc, 0x5d, 0xbe, 0x0f,
|
||||
0x1b, 0xcf, 0x86, 0xef, 0x73, 0x91, 0x58, 0xc4, 0xdd, 0x1b, 0x09, 0x3d,
|
||||
0x77, 0xe0, 0x78, 0x5d, 0x21, 0xfe, 0x59, 0x9c, 0xb2, 0x12, 0xa6, 0x81,
|
||||
0x12, 0x96, 0x50, 0xd6, 0x5c, 0xe2, 0xc1, 0x99, 0xe3, 0x38, 0x39, 0x8e,
|
||||
0x55, 0xd2, 0x04, 0x73, 0x16, 0x39, 0xc7, 0x6a, 0xd3, 0x61, 0x2c, 0x22,
|
||||
0x59, 0x25, 0xa6, 0x20 };
|
||||
|
||||
TEST(encryptTest, test1){
|
||||
const std::vector<unsigned char> input(test1_str.begin(), test1_str.end());
|
||||
size_t output_len = input.size() + 16;
|
||||
std::vector<unsigned char> output(output_len);
|
||||
const std::vector<unsigned char> key(test1_key.begin(), test1_key.end());
|
||||
const std::vector<unsigned char> iv(test1_iv.begin(), test1_iv.end());
|
||||
|
||||
AES256 a;
|
||||
a.encrypt(key, iv, input, input.size(), output, output_len);
|
||||
|
||||
EXPECT_EQ(test1_enc, output);
|
||||
}
|
6
test/main.cpp
Normal file
6
test/main.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
45
test/utils-test.cpp
Normal file
45
test/utils-test.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "utils.h"
|
||||
|
||||
const std::string test1_str = "sei proprio un sandrone";
|
||||
const std::string test1_base64 = "c2VpIHByb3ByaW8gdW4gc2FuZHJvbmU=";
|
||||
|
||||
const std::string test2_str = "catopleba io ti dono le mie tepa";
|
||||
const std::string test2_base64 = "Y2F0b3BsZWJhIGlvIHRpIGRvbm8gbGUgbWllIHRlcGE=";
|
||||
|
||||
const std::string test3_str = "il pene mi da' si' la moto, ma la moto non da' pene";
|
||||
const std::string test3_base64 = "aWwgcGVuZSBtaSBkYScgc2knIGxhIG1vdG8sIG1hIGxhIG1vdG8gbm9uIGRhJyBwZW5l";
|
||||
|
||||
const std::string test4_str = "mi e' entrata una bruschetta nell'occhio";
|
||||
const std::string test4_base64 = "bWkgZScgZW50cmF0YSB1bmEgYnJ1c2NoZXR0YSBuZWxsJ29jY2hpbw==";
|
||||
|
||||
TEST(utilTests, to_base64Test){
|
||||
EXPECT_EQ(test1_base64, utils::to_base64(std::vector<unsigned char>(test1_str.begin(), test1_str.end())));
|
||||
EXPECT_EQ(test2_base64, utils::to_base64(std::vector<unsigned char>(test2_str.begin(), test2_str.end())));
|
||||
EXPECT_EQ(test3_base64, utils::to_base64(std::vector<unsigned char>(test3_str.begin(), test3_str.end())));
|
||||
EXPECT_EQ(test4_base64, utils::to_base64(std::vector<unsigned char>(test4_str.begin(), test4_str.end())));
|
||||
}
|
||||
|
||||
TEST(utilTests, from_base64Test){
|
||||
auto result = utils::from_base64(test1_base64);
|
||||
EXPECT_EQ(test1_str, std::string(result.begin(), result.end()));
|
||||
|
||||
result = utils::from_base64(test2_base64);
|
||||
EXPECT_EQ(test2_str, std::string(result.begin(), result.end()));
|
||||
|
||||
result = utils::from_base64(test3_base64);
|
||||
EXPECT_EQ(test3_str, std::string(result.begin(), result.end()));
|
||||
|
||||
result = utils::from_base64(test4_base64);
|
||||
EXPECT_EQ(test4_str, std::string(result.begin(), result.end()));
|
||||
}
|
||||
|
||||
TEST(utilTests, generate_random){
|
||||
EXPECT_NE(utils::generate_random(32), utils::generate_random(32));
|
||||
EXPECT_NE(utils::generate_random(16), utils::generate_random(16));
|
||||
EXPECT_NE(utils::generate_random(8), utils::generate_random(8));
|
||||
EXPECT_NE(utils::generate_random(1), utils::generate_random(1));
|
||||
EXPECT_EQ(utils::generate_random(0), utils::generate_random(0));
|
||||
}
|
Loading…
Reference in New Issue
Block a user