From 700dfa40d3d2c5b60bf5937f74c0ab59561115f8 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Wed, 26 Jan 2022 13:17:57 -0500 Subject: QPDFJob: convert encryption handlers --- libqpdf/QPDFJob_argv.cc | 174 +++-------------------------------- libqpdf/QPDFJob_config.cc | 195 ++++++++++++++++++++++++++++++++++++++++ libqpdf/qpdf/auto_job_decl.hh | 17 ---- libqpdf/qpdf/auto_job_init.hh | 53 ++++++----- libqpdf/qpdf/auto_job_schema.hh | 2 +- 5 files changed, 232 insertions(+), 209 deletions(-) (limited to 'libqpdf') diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index d2b38211..8882a7d7 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -44,6 +44,7 @@ namespace std::shared_ptr c_att; std::shared_ptr c_pages; std::shared_ptr c_uo; + std::shared_ptr c_enc; std::vector accumulated_args; // points to member in ap char* pages_password; }; @@ -217,35 +218,30 @@ ArgParser::argEncPositional(char* arg) } return; } - o.user_password = this->accumulated_args.at(0); - o.owner_password = this->accumulated_args.at(1); + std::string user_password = this->accumulated_args.at(0); + std::string owner_password = this->accumulated_args.at(1); std::string len_str = this->accumulated_args.at(2); + int keylen = 0; if (len_str == "40") { - o.keylen = 40; + keylen = 40; this->ap.selectOptionTable(O_40_BIT_ENCRYPTION); } else if (len_str == "128") { - o.keylen = 128; + keylen = 128; this->ap.selectOptionTable(O_128_BIT_ENCRYPTION); } else if (len_str == "256") { - o.keylen = 256; - o.use_aes = true; + keylen = 256; this->ap.selectOptionTable(O_256_BIT_ENCRYPTION); } else { usage("encryption key length must be 40, 128, or 256"); } -} - -void -ArgParser::argEnc256AllowInsecure() -{ - o.allow_insecure = true; + this->c_enc = c_main->encrypt(keylen, user_password, owner_password); } void @@ -394,161 +390,11 @@ ArgParser::argCopyAttachmentsFrom() this->ap.selectOptionTable(O_COPY_ATTACHMENT); } -void -ArgParser::argEnc40Print(char* parameter) -{ - o.r2_print = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc40Modify(char* parameter) -{ - o.r2_modify = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc40Extract(char* parameter) -{ - o.r2_extract = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc40Annotate(char* parameter) -{ - o.r2_annotate = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128Accessibility(char* parameter) -{ - o.r3_accessibility = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128Extract(char* parameter) -{ - o.r3_extract = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128Print(char* parameter) -{ - if (strcmp(parameter, "full") == 0) - { - o.r3_print = qpdf_r3p_full; - } - else if (strcmp(parameter, "low") == 0) - { - o.r3_print = qpdf_r3p_low; - } - else if (strcmp(parameter, "none") == 0) - { - o.r3_print = qpdf_r3p_none; - } - else - { - usage("invalid print option"); - } -} - -void -ArgParser::argEnc128Modify(char* parameter) -{ - if (strcmp(parameter, "all") == 0) - { - o.r3_assemble = true; - o.r3_annotate_and_form = true; - o.r3_form_filling = true; - o.r3_modify_other = true; - } - else if (strcmp(parameter, "annotate") == 0) - { - o.r3_assemble = true; - o.r3_annotate_and_form = true; - o.r3_form_filling = true; - o.r3_modify_other = false; - } - else if (strcmp(parameter, "form") == 0) - { - o.r3_assemble = true; - o.r3_annotate_and_form = false; - o.r3_form_filling = true; - o.r3_modify_other = false; - } - else if (strcmp(parameter, "assembly") == 0) - { - o.r3_assemble = true; - o.r3_annotate_and_form = false; - o.r3_form_filling = false; - o.r3_modify_other = false; - } - else if (strcmp(parameter, "none") == 0) - { - o.r3_assemble = false; - o.r3_annotate_and_form = false; - o.r3_form_filling = false; - o.r3_modify_other = false; - } - else - { - usage("invalid modify option"); - } -} - -void -ArgParser::argEnc128CleartextMetadata() -{ - o.cleartext_metadata = true; -} - -void -ArgParser::argEnc128Assemble(char* parameter) -{ - o.r3_assemble = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128Annotate(char* parameter) -{ - o.r3_annotate_and_form = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128Form(char* parameter) -{ - o.r3_form_filling = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128ModifyOther(char* parameter) -{ - o.r3_modify_other = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128UseAes(char* parameter) -{ - o.use_aes = (strcmp(parameter, "y") == 0); -} - -void -ArgParser::argEnc128ForceV4() -{ - o.force_V4 = true; -} - -void -ArgParser::argEnc256ForceR5() -{ - o.force_R5 = true; -} - void ArgParser::argEndEncryption() { - o.encrypt = true; - o.decrypt = false; - o.copy_encryption = false; + c_enc->end(); + c_enc = nullptr; } void diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index c313c219..85aa3a3b 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -963,3 +963,198 @@ QPDFJob::UOConfig::password(char const* parameter) config.o.under_overlay->password = QUtil::make_shared_cstr(parameter); return *this; } + +std::shared_ptr +QPDFJob::Config::encrypt(int keylen, + std::string const& user_password, + std::string const& owner_password) +{ + o.keylen = keylen; + if (keylen == 256) + { + o.use_aes = true; + } + o.user_password = user_password; + o.owner_password = owner_password; + return std::shared_ptr(new EncConfig(*this)); +} + +QPDFJob::EncConfig::EncConfig(Config& c) : + config(c) +{ +} + +QPDFJob::Config& +QPDFJob::EncConfig::end() +{ + config.o.encrypt = true; + config.o.decrypt = false; + config.o.copy_encryption = false; + return this->config; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::allowInsecure() +{ + config.o.allow_insecure = true; + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::accessibility(char const* parameter) +{ + config.o.r3_accessibility = (strcmp(parameter, "y") == 0); + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::extract(char const* parameter) +{ + if (config.o.keylen == 40) + { + config.o.r2_extract = (strcmp(parameter, "y") == 0); + } + else + { + config.o.r3_extract = (strcmp(parameter, "y") == 0); + } + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::print(char const* parameter) +{ + if (config.o.keylen == 40) + { + config.o.r2_print = (strcmp(parameter, "y") == 0); + } + else if (strcmp(parameter, "full") == 0) + { + config.o.r3_print = qpdf_r3p_full; + } + else if (strcmp(parameter, "low") == 0) + { + config.o.r3_print = qpdf_r3p_low; + } + else if (strcmp(parameter, "none") == 0) + { + config.o.r3_print = qpdf_r3p_none; + } + else + { + usage("invalid print option"); + } + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::modify(char const* parameter) +{ + if (config.o.keylen == 40) + { + config.o.r2_modify = (strcmp(parameter, "y") == 0); + } + else if (strcmp(parameter, "all") == 0) + { + config.o.r3_assemble = true; + config.o.r3_annotate_and_form = true; + config.o.r3_form_filling = true; + config.o.r3_modify_other = true; + } + else if (strcmp(parameter, "annotate") == 0) + { + config.o.r3_assemble = true; + config.o.r3_annotate_and_form = true; + config.o.r3_form_filling = true; + config.o.r3_modify_other = false; + } + else if (strcmp(parameter, "form") == 0) + { + config.o.r3_assemble = true; + config.o.r3_annotate_and_form = false; + config.o.r3_form_filling = true; + config.o.r3_modify_other = false; + } + else if (strcmp(parameter, "assembly") == 0) + { + config.o.r3_assemble = true; + config.o.r3_annotate_and_form = false; + config.o.r3_form_filling = false; + config.o.r3_modify_other = false; + } + else if (strcmp(parameter, "none") == 0) + { + config.o.r3_assemble = false; + config.o.r3_annotate_and_form = false; + config.o.r3_form_filling = false; + config.o.r3_modify_other = false; + } + else + { + usage("invalid modify option"); + } + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::cleartextMetadata() +{ + config.o.cleartext_metadata = true; + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::assemble(char const* parameter) +{ + config.o.r3_assemble = (strcmp(parameter, "y") == 0); + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::annotate(char const* parameter) +{ + if (config.o.keylen == 40) + { + config.o.r2_annotate = (strcmp(parameter, "y") == 0); + } + else + { + config.o.r3_annotate_and_form = (strcmp(parameter, "y") == 0); + } + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::form(char const* parameter) +{ + config.o.r3_form_filling = (strcmp(parameter, "y") == 0); + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::modifyOther(char const* parameter) +{ + config.o.r3_modify_other = (strcmp(parameter, "y") == 0); + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::useAes(char const* parameter) +{ + config.o.use_aes = (strcmp(parameter, "y") == 0); + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::forceV4() +{ + config.o.force_V4 = true; + return *this; +} + +QPDFJob::EncConfig& +QPDFJob::EncConfig::forceR5() +{ + config.o.force_R5 = true; + return *this; +} diff --git a/libqpdf/qpdf/auto_job_decl.hh b/libqpdf/qpdf/auto_job_decl.hh index 1dc3fef5..1f868187 100644 --- a/libqpdf/qpdf/auto_job_decl.hh +++ b/libqpdf/qpdf/auto_job_decl.hh @@ -29,25 +29,8 @@ void argPagesPassword(char *); void argEndPages(); void argEncPositional(char*); void argEndEncryption(); -void argEnc40Extract(char *); -void argEnc40Annotate(char *); -void argEnc40Print(char *); -void argEnc40Modify(char *); void argEnd40BitEncryption(); -void argEnc128CleartextMetadata(); -void argEnc128ForceV4(); -void argEnc128Accessibility(char *); -void argEnc128Extract(char *); -void argEnc128Print(char *); -void argEnc128Assemble(char *); -void argEnc128Annotate(char *); -void argEnc128Form(char *); -void argEnc128ModifyOther(char *); -void argEnc128Modify(char *); -void argEnc128UseAes(char *); void argEnd128BitEncryption(); -void argEnc256ForceR5(); -void argEnc256AllowInsecure(); void argEnd256BitEncryption(); void argUOPositional(char*); void argEndUnderlayOverlay(); diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh index 7c34e8b1..7fc044dc 100644 --- a/libqpdf/qpdf/auto_job_init.hh +++ b/libqpdf/qpdf/auto_job_init.hh @@ -116,25 +116,34 @@ this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "pass this->ap.registerOptionTable("encryption", b(&ArgParser::argEndEncryption)); this->ap.addPositional(p(&ArgParser::argEncPositional)); this->ap.registerOptionTable("40-bit encryption", b(&ArgParser::argEnd40BitEncryption)); -this->ap.addChoices("extract", p(&ArgParser::argEnc40Extract), true, yn_choices); -this->ap.addChoices("annotate", p(&ArgParser::argEnc40Annotate), true, yn_choices); -this->ap.addChoices("print", p(&ArgParser::argEnc40Print), true, yn_choices); -this->ap.addChoices("modify", p(&ArgParser::argEnc40Modify), true, yn_choices); +this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices); +this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices); +this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, yn_choices); +this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, yn_choices); this->ap.registerOptionTable("128-bit encryption", b(&ArgParser::argEnd128BitEncryption)); -this->ap.addBare("cleartext-metadata", b(&ArgParser::argEnc128CleartextMetadata)); -this->ap.addBare("force-V4", b(&ArgParser::argEnc128ForceV4)); -this->ap.addChoices("accessibility", p(&ArgParser::argEnc128Accessibility), true, yn_choices); -this->ap.addChoices("extract", p(&ArgParser::argEnc128Extract), true, yn_choices); -this->ap.addChoices("print", p(&ArgParser::argEnc128Print), true, print128_choices); -this->ap.addChoices("assemble", p(&ArgParser::argEnc128Assemble), true, yn_choices); -this->ap.addChoices("annotate", p(&ArgParser::argEnc128Annotate), true, yn_choices); -this->ap.addChoices("form", p(&ArgParser::argEnc128Form), true, yn_choices); -this->ap.addChoices("modify-other", p(&ArgParser::argEnc128ModifyOther), true, yn_choices); -this->ap.addChoices("modify", p(&ArgParser::argEnc128Modify), true, modify128_choices); -this->ap.addChoices("use-aes", p(&ArgParser::argEnc128UseAes), true, yn_choices); +this->ap.addBare("cleartext-metadata", [this](){c_enc->cleartextMetadata();}); +this->ap.addBare("force-V4", [this](){c_enc->forceV4();}); +this->ap.addChoices("accessibility", [this](char *x){c_enc->accessibility(x);}, true, yn_choices); +this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices); +this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, print128_choices); +this->ap.addChoices("assemble", [this](char *x){c_enc->assemble(x);}, true, yn_choices); +this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices); +this->ap.addChoices("form", [this](char *x){c_enc->form(x);}, true, yn_choices); +this->ap.addChoices("modify-other", [this](char *x){c_enc->modifyOther(x);}, true, yn_choices); +this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, modify128_choices); +this->ap.addChoices("use-aes", [this](char *x){c_enc->useAes(x);}, true, yn_choices); this->ap.registerOptionTable("256-bit encryption", b(&ArgParser::argEnd256BitEncryption)); -this->ap.addBare("force-R5", b(&ArgParser::argEnc256ForceR5)); -this->ap.addBare("allow-insecure", b(&ArgParser::argEnc256AllowInsecure)); +this->ap.addBare("cleartext-metadata", [this](){c_enc->cleartextMetadata();}); +this->ap.addBare("force-R5", [this](){c_enc->forceR5();}); +this->ap.addBare("allow-insecure", [this](){c_enc->allowInsecure();}); +this->ap.addChoices("accessibility", [this](char *x){c_enc->accessibility(x);}, true, yn_choices); +this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices); +this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, print128_choices); +this->ap.addChoices("assemble", [this](char *x){c_enc->assemble(x);}, true, yn_choices); +this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices); +this->ap.addChoices("form", [this](char *x){c_enc->form(x);}, true, yn_choices); +this->ap.addChoices("modify-other", [this](char *x){c_enc->modifyOther(x);}, true, yn_choices); +this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, modify128_choices); this->ap.registerOptionTable("underlay/overlay", b(&ArgParser::argEndUnderlayOverlay)); this->ap.addPositional(p(&ArgParser::argUOPositional)); this->ap.addRequiredParameter("to", [this](char *x){c_uo->to(x);}, "page-range"); @@ -154,13 +163,3 @@ this->ap.registerOptionTable("copy attachment", b(&ArgParser::argEndCopyAttachme this->ap.addPositional(p(&ArgParser::argCopyAttPositional)); this->ap.addRequiredParameter("prefix", [this](char *x){c_copy_att->prefix(x);}, "prefix"); this->ap.addRequiredParameter("password", [this](char *x){c_copy_att->password(x);}, "password"); -this->ap.selectOptionTable("256-bit encryption"); -this->ap.copyFromOtherTable("cleartext-metadata", "128-bit encryption"); -this->ap.copyFromOtherTable("accessibility", "128-bit encryption"); -this->ap.copyFromOtherTable("extract", "128-bit encryption"); -this->ap.copyFromOtherTable("print", "128-bit encryption"); -this->ap.copyFromOtherTable("assemble", "128-bit encryption"); -this->ap.copyFromOtherTable("annotate", "128-bit encryption"); -this->ap.copyFromOtherTable("form", "128-bit encryption"); -this->ap.copyFromOtherTable("modify-other", "128-bit encryption"); -this->ap.copyFromOtherTable("modify", "128-bit encryption"); diff --git a/libqpdf/qpdf/auto_job_schema.hh b/libqpdf/qpdf/auto_job_schema.hh index 7fe018af..376d0c19 100644 --- a/libqpdf/qpdf/auto_job_schema.hh +++ b/libqpdf/qpdf/auto_job_schema.hh @@ -35,9 +35,9 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({ "forceVersion": "set output PDF version", "progress": "show progress when writing", "encrypt": { + "keyLength": "key length: 48, 128, 256", "userPassword": "user password", "ownerPassword": "owner password", - "keyLength": "key length: 48, 128, 256", "40Bit": { "annotate": "restrict document annotation", "extract": "restrict text/graphic extraction", -- cgit v1.2.3-54-g00ecf