summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/cli/utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/cli/utils.cpp')
-rw-r--r--comm/third_party/botan/src/cli/utils.cpp391
1 files changed, 391 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/cli/utils.cpp b/comm/third_party/botan/src/cli/utils.cpp
new file mode 100644
index 0000000000..c6d013029a
--- /dev/null
+++ b/comm/third_party/botan/src/cli/utils.cpp
@@ -0,0 +1,391 @@
+/*
+* (C) 2009,2010,2014,2015 Jack Lloyd
+* (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "cli.h"
+
+#include <botan/version.h>
+#include <botan/cpuid.h>
+#include <botan/internal/stl_util.h>
+#include <botan/internal/os_utils.h>
+#include <sstream>
+#include <iomanip>
+
+#if defined(BOTAN_HAS_HTTP_UTIL)
+ #include <botan/http_util.h>
+#endif
+
+#if defined(BOTAN_HAS_UUID)
+ #include <botan/uuid.h>
+#endif
+
+namespace Botan_CLI {
+
+class Print_Help final : public Command
+ {
+ public:
+ Print_Help() : Command("help") {}
+
+ std::string help_text() const override
+ {
+ std::map<std::string, std::vector<std::unique_ptr<Command>>> grouped_commands;
+
+ auto reg_commands = Command::registered_cmds();
+ for(const auto& cmd_name : reg_commands)
+ {
+ auto cmd = Command::get_cmd(cmd_name);
+ if(cmd)
+ {
+ grouped_commands[cmd->group()].push_back(std::move(cmd));
+ }
+ }
+
+ const std::map<std::string, std::string> groups_description {
+ { "encryption", "Encryption" },
+ { "compression", "Compression" },
+ { "codec", "Encoders/Decoders" },
+ { "hash", "Hash Functions" },
+ { "hmac", "HMAC" },
+ { "info", "Informational" },
+ { "numtheory", "Number Theory" },
+ { "passhash", "Password Hashing" },
+ { "psk", "PSK Database" },
+ { "pubkey", "Public Key Cryptography" },
+ { "tls", "TLS" },
+ { "tss", "Secret Sharing" },
+ { "x509", "X.509" },
+ { "misc", "Miscellaneous" }
+ };
+
+ std::ostringstream oss;
+
+ oss << "Usage: botan <cmd> <cmd-options>\n";
+ oss << "All commands support --verbose --help --output= --error-output= --rng-type= --drbg-seed=\n\n";
+ oss << "Available commands:\n\n";
+
+ for(const auto& commands : grouped_commands)
+ {
+ std::string desc = commands.first;
+ if(desc.empty())
+ {
+ continue;
+ }
+
+ oss << Botan::search_map(groups_description, desc, desc) << ":\n";
+ for(auto& cmd : commands.second)
+ {
+ oss << " " << std::setw(16) << std::left << cmd->cmd_name() << " " << cmd->description() << "\n";
+ }
+ oss << "\n";
+ }
+
+ return oss.str();
+ }
+
+ std::string group() const override
+ {
+ return "";
+ }
+
+ std::string description() const override
+ {
+ return "Prints a help string";
+ }
+
+ void go() override
+ {
+ this->set_return_code(1);
+ output() << help_text();
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("help", Print_Help);
+
+class Has_Command final : public Command
+ {
+ public:
+ Has_Command() : Command("has_command cmd") {}
+
+ std::string group() const override
+ {
+ return "info";
+ }
+
+ std::string description() const override
+ {
+ return "Test if a command is available";
+ }
+
+ void go() override
+ {
+ const std::string cmd = get_arg("cmd");
+
+ bool exists = false;
+ for(auto registered_cmd : Command::registered_cmds())
+ {
+ if(cmd == registered_cmd)
+ {
+ exists = true;
+ break;
+ }
+ }
+
+ if(verbose())
+ {
+ output() << "Command '" << cmd << "' is "
+ << (exists ? "": "not ") << "available\n";
+ }
+
+ if(exists == false)
+ this->set_return_code(1);
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("has_command", Has_Command);
+
+class Config_Info final : public Command
+ {
+ public:
+ Config_Info() : Command("config info_type") {}
+
+ std::string help_text() const override
+ {
+ return "Usage: config info_type\n"
+ " prefix: Print install prefix\n"
+ " cflags: Print include params\n"
+ " ldflags: Print linker params\n"
+ " libs: Print libraries\n";
+ }
+
+ std::string group() const override
+ {
+ return "info";
+ }
+
+ std::string description() const override
+ {
+ return "Print the used prefix, cflags, ldflags or libs";
+ }
+
+ void go() override
+ {
+ const std::string arg = get_arg("info_type");
+
+ if(arg == "prefix")
+ {
+ output() << BOTAN_INSTALL_PREFIX << "\n";
+ }
+ else if(arg == "cflags")
+ {
+ output() << "-I" << BOTAN_INSTALL_PREFIX << "/" << BOTAN_INSTALL_HEADER_DIR << "\n";
+ }
+ else if(arg == "ldflags")
+ {
+ if(*BOTAN_LINK_FLAGS)
+ output() << BOTAN_LINK_FLAGS << ' ';
+ output() << "-L" << BOTAN_INSTALL_LIB_DIR << "\n";
+ }
+ else if(arg == "libs")
+ {
+ output() << "-lbotan-" << Botan::version_major() << " " << BOTAN_LIB_LINK << "\n";
+ }
+ else
+ {
+ throw CLI_Usage_Error("Unknown option to botan config " + arg);
+ }
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("config", Config_Info);
+
+class Version_Info final : public Command
+ {
+ public:
+ Version_Info() : Command("version --full") {}
+
+ std::string group() const override
+ {
+ return "info";
+ }
+
+ std::string description() const override
+ {
+ return "Print version info";
+ }
+
+ void go() override
+ {
+ if(flag_set("full"))
+ {
+ output() << Botan::version_string() << "\n";
+ }
+ else
+ {
+ output() << Botan::short_version_string() << "\n";
+ }
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("version", Version_Info);
+
+class Print_Cpuid final : public Command
+ {
+ public:
+ Print_Cpuid() : Command("cpuid") {}
+
+ std::string group() const override
+ {
+ return "info";
+ }
+
+ std::string description() const override
+ {
+ return "List available processor flags (aes_ni, SIMD extensions, ...)";
+ }
+
+ void go() override
+ {
+ output() << "CPUID flags: " << Botan::CPUID::to_string() << "\n";
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("cpuid", Print_Cpuid);
+
+class Cycle_Counter final : public Command
+ {
+ public:
+ Cycle_Counter() : Command("cpu_clock --test-duration=500") {}
+
+ std::string group() const override
+ {
+ return "info";
+ }
+
+ std::string description() const override
+ {
+ return "Estimate the speed of the CPU cycle counter";
+ }
+
+ void go() override
+ {
+ if(Botan::OS::get_cpu_cycle_counter() == 0)
+ {
+ output() << "No CPU cycle counter on this machine\n";
+ return;
+ }
+
+ const uint64_t test_duration_ns = get_arg_sz("test-duration") * 1000000;
+
+ if(test_duration_ns == 0)
+ {
+ output() << "Invalid test duration\n";
+ return;
+ }
+
+ const uint64_t cc_start = Botan::OS::get_cpu_cycle_counter();
+ const uint64_t ns_start = Botan::OS::get_system_timestamp_ns();
+
+ uint64_t cc_end = 0;
+ uint64_t ns_end = ns_start;
+
+ while((ns_end - ns_start) < test_duration_ns)
+ {
+ ns_end = Botan::OS::get_system_timestamp_ns();
+ cc_end = Botan::OS::get_cpu_cycle_counter();
+ }
+
+ if(cc_end <= cc_start)
+ {
+ output() << "Cycle counter seems to have wrapped, try again\n";
+ return;
+ }
+
+ if(ns_end <= ns_start)
+ {
+ output() << "System clock seems to have wrapped (?!?)\n";
+ return;
+ }
+
+ const uint64_t ns_duration = ns_end - ns_start;
+ const uint64_t cc_duration = cc_end - cc_start;
+
+ const double ratio = static_cast<double>(cc_duration) / ns_duration;
+
+ if(ratio >= 1.0)
+ {
+ // GHz
+ output() << "Estimated CPU clock " << std::setprecision(2) << ratio << " GHz\n";
+ }
+ else
+ {
+ // MHz
+ output() << "Estimated CPU clock " << static_cast<size_t>(ratio * 1000) << " MHz\n";
+ }
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("cpu_clock", Cycle_Counter);
+
+#if defined(BOTAN_HAS_UUID)
+
+class Print_UUID final : public Command
+ {
+ public:
+ Print_UUID() : Command("uuid") {}
+
+ std::string group() const override
+ {
+ return "misc";
+ }
+
+ std::string description() const override
+ {
+ return "Print a random UUID";
+ }
+
+ void go() override
+ {
+ Botan::UUID uuid(rng());
+ output() << uuid.to_string() << "\n";
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("uuid", Print_UUID);
+
+#endif
+
+#if defined(BOTAN_HAS_HTTP_UTIL)
+
+class HTTP_Get final : public Command
+ {
+ public:
+ HTTP_Get() : Command("http_get --redirects=1 --timeout=3000 url") {}
+
+ std::string group() const override
+ {
+ return "misc";
+ }
+
+ std::string description() const override
+ {
+ return "Retrieve resource from the passed http/https url";
+ }
+
+ void go() override
+ {
+ const std::string url = get_arg("url");
+ const std::chrono::milliseconds timeout(get_arg_sz("timeout"));
+ const size_t redirects = get_arg_sz("redirects");
+
+ output() << Botan::HTTP::GET_sync(url, redirects, timeout) << "\n";
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("http_get", HTTP_Get);
+
+#endif // http_util
+
+}