aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-07-31 10:25:43 -0400
committerJack Lloyd <[email protected]>2017-07-31 10:25:43 -0400
commitbb30a1e1ffbe839478b4bf04624d841c6d9ecfc3 (patch)
treef819222abac3c1362830515afc0d027a2e16f573
parent274fe964858102c7e0d9077dacb882fa495980e3 (diff)
parent9864578977e40715854de1b60501f217147b7452 (diff)
Merge GH #1128 Improve FFI exception safety
-rw-r--r--src/lib/ffi/ffi.cpp1048
-rw-r--r--src/lib/ffi/ffi.h8
-rw-r--r--src/lib/prov/openssl/openssl_block.cpp10
-rw-r--r--src/lib/prov/openssl/openssl_hash.cpp2
-rw-r--r--src/lib/prov/openssl/openssl_mode.cpp3
5 files changed, 368 insertions, 703 deletions
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index d5bbe4896..f13ab7b83 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -112,9 +112,11 @@ struct botan_struct
botan_struct(T* obj) : m_magic(MAGIC), m_obj(obj) {}
~botan_struct() { m_magic = 0; m_obj.reset(); }
+ bool magic_ok() const { return (m_magic == MAGIC); }
+
T* get() const
{
- if(m_magic != MAGIC)
+ if(magic_ok() == false)
throw FFI_Error("Bad magic " + std::to_string(m_magic) +
" in ffi object expected " + std::to_string(MAGIC));
return m_obj.get();
@@ -124,14 +126,9 @@ struct botan_struct
std::unique_ptr<T> m_obj;
};
-void log_exception(const char* func_name, const char* what)
+int ffi_error_exception_thrown(const char* func_name, const char* exn)
{
- fprintf(stderr, "%s: %s\n", func_name, what);
- }
-
-int ffi_error_exception_thrown(const char* exn)
- {
- fprintf(stderr, "exception %s\n", exn);
+ fprintf(stderr, "in %s exception %s\n", func_name, exn);
return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
}
@@ -155,6 +152,31 @@ const T& safe_get(const botan_struct<T,M>* p)
throw FFI_Error("Invalid object pointer");
}
+template<typename Thunk>
+int ffi_guard_thunk(const char* func_name, Thunk thunk)
+ {
+ try
+ {
+ return thunk();
+ }
+ catch(std::bad_alloc)
+ {
+ return ffi_error_exception_thrown(func_name, "bad_alloc");
+ }
+ catch(std::exception& e)
+ {
+ return ffi_error_exception_thrown(func_name, e.what());
+ }
+ catch(...)
+ {
+ return ffi_error_exception_thrown(func_name, "unknown exception");
+ }
+
+ return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
+ }
+
+#define BOTAN_GUARD_BLOCK(b) ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, []() t))
+
template<typename T, uint32_t M, typename F>
int apply_fn(botan_struct<T, M>* o, const char* func_name, F func)
{
@@ -165,20 +187,52 @@ int apply_fn(botan_struct<T, M>* o, const char* func_name, F func)
if(T* t = o->get())
return func(*t);
}
+ catch(std::bad_alloc)
+ {
+ return ffi_error_exception_thrown(func_name, "bad_alloc");
+ }
catch(std::exception& e)
{
- log_exception(func_name, e.what());
- return -1;
+ return ffi_error_exception_thrown(func_name, e.what());
}
catch(...)
{
- log_exception(func_name, "unknown exception type");
- return -2;
+ return ffi_error_exception_thrown(func_name, "unknown exception");
}
- return -1;
+ return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
}
+#define BOTAN_FFI_DO(T, obj, param, block) \
+ apply_fn(obj, BOTAN_CURRENT_FUNCTION, \
+ [=](T& param) -> int { do { block } while(0); return BOTAN_FFI_SUCCESS; })
+
+template<typename T, uint32_t M>
+int ffi_delete_object(botan_struct<T, M>* obj, const char* func_name)
+ {
+ try
+ {
+ if(obj == nullptr)
+ return BOTAN_FFI_SUCCESS; // ignore delete of null objects
+
+ if(obj->magic_ok() == false)
+ return BOTAN_FFI_ERROR_INVALID_INPUT;
+
+ delete obj;
+ return BOTAN_FFI_SUCCESS;
+ }
+ catch(std::exception& e)
+ {
+ return ffi_error_exception_thrown(func_name, e.what());
+ }
+ catch(...)
+ {
+ return ffi_error_exception_thrown(func_name, "unknown exception");
+ }
+ }
+
+#define BOTAN_FFI_CHECKED_DELETE(o) ffi_delete_object(o, BOTAN_CURRENT_FUNCTION)
+
inline int write_output(uint8_t out[], size_t* out_len, const uint8_t buf[], size_t buf_len)
{
const size_t avail = *out_len;
@@ -187,7 +241,7 @@ inline int write_output(uint8_t out[], size_t* out_len, const uint8_t buf[], siz
if(avail >= buf_len)
{
Botan::copy_mem(out, buf, buf_len);
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
else
{
@@ -221,8 +275,6 @@ inline int write_str_output(char out[], size_t* out_len, const std::vector<uint8
str_vec.size());
}
-#define BOTAN_FFI_DO(T, obj, param, block) apply_fn(obj, BOTAN_CURRENT_FUNCTION, [=](T& param) -> int { do { block } while(0); return 0; })
-
Botan::BigInt pubkey_get_field(const Botan::Public_Key& key,
const std::string& field)
{
@@ -338,56 +390,40 @@ Botan::BigInt privkey_get_field(const Botan::Private_Key& key,
throw Botan::Exception("Unsupported algorithm type for botan_privkey_get_field");
}
-#if defined(BOTAN_HAS_ECDSA) || defined(BOTAN_HAS_ECDH)
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+
+// These are always called within an existing try/catch block
+
template<class ECPrivateKey_t>
int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
const Botan::BigInt& scalar,
const char* curve_name)
{
-
if(curve_name == nullptr)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
- try
- {
- Botan::Null_RNG null_rng;
- Botan::EC_Group grp(curve_name);
- key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return -1;
+ Botan::Null_RNG null_rng;
+ Botan::EC_Group grp(curve_name);
+ key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
+ return BOTAN_FFI_SUCCESS;
}
-#endif
-#if defined(BOTAN_HAS_ECDSA) || defined(BOTAN_HAS_ECDH)
template<class ECPublicKey_t>
-int pubkey_load_ec( std::unique_ptr<ECPublicKey_t>& key,
- const Botan::BigInt& public_x,
- const Botan::BigInt& public_y,
- const char* curve_name)
+int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
+ const Botan::BigInt& public_x,
+ const Botan::BigInt& public_y,
+ const char* curve_name)
{
-
if(curve_name == nullptr)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
- try
- {
- Botan::Null_RNG null_rng;
- Botan::EC_Group grp(curve_name);
- Botan::PointGFp uncompressed_point(grp.get_curve(), public_x, public_y);
- key.reset(new ECPublicKey_t(grp, uncompressed_point));
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return -1;
+ Botan::Null_RNG null_rng;
+ Botan::EC_Group grp(curve_name);
+ Botan::PointGFp uncompressed_point(grp.get_curve(), public_x, public_y);
+ key.reset(new ECPublicKey_t(grp, uncompressed_point));
+ return BOTAN_FFI_SUCCESS;
}
+
#endif
} // closes anonymous namespace
@@ -438,7 +474,7 @@ int botan_ffi_supports_api(uint32_t api_version)
* function would accept any of them.
*/
if(api_version == BOTAN_HAS_FFI)
- return 0;
+ return BOTAN_FFI_SUCCESS;
return -1;
}
@@ -460,35 +496,24 @@ int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len)
int botan_scrub_mem(uint8_t* mem, size_t bytes)
{
Botan::secure_scrub_memory(mem, bytes);
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
int botan_hex_encode(const uint8_t* in, size_t len, char* out, uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
const bool uppercase = (flags & BOTAN_FFI_HEX_LOWER_CASE) == 0;
Botan::hex_encode(out, in, len, uppercase);
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return 1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_rng_init(botan_rng_t* rng_out, const char* rng_type)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_ARG_NON_NULL(rng_out);
- if(rng_type == nullptr || *rng_type == 0)
- rng_type = "system";
-
- const std::string rng_type_s(rng_type);
+ const std::string rng_type_s(rng_type ? rng_type : "system");
std::unique_ptr<Botan::RandomNumberGenerator> rng;
@@ -496,29 +521,17 @@ int botan_rng_init(botan_rng_t* rng_out, const char* rng_type)
rng.reset(new Botan::System_RNG);
else if(rng_type_s == "user")
rng.reset(new Botan::AutoSeeded_RNG);
+ else
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
- if(rng)
- {
- *rng_out = new botan_rng_struct(rng.release());
- return 0;
- }
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
-
- return -1;
+ *rng_out = new botan_rng_struct(rng.release());
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_rng_destroy(botan_rng_t rng)
{
- delete rng;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(rng);
}
int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t out_len)
@@ -533,28 +546,12 @@ int botan_rng_reseed(botan_rng_t rng, size_t bits)
int botan_mp_init(botan_mp_t* mp_out)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_ARG_NON_NULL(mp_out);
- std::unique_ptr<Botan::BigInt> mp(new Botan::BigInt);
-
- if(mp)
- {
- *mp_out = new botan_mp_struct(mp.release());
- return 0;
- }
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
-
- return -1;
+ *mp_out = new botan_mp_struct(new Botan::BigInt);
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_mp_clear(botan_mp_t mp)
@@ -666,8 +663,7 @@ int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val)
int botan_mp_destroy(botan_mp_t mp)
{
- delete mp;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(mp);
}
int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
@@ -810,29 +806,19 @@ int botan_mp_num_bytes(const botan_mp_t mp, size_t* bytes)
int botan_block_cipher_init(botan_block_cipher_t* bc, const char* bc_name)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(bc == nullptr || bc_name == nullptr || *bc_name == 0)
return BOTAN_FFI_ERROR_NULL_POINTER;
- std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create(bc_name));
- if(cipher)
- {
- *bc = new botan_block_cipher_struct(cipher.release());
- return 0;
- }
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
+ *bc = nullptr;
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
+ std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create(bc_name));
+ if(cipher == nullptr)
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+ *bc = new botan_block_cipher_struct(cipher.release());
+ return BOTAN_FFI_SUCCESS;
+ });
}
/**
@@ -840,8 +826,7 @@ int botan_block_cipher_init(botan_block_cipher_t* bc, const char* bc_name)
*/
int botan_block_cipher_destroy(botan_block_cipher_t bc)
{
- delete bc;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(bc);
}
int botan_block_cipher_clear(botan_block_cipher_t bc)
@@ -885,36 +870,24 @@ int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc,
int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(hash == nullptr || hash_name == nullptr || *hash_name == 0)
return BOTAN_FFI_ERROR_NULL_POINTER;
if(flags != 0)
return BOTAN_FFI_ERROR_BAD_FLAG;
- auto h = Botan::HashFunction::create(hash_name);
- if(h)
- {
- *hash = new botan_hash_struct(h.release());
- return 0;
- }
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
+ std::unique_ptr<Botan::HashFunction> h = Botan::HashFunction::create(hash_name);
+ if(h == nullptr)
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
+ *hash = new botan_hash_struct(h.release());
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_hash_destroy(botan_hash_t hash)
{
- delete hash;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(hash);
}
int botan_hash_output_length(botan_hash_t hash, size_t* out)
@@ -950,34 +923,24 @@ int botan_hash_copy_state(botan_hash_t* dest, const botan_hash_t source)
int botan_mac_init(botan_mac_t* mac, const char* mac_name, uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(!mac || !mac_name || flags != 0)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
- auto m = Botan::MessageAuthenticationCode::create(mac_name);
- if(m)
- {
- *mac = new botan_mac_struct(m.release());
- return 0;
- }
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
+ std::unique_ptr<Botan::MessageAuthenticationCode> m =
+ Botan::MessageAuthenticationCode::create(mac_name);
+
+ if(m == nullptr)
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
- return -2;
+ *mac = new botan_mac_struct(m.release());
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_mac_destroy(botan_mac_t mac)
{
- delete mac;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(mac);
}
int botan_mac_set_key(botan_mac_t mac, const uint8_t* key, size_t key_len)
@@ -1007,32 +970,20 @@ int botan_mac_final(botan_mac_t mac, uint8_t out[])
int botan_cipher_init(botan_cipher_t* cipher, const char* cipher_name, uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
const bool encrypt_p = ((flags & BOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION) == BOTAN_CIPHER_INIT_FLAG_ENCRYPT);
const Botan::Cipher_Dir dir = encrypt_p ? Botan::ENCRYPTION : Botan::DECRYPTION;
std::unique_ptr<Botan::Cipher_Mode> mode(Botan::get_cipher_mode(cipher_name, dir));
if(!mode)
- return -1;
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
*cipher = new botan_cipher_struct(mode.release());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_cipher_destroy(botan_cipher_t cipher)
{
- delete cipher;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(cipher);
}
int botan_cipher_clear(botan_cipher_t cipher)
@@ -1059,34 +1010,31 @@ int botan_cipher_set_key(botan_cipher_t cipher,
int botan_cipher_start(botan_cipher_t cipher_obj,
const uint8_t* nonce, size_t nonce_len)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::Cipher_Mode& cipher = safe_get(cipher_obj);
cipher.start(nonce, nonce_len);
cipher_obj->m_buf.reserve(cipher.update_granularity());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_cipher_update(botan_cipher_t cipher_obj,
uint32_t flags,
- uint8_t output[],
- size_t output_size,
+ uint8_t output_ptr[],
+ size_t orig_output_size,
size_t* output_written,
- const uint8_t input[],
- size_t input_size,
+ const uint8_t input_ptr[],
+ size_t orig_input_size,
size_t* input_consumed)
{
- using namespace Botan;
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
- try
- {
+ size_t input_size = orig_input_size;
+ size_t output_size = orig_output_size;
+ const uint8_t* input = input_ptr;
+ uint8_t* output = output_ptr;
+
+ using namespace Botan;
Cipher_Mode& cipher = safe_get(cipher_obj);
secure_vector<uint8_t>& mbuf = cipher_obj->m_buf;
@@ -1104,8 +1052,7 @@ int botan_cipher_update(botan_cipher_t cipher_obj,
}
catch(Integrity_Failure& e)
{
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- return -2;
+ return BOTAN_FFI_ERROR_BAD_MAC;
}
*output_written = mbuf.size();
@@ -1114,7 +1061,7 @@ int botan_cipher_update(botan_cipher_t cipher_obj,
{
copy_mem(output, mbuf.data(), mbuf.size());
mbuf.clear();
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
return -1;
@@ -1128,7 +1075,7 @@ int botan_cipher_update(botan_cipher_t cipher_obj,
{
copy_mem(output, mbuf.data(), mbuf.size());
mbuf.clear();
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
return -1;
@@ -1137,19 +1084,6 @@ int botan_cipher_update(botan_cipher_t cipher_obj,
const size_t ud = cipher.update_granularity();
BOTAN_ASSERT(cipher.update_granularity() > cipher.minimum_final_size(), "logic error");
-#if 0
- // Avoiding double copy:
- if(Online_Cipher_Mode* ocm = dynamic_cast<Online_Cipher_Mode*>(&cipher))
- {
- const size_t taken = round_down(input_size, ud);
- *input_consumed = taken;
- *output_size = taken;
- copy_mem(output, input, taken);
- ocm->update_in_place(output, taken);
- return 0;
- }
-#endif
-
mbuf.resize(ud);
size_t taken = 0, written = 0;
@@ -1171,14 +1105,8 @@ int botan_cipher_update(botan_cipher_t cipher_obj,
*output_written = written;
*input_consumed = taken;
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_cipher_set_associated_data(botan_cipher_t cipher,
@@ -1189,9 +1117,9 @@ int botan_cipher_set_associated_data(botan_cipher_t cipher,
if(Botan::AEAD_Mode* aead = dynamic_cast<Botan::AEAD_Mode*>(&c))
{
aead->set_associated_data(ad, ad_len);
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
- return -1;
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
});
}
@@ -1219,18 +1147,11 @@ int botan_pbkdf(const char* pbkdf_algo, uint8_t out[], size_t out_len,
const char* pass, const uint8_t salt[], size_t salt_len,
size_t iterations)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo));
pbkdf->pbkdf_iterations(out, out_len, pass, salt, salt_len, iterations);
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_pbkdf_timed(const char* pbkdf_algo,
@@ -1240,20 +1161,13 @@ int botan_pbkdf_timed(const char* pbkdf_algo,
size_t ms_to_run,
size_t* iterations_used)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo));
pbkdf->pbkdf_timed(out, out_len, password, salt, salt_len,
std::chrono::milliseconds(ms_to_run),
*iterations_used);
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_kdf(const char* kdf_algo,
@@ -1262,18 +1176,11 @@ int botan_kdf(const char* kdf_algo,
const uint8_t salt[], size_t salt_len,
const uint8_t label[], size_t label_len)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
std::unique_ptr<Botan::KDF> kdf(Botan::get_kdf(kdf_algo));
kdf->kdf(out, out_len, secret, secret_len, salt, salt_len, label, label_len);
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
@@ -1281,8 +1188,8 @@ int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
botan_rng_t rng_obj, size_t wf,
uint32_t flags)
{
- try
- {
+#if defined(BOTAN_HAS_BCRYPT)
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_ARG_NON_NULL(out);
BOTAN_ASSERT_ARG_NON_NULL(out_len);
BOTAN_ASSERT_ARG_NON_NULL(pass);
@@ -1293,46 +1200,24 @@ int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
if(wf < 2 || wf > 30)
throw FFI_Error("Bad bcrypt work factor " + std::to_string(wf));
-#if defined(BOTAN_HAS_BCRYPT)
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
const std::string bcrypt = Botan::generate_bcrypt(pass, rng, wf);
return write_str_output(out, out_len, bcrypt);
+ });
#else
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
-
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
}
int botan_bcrypt_is_valid(const char* pass, const char* hash)
{
- try
- {
#if defined(BOTAN_HAS_BCRYPT)
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
return Botan::check_bcrypt(pass, hash) ? 0 : 1;
+ });
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
-
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
}
int botan_privkey_create(botan_privkey_t* key_obj,
@@ -1340,8 +1225,7 @@ int botan_privkey_create(botan_privkey_t* key_obj,
const char* algo_params,
botan_rng_t rng_obj)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(key_obj == nullptr)
return BOTAN_FFI_ERROR_NULL_POINTER;
@@ -1349,120 +1233,89 @@ int botan_privkey_create(botan_privkey_t* key_obj,
if(rng_obj == nullptr)
return BOTAN_FFI_ERROR_NULL_POINTER;
- if(algo_name == nullptr)
- algo_name = "RSA";
- if(algo_params == nullptr)
- algo_params = "";
-
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
std::unique_ptr<Botan::Private_Key> key(
- Botan::create_private_key(algo_name, rng, algo_params));
+ Botan::create_private_key(algo_name ? algo_name : "RSA",
+ rng,
+ algo_params ? algo_params : ""));
if(key)
{
*key_obj = new botan_privkey_struct(key.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
else
{
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
}
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
+ });
}
int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits)
{
- try
- {
+#if defined(BOTAN_HAS_RSA)
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(key_obj == nullptr || rng_obj == nullptr)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
if(n_bits < 1024 || n_bits > 16*1024)
- return -2;
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
*key_obj = nullptr;
-#if defined(BOTAN_HAS_RSA)
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
std::unique_ptr<Botan::Private_Key> key(new Botan::RSA_PrivateKey(rng, n_bits));
*key_obj = new botan_privkey_struct(key.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
}
-
int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
- {
- try
- {
+ {
+#if defined(BOTAN_HAS_ECDSA)
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(key_obj == nullptr || rng_obj == nullptr || param_str == nullptr || *param_str == 0)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
*key_obj = nullptr;
-#if defined(BOTAN_HAS_ECDSA)
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
Botan::EC_Group grp(param_str);
std::unique_ptr<Botan::Private_Key> key(new Botan::ECDSA_PrivateKey(rng, grp));
*key_obj = new botan_privkey_struct(key.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
}
int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t)
{
- try
- {
+#if defined(BOTAN_HAS_MCELIECE)
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(key_obj == nullptr || rng_obj == nullptr || n == 0 || t == 0)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
*key_obj = nullptr;
-#if defined(BOTAN_HAS_MCELIECE)
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
std::unique_ptr<Botan::Private_Key> key(new Botan::McEliece_PrivateKey(rng, n, t));
*key_obj = new botan_privkey_struct(key.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
- }
}
int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(key_obj == nullptr || rng_obj == nullptr || param_str == nullptr || *param_str == 0)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
*key_obj = nullptr;
@@ -1473,7 +1326,7 @@ int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, con
{
std::unique_ptr<Botan::Private_Key> key(new Botan::Curve25519_PrivateKey(safe_get(rng_obj)));
*key_obj = new botan_privkey_struct(key.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
#endif
@@ -1481,15 +1334,11 @@ int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, con
Botan::EC_Group grp(params);
std::unique_ptr<Botan::Private_Key> key(new Botan::ECDH_PrivateKey(safe_get(rng_obj), grp));
*key_obj = new botan_privkey_struct(key.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+ });
}
int botan_privkey_load(botan_privkey_t* key, botan_rng_t rng_obj,
@@ -1498,30 +1347,24 @@ int botan_privkey_load(botan_privkey_t* key, botan_rng_t rng_obj,
{
*key = nullptr;
- try
- {
- Botan::DataSource_Memory src(bits, len);
+ if(password == nullptr)
+ password = "";
- if(password == nullptr)
- password = "";
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ Botan::DataSource_Memory src(bits, len);
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
- std::unique_ptr<Botan::PKCS8_PrivateKey> pkcs8;
- pkcs8.reset(Botan::PKCS8::load_key(src, rng, static_cast<std::string>(password)));
+ std::unique_ptr<Botan::PKCS8_PrivateKey> pkcs8(
+ Botan::PKCS8::load_key(src, rng, static_cast<std::string>(password)));
if(pkcs8)
{
*key = new botan_privkey_struct(pkcs8.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
+ });
}
int botan_pubkey_load(botan_pubkey_t* key,
@@ -1529,23 +1372,16 @@ int botan_pubkey_load(botan_pubkey_t* key,
{
*key = nullptr;
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::DataSource_Memory src(bits, bits_len);
std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(src));
- if(pubkey)
- {
- *key = new botan_pubkey_struct(pubkey.release());
- return 0;
- }
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
+ if(pubkey == nullptr)
+ return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
- return -1;
+ *key = new botan_pubkey_struct(pubkey.release());
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_privkey_load_rsa(botan_privkey_t* key,
@@ -1553,18 +1389,13 @@ int botan_privkey_load_rsa(botan_privkey_t* key,
{
#if defined(BOTAN_HAS_RSA)
*key = nullptr;
- try
- {
+
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
*key = new botan_privkey_struct(new Botan::RSA_PrivateKey(safe_get(rsa_p),
safe_get(rsa_q),
safe_get(rsa_e)));
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1576,17 +1407,10 @@ int botan_pubkey_load_rsa(botan_pubkey_t* key,
{
#if defined(BOTAN_HAS_RSA)
*key = nullptr;
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
*key = new botan_pubkey_struct(new Botan::RSA_PublicKey(safe_get(n), safe_get(e)));
- return 0;
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, n, e);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1598,18 +1422,13 @@ int botan_privkey_load_dsa(botan_privkey_t* key,
{
#if defined(BOTAN_HAS_DSA)
*key = nullptr;
- try
- {
+
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::Null_RNG null_rng;
Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
*key = new botan_privkey_struct(new Botan::DSA_PrivateKey(null_rng, group, safe_get(x)));
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, p, q, g, x);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1621,18 +1440,12 @@ int botan_pubkey_load_dsa(botan_pubkey_t* key,
{
#if defined(BOTAN_HAS_DSA)
*key = nullptr;
- try
- {
+
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
*key = new botan_pubkey_struct(new Botan::DSA_PublicKey(group, safe_get(y)));
- return 0;
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, p, q, g, y);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1644,18 +1457,11 @@ int botan_pubkey_load_elgamal(botan_pubkey_t* key,
{
#if defined(BOTAN_HAS_ELGAMAL)
*key = nullptr;
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::DL_Group group(safe_get(p), safe_get(g));
*key = new botan_pubkey_struct(new Botan::ElGamal_PublicKey(group, safe_get(y)));
- return 0;
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, p, g, y);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1667,18 +1473,12 @@ int botan_privkey_load_elgamal(botan_privkey_t* key,
{
#if defined(BOTAN_HAS_ELGAMAL)
*key = nullptr;
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::Null_RNG null_rng;
Botan::DL_Group group(safe_get(p), safe_get(g));
*key = new botan_privkey_struct(new Botan::ElGamal_PrivateKey(null_rng, group, safe_get(x)));
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, p, g, x);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1690,18 +1490,11 @@ int botan_privkey_load_ed25519(botan_privkey_t* key,
{
#if defined(BOTAN_HAS_ED25519)
*key = nullptr;
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
*key = new botan_privkey_struct(new Botan::Ed25519_PrivateKey(privkey_vec));
- return 0;
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, privkey);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1713,18 +1506,11 @@ int botan_pubkey_load_ed25519(botan_pubkey_t* key,
{
#if defined(BOTAN_HAS_ED25519)
*key = nullptr;
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
*key = new botan_pubkey_struct(new Botan::Ed25519_PublicKey(pubkey_vec));
- return 0;
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
#else
BOTAN_UNUSED(key, pubkey);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1742,11 +1528,11 @@ int botan_privkey_ed25519_get_privkey(botan_privkey_t key,
if(key.size() != 64)
return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
Botan::copy_mem(output, key.data(), key.size());
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
else
{
- return -1;
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
}
});
#else
@@ -1766,11 +1552,11 @@ int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key,
if(key.size() != 32)
return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
Botan::copy_mem(output, key.data(), key.size());
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
else
{
- return -1;
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
}
});
#else
@@ -1785,20 +1571,15 @@ int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
const char* curve_name)
{
#if defined(BOTAN_HAS_ECDSA)
- std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
- try
- {
- if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
+
+ int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
+ if(rc == BOTAN_FFI_SUCCESS)
*key = new botan_pubkey_struct(p_key.release());
- return 0;
- }
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
- return -1;
+
+ return rc;
+ });
#else
BOTAN_UNUSED(key, public_x, public_y, curve_name);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1811,20 +1592,15 @@ int botan_pubkey_load_sm2(botan_pubkey_t* key,
const char* curve_name)
{
#if defined(BOTAN_HAS_SM2)
- std::unique_ptr<Botan::SM2_Signature_PublicKey> p_key;
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::SM2_Signature_PublicKey> p_key;
if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
{
*key = new botan_pubkey_struct(p_key.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
}
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
- return -1;
+ return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
+ });
#else
BOTAN_UNUSED(key, public_x, public_y, curve_name);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1837,20 +1613,14 @@ int botan_pubkey_load_ecdh(botan_pubkey_t* key,
const char* curve_name)
{
#if defined(BOTAN_HAS_ECDH)
- std::unique_ptr<Botan::ECDH_PublicKey> p_key;
- try
- {
- if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::ECDH_PublicKey> p_key;
+ int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
+
+ if(rc == BOTAN_FFI_SUCCESS)
*key = new botan_pubkey_struct(p_key.release());
- return 0;
- }
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
- return -1;
+ return rc;
+ });
#else
BOTAN_UNUSED(key, public_x, public_y, curve_name);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1862,20 +1632,13 @@ int botan_privkey_load_ecdsa(botan_privkey_t* key,
const char* curve_name)
{
#if defined(BOTAN_HAS_ECDSA)
- std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
- try
- {
- if(!privkey_load_ec(p_key, safe_get(scalar), curve_name))
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
+ int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
+ if(rc == BOTAN_FFI_SUCCESS)
*key = new botan_privkey_struct(p_key.release());
- return 0;
- }
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
- return -1;
+ return rc;
+ });
#else
BOTAN_UNUSED(key, scalar, curve_name);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1887,20 +1650,14 @@ int botan_privkey_load_sm2(botan_privkey_t* key,
const char* curve_name)
{
#if defined(BOTAN_HAS_SM2)
- std::unique_ptr<Botan::SM2_Signature_PrivateKey> p_key;
- try
- {
- if(!privkey_load_ec(p_key, safe_get(scalar), curve_name))
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::SM2_Signature_PrivateKey> p_key;
+ int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
+
+ if(rc == BOTAN_FFI_SUCCESS)
*key = new botan_privkey_struct(p_key.release());
- return 0;
- }
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
- return -1;
+ return rc;
+ });
#else
BOTAN_UNUSED(key, scalar, curve_name);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -1912,20 +1669,13 @@ int botan_privkey_load_ecdh(botan_privkey_t* key,
const char* curve_name)
{
#if defined(BOTAN_HAS_ECDH)
- std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
- try
- {
- if(!privkey_load_ec(p_key, safe_get(scalar), curve_name))
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
+ int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
+ if(rc == BOTAN_FFI_SUCCESS)
*key = new botan_privkey_struct(p_key.release());
- return 0;
- }
- }
- catch(std::exception& exn)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
- }
- return -1;
+ return rc;
+ });
#else
BOTAN_UNUSED(key, scalar, curve_name);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
@@ -2017,35 +1767,25 @@ int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
return botan_pubkey_get_field(y, key, "y");
}
-
int botan_privkey_destroy(botan_privkey_t key)
{
- delete key;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(key);
}
int botan_pubkey_destroy(botan_pubkey_t key)
{
- delete key;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(key);
}
int botan_privkey_export_pubkey(botan_pubkey_t* pubout, botan_privkey_t key_obj)
{
- try
- {
- std::unique_ptr<Botan::Public_Key> pubkey(
- Botan::X509::load_key(
- Botan::X509::BER_encode(safe_get(key_obj))));
- *pubout = new botan_pubkey_struct(pubkey.release());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::Public_Key>
+ pubkey(Botan::X509::load_key(Botan::X509::BER_encode(safe_get(key_obj))));
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
+ *pubout = new botan_pubkey_struct(pubkey.release());
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len)
@@ -2076,7 +1816,7 @@ int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint
else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
return write_str_output(out, out_len, Botan::X509::PEM_encode(k));
else
- return -2;
+ return BOTAN_FFI_ERROR_BAD_FLAG;
});
}
@@ -2088,7 +1828,7 @@ int botan_privkey_export(botan_privkey_t key, uint8_t out[], size_t* out_len, ui
else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
return write_str_output(out, out_len, Botan::PKCS8::PEM_encode(k));
else
- return -2;
+ return BOTAN_FFI_ERROR_BAD_FLAG;
});
}
@@ -2205,8 +1945,7 @@ int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op,
const char* padding,
uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_NONNULL(op);
*op = nullptr;
@@ -2216,20 +1955,13 @@ int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op,
std::unique_ptr<Botan::PK_Encryptor> pk(new Botan::PK_Encryptor_EME(safe_get(key_obj), Botan::system_rng(), padding));
*op = new botan_pk_op_encrypt_struct(pk.release());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op)
{
- delete op;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(op);
}
int botan_pk_op_encrypt(botan_pk_op_encrypt_t op,
@@ -2250,8 +1982,7 @@ int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
const char* padding,
uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_NONNULL(op);
*op = nullptr;
@@ -2261,20 +1992,13 @@ int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
std::unique_ptr<Botan::PK_Decryptor> pk(new Botan::PK_Decryptor_EME(safe_get(key_obj), Botan::system_rng(), padding));
*op = new botan_pk_op_decrypt_struct(pk.release());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op)
{
- delete op;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(op);
}
int botan_pk_op_decrypt(botan_pk_op_decrypt_t op,
@@ -2294,8 +2018,7 @@ int botan_pk_op_sign_create(botan_pk_op_sign_t* op,
const char* hash,
uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_NONNULL(op);
*op = nullptr;
@@ -2305,20 +2028,13 @@ int botan_pk_op_sign_create(botan_pk_op_sign_t* op,
std::unique_ptr<Botan::PK_Signer> pk(new Botan::PK_Signer(safe_get(key_obj),Botan::system_rng(), hash));
*op = new botan_pk_op_sign_struct(pk.release());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_pk_op_sign_destroy(botan_pk_op_sign_t op)
{
- delete op;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(op);
}
int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len)
@@ -2338,8 +2054,7 @@ int botan_pk_op_verify_create(botan_pk_op_verify_t* op,
const char* hash,
uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_NONNULL(op);
if(flags != 0)
@@ -2347,20 +2062,13 @@ int botan_pk_op_verify_create(botan_pk_op_verify_t* op,
std::unique_ptr<Botan::PK_Verifier> pk(new Botan::PK_Verifier(safe_get(key_obj), hash));
*op = new botan_pk_op_verify_struct(pk.release());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_pk_op_verify_destroy(botan_pk_op_verify_t op)
{
- delete op;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(op);
}
int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len)
@@ -2374,9 +2082,9 @@ int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size
const bool legit = o.check_signature(sig, sig_len);
if(legit)
- return 0;
+ return BOTAN_FFI_SUCCESS;
else
- return 1;
+ return BOTAN_FFI_ERROR_INVALID_INPUT;
});
}
@@ -2385,8 +2093,7 @@ int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op,
const char* kdf,
uint32_t flags)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
BOTAN_ASSERT_NONNULL(op);
*op = nullptr;
@@ -2396,20 +2103,13 @@ int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op,
std::unique_ptr<Botan::PK_Key_Agreement> pk(new Botan::PK_Key_Agreement(safe_get(key_obj), Botan::system_rng(), kdf));
*op = new botan_pk_op_ka_struct(pk.release());
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return -1;
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op)
{
- delete op;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(op);
}
int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
@@ -2418,7 +2118,7 @@ int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
if(auto kak = dynamic_cast<const Botan::PK_Key_Agreement_Key*>(&k))
return write_vec_output(out, out_len, kak->public_value());
- return -2;
+ return BOTAN_FFI_ERROR_BAD_FLAG;
});
}
@@ -2435,69 +2135,37 @@ int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* cert_path)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(!cert_obj || !cert_path)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
std::unique_ptr<Botan::X509_Certificate> c(new Botan::X509_Certificate(cert_path));
-
- if(c)
- {
- *cert_obj = new botan_x509_cert_struct(c.release());
- return 0;
- }
+ *cert_obj = new botan_x509_cert_struct(c.release());
+ return BOTAN_FFI_SUCCESS;
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
-
- return -2;
+ });
}
int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert_bits[], size_t cert_bits_len)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(!cert_obj || !cert_bits)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
Botan::DataSource_Memory bits(cert_bits, cert_bits_len);
std::unique_ptr<Botan::X509_Certificate> c(new Botan::X509_Certificate(bits));
-
- if(c)
- {
- *cert_obj = new botan_x509_cert_struct(c.release());
- return 0;
- }
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- catch(...)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, "unknown");
- }
-
- return -2;
-
+ *cert_obj = new botan_x509_cert_struct(c.release());
+ return BOTAN_FFI_SUCCESS;
+ });
}
int botan_x509_cert_destroy(botan_x509_cert_t cert)
{
- delete cert;
- return 0;
+ return BOTAN_FFI_CHECKED_DELETE(cert);
}
int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len)
@@ -2544,27 +2212,20 @@ int botan_x509_cert_path_verify(botan_x509_cert_t cert, const char* dir)
int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
if(key == nullptr)
- return -1;
+ return BOTAN_FFI_ERROR_NULL_POINTER;
*key = nullptr;
#if defined(BOTAN_HAS_RSA)
std::unique_ptr<Botan::Public_Key> publicKey(safe_get(cert).subject_public_key());
*key = new botan_pubkey_struct(publicKey.release());
- return 0;
+ return BOTAN_FFI_SUCCESS;
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
-
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
+ });
}
int botan_x509_cert_get_issuer_dn(botan_x509_cert_t cert,
@@ -2591,7 +2252,7 @@ int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage
return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, {
const Botan::Key_Constraints k = static_cast<Botan::Key_Constraints>(key_usage);
if(c.allowed_usage(k))
- return 0;
+ return BOTAN_FFI_SUCCESS;
return 1;
});
}
@@ -2599,15 +2260,10 @@ int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage
int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len)
{
#if defined(BOTAN_HAS_HASH_ID)
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
const std::vector<uint8_t> hash_id = Botan::pkcs_hash_id(hash_name);
return write_output(pkcs_id, pkcs_id_len, hash_id.data(), hash_id.size());
- }
- catch(...)
- {
- return BOTAN_FFI_ERROR_EXCEPTION_THROWN;
- }
+ });
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
@@ -2619,25 +2275,20 @@ int botan_mceies_decrypt(botan_privkey_t mce_key_obj,
const uint8_t ad[], size_t ad_len,
uint8_t out[], size_t* out_len)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::Private_Key& key = safe_get(mce_key_obj);
#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
Botan::McEliece_PrivateKey* mce = dynamic_cast<Botan::McEliece_PrivateKey*>(&key);
if(!mce)
- return -2;
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
const Botan::secure_vector<uint8_t> pt = mceies_decrypt(*mce, ct, ct_len, ad, ad_len, aead);
return write_vec_output(out, out_len, pt);
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- return ffi_error_exception_thrown(e.what());
- }
+ });
}
int botan_mceies_encrypt(botan_pubkey_t mce_key_obj,
@@ -2647,26 +2298,21 @@ int botan_mceies_encrypt(botan_pubkey_t mce_key_obj,
const uint8_t ad[], size_t ad_len,
uint8_t out[], size_t* out_len)
{
- try
- {
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
Botan::Public_Key& key = safe_get(mce_key_obj);
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
Botan::McEliece_PublicKey* mce = dynamic_cast<Botan::McEliece_PublicKey*>(&key);
if(!mce)
- return -2;
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
Botan::secure_vector<uint8_t> ct = mceies_encrypt(*mce, pt, pt_len, ad, ad_len, rng, aead);
return write_vec_output(out, out_len, ct);
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
- }
- catch(std::exception& e)
- {
- return ffi_error_exception_thrown(e.what());
- }
+ });
}
int botan_key_wrap3394( uint8_t key[], size_t key_len,
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index cbe883f8d..e56ad5629 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -134,12 +134,20 @@ doesn't exactly work well either!
* To recover the msg, func, and line
*/
+#define BOTAN_FFI_SUCCESS (0)
+
+#define BOTAN_FFI_ERROR_INVALID_INPUT (-1)
+#define BOTAN_FFI_ERROR_BAD_MAC (-2)
+
#define BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE (-10)
#define BOTAN_FFI_ERROR_EXCEPTION_THROWN (-20)
#define BOTAN_FFI_ERROR_BAD_FLAG (-30)
#define BOTAN_FFI_ERROR_NULL_POINTER (-31)
+#define BOTAN_FFI_ERROR_BAD_PARAMETER (-32)
#define BOTAN_FFI_ERROR_NOT_IMPLEMENTED (-40)
+#define BOTAN_FFI_ERROR_UNKNOWN_ERROR (-100)
+
//const char* botan_error_description(int err);
/**
diff --git a/src/lib/prov/openssl/openssl_block.cpp b/src/lib/prov/openssl/openssl_block.cpp
index 5d5cf0b47..122678b6d 100644
--- a/src/lib/prov/openssl/openssl_block.cpp
+++ b/src/lib/prov/openssl/openssl_block.cpp
@@ -67,8 +67,11 @@ OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
m_encrypt = EVP_CIPHER_CTX_new();
- EVP_CIPHER_CTX_init(m_encrypt);
m_decrypt = EVP_CIPHER_CTX_new();
+ if (m_encrypt == nullptr || m_decrypt == nullptr)
+ throw OpenSSL_Error("Can't allocate new context");
+
+ EVP_CIPHER_CTX_init(m_encrypt);
EVP_CIPHER_CTX_init(m_decrypt);
if(!EVP_EncryptInit_ex(m_encrypt, algo, nullptr, nullptr, nullptr))
@@ -95,8 +98,11 @@ OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
m_encrypt = EVP_CIPHER_CTX_new();
- EVP_CIPHER_CTX_init(m_encrypt);
m_decrypt = EVP_CIPHER_CTX_new();
+ if (m_encrypt == nullptr || m_decrypt == nullptr)
+ throw OpenSSL_Error("Can't allocate new context");
+
+ EVP_CIPHER_CTX_init(m_encrypt);
EVP_CIPHER_CTX_init(m_decrypt);
if(!EVP_EncryptInit_ex(m_encrypt, algo, nullptr, nullptr, nullptr))
diff --git a/src/lib/prov/openssl/openssl_hash.cpp b/src/lib/prov/openssl/openssl_hash.cpp
index d7a8014a8..16b1a79fe 100644
--- a/src/lib/prov/openssl/openssl_hash.cpp
+++ b/src/lib/prov/openssl/openssl_hash.cpp
@@ -58,6 +58,8 @@ class OpenSSL_HashFunction : public HashFunction
m_md = EVP_MD_CTX_new();
#endif
+ if(m_md == nullptr)
+ throw OpenSSL_Error("Can't allocate new context");
EVP_MD_CTX_init(m_md);
if(md && !EVP_DigestInit_ex(m_md, md, nullptr))
throw OpenSSL_Error("EVP_DigestInit_ex");
diff --git a/src/lib/prov/openssl/openssl_mode.cpp b/src/lib/prov/openssl/openssl_mode.cpp
index 36f19eaec..bbb193feb 100644
--- a/src/lib/prov/openssl/openssl_mode.cpp
+++ b/src/lib/prov/openssl/openssl_mode.cpp
@@ -59,6 +59,9 @@ OpenSSL_Cipher_Mode::OpenSSL_Cipher_Mode(const std::string& name,
throw Invalid_Argument("OpenSSL_BlockCipher: Non-CBC EVP was passed in");
m_cipher = EVP_CIPHER_CTX_new();
+ if (m_cipher == nullptr)
+ throw OpenSSL_Error("Can't allocate new context");
+
EVP_CIPHER_CTX_init(m_cipher);
if(!EVP_CipherInit_ex(m_cipher, algo, nullptr, nullptr, nullptr,
m_direction == ENCRYPTION ? 1 : 0))