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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
* (C) 2015,2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/ffi.h>
#include <botan/internal/ffi_util.h>
#include <botan/version.h>
#include <botan/mem_ops.h>
#include <botan/hex.h>
#include <botan/base64.h>
#include <cstdio>
namespace Botan_FFI {
int ffi_error_exception_thrown(const char* func_name, const char* exn)
{
fprintf(stderr, "in %s exception %s\n", func_name, exn);
return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
}
}
extern "C" {
using namespace Botan_FFI;
/*
* Versioning
*/
uint32_t botan_ffi_api_version()
{
return BOTAN_HAS_FFI;
}
int botan_ffi_supports_api(uint32_t api_version)
{
// Current API version
if(api_version == BOTAN_HAS_FFI)
return BOTAN_FFI_SUCCESS;
// Older versions that are still supported
// This is the 2.1/2.2 API
if(api_version == 20170327)
return BOTAN_FFI_SUCCESS;
// This is the 2.0 API
if(api_version == 20150515)
return BOTAN_FFI_SUCCESS;
return -1;
}
const char* botan_version_string()
{
return Botan::version_cstr();
}
uint32_t botan_version_major() { return Botan::version_major(); }
uint32_t botan_version_minor() { return Botan::version_minor(); }
uint32_t botan_version_patch() { return Botan::version_patch(); }
uint32_t botan_version_datestamp() { return Botan::version_datestamp(); }
int botan_constant_time_compare(const uint8_t* x, const uint8_t* y, size_t len)
{
return Botan::constant_time_compare(x, y, len) ? 0 : -1;
}
int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len)
{
return botan_constant_time_compare(x, y, len);
}
int botan_scrub_mem(void* mem, size_t bytes)
{
Botan::secure_scrub_memory(mem, bytes);
return BOTAN_FFI_SUCCESS;
}
int botan_hex_encode(const uint8_t* in, size_t len, char* out, uint32_t flags)
{
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
const bool uppercase = (flags & BOTAN_FFI_HEX_LOWER_CASE) == 0;
Botan::hex_encode(out, in, len, uppercase);
return BOTAN_FFI_SUCCESS;
});
}
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, [=]() -> int {
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, [=]() -> int {
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, [=]() -> int {
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;
});
}
}
|