diff options
Diffstat (limited to 'src/lib/base')
-rw-r--r-- | src/lib/base/algo_registry.h | 299 | ||||
-rw-r--r-- | src/lib/base/info.txt | 4 | ||||
-rw-r--r-- | src/lib/base/scan_name.cpp | 78 | ||||
-rw-r--r-- | src/lib/base/scan_name.h | 45 |
4 files changed, 20 insertions, 406 deletions
diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h deleted file mode 100644 index bca3715b6..000000000 --- a/src/lib/base/algo_registry.h +++ /dev/null @@ -1,299 +0,0 @@ -/* -* (C) 2014,2015 Jack Lloyd -* (C) 2015 Matej Kenda -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_ALGO_REGISTRY_H__ -#define BOTAN_ALGO_REGISTRY_H__ - -#include <botan/build.h> -#include <botan/types.h> -#include <botan/exceptn.h> -#include <botan/scan_name.h> -#include <functional> -#include <botan/mutex.h> -#include <vector> -#include <map> -#include <string> -#include <unordered_map> - -#if defined(_MSC_VER) && (_MSC_VER <= 1800) - - #define BOTAN_WORKAROUND_GH_321 - #define NOMINMAX 1 - #define WIN32_LEAN_AND_MEAN 1 - #include <windows.h> - -#endif - -namespace Botan { - -#if defined(BOTAN_WORKAROUND_GH_321) - -class WinCS_Mutex - { - public: - WinCS_Mutex() - { - ::InitializeCriticalSection(&m_cs); - } - - ~WinCS_Mutex() - { - ::DeleteCriticalSection(&m_cs); - } - - void lock() - { - ::EnterCriticalSection(&m_cs); - } - - void unlock() - { - ::LeaveCriticalSection(&m_cs); - } - - private: - CRITICAL_SECTION m_cs; - }; - -#endif - -template<typename T> -class Algo_Registry - { - public: - typedef typename T::Spec Spec; - - typedef std::function<T* (const Spec&)> maker_fn; - - static Algo_Registry<T>& global_registry() - { - static Algo_Registry<T> g_registry; - return g_registry; - } - - void add(const std::string& name, const std::string& provider, maker_fn fn, byte pref) - { - lock_guard_type<af_mutex_type> lock(m_mutex); - if(!m_algo_info[name].add_provider(provider, fn, pref)) - throw Exception("Duplicated registration of " + name + "/" + provider); - } - - std::vector<std::string> providers_of(const Spec& spec) - { - lock_guard_type<af_mutex_type> lock(m_mutex); - auto i = m_algo_info.find(spec.algo_name()); - if(i != m_algo_info.end()) - return i->second.providers(); - return std::vector<std::string>(); - } - - void set_provider_preference(const Spec& spec, const std::string& provider, byte pref) - { - lock_guard_type<af_mutex_type> lock(m_mutex); - auto i = m_algo_info.find(spec.algo_name()); - if(i != m_algo_info.end()) - i->second.set_pref(provider, pref); - } - - T* make(const Spec& spec, const std::string& provider = "") - { - const std::vector<maker_fn> makers = get_makers(spec, provider); - - try - { - for(auto&& maker : makers) - { - if(T* t = maker(spec)) - return t; - } - } - catch(std::exception& e) - { - throw Lookup_Error("Creating '" + spec.as_string() + "' failed: " + e.what()); - } - - return nullptr; - } - - class Add - { - public: - Add(const std::string& basename, maker_fn fn, const std::string& provider, byte pref) - { - Algo_Registry<T>::global_registry().add(basename, provider, fn, pref); - } - - Add(bool cond, const std::string& basename, maker_fn fn, const std::string& provider, byte pref) - { - if(cond) - Algo_Registry<T>::global_registry().add(basename, provider, fn, pref); - } - }; - - private: - -#if defined(BOTAN_WORKAROUND_GH_321) - using af_mutex_type = WinCS_Mutex; -#else - using af_mutex_type = mutex_type; -#endif - - Algo_Registry() { } - - std::vector<maker_fn> get_makers(const Spec& spec, const std::string& provider) - { - lock_guard_type<af_mutex_type> lock(m_mutex); - return m_algo_info[spec.algo_name()].get_makers(provider); - } - - struct Algo_Info - { - public: - bool add_provider(const std::string& provider, maker_fn fn, byte pref) - { - if(m_maker_fns.count(provider) > 0) - return false; - - m_maker_fns[provider] = fn; - m_prefs.insert(std::make_pair(pref, provider)); - return true; - } - - std::vector<std::string> providers() const - { - std::vector<std::string> v; - for(auto&& k : m_prefs) - v.push_back(k.second); - return v; - } - - void set_pref(const std::string& provider, byte pref) - { - auto i = m_prefs.begin(); - while(i != m_prefs.end()) - { - if(i->second == provider) - i = m_prefs.erase(i); - else - ++i; - } - m_prefs.insert(std::make_pair(pref, provider)); - } - - std::vector<maker_fn> get_makers(const std::string& req_provider) - { - std::vector<maker_fn> r; - - if(!req_provider.empty()) - { - // find one explicit provider requested by user or fail - auto i = m_maker_fns.find(req_provider); - if(i != m_maker_fns.end()) - r.push_back(i->second); - } - else - { - for(auto&& pref : m_prefs) - r.push_back(m_maker_fns[pref.second]); - } - - return r; - } - private: - std::multimap<byte, std::string, std::greater<byte>> m_prefs; - std::unordered_map<std::string, maker_fn> m_maker_fns; - }; - - af_mutex_type m_mutex; - std::unordered_map<std::string, Algo_Info> m_algo_info; - }; - -template<typename T> T* -make_a(const typename T::Spec& spec, const std::string& provider = "") - { - return Algo_Registry<T>::global_registry().make(spec, provider); - } - -template<typename T> std::vector<std::string> providers_of(const typename T::Spec& spec) - { - return Algo_Registry<T>::global_registry().providers_of(spec); - } - -template<typename T> T* -make_new_T(const typename Algo_Registry<T>::Spec& spec) - { - if(spec.arg_count() == 0) - return new T; - return nullptr; - } - -template<typename T, size_t DEF_VAL> T* -make_new_T_1len(const typename Algo_Registry<T>::Spec& spec) - { - return new T(spec.arg_as_integer(0, DEF_VAL)); - } - -template<typename T, size_t DEF1, size_t DEF2> T* -make_new_T_2len(const typename Algo_Registry<T>::Spec& spec) - { - return new T(spec.arg_as_integer(0, DEF1), spec.arg_as_integer(1, DEF2)); - } - -template<typename T> T* -make_new_T_1str(const typename Algo_Registry<T>::Spec& spec, const std::string& def) - { - return new T(spec.arg(0, def)); - } - -template<typename T> T* -make_new_T_1str_req(const typename Algo_Registry<T>::Spec& spec) - { - return new T(spec.arg(0)); - } - -template<typename T, typename X> T* -make_new_T_1X(const typename Algo_Registry<T>::Spec& spec) - { - std::unique_ptr<X> x(Algo_Registry<X>::global_registry().make(Botan::SCAN_Name(spec.arg(0)))); - if(!x) - throw Exception(spec.arg(0)); - return new T(x.release()); - } - -#define BOTAN_REGISTER_TYPE(T, type, name, maker, provider, pref) \ - namespace { Algo_Registry<T>::Add g_ ## type ## _reg(name, maker, provider, pref); } \ - BOTAN_FORCE_SEMICOLON - -#define BOTAN_REGISTER_TYPE_COND(cond, T, type, name, maker, provider, pref) \ - namespace { Algo_Registry<T>::Add g_ ## type ## _reg(cond, name, maker, provider, pref); } \ - BOTAN_FORCE_SEMICOLON - -#define BOTAN_DEFAULT_ALGORITHM_PRIO 100 -#define BOTAN_SIMD_ALGORITHM_PRIO 110 - -#define BOTAN_REGISTER_NAMED_T(T, name, type, maker) \ - BOTAN_REGISTER_TYPE(T, type, name, maker, "base", BOTAN_DEFAULT_ALGORITHM_PRIO) - -#define BOTAN_REGISTER_T(T, type, maker) \ - BOTAN_REGISTER_TYPE(T, type, #type, maker, "base", BOTAN_DEFAULT_ALGORITHM_PRIO) - -#define BOTAN_REGISTER_T_NOARGS(T, type) \ - BOTAN_REGISTER_TYPE(T, type, #type, make_new_T<type>, "base", BOTAN_DEFAULT_ALGORITHM_PRIO) -#define BOTAN_REGISTER_T_1LEN(T, type, def) \ - BOTAN_REGISTER_TYPE(T, type, #type, (make_new_T_1len<type,def>), "base", BOTAN_DEFAULT_ALGORITHM_PRIO) - -#define BOTAN_REGISTER_NAMED_T_NOARGS(T, type, name, provider) \ - BOTAN_REGISTER_TYPE(T, type, name, make_new_T<type>, provider, BOTAN_DEFAULT_ALGORITHM_PRIO) -#define BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, T, type, name, provider, pref) \ - BOTAN_REGISTER_TYPE_COND(cond, T, type, name, make_new_T<type>, provider, pref) - -#define BOTAN_REGISTER_NAMED_T_2LEN(T, type, name, provider, len1, len2) \ - BOTAN_REGISTER_TYPE(T, type, name, (make_new_T_2len<type,len1,len2>), provider, BOTAN_DEFAULT_ALGORITHM_PRIO) - -} - -#endif diff --git a/src/lib/base/info.txt b/src/lib/base/info.txt index 7553007e5..001ed9e1b 100644 --- a/src/lib/base/info.txt +++ b/src/lib/base/info.txt @@ -10,10 +10,6 @@ sym_algo.h symkey.h </header:public> -<header:internal> -algo_registry.h -</header:internal> - <requires> block hash diff --git a/src/lib/base/scan_name.cpp b/src/lib/base/scan_name.cpp index 76d9b1a17..70c6e7f25 100644 --- a/src/lib/base/scan_name.cpp +++ b/src/lib/base/scan_name.cpp @@ -52,20 +52,8 @@ std::string make_arg( return output; } -std::pair<size_t, std::string> -deref_aliases(const std::pair<size_t, std::string>& in) - { - return std::make_pair(in.first, - SCAN_Name::deref_alias(in.second)); - } - } -SCAN_Name::SCAN_Name(std::string algo_spec, const std::string& extra) : SCAN_Name(algo_spec) - { - m_alg_name += extra; - } - SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec)) { } @@ -78,8 +66,6 @@ SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': "; - algo_spec = SCAN_Name::deref_alias(algo_spec); - for(size_t i = 0; i != algo_spec.size(); ++i) { char c = algo_spec[i]; @@ -100,7 +86,7 @@ SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg else { if(accum.second != "") - name.push_back(deref_aliases(accum)); + name.push_back(accum); accum = std::make_pair(level, ""); } } @@ -109,7 +95,7 @@ SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg } if(accum.second != "") - name.push_back(deref_aliases(accum)); + name.push_back(accum); if(level != 0) throw Decoding_Error(decoding_error + "Missing close paren"); @@ -133,23 +119,6 @@ SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg } } -std::string SCAN_Name::all_arguments() const - { - std::string out; - if(arg_count()) - { - out += "("; - for(size_t i = 0; i != arg_count(); ++i) - { - out += arg(i); - if(i != arg_count() - 1) - out += ","; - } - out += ")"; - } - return out; - } - std::string SCAN_Name::arg(size_t i) const { if(i >= arg_count()) @@ -172,47 +141,4 @@ size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const return to_u32bit(m_args[i]); } -mutex_type SCAN_Name::g_alias_map_mutex; -std::map<std::string, std::string> SCAN_Name::g_alias_map = { - { "3DES", "TripleDES" }, - { "ARC4", "RC4" }, - { "CAST5", "CAST-128" }, - { "DES-EDE", "TripleDES" }, - { "EME-OAEP", "OAEP" }, - { "EME-PKCS1-v1_5", "PKCS1v15" }, - { "EME1", "OAEP" }, - { "EMSA-PKCS1-v1_5", "EMSA_PKCS1" }, - { "EMSA-PSS", "PSSR" }, - { "EMSA2", "EMSA_X931" }, - { "EMSA3", "EMSA_PKCS1" }, - { "EMSA4", "PSSR" }, - { "GOST-34.11", "GOST-R-34.11-94" }, - { "MARK-4", "RC4(256)" }, - { "OMAC", "CMAC" }, - { "PSS-MGF1", "PSSR" }, - { "SHA-1", "SHA-160" }, - { "SHA1", "SHA-160" }, - { "X9.31", "EMSA2" } -}; - -void SCAN_Name::add_alias(const std::string& alias, const std::string& basename) - { - lock_guard_type<mutex_type> lock(g_alias_map_mutex); - - if(g_alias_map.find(alias) == g_alias_map.end()) - g_alias_map[alias] = basename; - } - -std::string SCAN_Name::deref_alias(const std::string& alias) - { - lock_guard_type<mutex_type> lock(g_alias_map_mutex); - - std::string name = alias; - - for(auto i = g_alias_map.find(name); i != g_alias_map.end(); i = g_alias_map.find(name)) - name = i->second; - - return name; - } - } diff --git a/src/lib/base/scan_name.h b/src/lib/base/scan_name.h index 75f7d1089..8356863ed 100644 --- a/src/lib/base/scan_name.h +++ b/src/lib/base/scan_name.h @@ -8,7 +8,7 @@ #ifndef BOTAN_SCAN_NAME_H__ #define BOTAN_SCAN_NAME_H__ -#include <botan/types.h> +#include <botan/exceptn.h> #include <string> #include <vector> #include <botan/mutex.h> @@ -36,13 +36,6 @@ class BOTAN_DLL SCAN_Name explicit SCAN_Name(std::string algo_spec); /** - * Create a SCAN_Name - * @param algo_spec A SCAN-format name - * @param extra An extra string appended to the algorithm name - */ - SCAN_Name(std::string algo_spec, const std::string& extra); - - /** * @return original input string */ const std::string& as_string() const { return m_orig_algo_spec; } @@ -53,16 +46,6 @@ class BOTAN_DLL SCAN_Name const std::string& algo_name() const { return m_alg_name; } /** - * @return algorithm name plus any arguments - */ - std::string algo_name_and_args() const { return algo_name() + all_arguments(); } - - /** - * @return all arguments - */ - std::string all_arguments() const; - - /** * @return number of arguments */ size_t arg_count() const { return m_args.size(); } @@ -107,15 +90,6 @@ class BOTAN_DLL SCAN_Name std::string cipher_mode_pad() const { return (m_mode_info.size() >= 2) ? m_mode_info[1] : ""; } - /* - * FIXME add doc - */ - static void add_alias(const std::string& alias, const std::string& basename); - - /* - * FIXME add doc - */ - static std::string deref_alias(const std::string& alias); private: static mutex_type g_alias_map_mutex; static std::map<std::string, std::string> g_alias_map; @@ -126,6 +100,23 @@ class BOTAN_DLL SCAN_Name std::vector<std::string> m_mode_info; }; +// This is unrelated but it is convenient to stash it here +template<typename T> +std::vector<std::string> probe_providers_of(const std::string& algo_spec, + const std::vector<std::string>& possible) + { + std::vector<std::string> providers; + for(auto&& prov : possible) + { + std::unique_ptr<T> o(T::create(algo_spec, prov)); + if(o) + { + providers.push_back(prov); // available + } + } + return providers; + } + } #endif |