Repository: randombit/botan
Pull request #2193 (2019-11-10 21:00:33)

CLI fingerprint read from stdin
This allows at least to verify a DER public key from stdin, while not to convert to PEM.


Patch:
diff --git a/src/cli/pubkey.cpp b/src/cli/pubkey.cpp
index 74ffde906..39923bc1f 100644
--- a/src/cli/pubkey.cpp
+++ b/src/cli/pubkey.cpp
@@ -101,7 +101,7 @@ BOTAN_REGISTER_COMMAND("keygen", PK_Keygen);
 namespace {
 
 std::string choose_sig_padding(const std::string& key, const std::string& emsa, const std::string& hash)
-{
+   {
    std::string emsa_or_default = [&]() -> std::string
       {
       if(!emsa.empty())
@@ -133,7 +133,7 @@ std::string choose_sig_padding(const std::string& key, const std::string& emsa,
       }
 
    return emsa_or_default + "(" + hash + ")";
-}
+   }
 
 }
 
@@ -159,14 +159,17 @@ class PK_Fingerprint final : public Command
 
          for(std::string key_file : get_arg_list("keys"))
             {
-            std::unique_ptr<Botan::Public_Key> key(Botan::X509::load_key(key_file));
+            std::unique_ptr<Botan::Public_Key> key(
+               key_file == "-"
+               ? Botan::X509::load_key(this->slurp_file("-", 4096))
+               : Botan::X509::load_key(key_file));
 
             const std::string fprint = key->fingerprint_public(hash_algo);
 
-            if(no_fsname)
-               output() << fprint << "\n";
+            if(no_fsname || key_file == "-")
+               { output() << fprint << "\n"; }
             else
-               output() << key_file << ": " << fprint << "\n";
+               { output() << key_file << ": " << fprint << "\n"; }
             }
          }
    };
@@ -223,9 +226,9 @@ class PK_Sign final : public Command
             {
             std::ofstream updated_key(key_file);
             if(passphrase.empty())
-               updated_key << Botan::PKCS8::PEM_encode(*key);
+               { updated_key << Botan::PKCS8::PEM_encode(*key); }
             else
-               updated_key << Botan::PKCS8::PEM_encode(*key, rng(), passphrase);
+               { updated_key << Botan::PKCS8::PEM_encode(*key, rng(), passphrase); }
             }
 
          output() << Botan::base64_encode(sig) << "\n";
@@ -460,13 +463,13 @@ class PK_Workfactor final : public Command
          const std::string type = get_arg("type");
 
          if(type == "rsa")
-            output() << Botan::if_work_factor(bits) << "\n";
+            { output() << Botan::if_work_factor(bits) << "\n"; }
          else if(type == "dl")
-            output() << Botan::dl_work_factor(bits) << "\n";
+            { output() << Botan::dl_work_factor(bits) << "\n"; }
          else if(type == "dl_exp")
-            output() << Botan::dl_exponent_size(bits) << "\n";
+            { output() << Botan::dl_exponent_size(bits) << "\n"; }
          else
-            throw CLI_Usage_Error("Unknown type for pk_workfactor");
+            { throw CLI_Usage_Error("Unknown type for pk_workfactor"); }
          }
    };
 
@@ -498,14 +501,14 @@ class Gen_DL_Group final : public Command
          if(type == "strong")
             {
             if(seed_str.size() > 0)
-               throw CLI_Usage_Error("Seed only supported for DSA param gen");
+               { throw CLI_Usage_Error("Seed only supported for DSA param gen"); }
             Botan::DL_Group grp(rng(), Botan::DL_Group::Strong, pbits);
             output() << grp.PEM_encode(Botan::DL_Group::ANSI_X9_42);
             }
          else if(type == "subgroup")
             {
             if(seed_str.size() > 0)
-               throw CLI_Usage_Error("Seed only supported for DSA param gen");
+               { throw CLI_Usage_Error("Seed only supported for DSA param gen"); }
             Botan::DL_Group grp(rng(), Botan::DL_Group::Prime_Subgroup, pbits, qbits);
             output() << grp.PEM_encode(Botan::DL_Group::ANSI_X9_42);
             }
@@ -515,11 +518,11 @@ class Gen_DL_Group final : public Command
             if(dsa_qbits == 0)
                {
                if(pbits == 1024)
-                  dsa_qbits = 160;
+                  { dsa_qbits = 160; }
                else if(pbits == 2048 || pbits == 3072)
-                  dsa_qbits = 256;
+                  { dsa_qbits = 256; }
                else
-                  throw CLI_Usage_Error("Invalid DSA p/q sizes");
+                  { throw CLI_Usage_Error("Invalid DSA p/q sizes"); }
                }
 
             if(seed_str.empty())


Test patch:
diff --git a/src/scripts/test_cli.py b/src/scripts/test_cli.py
index e4da5a898..993284951 100755
--- a/src/scripts/test_cli.py
+++ b/src/scripts/test_cli.py
@@ -314,6 +314,18 @@ mlLtJ5JvZ0/p6zP3x+Y9yPIrAR8L/acG5ItSrAKXzzuqQQZMv4aN
     test_cli("fingerprint", ['--no-fsname', pub_der_key],
              "83:FC:67:87:30:C7:0C:9C:54:9A:E7:A1:FA:25:83:4C:77:A4:43:16:33:6D:47:3C:CE:4B:91:62:30:97:62:D4")
 
+    test_cli("fingerprint", ['--no-fsname', pub_key, pub_der_key],
+             "83:FC:67:87:30:C7:0C:9C:54:9A:E7:A1:FA:25:83:4C:77:A4:43:16:33:6D:47:3C:CE:4B:91:62:30:97:62:D4\n"
+             "83:FC:67:87:30:C7:0C:9C:54:9A:E7:A1:FA:25:83:4C:77:A4:43:16:33:6D:47:3C:CE:4B:91:62:30:97:62:D4")
+
+    test_cli("fingerprint", [pub_der_key],
+             pub_der_key +
+             ": 83:FC:67:87:30:C7:0C:9C:54:9A:E7:A1:FA:25:83:4C:77:A4:43:16:33:6D:47:3C:CE:4B:91:62:30:97:62:D4")
+
+    test_cli("fingerprint", ['-'],
+             "83:FC:67:87:30:C7:0C:9C:54:9A:E7:A1:FA:25:83:4C:77:A4:43:16:33:6D:47:3C:CE:4B:91:62:30:97:62:D4",
+             open(pub_key, 'rb').read().decode())
+
     valid_sig = "nI4mI1ec14Y7nYUWs2edysAVvkob0TWpmGh5rrYWDA+/W9Fj0ZM21qJw8qa3/avAOIVBO6hoMEVmfJYXlS+ReA=="
 
     test_cli("sign", "--provider=base %s %s" % (priv_key, pub_key), valid_sig)