aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/ffi/ffi.cpp32
-rw-r--r--src/lib/ffi/ffi.h23
-rw-r--r--src/tests/test_ffi.cpp30
3 files changed, 82 insertions, 3 deletions
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 28eac401a..1cd8e4b90 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -9,6 +9,7 @@
#include <botan/version.h>
#include <botan/mem_ops.h>
#include <botan/hex.h>
+#include <botan/base64.h>
#include <cstdio>
namespace Botan_FFI {
@@ -74,5 +75,36 @@ int botan_hex_encode(const uint8_t* in, size_t len, char* out, uint32_t flags)
});
}
+int botan_hex_decode(const char* hex_str, size_t in_len, uint8_t* out, size_t* out_len)
+ {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ const std::vector<uint8_t> bin = Botan::hex_decode(hex_str, in_len);
+ return Botan_FFI::write_vec_output(out, out_len, bin);
+ });
+ }
+
+int botan_base64_encode(const uint8_t* in, size_t len, char* out, size_t* out_len)
+ {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ const std::string base64 = Botan::base64_encode(in, len);
+ return Botan_FFI::write_str_output(out, out_len, base64);
+ });
+ }
+
+int botan_base64_decode(const char* base64_str, size_t in_len,
+ uint8_t* out, size_t* out_len)
+ {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ if(*out_len < Botan::base64_decode_max_output(in_len))
+ {
+ *out_len = Botan::base64_decode_max_output(in_len);
+ return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
+ }
+
+ *out_len = Botan::base64_decode(out, std::string(base64_str, in_len));
+ return BOTAN_FFI_SUCCESS;
+ });
+ }
+
}
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index 37f38ae1b..6ee286ad3 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -173,9 +173,26 @@ BOTAN_DLL int botan_scrub_mem(uint8_t* mem, size_t bytes);
*/
BOTAN_DLL int botan_hex_encode(const uint8_t* x, size_t len, char* out, uint32_t flags);
-// TODO: botan_hex_decode
-// TODO: botan_base64_encode
-// TODO: botan_base64_decode
+/**
+* Perform hex decoding
+* @param hex_str a string of hex chars (whitespace is ignored)
+* @param in_len the length of hex_str
+* @param out the output buffer should be at least strlen(hex_str)/2 bytes
+* @param out_len the size of out
+*/
+BOTAN_DLL int botan_hex_decode(const char* hex_str, size_t in_len, uint8_t* out, size_t* out_len);
+
+/**
+* Perform base64 encoding
+*/
+BOTAN_DLL int botan_base64_encode(const uint8_t* x, size_t len, char* out, size_t* out_len);
+
+
+/**
+* Perform base64 decoding
+*/
+BOTAN_DLL int botan_base64_decode(const char* base64_str, size_t in_len,
+ uint8_t* out, size_t* out_len);
/**
* RNG type
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
index 3b825ad4e..34d832026 100644
--- a/src/tests/test_ffi.cpp
+++ b/src/tests/test_ffi.cpp
@@ -361,6 +361,7 @@ class FFI_Unit_Tests : public Test
std::vector<Test::Result> results;
results.push_back(ffi_test_errors());
+ results.push_back(ffi_test_base64());
results.push_back(ffi_test_mp(rng));
results.push_back(ffi_test_block_ciphers());
results.push_back(ffi_test_ciphers_cbc());
@@ -697,6 +698,35 @@ class FFI_Unit_Tests : public Test
return result;
}
+ Test::Result ffi_test_base64()
+ {
+ Test::Result result("FFI base64");
+
+ const uint8_t bin[9] = { 0x16, 0x8a, 0x1f, 0x06, 0xe9, 0xe7, 0xcb, 0xdd, 0x34 };
+ char out_buf[1024] = { 0 };
+
+ size_t out_len = sizeof(out_buf);
+ TEST_FFI_OK(botan_base64_encode, (bin, sizeof(bin), out_buf, &out_len));
+
+ result.test_eq("encoded string", out_buf, "FoofBunny900");
+
+ out_len -= 1;
+ TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE,
+ botan_base64_encode,
+ (bin, sizeof(bin), out_buf, &out_len));
+
+ const char* base64 = "U3VjaCBiYXNlNjQgd293IQ==";
+ uint8_t out_bin[1024] = { 0 };
+ out_len = sizeof(out_bin);
+ TEST_FFI_OK(botan_base64_decode, (base64, strlen(base64), out_bin, &out_len));
+
+ result.test_eq("decoded string",
+ std::string(reinterpret_cast<const char*>(out_bin), out_len),
+ "Such base64 wow!");
+
+ return result;
+ }
+
Test::Result ffi_test_mp(botan_rng_t rng)
{
Test::Result result("FFI MP");