aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli/cli.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/cli.h')
-rw-r--r--src/cli/cli.h71
1 files changed, 57 insertions, 14 deletions
diff --git a/src/cli/cli.h b/src/cli/cli.h
index 017966eca..49167b2ad 100644
--- a/src/cli/cli.h
+++ b/src/cli/cli.h
@@ -10,6 +10,11 @@
#include <botan/build.h>
#include <botan/parsing.h>
#include <botan/rng.h>
+#include <botan/auto_rng.h>
+
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#endif
#include <fstream>
#include <iostream>
@@ -106,6 +111,7 @@ class Command
// for checking all spec strings at load time
//parse_spec();
}
+ virtual ~Command() = default;
int run(const std::vector<std::string>& params)
{
@@ -195,7 +201,7 @@ class Command
if(flag_set("help"))
{
output() << help_text() << "\n";
- return 1;
+ return 2;
}
if(m_user_args.count("output"))
@@ -308,6 +314,7 @@ class Command
m_spec_flags.insert("help");
m_spec_opts.insert(std::make_pair("output", ""));
m_spec_opts.insert(std::make_pair("error-output", ""));
+ m_spec_opts.insert(std::make_pair("rng-type", "auto"));
}
/*
@@ -371,7 +378,7 @@ class Command
{
return static_cast<size_t>(std::stoul(s));
}
- catch(std::exception& e)
+ catch(std::exception&)
{
throw CLI_Usage_Error("Invalid integer value '" + s + "' for option " + opt_name);
}
@@ -420,6 +427,8 @@ class Command
else
{
std::ifstream in(input_file, std::ios::binary);
+ if(!in)
+ throw CLI_IO_Error("reading file", input_file);
do_read_file(in, consumer_fn, buf_size);
}
}
@@ -444,6 +453,36 @@ class Command
output().write(reinterpret_cast<const char*>(vec.data()), vec.size());
}
+ Botan::RandomNumberGenerator& rng()
+ {
+ if(m_rng == nullptr)
+ {
+ const std::string rng_type = get_arg("rng-type");
+
+ if(rng_type == "system")
+ {
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ m_rng.reset(new Botan::System_RNG);
+#endif
+ }
+
+ // TODO --rng-type=drbg
+ // TODO --drbg-seed=hexstr
+
+ if(rng_type == "auto")
+ {
+ m_rng.reset(new Botan::AutoSeeded_RNG);
+ }
+
+ if(!m_rng)
+ {
+ throw CLI_Error_Unsupported("rng", rng_type);
+ }
+ }
+
+ return *m_rng.get();
+ }
+
private:
// set in constructor
std::string m_spec;
@@ -462,34 +501,38 @@ class Command
std::unique_ptr<std::ofstream> m_output_stream;
std::unique_ptr<std::ofstream> m_error_output_stream;
+ std::unique_ptr<Botan::RandomNumberGenerator> m_rng;
public:
// the registry interface:
- static std::map<std::string, std::unique_ptr<Command>>& global_registry()
+ typedef std::function<Command* ()> cmd_maker_fn;
+
+ static std::map<std::string, cmd_maker_fn>& global_registry()
{
- static std::map<std::string, std::unique_ptr<Command>> g_cmds;
+ static std::map<std::string, cmd_maker_fn> g_cmds;
return g_cmds;
}
- static Command* get_cmd(const std::string& name)
+ static std::unique_ptr<Command> get_cmd(const std::string& name)
{
auto& reg = Command::global_registry();
+
+ std::unique_ptr<Command> r;
auto i = reg.find(name);
- if(i == reg.end())
+ if(i != reg.end())
{
- return nullptr;
+ r.reset(i->second());
}
- return i->second.get();
+ return r;
}
class Registration
{
public:
- Registration(Command* cmd)
+ Registration(const std::string& name, cmd_maker_fn maker_fn)
{
- const std::string name = cmd->cmd_name();
auto& reg = Command::global_registry();
if(reg.count(name) > 0)
@@ -497,14 +540,14 @@ class Command
throw CLI_Error("Duplicated registration of command " + name);
}
- Command::global_registry().insert(
- std::make_pair(name, std::unique_ptr<Command>(cmd)));
+ Command::global_registry().insert(std::make_pair(name, maker_fn));
}
};
};
-#define BOTAN_REGISTER_COMMAND(CLI_Class) \
- namespace { Botan_CLI::Command::Registration reg_cmd_ ## CLI_Class(new CLI_Class); }
+#define BOTAN_REGISTER_COMMAND(name, CLI_Class) \
+ namespace { Botan_CLI::Command::Registration \
+ reg_cmd_ ## CLI_Class(name, []() -> Botan_CLI::Command* { return new CLI_Class; }); }
}