summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/codec/c++/base64.hpp104
-rw-r--r--modules/codec/c++/data.hpp7
-rw-r--r--modules/codec/tests/base64.cpp24
-rw-r--r--modules/crypto/c++/hash.hpp26
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;
}
};
}