diff options
-rw-r--r-- | src/build-data/os/linux.txt | 1 | ||||
-rw-r--r-- | src/engine/dyn_engine/dyn_engine.cpp | 67 | ||||
-rw-r--r-- | src/engine/dyn_engine/dyn_engine.h | 100 | ||||
-rw-r--r-- | src/engine/dyn_engine/info.txt | 18 | ||||
-rw-r--r-- | src/utils/dyn_load/dyn_load.cpp | 53 | ||||
-rw-r--r-- | src/utils/dyn_load/dyn_load.h | 56 | ||||
-rw-r--r-- | src/utils/dyn_load/info.txt | 13 |
7 files changed, 308 insertions, 0 deletions
diff --git a/src/build-data/os/linux.txt b/src/build-data/os/linux.txt index 8bfacd4c9..4c0965764 100644 --- a/src/build-data/os/linux.txt +++ b/src/build-data/os/linux.txt @@ -5,4 +5,5 @@ clock_gettime gettimeofday posix_mlock gmtime_r +dlopen </target_features> diff --git a/src/engine/dyn_engine/dyn_engine.cpp b/src/engine/dyn_engine/dyn_engine.cpp new file mode 100644 index 000000000..2dc76d7d6 --- /dev/null +++ b/src/engine/dyn_engine/dyn_engine.cpp @@ -0,0 +1,67 @@ +/** +* Dynamically Loaded Engine +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/dyn_engine.h> +#include <botan/internal/dyn_load.h> + +namespace Botan { + +namespace { + +extern "C" { + typedef Engine* (*creator_function)(void); + typedef void (*destructor_function)(Engine*); +} + +} + +Dynamically_Loaded_Engine::Dynamically_Loaded_Engine( + const std::string& library_path) : + engine(0) + { + lib = new Dynamically_Loaded_Library(library_path); + + try + { + creator_function creator = lib->resolve<creator_function>("create_engine"); + + engine = creator(); + + if(!engine) + throw std::runtime_error("Creator function in " + library_path + " failed"); + } + catch(...) + { + delete lib; + lib = 0; + throw; + } + } + +Dynamically_Loaded_Engine::~Dynamically_Loaded_Engine() + { + if(lib && engine) + { + try + { + destructor_function destroy = + lib->resolve<destructor_function>("destroy_engine"); + destroy(engine); + } + catch(...) + { + delete lib; + lib = 0; + throw; + } + } + + if(lib) + delete lib; + } + +} diff --git a/src/engine/dyn_engine/dyn_engine.h b/src/engine/dyn_engine/dyn_engine.h new file mode 100644 index 000000000..46752f5a9 --- /dev/null +++ b/src/engine/dyn_engine/dyn_engine.h @@ -0,0 +1,100 @@ +/** +* Dynamically Loaded Engine +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/engine.h> + +namespace Botan { + +/** +* Dynamically_Loaded_Engine just proxies the requests to the underlying +* Engine object, and handles load/unload details +*/ +class BOTAN_DLL Dynamically_Loaded_Engine : public Engine + { + public: + /** + * @param lib_path full pathname to DLL to load + */ + Dynamically_Loaded_Engine(const std::string& lib_path); + + ~Dynamically_Loaded_Engine(); + + std::string provider_name() const { return engine->provider_name(); } + + BlockCipher* find_block_cipher(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const + { + return engine->find_block_cipher(algo_spec, af); + } + + StreamCipher* find_stream_cipher(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const + { + return engine->find_stream_cipher(algo_spec, af); + } + + HashFunction* find_hash(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const + { + return engine->find_hash(algo_spec, af); + } + + MessageAuthenticationCode* find_mac(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const + { + return engine->find_mac(algo_spec, af); + } + + Modular_Exponentiator* mod_exp(const BigInt& n, + Power_Mod::Usage_Hints hints) const + { + return engine->mod_exp(n, hints); + } + + Keyed_Filter* get_cipher(const std::string& algo_spec, + Cipher_Dir dir, + Algorithm_Factory& af) + { + return engine->get_cipher(algo_spec, dir, af); + } + + PK_Ops::Key_Agreement* + get_key_agreement_op(const Private_Key& key) const + { + return engine->get_key_agreement_op(key); + } + + PK_Ops::Signature* + get_signature_op(const Private_Key& key) const + { + return engine->get_signature_op(key); + } + + PK_Ops::Verification* + get_verify_op(const Public_Key& key) const + { + return engine->get_verify_op(key); + } + + PK_Ops::Encryption* + get_encryption_op(const Public_Key& key) const + { + return engine->get_encryption_op(key); + } + + PK_Ops::Decryption* + get_decryption_op(const Private_Key& key) const + { + return engine->get_decryption_op(key); + } + + private: + class Dynamically_Loaded_Library* lib; + Engine* engine; + }; + +} diff --git a/src/engine/dyn_engine/info.txt b/src/engine/dyn_engine/info.txt new file mode 100644 index 000000000..469583522 --- /dev/null +++ b/src/engine/dyn_engine/info.txt @@ -0,0 +1,18 @@ +define DYNAMICALLY_LOADED_ENGINE + +<header:public> +dyn_engine.h +</header:public> + +<source> +dyn_engine.cpp +</source> + +<requires> +engine +dyn_load +</requires> + +<libs> +linux -> dl +</libs> diff --git a/src/utils/dyn_load/dyn_load.cpp b/src/utils/dyn_load/dyn_load.cpp new file mode 100644 index 000000000..621737d0c --- /dev/null +++ b/src/utils/dyn_load/dyn_load.cpp @@ -0,0 +1,53 @@ +/** +* Dynamically Loaded Object +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/dyn_load.h> +#include <botan/build.h> +#include <stdexcept> + +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + #include <dlfcn.h> +#endif + +namespace Botan { + +Dynamically_Loaded_Library::Dynamically_Loaded_Library( + const std::string& library) : + lib_name(library), lib(0) + { +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + lib = ::dlopen(lib_name.c_str(), RTLD_LAZY); + + if(!lib) + throw std::runtime_error("Failed to load engine " + lib_name); +#endif + + } + +Dynamically_Loaded_Library::~Dynamically_Loaded_Library() + { +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + ::dlclose(lib); +#endif + } + +void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) + { + void* addr = 0; + +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + addr = ::dlsym(lib, symbol.c_str()); +#endif + + if(!addr) + throw std::runtime_error("Failed to resolve symbol " + symbol + + " in " + lib_name); + + return addr; + } + +} diff --git a/src/utils/dyn_load/dyn_load.h b/src/utils/dyn_load/dyn_load.h new file mode 100644 index 000000000..d5476b389 --- /dev/null +++ b/src/utils/dyn_load/dyn_load.h @@ -0,0 +1,56 @@ +/** +* Dynamically Loaded Object +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_DYNAMIC_LOADER_H__ +#define BOTAN_DYNAMIC_LOADER_H__ + +#include <string> + +namespace Botan { + +class Dynamically_Loaded_Library + { + public: + /** + * Load a DLL (or fail with an exception) + * @param lib_name name or path to a library + */ + Dynamically_Loaded_Library(const std::string& lib_name); + + /** + * Unload the DLL + * @warning Any pointers returned by resolve()/resolve_symbol() + * should not be used after this destructor runs. + */ + ~Dynamically_Loaded_Library(); + + /** + * Load a symbol (or fail with an exception) + * @param symbol names the symbol to load + * @return address of the loaded symbol + */ + void* resolve_symbol(const std::string& symbol); + + /** + * Convenience function for casting symbol to the right type + * @param symbol names the symbol to load + * @return address of the loaded symbol + */ + template<typename T> + T resolve(const std::string& symbol) + { + return reinterpret_cast<T>(resolve_symbol(symbol)); + } + + private: + std::string lib_name; + void* lib; + }; + +} + +#endif diff --git a/src/utils/dyn_load/info.txt b/src/utils/dyn_load/info.txt new file mode 100644 index 000000000..208870dac --- /dev/null +++ b/src/utils/dyn_load/info.txt @@ -0,0 +1,13 @@ +define DYNAMIC_LOADER + +<libs> +linux -> dl +</libs> + +<source> +dyn_load.cpp +</source> + +<header:internal> +dyn_load.h +</header:internal> |