Skip to content

ENH: Expose /Perms verification result on Encryption object#3672

Merged
stefan6419846 merged 6 commits intopy-pdf:mainfrom
costajohnt:feat/expose-perms-validation
Mar 12, 2026
Merged

ENH: Expose /Perms verification result on Encryption object#3672
stefan6419846 merged 6 commits intopy-pdf:mainfrom
costajohnt:feat/expose-perms-validation

Conversation

@costajohnt
Copy link
Contributor

Summary

Adds a perms_valid attribute to the Encryption class that stores the result of AlgV5.verify_perms(). This allows callers to programmatically detect when the /Perms integrity check fails for AES-256 encrypted documents (R5/R6), indicating the /P permissions field may have been tampered with.

Closes #3657

Changes

  • _encryption.py: Added self.perms_valid: bool = True to Encryption.__init__(). In verify_v5(), the AlgV5.verify_perms() result is now stored in self.perms_valid instead of only being used in a conditional.
  • _doc_common.py: Added a warning to the user_access_permissions docstring noting that returned permissions are only trustworthy if reader._encryption.perms_valid is True.
  • tests/test_encryption.py: Added 3 tests:
    • test_perms_valid_true_for_valid_r6 — verifies perms_valid is True for a valid R6 PDF
    • test_perms_valid_true_for_v4 — verifies default True for V4 (no /Perms field)
    • test_perms_valid_false_when_tampered — creates an AES-256 PDF, tampers with /Perms bytes, verifies perms_valid is False

Design Notes

  • perms_valid defaults to True because V4 and below don't use /Perms at all — only V5 (R5/R6) introduced the cryptographic integrity check.
  • The existing warning log is preserved — this change only adds programmatic access to the verification result.
  • No breaking changes — existing behavior is unchanged.

@costajohnt costajohnt marked this pull request as ready for review March 7, 2026 23:38
Copy link
Collaborator

@stefan6419846 stefan6419846 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. I have added a small remark where the approach does not look completely suitable.

@codecov
Copy link

codecov bot commented Mar 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.41%. Comparing base (2cfcd7e) to head (ad2b20e).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3672      +/-   ##
==========================================
+ Coverage   97.36%   97.41%   +0.04%     
==========================================
  Files          55       55              
  Lines        9949     9973      +24     
  Branches     1825     1831       +6     
==========================================
+ Hits         9687     9715      +28     
+ Misses        152      150       -2     
+ Partials      110      108       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@costajohnt costajohnt force-pushed the feat/expose-perms-validation branch from 968c59f to d15c397 Compare March 9, 2026 15:02
Add `perms_valid` attribute to the `Encryption` class that stores the
result of `AlgV5.verify_perms()`. This allows callers to detect when the
`/Perms` integrity check fails for AES-256 encrypted documents (R5/R6),
indicating that the `/P` permissions field may have been tampered with.

Previously, a failed `/Perms` check only logged a warning with no
programmatic way to detect it.

Closes py-pdf#3657
Expose /Perms verification result through a public property instead
of requiring access to the internal reader._encryption.perms_valid.

The new permissions_valid property returns None if the document is
not encrypted or not yet decrypted, True if permissions are verified
(or non-AES-256), and False if the /Perms integrity check failed.
Follow naming convention consistent with is_encrypted, as suggested
in review.
@costajohnt costajohnt force-pushed the feat/expose-perms-validation branch from a12fec7 to 322665a Compare March 10, 2026 15:45
Make the Encryption attribute private (underscore prefix) to prevent
direct write access, and align the name with the public
are_permissions_valid property on PdfDocCommon.

Also rename test functions for consistency:
test_perms_valid_* → test_are_permissions_valid_*
Copy link
Collaborator

@stefan6419846 stefan6419846 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert all the unnecessary formatting changes.

Revert all line-collapsing formatting changes in _doc_common.py and
_encryption.py as requested by maintainer. Only the are_permissions_valid
feature additions remain.
@stefan6419846 stefan6419846 merged commit a3451e8 into py-pdf:main Mar 12, 2026
18 checks passed
stefan6419846 added a commit that referenced this pull request Mar 15, 2026
## What's new

### New Features (ENH)
- Expose /Perms verification result on Encryption object (#3672) by @costajohnt

### Performance Improvements (PI)
- Fix O(n²) performance in NameObject read/write (#3679) by @dmitry-kostin
- Batch-parse all objects in ObjStm on first access (#3677) by @dmitry-kostin

### Bug Fixes (BUG)
- Avoid sharing array-based content streams between pages (#3681) by @stefan6419846
- Avoid accessing invalid page when inserting blank page under some conditions (#3529) by @j-t-1

[Full Changelog](6.8.0...6.9.0)
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.

user_access_permissions may return tampered /P value when /Perms validation fails

2 participants