aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cli/cli_rng.cpp44
-rw-r--r--src/cli/codec.cpp204
-rw-r--r--src/cli/hmac.cpp78
-rw-r--r--src/cli/pk_crypt.cpp14
-rw-r--r--src/cli/utils.cpp232
-rw-r--r--src/lib/codec/base58/base58.cpp11
-rwxr-xr-xsrc/scripts/test_cli.py8
7 files changed, 351 insertions, 240 deletions
diff --git a/src/cli/cli_rng.cpp b/src/cli/cli_rng.cpp
index 78af51314..90b30a820 100644
--- a/src/cli/cli_rng.cpp
+++ b/src/cli/cli_rng.cpp
@@ -9,6 +9,7 @@
#include <botan/entropy_src.h>
#include <botan/cpuid.h>
#include <botan/hex.h>
+#include <botan/parsing.h>
#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
#include <botan/auto_rng.h>
@@ -86,4 +87,47 @@ cli_make_rng(const std::string& rng_type, const std::string& hex_drbg_seed)
throw CLI_Error_Unsupported("RNG", rng_type);
}
+class RNG final : public Command
+ {
+ public:
+ RNG() : Command("rng --system --rdrand --auto --entropy --drbg --drbg-seed= *bytes") {}
+
+ std::string group() const override
+ {
+ return "misc";
+ }
+
+ std::string description() const override
+ {
+ return "Sample random bytes from the specified rng";
+ }
+
+ void go() override
+ {
+ std::string type = get_arg("rng-type");
+
+ if(type.empty())
+ {
+ for(std::string flag : { "system", "rdrand", "auto", "entropy", "drbg" })
+ {
+ if(flag_set(flag))
+ {
+ type = flag;
+ break;
+ }
+ }
+ }
+
+ const std::string drbg_seed = get_arg("drbg-seed");
+ std::unique_ptr<Botan::RandomNumberGenerator> rng = cli_make_rng(type, drbg_seed);
+
+ for(const std::string& req : get_arg_list("bytes"))
+ {
+ output() << Botan::hex_encode(rng->random_vec(Botan::to_u32bit(req))) << "\n";
+ }
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("rng", RNG);
+
}
diff --git a/src/cli/codec.cpp b/src/cli/codec.cpp
new file mode 100644
index 000000000..0d3df336d
--- /dev/null
+++ b/src/cli/codec.cpp
@@ -0,0 +1,204 @@
+/*
+* (C) 2019 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "cli.h"
+
+#if defined(BOTAN_HAS_HEX_CODEC)
+ #include <botan/hex.h>
+#endif
+
+#if defined(BOTAN_HAS_BASE58_CODEC)
+ #include <botan/base58.h>
+#endif
+
+#if defined(BOTAN_HAS_BASE64_CODEC)
+ #include <botan/base64.h>
+#endif
+
+namespace Botan_CLI {
+
+#if defined(BOTAN_HAS_HEX_CODEC)
+
+class Hex_Encode final : public Command
+ {
+ public:
+ Hex_Encode() : Command("hex_enc file") {}
+
+ std::string group() const override
+ {
+ return "codec";
+ }
+
+ std::string description() const override
+ {
+ return "Hex encode a given file";
+ }
+
+ void go() override
+ {
+ auto hex_enc_f = [&](const uint8_t b[], size_t l) { output() << Botan::hex_encode(b, l); };
+ this->read_file(get_arg("file"), hex_enc_f, 2);
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("hex_enc", Hex_Encode);
+
+class Hex_Decode final : public Command
+ {
+ public:
+ Hex_Decode() : Command("hex_dec file") {}
+
+ std::string group() const override
+ {
+ return "codec";
+ }
+
+ std::string description() const override
+ {
+ return "Hex decode a given file";
+ }
+
+ void go() override
+ {
+ auto hex_dec_f = [&](const uint8_t b[], size_t l)
+ {
+ std::vector<uint8_t> bin = Botan::hex_decode(reinterpret_cast<const char*>(b), l);
+ output().write(reinterpret_cast<const char*>(bin.data()), bin.size());
+ };
+
+ this->read_file(get_arg("file"), hex_dec_f, 2);
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("hex_dec", Hex_Decode);
+
+#endif
+
+#if defined(BOTAN_HAS_BASE58_CODEC)
+
+class Base58_Encode final : public Command
+ {
+ public:
+ Base58_Encode() : Command("base58_enc --check file") {}
+
+ std::string group() const override
+ {
+ return "codec";
+ }
+
+ std::string description() const override
+ {
+ return "Encode given file to Base58";
+ }
+
+ void go() override
+ {
+ auto data = slurp_file(get_arg("file"));
+
+ if(flag_set("check"))
+ output() << Botan::base58_check_encode(data);
+ else
+ output() << Botan::base58_encode(data);
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("base58_enc", Base58_Encode);
+
+class Base58_Decode final : public Command
+ {
+ public:
+ Base58_Decode() : Command("base58_dec --check file") {}
+
+ std::string group() const override
+ {
+ return "codec";
+ }
+
+ std::string description() const override
+ {
+ return "Decode Base58 encoded file";
+ }
+
+ void go() override
+ {
+ auto data = slurp_file_as_str(get_arg("file"));
+
+ std::vector<uint8_t> bin;
+
+ if(flag_set("check"))
+ bin = Botan::base58_check_decode(data);
+ else
+ bin = Botan::base58_decode(data);
+
+ output().write(reinterpret_cast<const char*>(bin.data()), bin.size());
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("base58_dec", Base58_Decode);
+
+#endif // base64
+
+#if defined(BOTAN_HAS_BASE64_CODEC)
+
+class Base64_Encode final : public Command
+ {
+ public:
+ Base64_Encode() : Command("base64_enc file") {}
+
+ std::string group() const override
+ {
+ return "codec";
+ }
+
+ std::string description() const override
+ {
+ return "Encode given file to Base64";
+ }
+
+ void go() override
+ {
+ auto onData = [&](const uint8_t b[], size_t l)
+ {
+ output() << Botan::base64_encode(b, l);
+ };
+ this->read_file(get_arg("file"), onData, 768);
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("base64_enc", Base64_Encode);
+
+class Base64_Decode final : public Command
+ {
+ public:
+ Base64_Decode() : Command("base64_dec file") {}
+
+ std::string group() const override
+ {
+ return "codec";
+ }
+
+ std::string description() const override
+ {
+ return "Decode Base64 encoded 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_dec", Base64_Decode);
+
+#endif // base64
+
+}
diff --git a/src/cli/hmac.cpp b/src/cli/hmac.cpp
new file mode 100644
index 000000000..5b7345c50
--- /dev/null
+++ b/src/cli/hmac.cpp
@@ -0,0 +1,78 @@
+/*
+* (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/hex.h>
+
+#if defined(BOTAN_HAS_MAC)
+ #include <botan/mac.h>
+#endif
+
+namespace Botan_CLI {
+
+#if defined(BOTAN_HAS_HMAC)
+
+class HMAC final : public Command
+ {
+ public:
+ HMAC() : Command("hmac --hash=SHA-256 --buf-size=4096 --no-fsname key *files") {}
+
+ std::string group() const override
+ {
+ return "hmac";
+ }
+
+ std::string description() const override
+ {
+ return "Compute the HMAC tag of given file(s)";
+ }
+
+ void go() override
+ {
+ const bool no_fsname = flag_set("no-fsname");
+ const std::string hash_algo = get_arg("hash");
+ std::unique_ptr<Botan::MessageAuthenticationCode> hmac =
+ Botan::MessageAuthenticationCode::create("HMAC(" + hash_algo + ")");
+
+ if(!hmac)
+ { throw CLI_Error_Unsupported("HMAC", hash_algo); }
+
+ hmac->set_key(slurp_file(get_arg("key")));
+
+ const size_t buf_size = get_arg_sz("buf-size");
+
+ std::vector<std::string> files = get_arg_list("files");
+ if(files.empty())
+ { files.push_back("-"); } // read stdin if no arguments on command line
+
+ for(const std::string& fsname : files)
+ {
+ try
+ {
+ auto update_hmac = [&](const uint8_t b[], size_t l) { hmac->update(b, l); };
+ read_file(fsname, update_hmac, buf_size);
+ output() << Botan::hex_encode(hmac->final());
+
+ if(no_fsname == false)
+ output() << " " << fsname;
+
+ output() << "\n";
+ }
+ catch(CLI_IO_Error& e)
+ {
+ error_output() << e.what() << "\n";
+ }
+ }
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("hmac", HMAC);
+
+#endif // hmac
+
+}
diff --git a/src/cli/pk_crypt.cpp b/src/cli/pk_crypt.cpp
index 9b7f50746..4888a742f 100644
--- a/src/cli/pk_crypt.cpp
+++ b/src/cli/pk_crypt.cpp
@@ -189,13 +189,19 @@ class PK_Decrypt final : public Command
return set_return_code(1);
}
- Botan::PK_Decryptor_EME dec(*key, rng(), "OAEP(" + oaep_hash + ")");
-
- const Botan::secure_vector<uint8_t> file_key = dec.decrypt(encrypted_key);
-
std::unique_ptr<Botan::AEAD_Mode> aead =
Botan::AEAD_Mode::create_or_throw(aead_algo, Botan::DECRYPTION);
+ const size_t expected_keylen = aead->key_spec().maximum_keylength();
+
+ Botan::PK_Decryptor_EME dec(*key, rng(), "OAEP(" + oaep_hash + ")");
+
+ const Botan::secure_vector<uint8_t> file_key =
+ dec.decrypt_or_random(encrypted_key.data(),
+ encrypted_key.size(),
+ expected_keylen,
+ rng());
+
aead->set_key(file_key);
aead->set_associated_data_vec(encrypted_key);
aead->start(nonce);
diff --git a/src/cli/utils.cpp b/src/cli/utils.cpp
index c9075e2f8..2de6b0ccb 100644
--- a/src/cli/utils.cpp
+++ b/src/cli/utils.cpp
@@ -8,23 +8,11 @@
#include "cli.h"
#include <botan/version.h>
-#include <botan/rng.h>
#include <botan/cpuid.h>
-#include <botan/hex.h>
-#include <botan/parsing.h>
#include <botan/internal/stl_util.h>
#include <sstream>
-#include <iterator>
#include <iomanip>
-#if defined(BOTAN_HAS_MAC)
- #include <botan/mac.h>
-#endif
-
-#if defined(BOTAN_HAS_BASE64_CODEC)
- #include <botan/base64.h>
-#endif
-
#if defined(BOTAN_HAS_HTTP_UTIL)
#include <botan/http_util.h>
#endif
@@ -261,49 +249,6 @@ class Print_Cpuid final : public Command
BOTAN_REGISTER_COMMAND("cpuid", Print_Cpuid);
-class RNG final : public Command
- {
- public:
- RNG() : Command("rng --system --rdrand --auto --entropy --drbg --drbg-seed= *bytes") {}
-
- std::string group() const override
- {
- return "misc";
- }
-
- std::string description() const override
- {
- return "Sample random bytes from the specified rng";
- }
-
- void go() override
- {
- std::string type = get_arg("rng-type");
-
- if(type.empty())
- {
- for(std::string flag : { "system", "rdrand", "auto", "entropy", "drbg" })
- {
- if(flag_set(flag))
- {
- type = flag;
- break;
- }
- }
- }
-
- const std::string drbg_seed = get_arg("drbg-seed");
- std::unique_ptr<Botan::RandomNumberGenerator> rng = cli_make_rng(type, drbg_seed);
-
- for(const std::string& req : get_arg_list("bytes"))
- {
- output() << Botan::hex_encode(rng->random_vec(Botan::to_u32bit(req))) << "\n";
- }
- }
- };
-
-BOTAN_REGISTER_COMMAND("rng", RNG);
-
#if defined(BOTAN_HAS_HTTP_UTIL)
class HTTP_Get final : public Command
@@ -335,181 +280,4 @@ BOTAN_REGISTER_COMMAND("http_get", HTTP_Get);
#endif // http_util
-#if defined(BOTAN_HAS_HEX_CODEC)
-
-class Hex_Encode final : public Command
- {
- public:
- Hex_Encode() : Command("hex_enc file") {}
-
- std::string group() const override
- {
- return "codec";
- }
-
- std::string description() const override
- {
- return "Hex encode a given file";
- }
-
- void go() override
- {
- auto hex_enc_f = [&](const uint8_t b[], size_t l) { output() << Botan::hex_encode(b, l); };
- this->read_file(get_arg("file"), hex_enc_f, 2);
- }
- };
-
-BOTAN_REGISTER_COMMAND("hex_enc", Hex_Encode);
-
-class Hex_Decode final : public Command
- {
- public:
- Hex_Decode() : Command("hex_dec file") {}
-
- std::string group() const override
- {
- return "codec";
- }
-
- std::string description() const override
- {
- return "Hex decode a given file";
- }
-
- void go() override
- {
- auto hex_dec_f = [&](const uint8_t b[], size_t l)
- {
- std::vector<uint8_t> bin = Botan::hex_decode(reinterpret_cast<const char*>(b), l);
- output().write(reinterpret_cast<const char*>(bin.data()), bin.size());
- };
-
- this->read_file(get_arg("file"), hex_dec_f, 2);
- }
- };
-
-BOTAN_REGISTER_COMMAND("hex_dec", Hex_Decode);
-
-#endif
-
-#if defined(BOTAN_HAS_BASE64_CODEC)
-
-class Base64_Encode final : public Command
- {
- public:
- Base64_Encode() : Command("base64_enc file") {}
-
- std::string group() const override
- {
- return "codec";
- }
-
- std::string description() const override
- {
- return "Encode given file to Base64";
- }
-
- void go() override
- {
- auto onData = [&](const uint8_t b[], size_t l)
- {
- output() << Botan::base64_encode(b, l);
- };
- this->read_file(get_arg("file"), onData, 768);
- }
- };
-
-BOTAN_REGISTER_COMMAND("base64_enc", Base64_Encode);
-
-class Base64_Decode final : public Command
- {
- public:
- Base64_Decode() : Command("base64_dec file") {}
-
- std::string group() const override
- {
- return "codec";
- }
-
- std::string description() const override
- {
- return "Decode Base64 encoded 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_dec", Base64_Decode);
-
-#endif // base64
-
-#if defined(BOTAN_HAS_HMAC)
-
-class HMAC final : public Command
- {
- public:
- HMAC() : Command("hmac --hash=SHA-256 --buf-size=4096 --no-fsname key *files") {}
-
- std::string group() const override
- {
- return "hmac";
- }
-
- std::string description() const override
- {
- return "Compute the HMAC tag of given file(s)";
- }
-
- void go() override
- {
- const bool no_fsname = flag_set("no-fsname");
- const std::string hash_algo = get_arg("hash");
- std::unique_ptr<Botan::MessageAuthenticationCode> hmac =
- Botan::MessageAuthenticationCode::create("HMAC(" + hash_algo + ")");
-
- if(!hmac)
- { throw CLI_Error_Unsupported("HMAC", hash_algo); }
-
- hmac->set_key(slurp_file(get_arg("key")));
-
- const size_t buf_size = get_arg_sz("buf-size");
-
- std::vector<std::string> files = get_arg_list("files");
- if(files.empty())
- { files.push_back("-"); } // read stdin if no arguments on command line
-
- for(const std::string& fsname : files)
- {
- try
- {
- auto update_hmac = [&](const uint8_t b[], size_t l) { hmac->update(b, l); };
- read_file(fsname, update_hmac, buf_size);
- output() << Botan::hex_encode(hmac->final());
-
- if(no_fsname == false)
- output() << " " << fsname;
-
- output() << "\n";
- }
- catch(CLI_IO_Error& e)
- {
- error_output() << e.what() << "\n";
- }
- }
- }
- };
-
-BOTAN_REGISTER_COMMAND("hmac", HMAC);
-
-#endif // hmac
-
}
diff --git a/src/lib/codec/base58/base58.cpp b/src/lib/codec/base58/base58.cpp
index ba974f96a..5aa9441d3 100644
--- a/src/lib/codec/base58/base58.cpp
+++ b/src/lib/codec/base58/base58.cpp
@@ -27,9 +27,7 @@ uint32_t sha256_d_checksum(const uint8_t input[], size_t input_length)
sha256->update(checksum);
sha256->final(checksum);
- checksum.resize(4);
- uint32_t c = load_be<uint32_t>(checksum.data(), 0);
- return c;
+ return load_be<uint32_t>(checksum.data(), 0);
}
class Character_Table
@@ -140,7 +138,12 @@ std::vector<uint8_t> base58_decode(const char input[], size_t input_length)
for(size_t i = leading_zeros; i != input_length; ++i)
{
- size_t idx = base58.code_for(input[i]);
+ const char c = input[i];
+
+ if(c == ' ' || c == '\n')
+ continue;
+
+ const size_t idx = base58.code_for(c);
if(idx == 0x80)
throw Decoding_Error("Invalid base58");
diff --git a/src/scripts/test_cli.py b/src/scripts/test_cli.py
index f63b9dad9..d09ecf611 100755
--- a/src/scripts/test_cli.py
+++ b/src/scripts/test_cli.py
@@ -150,6 +150,13 @@ def cli_base64_tests():
test_cli("base64_enc", "-", "YmVlcyE=", "bees!")
test_cli("base64_dec", "-", "bees!", "YmVlcyE=")
+def cli_base58_tests():
+ test_cli("base58_enc", "-", "C6sRAr4", "bees!")
+ test_cli("base58_dec", "-", "bees!", "C6sRAr4")
+
+ test_cli("base58_enc", ["--check", "-"], "Cjv15cdjaBc", "F00F")
+ test_cli("base58_dec", ["--check", "-"], "F00F", "Cjv15cdjaBc")
+
def cli_hex_tests():
test_cli("hex_enc", "-", "6265657321", "bees!")
test_cli("hex_dec", "-", "bees!", "6265657321")
@@ -750,6 +757,7 @@ def main(args=None):
test_fns = [
cli_asn1_tests,
cli_asn1_tests,
+ cli_base58_tests,
cli_base64_tests,
cli_bcrypt_tests,
cli_cc_enc_tests,