From e57c25814e49b82863753894ee7d97c18e4c4525 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 29 Dec 2012 21:31:21 -0500 Subject: Support for encryption with /V=5 and /R=5 and /R=6 Read and write support is implemented for /V=5 with /R=5 as well as /R=6. /R=5 is the deprecated encryption method used by Acrobat IX. /R=6 is the encryption method used by PDF 2.0 from ISO 32000-2. --- include/qpdf/QPDF.hh | 24 ++++++++++++++++++++++-- include/qpdf/QPDFWriter.hh | 25 ++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 7028bf1c..beb5cb7e 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -224,7 +224,7 @@ class QPDF // Encryption support - enum encryption_method_e { e_none, e_unknown, e_rc4, e_aes }; + enum encryption_method_e { e_none, e_unknown, e_rc4, e_aes, e_aesv3 }; class EncryptionData { public: @@ -326,7 +326,7 @@ class QPDF QPDF_DLL static std::string compute_data_key( std::string const& encryption_key, int objid, int generation, - bool use_aes); + bool use_aes, int encryption_V, int encryption_R); QPDF_DLL static std::string compute_encryption_key( std::string const& password, EncryptionData const& data); @@ -337,6 +337,14 @@ class QPDF int V, int R, int key_len, int P, bool encrypt_metadata, std::string const& id1, std::string& O, std::string& U); + QPDF_DLL + static void compute_encryption_parameters_V5( + char const* user_password, char const* owner_password, + int V, int R, int key_len, int P, bool encrypt_metadata, + std::string const& id1, + std::string& encryption_key, + std::string& O, std::string& U, + std::string& OE, std::string& UE, std::string& Perms); // Return the full user password as stored in the PDF file. If // you are attempting to recover the user password in a // user-presentable form, call getTrimmedUserPassword() instead. @@ -345,6 +353,10 @@ class QPDF // Return human-readable form of user password. QPDF_DLL std::string getTrimmedUserPassword() const; + // Return the previously computed or retrieved encryption key for + // this file + QPDF_DLL + std::string getEncryptionKey() const; // Linearization support @@ -628,6 +640,13 @@ class QPDF void initializeEncryption(); std::string getKeyForObject(int objid, int generation, bool use_aes); void decryptString(std::string&, int objid, int generation); + static std::string compute_encryption_key_from_password( + std::string const& password, EncryptionData const& data); + static std::string recover_encryption_key_with_password( + std::string const& password, EncryptionData const& data); + static std::string recover_encryption_key_with_password( + std::string const& password, EncryptionData const& data, + bool& perms_valid); void decryptStream( Pipeline*& pipeline, int objid, int generation, QPDFObjectHandle& stream_dict, @@ -981,6 +1000,7 @@ class QPDF std::ostream* err_stream; bool attempt_recovery; int encryption_V; + int encryption_R; bool encrypt_metadata; std::map crypt_filters; encryption_method_e cf_stream; diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh index 15963890..a8cf5054 100644 --- a/include/qpdf/QPDFWriter.hh +++ b/include/qpdf/QPDFWriter.hh @@ -223,8 +223,9 @@ class QPDFWriter // content normalization. Note that setting R2 encryption // parameters sets the PDF version to at least 1.3, setting R3 // encryption parameters pushes the PDF version number to at least - // 1.4, and setting R4 parameters pushes the version to at least - // 1.5, or if AES is used, 1.6. + // 1.4, setting R4 parameters pushes the version to at least 1.5, + // or if AES is used, 1.6, and setting R5 or R6 parameters pushes + // the version to at least 1.7 with extension level 3. QPDF_DLL void setR2EncryptionParameters( char const* user_password, char const* owner_password, @@ -241,6 +242,21 @@ class QPDFWriter bool allow_accessibility, bool allow_extract, qpdf_r3_print_e print, qpdf_r3_modify_e modify, bool encrypt_metadata, bool use_aes); + // R5 is deprecated. Do not use it for production use. Writing + // R5 is supported by qpdf primarily to generate test files for + // applications that may need to test R5 support. + QPDF_DLL + void setR5EncryptionParameters( + char const* user_password, char const* owner_password, + bool allow_accessibility, bool allow_extract, + qpdf_r3_print_e print, qpdf_r3_modify_e modify, + bool encrypt_metadata); + QPDF_DLL + void setR6EncryptionParameters( + char const* user_password, char const* owner_password, + bool allow_accessibility, bool allow_extract, + qpdf_r3_print_e print, qpdf_r3_modify_e modify, + bool encrypt_metadata_aes); // Create linearized output. Disables qdf mode, content // normalization, and stream prefiltering. @@ -302,7 +318,8 @@ class QPDFWriter int V, int R, int key_len, long P, std::string const& O, std::string const& U, std::string const& OE, std::string const& UE, std::string const& Perms, - std::string const& id1, std::string const& user_password); + std::string const& id1, std::string const& user_password, + std::string const& encryption_key); void setDataKey(int objid); int openObject(int objid = 0); void closeObject(int objid); @@ -378,6 +395,8 @@ class QPDFWriter bool encrypt_metadata; bool encrypt_use_aes; std::map encryption_dictionary; + int encryption_V; + int encryption_R; std::string id1; // for /ID key of std::string id2; // trailer dictionary -- cgit v1.2.3-54-g00ecf