diff options
author | Jack Lloyd <[email protected]> | 2015-12-19 15:36:40 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2015-12-19 15:36:40 -0500 |
commit | b48e6fb097c62bb246629ee7a182c57e497e4130 (patch) | |
tree | 0cb8ea2d05a89f5e90467f323ae56268d4d3480e /src/cli/utils.cpp | |
parent | d774a9edc46ffcebb28205a678058f083ea75c28 (diff) |
CLI rewrite
The command line tools' origin as a collection of examples and test
programs glued together led to some unfortunate problems; lots of
hardcoded values, missing parameters, and obsolete crypto.
Adds a small library for writing command line programs of the sort
needed here (cli.h), which cuts the length of many of the commands in
half and makes commands more pleasant to write and extend.
Generalizes a lot of the commands also, eg previously only
signing/verification with DSA/SHA-1 was included!
Removes the fuzzer entry point since that's fairly useless outside of
an instrumented build.
Removes the in-library API for benchmarking.
Diffstat (limited to 'src/cli/utils.cpp')
-rw-r--r-- | src/cli/utils.cpp | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/src/cli/utils.cpp b/src/cli/utils.cpp new file mode 100644 index 000000000..f3ce5f0f9 --- /dev/null +++ b/src/cli/utils.cpp @@ -0,0 +1,266 @@ +/* +* (C) 2009,2010,2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "cli.h" + +#include <botan/version.h> +#include <botan/auto_rng.h> +#include <botan/hash.h> +#include <botan/cpuid.h> +#include <botan/hex.h> + +#if defined(BOTAN_HAS_BASE64_CODEC) + #include <botan/base64.h> +#endif + +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#endif + +#if defined(BOTAN_HAS_HTTP_UTIL) + #include <botan/http_util.h> +#endif + +#if defined(BOTAN_HAS_BCRYPT) + #include <botan/bcrypt.h> +#endif + +namespace Botan_CLI { + +class Config_Info : 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"; + } + + 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") + { + output() << "-L" << BOTAN_INSTALL_PREFIX << "/" << BOTAN_INSTALL_LIB_DIR << "\n"; + } + else if(arg == "libs") + { + output() << "-lbotan-" << Botan::version_major() << "." << Botan::version_minor() + << " " << BOTAN_LIB_LINK << "\n"; + } + else + { + throw CLI_Usage_Error("Unknown option to botan config " + arg); + } + } + }; + +BOTAN_REGISTER_COMMAND(Config_Info); + +class Version_Info : public Command + { + public: + Version_Info() : Command("version --full") {} + + void go() override + { + if(flag_set("full")) + { + output() << Botan::version_string() << "\n"; + } + else + { + output() << Botan::version_major() << "." + << Botan::version_minor() << "." + << Botan::version_patch() << "\n"; + } + } + }; + +BOTAN_REGISTER_COMMAND(Version_Info); + +class Print_Cpuid : public Command + { + public: + Print_Cpuid() : Command("cpuid") {} + + void go() override + { + Botan::CPUID::print(output()); + } + }; + +BOTAN_REGISTER_COMMAND(Print_Cpuid); + +class Hash : public Command + { + public: + Hash() : Command("hash --algo=SHA-256 --buf-size=4096 *files") {} + + void go() override + { + const std::string hash_algo = get_arg("algo"); + std::unique_ptr<Botan::HashFunction> hash_fn(Botan::HashFunction::create(hash_algo)); + + if(!hash_fn) + throw CLI_Error_Unsupported("hashing", hash_algo); + + const size_t buf_size = get_arg_sz("buf-size"); + + for(auto fsname : get_arg_list("files")) + { + auto update_hash = [&](const uint8_t b[], size_t l) { hash_fn->update(b, l); }; + read_file(fsname, update_hash, buf_size); + output() << Botan::hex_encode(hash_fn->final()) << " " << fsname << "\n"; + } + } + }; + +BOTAN_REGISTER_COMMAND(Hash); + +class RNG : public Command + { + public: + RNG() : Command("rng bytes --system") {} + + void go() override + { + const size_t bytes = get_arg_sz("bytes"); + + if(flag_set("system")) + { +#if defined(BOTAN_HAS_SYSTEM_RNG) + output() << Botan::hex_encode(Botan::system_rng().random_vec(bytes)) << "\n"; +#else + error_output() << "system_rng disabled in build\n"; +#endif + } + else + { + Botan::AutoSeeded_RNG rng; + output() << Botan::hex_encode(rng.random_vec(bytes)) << "\n"; + } + } + }; + +BOTAN_REGISTER_COMMAND(RNG); + +#if defined(BOTAN_HAS_HTTP_UTIL) + +class HTTP_Get : public Command + { + public: + HTTP_Get() : Command("http_get url") {} + + void go() override + { + output() << Botan::HTTP::GET_sync(get_arg("url")) << "\n"; + } + }; + +BOTAN_REGISTER_COMMAND(HTTP_Get); + +#endif // http_util + +#if defined(BOTAN_HAS_BASE64_CODEC) + +class Base64_Encode : public Command + { + public: + Base64_Encode() : Command("base64_enc file") {} + + void go() override + { + this->read_file(get_arg("file"), + [&](const uint8_t b[], size_t l) { output() << Botan::base64_encode(b, l); }, + 768); + } + }; + +BOTAN_REGISTER_COMMAND(Base64_Encode); + +class Base64_Decode : public Command + { + public: + Base64_Decode() : Command("base64_dec file") {} + + void go() override + { + auto write_bin = [&](const uint8_t b[], size_t l) + { + Botan::secure_vector<uint8_t> bin = Botan::base64_decode(reinterpret_cast<const char*>(b), l); + output().write(reinterpret_cast<const char*>(bin.data()), bin.size()); + }; + + this->read_file(get_arg("file"), + write_bin, + 1024); + } + }; + +BOTAN_REGISTER_COMMAND(Base64_Decode); + +#endif // base64 + +#if defined(BOTAN_HAS_BCRYPT) + +class Generate_Bcrypt : public Command + { + public: + Generate_Bcrypt() : Command("gen_bcrypt --work-factor=12 password") {} + + void go() + { + const std::string password = get_arg("password"); + const size_t wf = get_arg_sz("work_factor"); + + Botan::AutoSeeded_RNG rng; + output() << Botan::generate_bcrypt(password, rng, wf) << "\n"; + } + }; + +BOTAN_REGISTER_COMMAND(Generate_Bcrypt); + +class Check_Bcrypt : public Command + { + public: + Check_Bcrypt() : Command("check_bcrypt password hash") {} + + void go() + { + const std::string password = get_arg("password"); + const std::string hash = get_arg("hash"); + + if(hash.length() != 60) + { + error_output() << "Note: bcrypt '" << hash << "' has wrong length and cannot be valid\n"; + } + + const bool ok = Botan::check_bcrypt(password, hash); + + output() << "Password is " << (ok ? "valid" : "NOT valid") << std::endl; + } + }; + +BOTAN_REGISTER_COMMAND(Check_Bcrypt); + +#endif // bcrypt + +} |