mirror of
https://github.com/qpdf/qpdf.git
synced 2025-02-02 03:48:24 +00:00
add C API for R4 encryption
git-svn-id: svn+q:///qpdf/trunk@825 71b93d88-0707-0410-a8cf-f5a4172ac649
This commit is contained in:
parent
09175e4578
commit
a8715c495b
@ -110,6 +110,11 @@ class DLL_EXPORT QPDFWriter
|
|||||||
// suites.
|
// suites.
|
||||||
void setStaticID(bool);
|
void setStaticID(bool);
|
||||||
|
|
||||||
|
// Use a fixed initialization vector for AES-CBC encryption. This
|
||||||
|
// is not secure. It should be used only in test suites for
|
||||||
|
// creating predictable encrypted output.
|
||||||
|
void setStaticAesIV(bool);
|
||||||
|
|
||||||
// Suppress inclusion of comments indicating original object IDs
|
// Suppress inclusion of comments indicating original object IDs
|
||||||
// when writing QDF files. This can also be useful for testing,
|
// when writing QDF files. This can also be useful for testing,
|
||||||
// particularly when using comparison of two qdf files to
|
// particularly when using comparison of two qdf files to
|
||||||
|
@ -226,6 +226,12 @@ extern "C" {
|
|||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value);
|
void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value);
|
||||||
|
|
||||||
|
/* Never use qpdf_set_static_aes_IV except in test suites to
|
||||||
|
* create predictable AES encrypted output.
|
||||||
|
*/
|
||||||
|
DLL_EXPORT
|
||||||
|
void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value);
|
||||||
|
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
void qpdf_set_suppress_original_object_IDs(
|
void qpdf_set_suppress_original_object_IDs(
|
||||||
qpdf_data qpdf, QPDF_BOOL value);
|
qpdf_data qpdf, QPDF_BOOL value);
|
||||||
@ -258,6 +264,13 @@ extern "C" {
|
|||||||
QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
|
QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
|
||||||
int print, int modify);
|
int print, int modify);
|
||||||
|
|
||||||
|
DLL_EXPORT
|
||||||
|
void qpdf_set_r4_encryption_parameters(
|
||||||
|
qpdf_data qpdf, char const* user_password, char const* owner_password,
|
||||||
|
QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
|
||||||
|
int print, int modify,
|
||||||
|
QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes);
|
||||||
|
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value);
|
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value);
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
# define srandom srand
|
# define srandom srand
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool Pl_AES_PDF::use_static_iv = false;
|
||||||
|
|
||||||
Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
|
Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
|
||||||
bool encrypt, unsigned char const key[key_size]) :
|
bool encrypt, unsigned char const key[key_size]) :
|
||||||
Pipeline(identifier, next),
|
Pipeline(identifier, next),
|
||||||
@ -51,6 +53,12 @@ Pl_AES_PDF::disableCBC()
|
|||||||
this->cbc_mode = false;
|
this->cbc_mode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Pl_AES_PDF::useStaticIV()
|
||||||
|
{
|
||||||
|
use_static_iv = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Pl_AES_PDF::write(unsigned char* data, int len)
|
Pl_AES_PDF::write(unsigned char* data, int len)
|
||||||
{
|
{
|
||||||
@ -116,9 +124,19 @@ Pl_AES_PDF::initializeVector()
|
|||||||
srandom((int)QUtil::get_current_time() ^ 0xcccc);
|
srandom((int)QUtil::get_current_time() ^ 0xcccc);
|
||||||
seeded_random = true;
|
seeded_random = true;
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < this->buf_size; ++i)
|
if (use_static_iv)
|
||||||
{
|
{
|
||||||
this->cbc_block[i] = (unsigned char)((random() & 0xff0) >> 4);
|
for (unsigned int i = 0; i < this->buf_size; ++i)
|
||||||
|
{
|
||||||
|
this->cbc_block[i] = 14 * (1 + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < this->buf_size; ++i)
|
||||||
|
{
|
||||||
|
this->cbc_block[i] = (unsigned char)((random() & 0xff0) >> 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +139,15 @@ QPDFWriter::setStaticID(bool val)
|
|||||||
this->static_id = val;
|
this->static_id = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFWriter::setStaticAesIV(bool val)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
Pl_AES_PDF::useStaticIV();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFWriter::setSuppressOriginalObjectIDs(bool val)
|
QPDFWriter::setSuppressOriginalObjectIDs(bool val)
|
||||||
{
|
{
|
||||||
|
@ -313,6 +313,12 @@ void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value)
|
|||||||
qpdf->qpdf_writer->setStaticID(value);
|
qpdf->qpdf_writer->setStaticID(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value)
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "qpdf-c called qpdf_set_static_aes_IV");
|
||||||
|
qpdf->qpdf_writer->setStaticAesIV(value);
|
||||||
|
}
|
||||||
|
|
||||||
void qpdf_set_suppress_original_object_IDs(
|
void qpdf_set_suppress_original_object_IDs(
|
||||||
qpdf_data qpdf, QPDF_BOOL value)
|
qpdf_data qpdf, QPDF_BOOL value)
|
||||||
{
|
{
|
||||||
@ -356,6 +362,26 @@ void qpdf_set_r3_encryption_parameters(
|
|||||||
QPDFWriter::r3m_all));
|
QPDFWriter::r3m_all));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qpdf_set_r4_encryption_parameters(
|
||||||
|
qpdf_data qpdf, char const* user_password, char const* owner_password,
|
||||||
|
QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
|
||||||
|
int print, int modify, QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes)
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "qpdf-c called qpdf_set_r4_encryption_parameters");
|
||||||
|
qpdf->qpdf_writer->setR4EncryptionParameters(
|
||||||
|
user_password, owner_password,
|
||||||
|
allow_accessibility, allow_extract,
|
||||||
|
((print == QPDF_R3_PRINT_LOW) ? QPDFWriter::r3p_low :
|
||||||
|
(print == QPDF_R3_PRINT_NONE) ? QPDFWriter::r3p_none :
|
||||||
|
QPDFWriter::r3p_full),
|
||||||
|
((modify == QPDF_R3_MODIFY_ANNOTATE) ? QPDFWriter::r3m_annotate :
|
||||||
|
(modify == QPDF_R3_MODIFY_FORM) ? QPDFWriter::r3m_form :
|
||||||
|
(modify == QPDF_R3_MODIFY_ASSEMBLY) ? QPDFWriter::r3m_assembly :
|
||||||
|
(modify == QPDF_R3_MODIFY_NONE) ? QPDFWriter::r3m_none :
|
||||||
|
QPDFWriter::r3m_all),
|
||||||
|
encrypt_metadata, use_aes);
|
||||||
|
}
|
||||||
|
|
||||||
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
|
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
|
||||||
{
|
{
|
||||||
QTC::TC("qpdf", "qpdf-c called qpdf_set_linearization");
|
QTC::TC("qpdf", "qpdf-c called qpdf_set_linearization");
|
||||||
|
@ -20,12 +20,15 @@ class DLL_EXPORT Pl_AES_PDF: public Pipeline
|
|||||||
|
|
||||||
// For testing only; PDF always uses CBC
|
// For testing only; PDF always uses CBC
|
||||||
void disableCBC();
|
void disableCBC();
|
||||||
|
// For testing only: use a fixed initialization vector for CBC
|
||||||
|
static void useStaticIV();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void flush(bool discard_padding);
|
void flush(bool discard_padding);
|
||||||
void initializeVector();
|
void initializeVector();
|
||||||
|
|
||||||
static unsigned int const buf_size = 16;
|
static unsigned int const buf_size = 16;
|
||||||
|
static bool use_static_iv;
|
||||||
|
|
||||||
bool encrypt;
|
bool encrypt;
|
||||||
bool cbc_mode;
|
bool cbc_mode;
|
||||||
|
@ -229,6 +229,22 @@ static void test14(char const* infile,
|
|||||||
report_errors();
|
report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test15(char const* infile,
|
||||||
|
char const* password,
|
||||||
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
|
{
|
||||||
|
qpdf_read(qpdf, infile, password);
|
||||||
|
qpdf_init_write(qpdf, outfile);
|
||||||
|
qpdf_set_static_ID(qpdf, QPDF_TRUE);
|
||||||
|
qpdf_set_static_aes_IV(qpdf, QPDF_TRUE);
|
||||||
|
qpdf_set_r4_encryption_parameters(
|
||||||
|
qpdf, "user2", "owner2", QPDF_TRUE, QPDF_TRUE,
|
||||||
|
QPDF_R3_PRINT_LOW, QPDF_R3_MODIFY_ALL, QPDF_TRUE, QPDF_TRUE);
|
||||||
|
qpdf_write(qpdf);
|
||||||
|
report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
char* whoami = 0;
|
char* whoami = 0;
|
||||||
@ -278,6 +294,7 @@ int main(int argc, char* argv[])
|
|||||||
(n == 12) ? test12 :
|
(n == 12) ? test12 :
|
||||||
(n == 13) ? test13 :
|
(n == 13) ? test13 :
|
||||||
(n == 14) ? test14 :
|
(n == 14) ? test14 :
|
||||||
|
(n == 15) ? test15 :
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (fn == 0)
|
if (fn == 0)
|
||||||
|
11
qpdf/qpdf.cc
11
qpdf/qpdf.cc
@ -146,6 +146,8 @@ These options can be useful for digging into PDF files or for use in\n\
|
|||||||
automated test suites for software that uses the qpdf library.\n\
|
automated test suites for software that uses the qpdf library.\n\
|
||||||
\n\
|
\n\
|
||||||
--static-id generate static /ID: FOR TESTING ONLY!\n\
|
--static-id generate static /ID: FOR TESTING ONLY!\n\
|
||||||
|
--static-aes-iv use a static initialization vector for AES-CBC\n\
|
||||||
|
This is option is not secure! FOR TESTING ONLY!\n\
|
||||||
--no-original-object-ids suppress original object ID comments in qdf mode\n\
|
--no-original-object-ids suppress original object ID comments in qdf mode\n\
|
||||||
--show-encryption quickly show encryption parameters\n\
|
--show-encryption quickly show encryption parameters\n\
|
||||||
--check-linearization check file integrity and linearization status\n\
|
--check-linearization check file integrity and linearization status\n\
|
||||||
@ -604,6 +606,7 @@ int main(int argc, char* argv[])
|
|||||||
std::string force_version;
|
std::string force_version;
|
||||||
|
|
||||||
bool static_id = false;
|
bool static_id = false;
|
||||||
|
bool static_aes_iv = false;
|
||||||
bool suppress_original_object_id = false;
|
bool suppress_original_object_id = false;
|
||||||
bool show_encryption = false;
|
bool show_encryption = false;
|
||||||
bool check_linearization = false;
|
bool check_linearization = false;
|
||||||
@ -758,6 +761,10 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
static_id = true;
|
static_id = true;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(arg, "static-aes-iv") == 0)
|
||||||
|
{
|
||||||
|
static_aes_iv = true;
|
||||||
|
}
|
||||||
else if (strcmp(arg, "no-original-object-ids") == 0)
|
else if (strcmp(arg, "no-original-object-ids") == 0)
|
||||||
{
|
{
|
||||||
suppress_original_object_id = true;
|
suppress_original_object_id = true;
|
||||||
@ -1049,6 +1056,10 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
w.setStaticID(true);
|
w.setStaticID(true);
|
||||||
}
|
}
|
||||||
|
if (static_aes_iv)
|
||||||
|
{
|
||||||
|
w.setStaticAesIV(true);
|
||||||
|
}
|
||||||
if (suppress_original_object_id)
|
if (suppress_original_object_id)
|
||||||
{
|
{
|
||||||
w.setSuppressOriginalObjectIDs(true);
|
w.setSuppressOriginalObjectIDs(true);
|
||||||
|
@ -168,3 +168,5 @@ QPDF_encryption cleartext metadata 0
|
|||||||
QPDF_encryption aes decode stream 0
|
QPDF_encryption aes decode stream 0
|
||||||
QPDFWriter forcing object stream disable 0
|
QPDFWriter forcing object stream disable 0
|
||||||
QPDFWriter forced version disabled encryption 0
|
QPDFWriter forced version disabled encryption 0
|
||||||
|
qpdf-c called qpdf_set_r4_encryption_parameters 0
|
||||||
|
qpdf-c called qpdf_set_static_aes_IV 0
|
||||||
|
@ -954,6 +954,7 @@ $td->runtest("invalid password",
|
|||||||
my @cenc = (
|
my @cenc = (
|
||||||
[11, 'hybrid-xref.pdf', "''", 'r2', ""],
|
[11, 'hybrid-xref.pdf', "''", 'r2', ""],
|
||||||
[12, 'hybrid-xref.pdf', "''", 'r3', ""],
|
[12, 'hybrid-xref.pdf', "''", 'r3', ""],
|
||||||
|
[15, 'hybrid-xref.pdf', "''", 'r4', ""],
|
||||||
[13, 'c-r2.pdf', 'user1', 'decrypt with user',
|
[13, 'c-r2.pdf', 'user1', 'decrypt with user',
|
||||||
"user password: user1\n"],
|
"user password: user1\n"],
|
||||||
[13, 'c-r3.pdf', 'owner2', 'decrypt with owner',
|
[13, 'c-r3.pdf', 'owner2', 'decrypt with owner',
|
||||||
|
BIN
qpdf/qtest/qpdf/c-r4.pdf
Normal file
BIN
qpdf/qtest/qpdf/c-r4.pdf
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user