mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-06-06 13:34:22 +02:00
Compare commits
No commits in common. "1e6bb710e30e64ae55edb32d248deb21c852ced2" and "67704ce493a6b2501ad47a61f73019ac919a2475" have entirely different histories.
1e6bb710e3
...
67704ce493
@ -25,8 +25,6 @@ v1.5.3 - YYYY-MM-DD
|
|||||||
|
|
||||||
- Fixed decryption of PDF files "protected" by 40-bit RC4 (Issue #42)
|
- Fixed decryption of PDF files "protected" by 40-bit RC4 (Issue #42)
|
||||||
- Fixed decryption of UTF-16 strings (Issue #42)
|
- Fixed decryption of UTF-16 strings (Issue #42)
|
||||||
- Fixed decryption of PDF files with large permission values.
|
|
||||||
- Fixed support for EncryptMetadata key in the encryption dictionary.
|
|
||||||
|
|
||||||
|
|
||||||
v1.5.2 - 2025-04-12
|
v1.5.2 - 2025-04-12
|
||||||
|
@ -98,7 +98,7 @@ static uint8_t pdf_passpad[32] = // Padding for passwords
|
|||||||
|
|
||||||
static void decrypt_user_key(pdfio_encryption_t encryption, const uint8_t *file_key, uint8_t user_key[32]);
|
static void decrypt_user_key(pdfio_encryption_t encryption, const uint8_t *file_key, uint8_t user_key[32]);
|
||||||
static void encrypt_user_key(pdfio_encryption_t encryption, const uint8_t *file_key, uint8_t user_key[32]);
|
static void encrypt_user_key(pdfio_encryption_t encryption, const uint8_t *file_key, uint8_t user_key[32]);
|
||||||
static void make_file_key(pdfio_encryption_t encryption, pdfio_permission_t permissions, const unsigned char *file_id, size_t file_idlen, const uint8_t *user_pad, const uint8_t *owner_key, bool encrypt_metadata, uint8_t file_key[16]);
|
static void make_file_key(pdfio_encryption_t encryption, pdfio_permission_t permissions, const unsigned char *file_id, size_t file_idlen, const uint8_t *user_pad, const uint8_t *owner_key, uint8_t file_key[16]);
|
||||||
static void make_owner_key(pdfio_encryption_t encryption, const uint8_t *owner_pad, const uint8_t *user_pad, uint8_t owner_key[32]);
|
static void make_owner_key(pdfio_encryption_t encryption, const uint8_t *owner_pad, const uint8_t *user_pad, uint8_t owner_key[32]);
|
||||||
static void make_user_key(const unsigned char *file_id, size_t file_idlen, uint8_t user_key[32]);
|
static void make_user_key(const unsigned char *file_id, size_t file_idlen, uint8_t user_key[32]);
|
||||||
static void pad_password(const char *password, uint8_t pad[32]);
|
static void pad_password(const char *password, uint8_t pad[32]);
|
||||||
@ -158,7 +158,7 @@ _pdfioCryptoLock(
|
|||||||
// Generate the encryption key
|
// Generate the encryption key
|
||||||
file_id = pdfioArrayGetBinary(pdf->id_array, 0, &file_idlen);
|
file_id = pdfioArrayGetBinary(pdf->id_array, 0, &file_idlen);
|
||||||
|
|
||||||
make_file_key(encryption, permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->encrypt_metadata, pdf->file_key);
|
make_file_key(encryption, permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->file_key);
|
||||||
pdf->file_keylen = 16;
|
pdf->file_keylen = 16;
|
||||||
|
|
||||||
// Generate the user key...
|
// Generate the user key...
|
||||||
@ -583,7 +583,6 @@ _pdfioCryptoUnlock(
|
|||||||
_pdfio_md5_t md5; // MD5 context
|
_pdfio_md5_t md5; // MD5 context
|
||||||
uint8_t file_digest[16]; // MD5 digest of file ID and pad
|
uint8_t file_digest[16]; // MD5 digest of file ID and pad
|
||||||
double p; // Permissions value as a double
|
double p; // Permissions value as a double
|
||||||
_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 object
|
||||||
@ -599,12 +598,7 @@ _pdfioCryptoUnlock(
|
|||||||
revision = (int)pdfioDictGetNumber(encrypt_dict, "R");
|
revision = (int)pdfioDictGetNumber(encrypt_dict, "R");
|
||||||
length = (int)pdfioDictGetNumber(encrypt_dict, "Length");
|
length = (int)pdfioDictGetNumber(encrypt_dict, "Length");
|
||||||
|
|
||||||
if ((value = _pdfioDictGetValue(encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
|
PDFIO_DEBUG("_pdfioCryptoUnlock: handler=%p(%s), version=%d, revision=%d, length=%d\n", (void *)handler, handler ? handler : "(null)", version, revision, length);
|
||||||
pdf->encrypt_metadata = value->value.boolean;
|
|
||||||
else
|
|
||||||
pdf->encrypt_metadata = true;
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioCryptoUnlock: handler=%p(%s), version=%d, revision=%d, length=%d, encrypt_metadata=%s\n", (void *)handler, handler ? handler : "(null)", version, revision, length, pdf->encrypt_metadata ? "true" : "false");
|
|
||||||
|
|
||||||
if (!handler || strcmp(handler, "Standard"))
|
if (!handler || strcmp(handler, "Standard"))
|
||||||
{
|
{
|
||||||
@ -774,7 +768,7 @@ _pdfioCryptoUnlock(
|
|||||||
make_owner_key(pdf->encryption, pad, pdf->owner_key, user_pad);
|
make_owner_key(pdf->encryption, pad, pdf->owner_key, user_pad);
|
||||||
PDFIO_DEBUG("_pdfioCryptoUnlock: Upad=%02X%02X%02X%02X...%02X%02X%02X%02X\n", user_pad[0], user_pad[1], user_pad[2], user_pad[3], user_pad[28], user_pad[29], user_pad[30], user_pad[31]);
|
PDFIO_DEBUG("_pdfioCryptoUnlock: Upad=%02X%02X%02X%02X...%02X%02X%02X%02X\n", user_pad[0], user_pad[1], user_pad[2], user_pad[3], user_pad[28], user_pad[29], user_pad[30], user_pad[31]);
|
||||||
|
|
||||||
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->encrypt_metadata, file_key);
|
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, user_pad, pdf->owner_key, file_key);
|
||||||
PDFIO_DEBUG("_pdfioCryptoUnlock: Fown=%02X%02X%02X%02X...%02X%02X%02X%02X\n", file_key[0], file_key[1], file_key[2], file_key[3], file_key[12], file_key[13], file_key[14], file_key[15]);
|
PDFIO_DEBUG("_pdfioCryptoUnlock: Fown=%02X%02X%02X%02X...%02X%02X%02X%02X\n", file_key[0], file_key[1], file_key[2], file_key[3], file_key[12], file_key[13], file_key[14], file_key[15]);
|
||||||
|
|
||||||
make_user_key(file_id, file_idlen, own_user_key);
|
make_user_key(file_id, file_idlen, own_user_key);
|
||||||
@ -792,7 +786,7 @@ _pdfioCryptoUnlock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not the owner password, try the user password...
|
// Not the owner password, try the user password...
|
||||||
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, pad, pdf->owner_key, pdf->encrypt_metadata, file_key);
|
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, pad, pdf->owner_key, file_key);
|
||||||
PDFIO_DEBUG("_pdfioCryptoUnlock: Fuse=%02X%02X%02X%02X...%02X%02X%02X%02X\n", file_key[0], file_key[1], file_key[2], file_key[3], file_key[12], file_key[13], file_key[14], file_key[15]);
|
PDFIO_DEBUG("_pdfioCryptoUnlock: Fuse=%02X%02X%02X%02X...%02X%02X%02X%02X\n", file_key[0], file_key[1], file_key[2], file_key[3], file_key[12], file_key[13], file_key[14], file_key[15]);
|
||||||
|
|
||||||
make_user_key(file_id, file_idlen, own_user_key);
|
make_user_key(file_id, file_idlen, own_user_key);
|
||||||
@ -924,8 +918,6 @@ make_file_key(
|
|||||||
size_t file_idlen, // I - Length of file ID
|
size_t file_idlen, // I - Length of file ID
|
||||||
const uint8_t *user_pad, // I - Padded user password
|
const uint8_t *user_pad, // I - Padded user password
|
||||||
const uint8_t *owner_key, // I - Owner key
|
const uint8_t *owner_key, // I - Owner key
|
||||||
bool encrypt_metadata,
|
|
||||||
// I - Encrypt metadata?
|
|
||||||
uint8_t file_key[16]) // O - Encryption key
|
uint8_t file_key[16]) // O - Encryption key
|
||||||
{
|
{
|
||||||
size_t i; // Looping var
|
size_t i; // Looping var
|
||||||
@ -939,25 +931,13 @@ make_file_key(
|
|||||||
perm_bytes[2] = (uint8_t)(permissions >> 16);
|
perm_bytes[2] = (uint8_t)(permissions >> 16);
|
||||||
perm_bytes[3] = (uint8_t)(permissions >> 24);
|
perm_bytes[3] = (uint8_t)(permissions >> 24);
|
||||||
|
|
||||||
PDFIO_DEBUG("make_file_key: user_pad[32]=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", user_pad[0], user_pad[1], user_pad[2], user_pad[3], user_pad[28], user_pad[29], user_pad[30], user_pad[31]);
|
|
||||||
PDFIO_DEBUG("make_file_key: owner_key[32]=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", owner_key[0], owner_key[1], owner_key[2], owner_key[3], owner_key[28], owner_key[29], owner_key[30], owner_key[31]);
|
|
||||||
PDFIO_DEBUG("make_file_key: permissions(%d)=<%02X%02X%02X%02X>\n", permissions, perm_bytes[0], perm_bytes[1], perm_bytes[2], perm_bytes[3]);
|
|
||||||
|
|
||||||
_pdfioCryptoMD5Init(&md5);
|
_pdfioCryptoMD5Init(&md5);
|
||||||
_pdfioCryptoMD5Append(&md5, user_pad, 32);
|
_pdfioCryptoMD5Append(&md5, user_pad, 32);
|
||||||
_pdfioCryptoMD5Append(&md5, owner_key, 32);
|
_pdfioCryptoMD5Append(&md5, owner_key, 32);
|
||||||
_pdfioCryptoMD5Append(&md5, perm_bytes, 4);
|
_pdfioCryptoMD5Append(&md5, perm_bytes, 4);
|
||||||
_pdfioCryptoMD5Append(&md5, file_id, file_idlen);
|
_pdfioCryptoMD5Append(&md5, file_id, file_idlen);
|
||||||
if (!encrypt_metadata)
|
|
||||||
{
|
|
||||||
uint8_t meta_bytes[4] = { 0xff, 0xff, 0xff, 0xff };
|
|
||||||
// Metadata bytes
|
|
||||||
_pdfioCryptoMD5Append(&md5, meta_bytes, 4);
|
|
||||||
}
|
|
||||||
_pdfioCryptoMD5Finish(&md5, digest);
|
_pdfioCryptoMD5Finish(&md5, digest);
|
||||||
|
|
||||||
PDFIO_DEBUG("make_file_key: first md5=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", digest[0], digest[1], digest[2], digest[3], digest[12], digest[13], digest[14], digest[15]);
|
|
||||||
|
|
||||||
if (encryption != PDFIO_ENCRYPTION_RC4_40)
|
if (encryption != PDFIO_ENCRYPTION_RC4_40)
|
||||||
{
|
{
|
||||||
// MD5 the result 50 times..
|
// MD5 the result 50 times..
|
||||||
@ -969,8 +949,6 @@ make_file_key(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFIO_DEBUG("make_file_key: file_key[16]=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", digest[0], digest[1], digest[2], digest[3], digest[12], digest[13], digest[14], digest[15]);
|
|
||||||
|
|
||||||
memcpy(file_key, digest, 16);
|
memcpy(file_key, digest, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1262,8 +1262,6 @@ pdfioFileSetPermissions(
|
|||||||
if (encryption == PDFIO_ENCRYPTION_NONE)
|
if (encryption == PDFIO_ENCRYPTION_NONE)
|
||||||
return (true);
|
return (true);
|
||||||
|
|
||||||
pdf->encrypt_metadata = true;
|
|
||||||
|
|
||||||
return (_pdfioCryptoLock(pdf, permissions, encryption, owner_password, user_password));
|
return (_pdfioCryptoLock(pdf, permissions, encryption, owner_password, user_password));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ _pdfioObjLoad(pdfio_obj_t *obj) // I - Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt as needed...
|
// Decrypt as needed...
|
||||||
if (obj->pdf->encryption && obj->pdf->encrypt_metadata)
|
if (obj->pdf->encryption)
|
||||||
{
|
{
|
||||||
PDFIO_DEBUG("_pdfioObjLoad: Decrypting value...\n");
|
PDFIO_DEBUG("_pdfioObjLoad: Decrypting value...\n");
|
||||||
|
|
||||||
|
@ -271,7 +271,6 @@ struct _pdfio_file_s // PDF file structure
|
|||||||
*cp1252_obj, // CP1252 font encoding object
|
*cp1252_obj, // CP1252 font encoding object
|
||||||
*unicode_obj; // Unicode font encoding object
|
*unicode_obj; // Unicode font encoding object
|
||||||
pdfio_array_t *id_array; // ID array
|
pdfio_array_t *id_array; // ID array
|
||||||
bool encrypt_metadata; // Encrypt metadata?
|
|
||||||
|
|
||||||
// Allocated data elements
|
// Allocated data elements
|
||||||
size_t num_arrays, // Number of arrays
|
size_t num_arrays, // Number of arrays
|
||||||
|
@ -562,13 +562,6 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
|
|||||||
if (predictor >= 10)
|
if (predictor >= 10)
|
||||||
st->pbsize ++; // Add PNG predictor byte
|
st->pbsize ++; // Add PNG predictor byte
|
||||||
|
|
||||||
if (st->pbsize < 2)
|
|
||||||
{
|
|
||||||
_pdfioFileError(st->pdf, "Bad Predictor buffer size %lu.", (unsigned long)st->pbsize);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioStreamOpen: st->predictor=%d, st->pbpixel=%u, st->pbsize=%lu\n", st->predictor, (unsigned)st->pbpixel, (unsigned long)st->pbsize);
|
|
||||||
if ((st->prbuffer = calloc(1, st->pbsize - 1)) == NULL || (st->psbuffer = calloc(1, st->pbsize)) == NULL)
|
if ((st->prbuffer = calloc(1, st->pbsize - 1)) == NULL || (st->psbuffer = calloc(1, st->pbsize)) == NULL)
|
||||||
{
|
{
|
||||||
_pdfioFileError(st->pdf, "Unable to allocate %lu bytes for Predictor buffers.", (unsigned long)st->pbsize);
|
_pdfioFileError(st->pdf, "Unable to allocate %lu bytes for Predictor buffers.", (unsigned long)st->pbsize);
|
||||||
@ -1235,18 +1228,7 @@ stream_read(pdfio_stream_t *st, // I - Stream
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply predictor for this line
|
// Apply predictor for this line
|
||||||
#ifdef DEBUG
|
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[0], sptr[2], sptr[3]);
|
||||||
if (remaining > 4)
|
|
||||||
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X %02X ...\n", sptr[-1], sptr[0], sptr[1], sptr[2], sptr[3]);
|
|
||||||
else if (remaining > 3)
|
|
||||||
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[1], sptr[2], sptr[3]);
|
|
||||||
else if (remaining > 2)
|
|
||||||
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[1], sptr[2]);
|
|
||||||
else if (remaining > 1)
|
|
||||||
PDFIO_DEBUG("stream_read: Line %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[1]);
|
|
||||||
else
|
|
||||||
PDFIO_DEBUG("stream_read: Line %02X %02X.\n", sptr[-1], sptr[0]);
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
switch (sptr[-1])
|
switch (sptr[-1])
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user