mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-04-19 23:16:48 +02:00
Fix decryption of RC4-40 files.
This commit is contained in:
parent
4219b8fd77
commit
20dd2a6d28
@ -2,6 +2,12 @@ Changes in PDFio
|
|||||||
================
|
================
|
||||||
|
|
||||||
|
|
||||||
|
v1.5.3 - YYYY-MM-DD
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Fixed decryption of PDF files "protected" by 40-bit RC4.
|
||||||
|
|
||||||
|
|
||||||
v1.5.2 - 2025-04-12
|
v1.5.2 - 2025-04-12
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -490,20 +490,20 @@ _pdfioCryptoMakeReader(
|
|||||||
|
|
||||||
case PDFIO_ENCRYPTION_RC4_40 :
|
case PDFIO_ENCRYPTION_RC4_40 :
|
||||||
// Copy the key data for the MD5 hash.
|
// Copy the key data for the MD5 hash.
|
||||||
memcpy(data, file_key, 16);
|
memcpy(data, file_key, 5);
|
||||||
data[16] = (uint8_t)obj->number;
|
data[5] = (uint8_t)obj->number;
|
||||||
data[17] = (uint8_t)(obj->number >> 8);
|
data[6] = (uint8_t)(obj->number >> 8);
|
||||||
data[18] = (uint8_t)(obj->number >> 16);
|
data[7] = (uint8_t)(obj->number >> 16);
|
||||||
data[19] = (uint8_t)obj->generation;
|
data[8] = (uint8_t)obj->generation;
|
||||||
data[20] = (uint8_t)(obj->generation >> 8);
|
data[9] = (uint8_t)(obj->generation >> 8);
|
||||||
|
|
||||||
// Hash it...
|
// Hash it...
|
||||||
_pdfioCryptoMD5Init(&md5);
|
_pdfioCryptoMD5Init(&md5);
|
||||||
_pdfioCryptoMD5Append(&md5, data, sizeof(data));
|
_pdfioCryptoMD5Append(&md5, data, 10);
|
||||||
_pdfioCryptoMD5Finish(&md5, digest);
|
_pdfioCryptoMD5Finish(&md5, digest);
|
||||||
|
|
||||||
// Initialize the RC4 context using 40 bits of the digest...
|
// Initialize the RC4 context using 80 bits of the digest...
|
||||||
_pdfioCryptoRC4Init(&ctx->rc4, digest, 5);
|
_pdfioCryptoRC4Init(&ctx->rc4, digest, 10);
|
||||||
*ivlen = 0;
|
*ivlen = 0;
|
||||||
return ((_pdfio_crypto_cb_t)_pdfioCryptoRC4Crypt);
|
return ((_pdfio_crypto_cb_t)_pdfioCryptoRC4Crypt);
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// Copy the decrypted string back to the value and adjust the length...
|
// Copy the decrypted string back to the value and adjust the length...
|
||||||
memcpy(v->value.binary.data, temp, templen);
|
memcpy(v->value.binary.data, temp, templen);
|
||||||
|
|
||||||
if (pdf->encryption >= PDFIO_ENCRYPTION_AES_128)
|
if (pdf->encryption >= PDFIO_ENCRYPTION_AES_128 && temp[templen - 1] <= templen)
|
||||||
v->value.binary.datalen = templen - temp[templen - 1];
|
v->value.binary.datalen = templen - temp[templen - 1];
|
||||||
else
|
else
|
||||||
v->value.binary.datalen = templen;
|
v->value.binary.datalen = templen;
|
||||||
@ -183,17 +183,26 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|||||||
case PDFIO_VALTYPE_STRING :
|
case PDFIO_VALTYPE_STRING :
|
||||||
// Decrypt regular string...
|
// Decrypt regular string...
|
||||||
templen = strlen(v->value.string);
|
templen = strlen(v->value.string);
|
||||||
if (templen > (sizeof(temp) - 33))
|
if (templen > (PDFIO_MAX_STRING - 1))
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Unable to read encrypted string - too long.");
|
_pdfioFileError(pdf, "Unable to read encrypted string - too long.");
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||||
|
{
|
||||||
|
_pdfioFileError(pdf, "Unable to read encrypted binary string - out of memory.");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
ivlen = templen;
|
ivlen = templen;
|
||||||
if ((cb = _pdfioCryptoMakeReader(pdf, obj, &ctx, (uint8_t *)v->value.string, &ivlen)) == NULL)
|
if ((cb = _pdfioCryptoMakeReader(pdf, obj, &ctx, (uint8_t *)v->value.string, &ivlen)) == NULL)
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
templen = (cb)(&ctx, temp, (uint8_t *)v->value.string + ivlen, templen - ivlen);
|
templen = (cb)(&ctx, temp, (uint8_t *)v->value.string + ivlen, templen - ivlen);
|
||||||
|
|
||||||
|
if (pdf->encryption >= PDFIO_ENCRYPTION_AES_128 && temp[templen - 1] <= templen)
|
||||||
|
templen -= temp[templen - 1];
|
||||||
|
|
||||||
temp[templen] = '\0';
|
temp[templen] = '\0';
|
||||||
|
|
||||||
if ((timeval = get_date_time((char *)temp)) != 0)
|
if ((timeval = get_date_time((char *)temp)) != 0)
|
||||||
@ -207,6 +216,8 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// Copy the decrypted string back to the value...
|
// Copy the decrypted string back to the value...
|
||||||
v->value.string = pdfioStringCreate(pdf, (char *)temp);
|
v->value.string = pdfioStringCreate(pdf, (char *)temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user