Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented password based AES256 (ISO 32000-2) support, see issue #375 #802

Merged
merged 18 commits into from
Sep 14, 2022

Conversation

mkl-public
Copy link
Contributor

Description of the new Feature

Support for PDF encryption using AES256 has been specified twice, first by Adobe in their developer extensions to ISO 32000-1, and later again in ISO 32000-2. The former variant is associated with the standard security handler revision 5 in the encryption dictionary, the latter variant with revision 6.

This pull request implements support for the latter variant, R = 6, in the context of password encryption. It does not add support for R = 5. Furthermore, providing support for AES256 in the context of certificate encryption was not an objective.

Related Issue: #375

@Lonzak helped a lot by testing and providing example files.

Unit-Tests for the new Feature

DecryptAES256R6Test

This class tests the OpenPDF decryption feature for AES256 encrypted files according to ISO 32000-2, i.e. for R = 6.

The test files were associated with issue #375, examples for stackoverflow.com issues, or provided by @Lonzak.

EncryptAES256R6Test

This class tests the OpenPDF encryption feature for AES256 encrypted files according to ISO 32000-2, i.e. for R = 6.

Both creation of a new encrypted PDF from scratch and stamping of an existing encrypted PDF are tested.

Compatibilities Issues

Some additional public constants in PdfEncryption, PdfName, PdfWriter.

Additional member variables in PdfEncryption.

These changes are unlikely to cause issues except with other OpenPDF patches changing encryption support.

First proof-of-concept: Enhanced OpenPdf to decrypt and read a PDF encrypted with AES256 as specified in ISO 32000-2.

The main changes are in PdfEncryption and PdfReader (method readDecryptedDocObj). StandardDecryption merely now recognizes AES256R3 as an AES variant, and PdfWriter and PdfName only provide extra constants.

DecryptAES256R6Test tests this POC using the example file pwProtectedAES256_openPDFiss375.pdf attached to LibrePDF#375.


LibrePDF#375 - "Unknown encryption type R = 6" support AES256
LibrePDF#375
pwProtectedAES256_openPDFiss375.pdf
https://github.com/LibrePDF/OpenPDF/files/4700100/pwProtectedAES256_openPDFiss375.pdf
DecryptAES256R6Test now tests this POC also using the example file Demo1_encrypted_.pdf provided by TvT.

LibrePDF#375 - "Unknown encryption type R = 6" support AES256
LibrePDF#375
Demo1_encrypted_.pdf provided by TvT
First proof-of-concept: Enhanced OpenPdf to encrypt and create a PDF from scratch with AES256 as specified in ISO 32000-2.

The main changes are in PdfEncryption. OutputStreamEncryption merely now recognizes AES256R3 as an AES variant, and PdfName only provides an extra constant.

EncryptAES256R6Test tests this POC.

LibrePDF#375 - "Unknown encryption type R = 6" support AES256
LibrePDF#375
Added more decryption tests with test file provided by TvT.

As it turns out, OpenPdf currently only supports all-or-nothing encryption (except Metadata and signatures), so test files with encryption of embedded files only or certain streams only cannot be processed.
New EncryptAES256R6Test test testStampPwProtectedAES256_openPDFiss375 which stamps the test file "pwProtectedAES256_openPDFiss375-Stamped.pdf" in append mode, re-using the existing encryption.

Hardened PdfEncryption against a NullPointerException relevant in this context.
A number of the example AES256R6 encrypted PDFs have a peculiarity: The U and O values by specification are 48 byte values, but in these PDFs they are supplemented with zeroes to 127 bytes each. In most contexts this is no problem as one usually takes n bytes starting at offset m for some calculation. When validating the owner password, though, the whole U value is used. To make this code work for the PDFs in question, one has to use only the leading 48 bytes of the U value.

PdfReader.readDecryptedDocObj has been adapted to do so.
Additionally the DecryptAES256R6Test tests have been adapted to take this into account.
Lonzak had reported a NullPointerException in setHashKey during the update of the MD5 hash by mkey when stamping legacy encrypted PDFs.

When stamping encrypted PDFs in append mode, a copy of the PdfEncryption instance of the PdfReader is stored in the PdfStamperImp instance.
The mkey value is used for the legacy encryption algorithms (and only there).
Thus, stamping tests with AES256R6 succeeded while stamping tests with legacy algorithms don't exist...
@alokkusingh
Copy link

Hi, can this PR be merged?

@asturio
Copy link
Member

asturio commented Sep 12, 2022

Hi @mkl-public , the checkstyle problems were fixed on master. Can you please rebase your branch onto OpenPdf/master?

@mkl-public
Copy link
Contributor Author

mkl-public commented Sep 12, 2022

@asturio

Hi @mkl-public , the checkstyle problems were fixed on master. Can you please rebase your branch onto OpenPdf/master?

Ah, I just see you said rebase but I merged. Is that ok, too?

@asturio asturio linked an issue Sep 13, 2022 that may be closed by this pull request
@sonarcloud
Copy link

sonarcloud bot commented Sep 13, 2022

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@asturio
Copy link
Member

asturio commented Sep 13, 2022

@asturio

Hi @mkl-public , the checkstyle problems were fixed on master. Can you please rebase your branch onto OpenPdf/master?

Ah, I just see you said rebase but I merged. Is that ok, too?

There are now some conflicts. I think the merge confuses now the merge strategy. I could squash and commit, or try to resolve the problem locally, cherry-picking your commits and resolve any conflict. Are you ok with a squash?

@asturio asturio linked an issue Sep 13, 2022 that may be closed by this pull request
@asturio asturio merged commit 05ff04f into LibrePDF:master Sep 14, 2022
@asturio
Copy link
Member

asturio commented Sep 14, 2022

@Lonzak , @mkl-public
Thank you for adding this so wanted feature.

@mkl-public
Copy link
Contributor Author

There are now some conflicts. I think the merge confuses now the merge strategy. I could squash and commit, or try to resolve the problem locally, cherry-picking your commits and resolve any conflict. Are you ok with a squash?

Squashing was ok

@asturio asturio added this to the 1.3.30 milestone Sep 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support AES-256 encryption "Unknown encryption type R = 6" support AES256
3 participants