aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF_encryption.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-08-22 03:33:44 +0200
committerJay Berkenbilt <ejb@ql.org>2017-08-22 03:35:11 +0200
commita8c93bd324d0362a26c1e6591eead5c52f865c0d (patch)
treeb3eda018bb384479c109640f442c94bc3d84ac0b /libqpdf/QPDF_encryption.cc
parent8288a4eb3a326acced6f07b0caf75f6ada53150d (diff)
downloadqpdf-a8c93bd324d0362a26c1e6591eead5c52f865c0d.tar.zst
Push QPDF member variables into a nested class
Pushing member variables into a nested class enables addition of new member variables without breaking binary compatibility.
Diffstat (limited to 'libqpdf/QPDF_encryption.cc')
-rw-r--r--libqpdf/QPDF_encryption.cc176
1 files changed, 91 insertions, 85 deletions
diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc
index 6c0c97ef..81325591 100644
--- a/libqpdf/QPDF_encryption.cc
+++ b/libqpdf/QPDF_encryption.cc
@@ -760,9 +760,9 @@ QPDF::interpretCF(QPDFObjectHandle cf)
if (cf.isName())
{
std::string filter = cf.getName();
- if (this->crypt_filters.count(filter) != 0)
+ if (this->m->crypt_filters.count(filter) != 0)
{
- return this->crypt_filters[filter];
+ return this->m->crypt_filters[filter];
}
else if (filter == "/Identity")
{
@@ -783,29 +783,29 @@ QPDF::interpretCF(QPDFObjectHandle cf)
void
QPDF::initializeEncryption()
{
- if (this->encryption_initialized)
+ if (this->m->encryption_initialized)
{
return;
}
- this->encryption_initialized = true;
+ this->m->encryption_initialized = true;
// After we initialize encryption parameters, we must used stored
// key information and never look at /Encrypt again. Otherwise,
// things could go wrong if someone mutates the encryption
// dictionary.
- if (! this->trailer.hasKey("/Encrypt"))
+ if (! this->m->trailer.hasKey("/Encrypt"))
{
return;
}
- // Go ahead and set this->encryption here. That way, isEncrypted
+ // Go ahead and set this->m->encrypted here. That way, isEncrypted
// will return true even if there were errors reading the
// encryption dictionary.
- this->encrypted = true;
+ this->m->encrypted = true;
std::string id1;
- QPDFObjectHandle id_obj = this->trailer.getKey("/ID");
+ QPDFObjectHandle id_obj = this->m->trailer.getKey("/ID");
if ((id_obj.isArray() &&
(id_obj.getArrayNItems() == 2) &&
id_obj.getArrayItem(0).isString()))
@@ -817,31 +817,31 @@ QPDF::initializeEncryption()
// Treating a missing ID as the empty string enables qpdf to
// decrypt some invalid encrypted files with no /ID that
// poppler can read but Adobe Reader can't.
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "trailer", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "trailer", this->m->file->getLastOffset(),
"invalid /ID in trailer dictionary"));
}
- QPDFObjectHandle encryption_dict = this->trailer.getKey("/Encrypt");
+ QPDFObjectHandle encryption_dict = this->m->trailer.getKey("/Encrypt");
if (! encryption_dict.isDictionary())
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"/Encrypt in trailer dictionary is not a dictionary");
}
if (! (encryption_dict.getKey("/Filter").isName() &&
(encryption_dict.getKey("/Filter").getName() == "/Standard")))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"unsupported encryption filter");
}
if (! encryption_dict.getKey("/SubFilter").isNull())
{
- warn(QPDFExc(qpdf_e_unsupported, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_unsupported, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"file uses encryption SubFilters,"
" which qpdf does not support"));
}
@@ -852,8 +852,8 @@ QPDF::initializeEncryption()
encryption_dict.getKey("/U").isString() &&
encryption_dict.getKey("/P").isInteger()))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"some encryption dictionary parameters are missing "
"or the wrong type");
}
@@ -869,15 +869,15 @@ QPDF::initializeEncryption()
if (! (((R >= 2) && (R <= 6)) &&
((V == 1) || (V == 2) || (V == 4) || (V == 5))))
{
- throw QPDFExc(qpdf_e_unsupported, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_unsupported, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"Unsupported /R or /V in encryption dictionary; R = " +
QUtil::int_to_string(R) + " (max 6), V = " +
QUtil::int_to_string(V) + " (max 5)");
}
- this->encryption_V = V;
- this->encryption_R = R;
+ this->m->encryption_V = V;
+ this->m->encryption_R = R;
// OE, UE, and Perms are only present if V >= 5.
std::string OE;
@@ -890,8 +890,9 @@ QPDF::initializeEncryption()
pad_short_parameter(U, key_bytes);
if (! ((O.length() == key_bytes) && (U.length() == key_bytes)))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"incorrect length for /O and/or /U in "
"encryption dictionary");
}
@@ -902,8 +903,9 @@ QPDF::initializeEncryption()
encryption_dict.getKey("/UE").isString() &&
encryption_dict.getKey("/Perms").isString()))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"some V=5 encryption dictionary parameters are "
"missing or the wrong type");
}
@@ -922,8 +924,9 @@ QPDF::initializeEncryption()
(UE.length() < OUE_key_bytes_V5) ||
(Perms.length() < Perms_key_bytes_V5))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"incorrect length for some of"
" /O, /U, /OE, /UE, or /Perms in"
" encryption dictionary");
@@ -936,16 +939,17 @@ QPDF::initializeEncryption()
Length = encryption_dict.getKey("/Length").getIntValue();
if ((Length % 8) || (Length < 40) || (Length > 256))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"invalid /Length value in encryption dictionary");
}
}
- this->encrypt_metadata = true;
+ this->m->encrypt_metadata = true;
if ((V >= 4) && (encryption_dict.getKey("/EncryptMetadata").isBool()))
{
- this->encrypt_metadata =
+ this->m->encrypt_metadata =
encryption_dict.getKey("/EncryptMetadata").getBoolValue();
}
@@ -986,40 +990,40 @@ QPDF::initializeEncryption()
method = e_unknown;
}
}
- this->crypt_filters[filter] = method;
+ this->m->crypt_filters[filter] = method;
}
}
QPDFObjectHandle StmF = encryption_dict.getKey("/StmF");
QPDFObjectHandle StrF = encryption_dict.getKey("/StrF");
QPDFObjectHandle EFF = encryption_dict.getKey("/EFF");
- this->cf_stream = interpretCF(StmF);
- this->cf_string = interpretCF(StrF);
+ this->m->cf_stream = interpretCF(StmF);
+ this->m->cf_string = interpretCF(StrF);
if (EFF.isName())
{
- this->cf_file = interpretCF(EFF);
+ this->m->cf_file = interpretCF(EFF);
}
else
{
- this->cf_file = this->cf_stream;
+ this->m->cf_file = this->m->cf_stream;
}
}
EncryptionData data(V, R, Length / 8, P, O, U, OE, UE, Perms,
- id1, this->encrypt_metadata);
+ id1, this->m->encrypt_metadata);
if (check_owner_password(
- this->user_password, this->provided_password, data))
+ this->m->user_password, this->m->provided_password, data))
{
// password supplied was owner password; user_password has
// been initialized for V < 5
}
- else if (check_user_password(this->provided_password, data))
+ else if (check_user_password(this->m->provided_password, data))
{
- this->user_password = this->provided_password;
+ this->m->user_password = this->m->provided_password;
}
else
{
- throw QPDFExc(qpdf_e_password, this->file->getName(),
+ throw QPDFExc(qpdf_e_password, this->m->file->getName(),
"", 0, "invalid password");
}
@@ -1028,8 +1032,8 @@ QPDF::initializeEncryption()
// For V < 5, the user password is encrypted with the owner
// password, and the user password is always used for
// computing the encryption key.
- this->encryption_key = compute_encryption_key(
- this->user_password, data);
+ this->m->encryption_key = compute_encryption_key(
+ this->m->user_password, data);
}
else
{
@@ -1037,12 +1041,13 @@ QPDF::initializeEncryption()
// compute the encryption key, and neither password can be
// used to recover the other.
bool perms_valid;
- this->encryption_key = recover_encryption_key_with_password(
- this->provided_password, data, perms_valid);
+ this->m->encryption_key = recover_encryption_key_with_password(
+ this->m->provided_password, data, perms_valid);
if (! perms_valid)
{
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"/Perms field in encryption dictionary"
" doesn't match expected value"));
}
@@ -1052,23 +1057,24 @@ QPDF::initializeEncryption()
std::string
QPDF::getKeyForObject(int objid, int generation, bool use_aes)
{
- if (! this->encrypted)
+ if (! this->m->encrypted)
{
throw std::logic_error(
"request for encryption key in non-encrypted PDF");
}
- if (! ((objid == this->cached_key_objid) &&
- (generation == this->cached_key_generation)))
+ if (! ((objid == this->m->cached_key_objid) &&
+ (generation == this->m->cached_key_generation)))
{
- this->cached_object_encryption_key =
- compute_data_key(this->encryption_key, objid, generation,
- use_aes, this->encryption_V, this->encryption_R);
- this->cached_key_objid = objid;
- this->cached_key_generation = generation;
+ this->m->cached_object_encryption_key =
+ compute_data_key(this->m->encryption_key, objid, generation,
+ use_aes, this->m->encryption_V,
+ this->m->encryption_R);
+ this->m->cached_key_objid = objid;
+ this->m->cached_key_generation = generation;
}
- return this->cached_object_encryption_key;
+ return this->m->cached_object_encryption_key;
}
void
@@ -1079,9 +1085,9 @@ QPDF::decryptString(std::string& str, int objid, int generation)
return;
}
bool use_aes = false;
- if (this->encryption_V >= 4)
+ if (this->m->encryption_V >= 4)
{
- switch (this->cf_string)
+ switch (this->m->cf_string)
{
case e_none:
return;
@@ -1098,15 +1104,15 @@ QPDF::decryptString(std::string& str, int objid, int generation)
break;
default:
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"unknown encryption filter for strings"
" (check /StrF in /Encrypt dictionary);"
" strings may be decrypted improperly"));
// To avoid repeated warnings, reset cf_string. Assume
// we'd want to use AES if V == 4.
- this->cf_string = e_aes;
+ this->m->cf_string = e_aes;
break;
}
}
@@ -1145,9 +1151,9 @@ QPDF::decryptString(std::string& str, int objid, int generation)
}
catch (std::runtime_error& e)
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"error decrypting string for object " +
QUtil::int_to_string(objid) + " " +
QUtil::int_to_string(generation) + ": " + e.what());
@@ -1170,7 +1176,7 @@ QPDF::decryptStream(Pipeline*& pipeline, int objid, int generation,
return;
}
bool use_aes = false;
- if (this->encryption_V >= 4)
+ if (this->m->encryption_V >= 4)
{
encryption_method_e method = e_unknown;
std::string method_source = "/StmF from /Encrypt dictionary";
@@ -1221,21 +1227,21 @@ QPDF::decryptStream(Pipeline*& pipeline, int objid, int generation,
if (method == e_unknown)
{
- if ((! this->encrypt_metadata) && (type == "/Metadata"))
+ if ((! this->m->encrypt_metadata) && (type == "/Metadata"))
{
QTC::TC("qpdf", "QPDF_encryption cleartext metadata");
method = e_none;
}
else
{
- if (this->attachment_streams.count(
+ if (this->m->attachment_streams.count(
QPDFObjGen(objid, generation)) > 0)
{
- method = this->cf_file;
+ method = this->m->cf_file;
}
else
{
- method = this->cf_stream;
+ method = this->m->cf_stream;
}
}
}
@@ -1259,15 +1265,15 @@ QPDF::decryptStream(Pipeline*& pipeline, int objid, int generation,
default:
// filter local to this stream.
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"unknown encryption filter for streams"
" (check " + method_source + ");"
" streams may be decrypted improperly"));
// To avoid repeated warnings, reset cf_stream. Assume
// we'd want to use AES if V == 4.
- this->cf_stream = e_aes;
+ this->m->cf_stream = e_aes;
break;
}
}
@@ -1331,13 +1337,13 @@ QPDF::compute_encryption_parameters_V5(
std::string const&
QPDF::getPaddedUserPassword() const
{
- return this->user_password;
+ return this->m->user_password;
}
std::string
QPDF::getTrimmedUserPassword() const
{
- std::string result = this->user_password;
+ std::string result = this->m->user_password;
trim_user_password(result);
return result;
}
@@ -1345,13 +1351,13 @@ QPDF::getTrimmedUserPassword() const
std::string
QPDF::getEncryptionKey() const
{
- return this->encryption_key;
+ return this->m->encryption_key;
}
bool
QPDF::isEncrypted() const
{
- return this->encrypted;
+ return this->m->encrypted;
}
bool
@@ -1368,7 +1374,7 @@ QPDF::isEncrypted(int& R, int& P, int& V,
encryption_method_e& string_method,
encryption_method_e& file_method)
{
- if (this->encrypted)
+ if (this->m->encrypted)
{
QPDFObjectHandle trailer = getTrailer();
QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
@@ -1378,9 +1384,9 @@ QPDF::isEncrypted(int& R, int& P, int& V,
P = Pkey.getIntValue();
R = Rkey.getIntValue();
V = Vkey.getIntValue();
- stream_method = this->cf_stream;
- string_method = this->cf_stream;
- file_method = this->cf_file;
+ stream_method = this->m->cf_stream;
+ string_method = this->m->cf_stream;
+ file_method = this->m->cf_file;
return true;
}
else