aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-07-27 20:58:47 +0000
committerlloyd <[email protected]>2010-07-27 20:58:47 +0000
commit2f3414c1bb2af4db4b03282b47decddf4f3e27e9 (patch)
tree8205bd36d88ec3f1168abda69ca87b5588edf335
parentb910f61fd17fabdf96140f921dc90ca8dbd364d3 (diff)
Add a new utility class Dynamically_Loaded_Library which wraps around
the system dynamic linker (if any). Currently it only supports dlopen, and is only enabled on Linux. It will almost certainly work on BSDs and Solaris as well, though, and should be easy to extend to support Win32-style dynamic loading. Also add a new engine, Dynamically_Loaded_Engine, which loads up a new Engine object from a shared library/DLL.
-rw-r--r--src/build-data/os/linux.txt1
-rw-r--r--src/engine/dyn_engine/dyn_engine.cpp67
-rw-r--r--src/engine/dyn_engine/dyn_engine.h100
-rw-r--r--src/engine/dyn_engine/info.txt18
-rw-r--r--src/utils/dyn_load/dyn_load.cpp53
-rw-r--r--src/utils/dyn_load/dyn_load.h56
-rw-r--r--src/utils/dyn_load/info.txt13
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>