Commit 127a957aee7bf7ae242a606d035e9e3d9b300307

Authored by Jay Berkenbilt
1 parent fb4c6c15

Allow runtime inspection/override of crypto provider

include/qpdf/QPDFCryptoProvider.hh
@@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
26 #include <qpdf/QPDFCryptoImpl.hh> 26 #include <qpdf/QPDFCryptoImpl.hh>
27 #include <string> 27 #include <string>
28 #include <map> 28 #include <map>
  29 +#include <set>
29 #include <memory> 30 #include <memory>
30 #include <functional> 31 #include <functional>
31 32
@@ -64,6 +65,14 @@ class QPDFCryptoProvider @@ -64,6 +65,14 @@ class QPDFCryptoProvider
64 QPDF_DLL 65 QPDF_DLL
65 static void setDefaultProvider(std::string const& name); 66 static void setDefaultProvider(std::string const& name);
66 67
  68 + // Get the names of registered implementations
  69 + QPDF_DLL
  70 + static std::set<std::string> getRegisteredImpls();
  71 +
  72 + // Get the name of the default crypto provider
  73 + QPDF_DLL
  74 + static std::string getDefaultProvider();
  75 +
67 private: 76 private:
68 QPDFCryptoProvider(); 77 QPDFCryptoProvider();
69 ~QPDFCryptoProvider() = default; 78 ~QPDFCryptoProvider() = default;
libqpdf/QPDFCryptoProvider.cc
1 #include <qpdf/QPDFCryptoProvider.hh> 1 #include <qpdf/QPDFCryptoProvider.hh>
2 #include <qpdf/qpdf-config.h> 2 #include <qpdf/qpdf-config.h>
  3 +#include <qpdf/QUtil.hh>
3 #include <stdexcept> 4 #include <stdexcept>
4 5
5 #ifdef USE_CRYPTO_NATIVE 6 #ifdef USE_CRYPTO_NATIVE
@@ -49,7 +50,12 @@ QPDFCryptoProvider::QPDFCryptoProvider() : @@ -49,7 +50,12 @@ QPDFCryptoProvider::QPDFCryptoProvider() :
49 #ifdef USE_CRYPTO_GNUTLS 50 #ifdef USE_CRYPTO_GNUTLS
50 registerImpl_internal<QPDFCrypto_gnutls>("gnutls"); 51 registerImpl_internal<QPDFCrypto_gnutls>("gnutls");
51 #endif 52 #endif
52 - setDefaultProvider_internal(DEFAULT_CRYPTO); 53 + std::string default_crypto;
  54 + if (! QUtil::get_env("QPDF_CRYPTO_PROVIDER", &default_crypto))
  55 + {
  56 + default_crypto = DEFAULT_CRYPTO;
  57 + }
  58 + setDefaultProvider_internal(default_crypto);
53 } 59 }
54 60
55 QPDFCryptoProvider& 61 QPDFCryptoProvider&
@@ -83,5 +89,31 @@ QPDFCryptoProvider::registerImpl_internal(std::string const&amp; name) @@ -83,5 +89,31 @@ QPDFCryptoProvider::registerImpl_internal(std::string const&amp; name)
83 void 89 void
84 QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name) 90 QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name)
85 { 91 {
  92 + if (! this->m->providers.count(name))
  93 + {
  94 + throw std::logic_error(
  95 + "QPDFCryptoProvider: request to set default"
  96 + " provider to unknown implementation \"" +
  97 + name + "\"");
  98 + }
86 this->m->default_provider = name; 99 this->m->default_provider = name;
87 } 100 }
  101 +
  102 +std::set<std::string>
  103 +QPDFCryptoProvider::getRegisteredImpls()
  104 +{
  105 + std::set<std::string> result;
  106 + QPDFCryptoProvider& p = getInstance();
  107 + for (auto iter = p.m->providers.begin(); iter != p.m->providers.end();
  108 + ++iter)
  109 + {
  110 + result.insert((*iter).first);
  111 + }
  112 + return result;
  113 +}
  114 +
  115 +std::string
  116 +QPDFCryptoProvider::getDefaultProvider()
  117 +{
  118 + return getInstance().m->default_provider;
  119 +}
qpdf/qpdf.cc
@@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
24 #include <qpdf/QPDFAcroFormDocumentHelper.hh> 24 #include <qpdf/QPDFAcroFormDocumentHelper.hh>
25 #include <qpdf/QPDFExc.hh> 25 #include <qpdf/QPDFExc.hh>
26 #include <qpdf/QPDFSystemError.hh> 26 #include <qpdf/QPDFSystemError.hh>
  27 +#include <qpdf/QPDFCryptoProvider.hh>
