aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstate
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstate')
-rw-r--r--src/libstate/libstate.cpp6
-rw-r--r--src/libstate/libstate.h2
-rw-r--r--src/libstate/scan_name.cpp132
-rw-r--r--src/libstate/scan_name.h30
4 files changed, 143 insertions, 27 deletions
diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp
index 3275c6493..ca454458b 100644
--- a/src/libstate/libstate.cpp
+++ b/src/libstate/libstate.cpp
@@ -7,6 +7,7 @@
#include <botan/libstate.h>
#include <botan/init.h>
+#include <botan/selftest.h>
#include <botan/engine.h>
#include <botan/stl_util.h>
#include <botan/mutex.h>
@@ -212,7 +213,7 @@ std::string Library_State::deref_alias(const std::string& key) const
/*
* Set/Add an option
*/
-void Library_State::set_option(const std::string key,
+void Library_State::set_option(const std::string& key,
const std::string& value)
{
set("conf", key, value);
@@ -302,6 +303,9 @@ void Library_State::initialize(bool thread_safe)
engines.push_back(new Default_Engine);
m_algorithm_factory = new Algorithm_Factory(engines, *mutex_factory);
+
+ if(!passes_self_tests(algorithm_factory()))
+ throw Self_Test_Failure("Startup self tests failed");
}
/*
diff --git a/src/libstate/libstate.h b/src/libstate/libstate.h
index 2493863a9..a0421953e 100644
--- a/src/libstate/libstate.h
+++ b/src/libstate/libstate.h
@@ -77,7 +77,7 @@ class BOTAN_DLL Library_State
* @param key the key of the option to set
* @param value the value to set
*/
- void set_option(const std::string key, const std::string& value);
+ void set_option(const std::string& key, const std::string& value);
/**
* Add a parameter value to the "alias" section.
diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp
index ef771871d..224d2e509 100644
--- a/src/libstate/scan_name.cpp
+++ b/src/libstate/scan_name.cpp
@@ -1,6 +1,6 @@
/**
-SCAN Name Abstraction
-(C) 2008 Jack Lloyd
+* SCAN Name Abstraction
+* (C) 2008 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -14,28 +14,50 @@ namespace Botan {
namespace {
-std::vector<std::string>
-parse_and_deref_aliases(const std::string& algo_spec)
+std::string make_arg(
+ const std::vector<std::pair<u32bit, std::string> >& name, u32bit start)
{
- std::vector<std::string> parts = parse_algorithm_name(algo_spec);
- std::vector<std::string> out;
+ std::string output = name[start].second;
+ u32bit level = name[start].first;
- for(size_t i = 0; i != parts.size(); ++i)
+ u32bit paren_depth = 0;
+
+ for(u32bit i = start + 1; i != name.size(); ++i)
{
- std::string part_i = global_state().deref_alias(parts[i]);
+ if(name[i].first <= name[start].first)
+ break;
- if(i == 0 && part_i.find_first_of(",()") != std::string::npos)
+ if(name[i].first > level)
{
- std::vector<std::string> parts_i = parse_and_deref_aliases(part_i);
-
- for(size_t j = 0; j != parts_i.size(); ++j)
- out.push_back(parts_i[j]);
+ output += '(' + name[i].second;
+ ++paren_depth;
+ }
+ else if(name[i].first < level)
+ {
+ output += ")," + name[i].second;
+ --paren_depth;
}
else
- out.push_back(part_i);
+ {
+ if(output[output.size() - 1] != '(')
+ output += ",";
+ output += name[i].second;
+ }
+
+ level = name[i].first;
}
- return out;
+ for(u32bit i = 0; i != paren_depth; ++i)
+ output += ')';
+
+ return output;
+ }
+
+std::pair<u32bit, std::string>
+deref_aliases(const std::pair<u32bit, std::string>& in)
+ {
+ return std::make_pair(in.first,
+ global_state().deref_alias(in.second));
}
}
@@ -44,31 +66,101 @@ SCAN_Name::SCAN_Name(const std::string& algo_spec)
{
orig_algo_spec = algo_spec;
- name = parse_and_deref_aliases(algo_spec);
+ std::vector<std::pair<u32bit, std::string> > name;
+ u32bit level = 0;
+ std::pair<u32bit, std::string> accum = std::make_pair(level, "");
+
+ for(u32bit i = 0; i != algo_spec.size(); ++i)
+ {
+ char c = algo_spec[i];
+
+ if(c == '/' || c == ',' || c == '(' || c == ')')
+ {
+ if(c == '(')
+ ++level;
+ else if(c == ')')
+ {
+ if(level == 0)
+ throw Decoding_Error("Bad SCAN name " + algo_spec);
+ --level;
+ }
+
+ if(c == '/' && level > 0)
+ accum.second.push_back(c);
+ else
+ {
+ if(accum.second != "")
+ name.push_back(deref_aliases(accum));
+ accum = std::make_pair(level, "");
+ }
+ }
+ else
+ accum.second.push_back(c);
+ }
+
+ if(accum.second != "")
+ name.push_back(deref_aliases(accum));
- if(name.size() == 0)
+ if(level != 0 || name.size() == 0)
throw Decoding_Error("Bad SCAN name " + algo_spec);
+
+ alg_name = name[0].second;
+
+ bool in_modes = false;
+
+ for(u32bit i = 1; i != name.size(); ++i)
+ {
+ if(name[i].first == 0)
+ {
+ mode_info.push_back(make_arg(name, i));
+ in_modes = true;
+ }
+ else if(name[i].first == 1 && !in_modes)
+ args.push_back(make_arg(name, i));
+ }
+ }
+
+std::string SCAN_Name::algo_name_and_args() const
+ {
+ std::string out;
+
+ out = algo_name();
+
+ if(arg_count())
+ {
+ out += '(';
+ for(u32bit i = 0; i != arg_count(); ++i)
+ {
+ out += arg(i);
+ if(i != arg_count() - 1)
+ out += ',';
+ }
+ out += ')';
+
+ }
+
+ return out;
}
std::string SCAN_Name::arg(u32bit i) const
{
if(i >= arg_count())
throw std::range_error("SCAN_Name::argument");
- return name[i+1];
+ return args[i];
}
std::string SCAN_Name::arg(u32bit i, const std::string& def_value) const
{
if(i >= arg_count())
return def_value;
- return name[i+1];
+ return args[i];
}
u32bit SCAN_Name::arg_as_u32bit(u32bit i, u32bit def_value) const
{
if(i >= arg_count())
return def_value;
- return to_u32bit(name[i+1]);
+ return to_u32bit(args[i]);
}
}
diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h
index 9e7af40d6..ced5f3e15 100644
--- a/src/libstate/scan_name.h
+++ b/src/libstate/scan_name.h
@@ -1,6 +1,6 @@
/**
-SCAN Name Abstraction
-(C) 2008 Jack Lloyd
+* SCAN Name Abstraction
+* (C) 2008 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -35,12 +35,17 @@ class SCAN_Name
/**
@return the algorithm name
*/
- std::string algo_name() const { return name[0]; }
+ std::string algo_name() const { return alg_name; }
+
+ /**
+ @return the algorithm name plus any arguments
+ */
+ std::string algo_name_and_args() const;
/**
@return the number of arguments
*/
- u32bit arg_count() const { return name.size() - 1; }
+ u32bit arg_count() const { return args.size(); }
/**
@return if the number of arguments is between lower and upper
@@ -67,9 +72,24 @@ class SCAN_Name
@return the ith argument as a u32bit, or the default value
*/
u32bit arg_as_u32bit(u32bit i, u32bit def_value) const;
+
+ /**
+ @return the cipher mode (if any)
+ */
+ std::string cipher_mode() const
+ { return (mode_info.size() >= 1) ? mode_info[0] : ""; }
+
+ /**
+ @return the cipher mode padding (if any)
+ */
+ std::string cipher_mode_pad() const
+ { return (mode_info.size() >= 2) ? mode_info[1] : ""; }
+
private:
std::string orig_algo_spec;
- std::vector<std::string> name;
+ std::string alg_name;
+ std::vector<std::string> args;
+ std::vector<std::string> mode_info;
};
}