diff --git a/include/qpdf/QPDFCryptoProvider.hh b/include/qpdf/QPDFCryptoProvider.hh index 4243fcfd..eb5dcf34 100644 --- a/include/qpdf/QPDFCryptoProvider.hh +++ b/include/qpdf/QPDFCryptoProvider.hh @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -64,6 +65,14 @@ class QPDFCryptoProvider QPDF_DLL static void setDefaultProvider(std::string const& name); + // Get the names of registered implementations + QPDF_DLL + static std::set getRegisteredImpls(); + + // Get the name of the default crypto provider + QPDF_DLL + static std::string getDefaultProvider(); + private: QPDFCryptoProvider(); ~QPDFCryptoProvider() = default; diff --git a/libqpdf/QPDFCryptoProvider.cc b/libqpdf/QPDFCryptoProvider.cc index 133a16f7..5755fcca 100644 --- a/libqpdf/QPDFCryptoProvider.cc +++ b/libqpdf/QPDFCryptoProvider.cc @@ -1,5 +1,6 @@ #include #include +#include #include #ifdef USE_CRYPTO_NATIVE @@ -49,7 +50,12 @@ QPDFCryptoProvider::QPDFCryptoProvider() : #ifdef USE_CRYPTO_GNUTLS registerImpl_internal("gnutls"); #endif - setDefaultProvider_internal(DEFAULT_CRYPTO); + std::string default_crypto; + if (! QUtil::get_env("QPDF_CRYPTO_PROVIDER", &default_crypto)) + { + default_crypto = DEFAULT_CRYPTO; + } + setDefaultProvider_internal(default_crypto); } QPDFCryptoProvider& @@ -83,5 +89,31 @@ QPDFCryptoProvider::registerImpl_internal(std::string const& name) void QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name) { + if (! this->m->providers.count(name)) + { + throw std::logic_error( + "QPDFCryptoProvider: request to set default" + " provider to unknown implementation \"" + + name + "\""); + } this->m->default_provider = name; } + +std::set +QPDFCryptoProvider::getRegisteredImpls() +{ + std::set result; + QPDFCryptoProvider& p = getInstance(); + for (auto iter = p.m->providers.begin(); iter != p.m->providers.end(); + ++iter) + { + result.insert((*iter).first); + } + return result; +} + +std::string +QPDFCryptoProvider::getDefaultProvider() +{ + return getInstance().m->default_provider; +} diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc index 3f23420d..2bd98ccb 100644 --- a/qpdf/qpdf.cc +++ b/qpdf/qpdf.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -624,6 +625,7 @@ class ArgParser void argCompletionBash(); void argCompletionZsh(); void argJsonHelp(); + void argShowCrypto(); void argPositional(char* arg); void argPassword(char* parameter); void argEmpty(); @@ -829,6 +831,7 @@ ArgParser::initOptionTable() (*t)["completion-bash"] = oe_bare(&ArgParser::argCompletionBash); (*t)["completion-zsh"] = oe_bare(&ArgParser::argCompletionZsh); (*t)["json-help"] = oe_bare(&ArgParser::argJsonHelp); + (*t)["show-crypto"] = oe_bare(&ArgParser::argShowCrypto); t = &this->main_option_table; char const* yn[] = {"y", "n", 0}; @@ -1098,6 +1101,7 @@ ArgParser::argHelp() << "--version show version of qpdf\n" << "--copyright show qpdf's copyright and license information\n" << "--help show command-line argument help\n" + << "--show-crypto show supported crypto providers; default is first\n" << "--completion-bash output a bash complete command you can eval\n" << "--completion-zsh output a zsh complete command you can eval\n" << "--password=password specify a password for accessing encrypted files\n" @@ -1551,6 +1555,21 @@ ArgParser::argJsonHelp() << std::endl; } +void +ArgParser::argShowCrypto() +{ + auto crypto = QPDFCryptoProvider::getRegisteredImpls(); + std::string default_crypto = QPDFCryptoProvider::getDefaultProvider(); + std::cout << default_crypto << std::endl; + for (auto iter = crypto.begin(); iter != crypto.end(); ++iter) + { + if (*iter != default_crypto) + { + std::cout << *iter << std::endl; + } + } +} + void ArgParser::argPassword(char* parameter) { @@ -5228,10 +5247,10 @@ int realmain(int argc, char* argv[]) // it holds dynamic memory used for argv. Options o; ArgParser ap(argc, argv, o); - ap.parseOptions(); try { + ap.parseOptions(); PointerHolder pdf_ph = process_file(o.infilename, o.password, o); QPDF& pdf = *pdf_ph;