27 28
28 #include <qpdf/QPDFWriter.hh> 29 #include <qpdf/QPDFWriter.hh>
29 #include <qpdf/QIntC.hh> 30 #include <qpdf/QIntC.hh>
@@ -624,6 +625,7 @@ class ArgParser @@ -624,6 +625,7 @@ class ArgParser
624 void argCompletionBash(); 625 void argCompletionBash();
625 void argCompletionZsh(); 626 void argCompletionZsh();
626 void argJsonHelp(); 627 void argJsonHelp();
  628 + void argShowCrypto();
627 void argPositional(char* arg); 629 void argPositional(char* arg);
628 void argPassword(char* parameter); 630 void argPassword(char* parameter);
629 void argEmpty(); 631 void argEmpty();
@@ -829,6 +831,7 @@ ArgParser::initOptionTable() @@ -829,6 +831,7 @@ ArgParser::initOptionTable()
829 (*t)["completion-bash"] = oe_bare(&ArgParser::argCompletionBash); 831 (*t)["completion-bash"] = oe_bare(&ArgParser::argCompletionBash);
830 (*t)["completion-zsh"] = oe_bare(&ArgParser::argCompletionZsh); 832 (*t)["completion-zsh"] = oe_bare(&ArgParser::argCompletionZsh);
831 (*t)["json-help"] = oe_bare(&ArgParser::argJsonHelp); 833 (*t)["json-help"] = oe_bare(&ArgParser::argJsonHelp);
  834 + (*t)["show-crypto"] = oe_bare(&ArgParser::argShowCrypto);
832 835
833 t = &this->main_option_table; 836 t = &this->main_option_table;
834 char const* yn[] = {"y", "n", 0}; 837 char const* yn[] = {"y", "n", 0};
@@ -1098,6 +1101,7 @@ ArgParser::argHelp() @@ -1098,6 +1101,7 @@ ArgParser::argHelp()
1098 << "--version show version of qpdf\n" 1101 << "--version show version of qpdf\n"
1099 << "--copyright show qpdf's copyright and license information\n" 1102 << "--copyright show qpdf's copyright and license information\n"
1100 << "--help show command-line argument help\n" 1103 << "--help show command-line argument help\n"
  1104 + << "--show-crypto show supported crypto providers; default is first\n"
1101 << "--completion-bash output a bash complete command you can eval\n" 1105 << "--completion-bash output a bash complete command you can eval\n"
1102 << "--completion-zsh output a zsh complete command you can eval\n" 1106 << "--completion-zsh output a zsh complete command you can eval\n"
1103 << "--password=password specify a password for accessing encrypted files\n" 1107 << "--password=password specify a password for accessing encrypted files\n"
@@ -1552,6 +1556,21 @@ ArgParser::argJsonHelp() @@ -1552,6 +1556,21 @@ ArgParser::argJsonHelp()
1552 } 1556 }
1553 1557
1554 void 1558 void
  1559 +ArgParser::argShowCrypto()
  1560 +{
  1561 + auto crypto = QPDFCryptoProvider::getRegisteredImpls();
  1562 + std::string default_crypto = QPDFCryptoProvider::getDefaultProvider();
  1563 + std::cout << default_crypto << std::endl;
  1564 + for (auto iter = crypto.begin(); iter != crypto.end(); ++iter)
  1565 + {
  1566 + if (*iter != default_crypto)
  1567 + {
  1568 + std::cout << *iter << std::endl;
  1569 + }
  1570 + }
  1571 +}
  1572 +
  1573 +void
1555 ArgParser::argPassword(char* parameter) 1574 ArgParser::argPassword(char* parameter)
1556 { 1575 {
1557 o.password = parameter; 1576 o.password = parameter;
@@ -5228,10 +5247,10 @@ int realmain(int argc, char* argv[]) @@ -5228,10 +5247,10 @@ int realmain(int argc, char* argv[])
5228 // it holds dynamic memory used for argv. 5247 // it holds dynamic memory used for argv.
5229 Options o; 5248 Options o;
5230 ArgParser ap(argc, argv, o); 5249 ArgParser ap(argc, argv, o);
5231 - ap.parseOptions();  
5232 5250
5233 try 5251 try
5234 { 5252 {
  5253 + ap.parseOptions();
5235 PointerHolder<QPDF> pdf_ph = 5254 PointerHolder<QPDF> pdf_ph =
5236 process_file(o.infilename, o.password, o); 5255 process_file(o.infilename, o.password, o);
5237 QPDF& pdf = *pdf_ph; 5256 QPDF& pdf = *pdf_ph;