Botan  2.11.0
Crypto and TLS for C++11
ffi.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2015,2017 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #include <botan/ffi.h>
8 #include <botan/internal/ffi_util.h>
9 #include <botan/internal/os_utils.h>
10 #include <botan/version.h>
11 #include <botan/mem_ops.h>
12 #include <botan/hex.h>
13 #include <botan/base64.h>
14 #include <cstdio>
15 #include <cstdlib>
16 
17 namespace Botan_FFI {
18 
19 int ffi_error_exception_thrown(const char* func_name, const char* exn, int rc)
20  {
21  if(Botan::OS::read_env_variable("BOTAN_FFI_PRINT_EXCEPTIONS") != nullptr)
22  {
23  std::fprintf(stderr, "in %s exception '%s' returning %d\n", func_name, exn, rc);
24  }
25  return rc;
26  }
27 
28 namespace {
29 
30 int ffi_map_error_type(Botan::ErrorType err)
31  {
32  switch(err)
33  {
36 
48 
62 
66 
69 
74 
79  }
80 
82  }
83 
84 }
85 
86 int ffi_guard_thunk(const char* func_name, std::function<int ()> thunk)
87  {
88  try
89  {
90  return thunk();
91  }
92  catch(std::bad_alloc&)
93  {
94  return ffi_error_exception_thrown(func_name, "bad_alloc", BOTAN_FFI_ERROR_OUT_OF_MEMORY);
95  }
96  catch(Botan_FFI::FFI_Error& e)
97  {
98  return ffi_error_exception_thrown(func_name, e.what(), e.error_code());
99  }
100  catch(Botan::Exception& e)
101  {
102  return ffi_error_exception_thrown(func_name, e.what(), ffi_map_error_type(e.error_type()));
103  }
104  catch(std::exception& e)
105  {
106  return ffi_error_exception_thrown(func_name, e.what());
107  }
108  catch(...)
109  {
110  return ffi_error_exception_thrown(func_name, "unknown exception");
111  }
112 
114  }
115 
116 }
117 
118 extern "C" {
119 
120 using namespace Botan_FFI;
121 
122 const char* botan_error_description(int err)
123  {
124  switch(err)
125  {
126  case BOTAN_FFI_SUCCESS:
127  return "OK";
128 
130  return "Invalid verifier";
131 
133  return "Invalid input";
134 
136  return "Invalid authentication code";
137 
139  return "Insufficient buffer space";
140 
142  return "Exception thrown";
143 
145  return "Out of memory";
146 
148  return "Error while calling system API";
149 
151  return "Internal error";
152 
154  return "Bad flag";
155 
157  return "Null pointer argument";
158 
160  return "Bad parameter";
161 
163  return "Key not set on object";
164 
166  return "Invalid key length";
167 
169  return "Invalid object state";
170 
172  return "Not implemented";
173 
175  return "Invalid object handle";
176 
178  return "TLS error";
179 
181  return "HTTP error";
182 
184  return "Unknown error";
185  }
186 
187  return "Unknown error";
188  }
189 
190 /*
191 * Versioning
192 */
194  {
195  return BOTAN_HAS_FFI;
196  }
197 
198 int botan_ffi_supports_api(uint32_t api_version)
199  {
200  // This is the API introduced in 2.8
201  if(api_version == 20180713)
202  return BOTAN_FFI_SUCCESS;
203 
204  // This is the API introduced in 2.3
205  if(api_version == 20170815)
206  return BOTAN_FFI_SUCCESS;
207 
208  // This is the API introduced in 2.1
209  if(api_version == 20170327)
210  return BOTAN_FFI_SUCCESS;
211 
212  // This is the API introduced in 2.0
213  if(api_version == 20150515)
214  return BOTAN_FFI_SUCCESS;
215 
216  // Something else:
217  return -1;
218  }
219 
220 const char* botan_version_string()
221  {
222  return Botan::version_cstr();
223  }
224 
229 
230 int botan_constant_time_compare(const uint8_t* x, const uint8_t* y, size_t len)
231  {
232  return Botan::constant_time_compare(x, y, len) ? 0 : -1;
233  }
234 
235 int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len)
236  {
238  }
239 
240 int botan_scrub_mem(void* mem, size_t bytes)
241  {
243  return BOTAN_FFI_SUCCESS;
244  }
245 
246 int botan_hex_encode(const uint8_t* in, size_t len, char* out, uint32_t flags)
247  {
248  return ffi_guard_thunk(__func__, [=]() -> int {
249  const bool uppercase = (flags & BOTAN_FFI_HEX_LOWER_CASE) == 0;
251  return BOTAN_FFI_SUCCESS;
252  });
253  }
254 
255 int botan_hex_decode(const char* hex_str, size_t in_len, uint8_t* out, size_t* out_len)
256  {
257  return ffi_guard_thunk(__func__, [=]() -> int {
258  const std::vector<uint8_t> bin = Botan::hex_decode(hex_str, in_len);
260  });
261  }
262 
263 int botan_base64_encode(const uint8_t* in, size_t len, char* out, size_t* out_len)
264  {
265  return ffi_guard_thunk(__func__, [=]() -> int {
266  const std::string base64 = Botan::base64_encode(in, len);
267  return Botan_FFI::write_str_output(out, out_len, base64);
268  });
269  }
270 
271 int botan_base64_decode(const char* base64_str, size_t in_len,
272  uint8_t* out, size_t* out_len)
273  {
274  return ffi_guard_thunk(__func__, [=]() -> int {
276  {
279  }
280 
281  *out_len = Botan::base64_decode(out, std::string(base64_str, in_len));
282  return BOTAN_FFI_SUCCESS;
283  });
284  }
285 
286 }
int ffi_guard_thunk(const char *func_name, std::function< int()> thunk)
Definition: ffi.cpp:86
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14
int botan_hex_encode(const uint8_t *in, size_t len, char *out, uint32_t flags)
Definition: ffi.cpp:246
int ffi_error_exception_thrown(const char *func_name, const char *exn, int rc)
Definition: ffi.cpp:19
size_t base64_decode_max_output(size_t input_length)
Definition: base64.cpp:224
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:81
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
Definition: ffi_util.h:146
const botan_mp_t x
Definition: ffi.h:823
#define BOTAN_FFI_HEX_LOWER_CASE
Definition: ffi.h:152
int botan_base64_encode(const uint8_t *in, size_t len, char *out, size_t *out_len)
Definition: ffi.cpp:263
uint32_t botan_version_patch()
Definition: ffi.cpp:227
int botan_scrub_mem(void *mem, size_t bytes)
Definition: ffi.cpp:240
uint32_t version_major()
Definition: version.cpp:72
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
Definition: ffi_util.h:151
const uint8_t * y
Definition: ffi.h:139
const uint8_t * in
Definition: ffi.h:297
const char * version_cstr()
Definition: version.cpp:29
size_t char * out
Definition: ffi.h:162
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:166
uint32_t botan_ffi_api_version()
Definition: ffi.cpp:193
uint32_t version_patch()
Definition: version.cpp:74
ErrorType
Definition: exceptn.h:20
size_t uint8_t size_t * out_len
Definition: ffi.h:171
uint32_t botan_version_major()
Definition: ffi.cpp:225
int botan_same_mem(const uint8_t *x, const uint8_t *y, size_t len)
Definition: ffi.cpp:235
uint32_t version_minor()
Definition: version.cpp:73
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition: hex.cpp:49
const char * botan_error_description(int err)
Definition: ffi.cpp:122
uint32_t botan_version_minor()
Definition: ffi.cpp:226
size_t bytes
Definition: ffi.h:150
uint32_t version_datestamp()
Definition: version.cpp:67
int botan_base64_decode(const char *base64_str, size_t in_len, uint8_t *out, size_t *out_len)
Definition: ffi.cpp:271
void secure_scrub_memory(void *ptr, size_t n)
Definition: os_utils.cpp:61
size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition: base64.cpp:181
uint32_t botan_version_datestamp()
Definition: ffi.cpp:228
int botan_hex_decode(const char *hex_str, size_t in_len, uint8_t *out, size_t *out_len)
Definition: ffi.cpp:255
size_t char uint32_t flags
Definition: ffi.h:162
int botan_ffi_supports_api(uint32_t api_version)
Definition: ffi.cpp:198
botan_mp_t botan_mp_t botan_mp_t e
Definition: ffi.h:1116
const uint8_t size_t len
Definition: ffi.h:139
size_t in_len
Definition: ffi.h:171
void const uint8_t size_t bool uppercase
Definition: hex.h:26
int botan_constant_time_compare(const uint8_t *x, const uint8_t *y, size_t len)
Definition: ffi.cpp:230
const char * read_env_variable(const std::string &var_name)
Definition: os_utils.cpp:382
const char * botan_version_string()
Definition: ffi.cpp:220