diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/codec/c++/base64.hpp | 104 | ||||
-rw-r--r-- | modules/codec/c++/data.hpp | 7 | ||||
-rw-r--r-- | modules/codec/tests/base64.cpp | 24 | ||||
-rw-r--r-- | modules/crypto/c++/hash.hpp | 26 |
4 files changed, 156 insertions, 5 deletions
diff --git a/modules/codec/c++/base64.hpp b/modules/codec/c++/base64.hpp new file mode 100644 index 0000000..fcd2f75 --- /dev/null +++ b/modules/codec/c++/base64.hpp @@ -0,0 +1,104 @@ +#pragma once + +namespace saw { +namespace encode { +struct Base64 {}; +} + +template<> +class data<schema::String, encode::Base64, storage::Default> { +public: + using Schema = schema::String; +private: + std::string data_; +public: + data() = default; + + data(std::string data__): + data_{std::move(data__)} + {} + + uint64_t size() const { + return data_.size(); + } + + char& at(uint64_t i){ + return data_.at(i); + } + + const char& at(uint64_t i) const { + return data_.at(i); + } + + bool operator==(const data<Schema, encode::Base64>& rhs) const { + return data_ == rhs.data_; + } +}; + +namespace impl { +constexpr char base64_char_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +} + +template<> +class codec<schema::String, encode::Base64> { +public: + using Schema = schema::String; +private: +public: + template<typename FromEncode> + static error_or<void> encode(const data<Schema, FromEncode>& from, data<Schema,encode::Base64>& to){ + std::string b64_str; + + try { + uint64_t unpadded_len = (from.size() * 4u + 2u) / 3u; + uint64_t padded_len = ( unpadded_len + 3u ) & ~3u; + b64_str.resize(padded_len); + }catch(const std::exception&){ + return make_error<err::out_of_memory>(); + } + + uint64_t j{0u}, k{0u}; + std::array<uint8_t,3> s{}; + + for(uint64_t i = 0u; i < from.size(); ++i){ + s[j] = from.at(i); + ++j; + if(j==3){ + b64_str.at(k) = impl::base64_char_map[(s[0u] & 0xFC) >> 2]; + b64_str.at(k+1u) = impl::base64_char_map[((s[0u] & 0x03) << 4) | ((s[1] & 0xF0) >> 4)]; + b64_str.at(k+2u) = impl::base64_char_map[((s[1u] & 0x0F) << 2) | ((s[2] & 0xC0) >> 6)]; + b64_str.at(k+3u) = impl::base64_char_map[(s[2u] & 0x3F)]; + j = 0u; + k+=4u; + } + } + + if(j > 0){ + if( j == 1u ){ + s[1u] = 0u; + } + + b64_str.at(k+0u) = impl::base64_char_map[(s[0u] & 0xFF) >> 2]; + b64_str.at(k+1u) = impl::base64_char_map[((s[0u] & 0x03)<<4) + ((s[1u]&0xF0)>>4)]; + if(j == 2u){ + b64_str[k+2u] = impl::base64_char_map[ ((s[1u]&0x0F)<<2) ]; + }else { + b64_str[k+2u] = '='; + } + b64_str[k+3u] = '='; + } + + to = {std::move(b64_str)}; + return void_t{}; + } + + template<typename ToDecode> + static error_or<void> decode(data<Schema,encode::Base64>& from, data<Schema, ToDecode>& to){ + (void) to; + (void) from; + + return make_error<err::not_implemented>(); + } + +}; +} diff --git a/modules/codec/c++/data.hpp b/modules/codec/c++/data.hpp index 8eff115..b3e4fe2 100644 --- a/modules/codec/c++/data.hpp +++ b/modules/codec/c++/data.hpp @@ -590,13 +590,14 @@ private: std::string value_; public: data() = default; + data(uint64_t size__){ + value_.resize(size__); + } + SAW_DEFAULT_COPY(data); SAW_DEFAULT_MOVE(data); data(std::string value__):value_{std::move(value__)}{} - data(std::size_t size_){ - value_.resize(size_); - } /** * Return the length of the string. diff --git a/modules/codec/tests/base64.cpp b/modules/codec/tests/base64.cpp new file mode 100644 index 0000000..7fb986b --- /dev/null +++ b/modules/codec/tests/base64.cpp @@ -0,0 +1,24 @@ +#include <forstio/test/suite.hpp> +#include "../c++/data.hpp" +#include "../c++/base64.hpp" + +#include <iostream> +namespace { +namespace sch { +using namespace saw::schema; +} +SAW_TEST("Codec Base64 Encode String"){ + using namespace saw; + + data<sch::String> inp_data{"Hello, World!"}; + + data<sch::String, encode::Base64> base64_str; + + codec<sch::String, encode::Base64> base64_codec; + + auto eov = base64_codec.encode(inp_data, base64_str); + SAW_EXPECT(eov.is_value(), "Couldn't encode data"); + + SAW_EXPECT((base64_str == data<sch::String, encode::Base64>{"SGVsbG8sIFdvcmxkIQ=="}), "Base64 not expected value"); +} +} diff --git a/modules/crypto/c++/hash.hpp b/modules/crypto/c++/hash.hpp index 3d25b4e..5898adc 100644 --- a/modules/crypto/c++/hash.hpp +++ b/modules/crypto/c++/hash.hpp @@ -1,5 +1,7 @@ #pragma once +#include <argon2.h> + namespace saw { namespace crypto { struct Argon2i {}; @@ -11,9 +13,29 @@ class hash; template<> class hash<crypto::Argon2i> { public: + error_or<data<schema::String>> apply(const data<schema::String>& input, const data<schema::String>& salt){ + SAW_ASSERT(input.size() > 0u){ + return make_error<err::invalid_state>("Strings for hashing shouldn't be zero"); + } + uint32_t t_cost = 2; + uint32_t m_cost = 1<<16; + uint32_t parallel = 1; + char* salt_c_ptr = nullptr; + if(salt.size() > 0){ + salt_c_ptr = &salt.at(0); + } + data<schema::String> hash; + try { + hash = {128u}; + }catch(const std::exception&){ + return make_error<err::out_of_memory>("Couldn't allocate hash string"); + } + int rv = argon2i_hash_raw(t_cost, m_cost, parallel, &input.at(0), input.size(), &salt.at(0), salt.size(), &hash.at(0), hash.size()); + if(rc != ARGON2_OK){ + return make_error<err::invalid_state>("Failed to hash"); + } - data<schema::String> apply(const data<schema::Array<schema::UInt8>>& input){ - return {""}; + return hash; } }; } |