mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-12-23 21:46:24 +01:00
Support Encrypt dictionaries as well as indirect references (Issue #139)
This commit is contained in:
@@ -8,6 +8,8 @@ v1.6.1 - YYYY-MM-DD
|
||||
- Added missing input checking to `pdfioFileCreateFontObjFromBase` function.
|
||||
- Updated support for UTF-16 strings (Issue #141)
|
||||
- Updated Xcode project to use installed PNG library.
|
||||
- Fixed decryption of PDF files using an Encrypt dictionary instead of an
|
||||
indirect reference (Issue #139)
|
||||
- Fixed character range checking in a TTF support function.
|
||||
- Fixed some clang warnings.
|
||||
|
||||
|
||||
@@ -214,8 +214,9 @@ _pdfioCryptoLock(
|
||||
|
||||
pdfioObjClose(pdf->encrypt_obj);
|
||||
|
||||
pdf->encryption = encryption;
|
||||
pdf->permissions = permissions;
|
||||
pdf->encrypt_dict = dict;
|
||||
pdf->encryption = encryption;
|
||||
pdf->permissions = permissions;
|
||||
|
||||
return (true);
|
||||
}
|
||||
@@ -570,7 +571,6 @@ _pdfioCryptoUnlock(
|
||||
{
|
||||
int tries; // Number of tries
|
||||
const char *password = NULL; // Password to try
|
||||
pdfio_dict_t *encrypt_dict; // Encrypt objection dictionary
|
||||
int version, // Version value
|
||||
revision, // Revision value
|
||||
length; // Key length value
|
||||
@@ -590,20 +590,14 @@ _pdfioCryptoUnlock(
|
||||
_pdfio_value_t *value; // Encrypt dictionary value, if any
|
||||
|
||||
|
||||
// See if we support the type of encryption specified by the Encrypt object
|
||||
// See if we support the type of encryption specified by the Encrypt
|
||||
// dictionary...
|
||||
if ((encrypt_dict = pdfioObjGetDict(pdf->encrypt_obj)) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to get encryption dictionary.");
|
||||
return (false);
|
||||
}
|
||||
handler = pdfioDictGetName(pdf->encrypt_dict, "Filter");
|
||||
version = (int)pdfioDictGetNumber(pdf->encrypt_dict, "V");
|
||||
revision = (int)pdfioDictGetNumber(pdf->encrypt_dict, "R");
|
||||
length = (int)pdfioDictGetNumber(pdf->encrypt_dict, "Length");
|
||||
|
||||
handler = pdfioDictGetName(encrypt_dict, "Filter");
|
||||
version = (int)pdfioDictGetNumber(encrypt_dict, "V");
|
||||
revision = (int)pdfioDictGetNumber(encrypt_dict, "R");
|
||||
length = (int)pdfioDictGetNumber(encrypt_dict, "Length");
|
||||
|
||||
if ((value = _pdfioDictGetValue(encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
|
||||
if ((value = _pdfioDictGetValue(pdf->encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
|
||||
pdf->encrypt_metadata = value->value.boolean;
|
||||
else
|
||||
pdf->encrypt_metadata = true;
|
||||
@@ -622,9 +616,9 @@ _pdfioCryptoUnlock(
|
||||
pdfio_dict_t *filter; // Crypt Filter
|
||||
const char *cfm; // Crypt filter method
|
||||
|
||||
stream_filter = pdfioDictGetName(encrypt_dict, "StmF");
|
||||
string_filter = pdfioDictGetName(encrypt_dict, "StrF");
|
||||
cf_dict = pdfioDictGetDict(encrypt_dict, "CF");
|
||||
stream_filter = pdfioDictGetName(pdf->encrypt_dict, "StmF");
|
||||
string_filter = pdfioDictGetName(pdf->encrypt_dict, "StrF");
|
||||
cf_dict = pdfioDictGetDict(pdf->encrypt_dict, "CF");
|
||||
|
||||
if (!cf_dict)
|
||||
{
|
||||
@@ -701,7 +695,7 @@ _pdfioCryptoUnlock(
|
||||
// Grab the remaining values we need to unlock the PDF...
|
||||
pdf->file_keylen = (size_t)(length / 8);
|
||||
|
||||
p = pdfioDictGetNumber(encrypt_dict, "P");
|
||||
p = pdfioDictGetNumber(pdf->encrypt_dict, "P");
|
||||
PDFIO_DEBUG("_pdfioCryptoUnlock: P=%.0f\n", p);
|
||||
if (p < 0x7fffffff) // Handle integers > 2^31-1
|
||||
pdf->permissions = (pdfio_permission_t)p;
|
||||
@@ -709,8 +703,8 @@ _pdfioCryptoUnlock(
|
||||
pdf->permissions = (pdfio_permission_t)(p - 4294967296.0);
|
||||
PDFIO_DEBUG("_pdfioCryptoUnlock: permissions=%d\n", pdf->permissions);
|
||||
|
||||
owner_key = pdfioDictGetBinary(encrypt_dict, "O", &owner_keylen);
|
||||
user_key = pdfioDictGetBinary(encrypt_dict, "U", &user_keylen);
|
||||
owner_key = pdfioDictGetBinary(pdf->encrypt_dict, "O", &owner_keylen);
|
||||
user_key = pdfioDictGetBinary(pdf->encrypt_dict, "U", &user_keylen);
|
||||
|
||||
if (!owner_key)
|
||||
{
|
||||
|
||||
41
pdfio-file.c
41
pdfio-file.c
@@ -2283,12 +2283,18 @@ load_xref(
|
||||
{
|
||||
// Save the trailer dictionary and grab the root (catalog) and info
|
||||
// objects...
|
||||
pdfio_obj_t *encrypt_obj; // Encryption object
|
||||
|
||||
pdf->trailer_dict = trailer.value.dict;
|
||||
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
|
||||
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
|
||||
|
||||
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
|
||||
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
|
||||
else
|
||||
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
|
||||
|
||||
// If the trailer contains an Encrypt key, try unlocking the file...
|
||||
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
|
||||
if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
|
||||
return (false);
|
||||
}
|
||||
|
||||
@@ -2434,12 +2440,18 @@ load_xref(
|
||||
{
|
||||
// Save the trailer dictionary and grab the root (catalog) and info
|
||||
// objects...
|
||||
pdfio_obj_t *encrypt_obj; // Encryption object
|
||||
|
||||
pdf->trailer_dict = trailer.value.dict;
|
||||
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
|
||||
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
|
||||
|
||||
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
|
||||
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
|
||||
else
|
||||
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
|
||||
|
||||
// If the trailer contains an Encrypt key, try unlocking the file...
|
||||
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
|
||||
if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
@@ -2529,7 +2541,7 @@ repair_xref(
|
||||
pdf->root_obj = NULL;
|
||||
pdf->info_obj = NULL;
|
||||
pdf->pages_obj = NULL;
|
||||
pdf->encrypt_obj = NULL;
|
||||
pdf->encrypt_dict = NULL;
|
||||
|
||||
// Read from the beginning of the file, looking for objects...
|
||||
if ((line_offset = _pdfioFileSeek(pdf, 0, SEEK_SET)) < 0)
|
||||
@@ -2603,10 +2615,17 @@ repair_xref(
|
||||
if (!strcmp(type, "XRef") && !pdf->trailer_dict)
|
||||
{
|
||||
// Save the trailer dictionary...
|
||||
pdfio_obj_t *encrypt_obj;
|
||||
// Encryption object
|
||||
|
||||
PDFIO_DEBUG("repair_xref: XRef stream...\n");
|
||||
pdf->trailer_dict = pdfioObjGetDict(obj);
|
||||
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
|
||||
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
|
||||
|
||||
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
|
||||
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
|
||||
else
|
||||
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
|
||||
}
|
||||
}
|
||||
else if (type && !strcmp(line, "endobj"))
|
||||
@@ -2660,11 +2679,17 @@ repair_xref(
|
||||
{
|
||||
// Save the trailer dictionary and grab the root (catalog) and info
|
||||
// objects...
|
||||
pdfio_obj_t *encrypt_obj; // Encryption object
|
||||
|
||||
PDFIO_DEBUG("repair_xref: Using this trailer dictionary.\n");
|
||||
|
||||
pdf->trailer_dict = trailer.value.dict;
|
||||
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
|
||||
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
|
||||
|
||||
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
|
||||
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
|
||||
else
|
||||
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2678,7 +2703,7 @@ repair_xref(
|
||||
pdf->trailer_dict = backup_trailer;
|
||||
|
||||
// If the trailer contains an Encrypt key, try unlocking the file...
|
||||
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
|
||||
if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
|
||||
return (false);
|
||||
|
||||
// Load any stream objects...
|
||||
|
||||
@@ -283,7 +283,8 @@ struct _pdfio_file_s // PDF file structure
|
||||
pdfio_obj_t *root_obj; // Root object/dictionary
|
||||
pdfio_obj_t *info_obj; // Information object
|
||||
pdfio_obj_t *pages_obj; // Root pages object
|
||||
pdfio_obj_t *encrypt_obj; // De/Encryption object/dictionary
|
||||
pdfio_obj_t *encrypt_obj; // Encryption object (not used for reading)
|
||||
pdfio_dict_t *encrypt_dict; // De/Encryption dictionary
|
||||
pdfio_obj_t *cgats001_obj, // CGATS001 ICC profile object
|
||||
*cp1252_obj, // CP1252 font encoding object
|
||||
*unicode_obj; // Unicode font encoding object
|
||||
|
||||
Reference in New Issue
Block a user