pyhanko.sign.diff_analysis.policy_api module

class pyhanko.sign.diff_analysis.policy_api.ModificationLevel(value)

Bases: pyhanko.pdf_utils.misc.OrderedEnum

Records the (semantic) modification level of a document.

Compare MDPPerm, which records the document modification policy associated with a particular signature, as opposed to the empirical judgment indicated by this enum.

NONE = 0

The document was not modified at all (i.e. it is byte-for-byte unchanged).

LTA_UPDATES = 1

The only updates are of the type that would be allowed as part of signature long term archival (LTA) processing. That is to say, updates to the document security store or new document time stamps. For the purposes of evaluating whether a document has been modified in the sense defined in the PAdES and ISO 32000-2 standards, these updates do not count. Adding form fields is permissible at this level, but only if they are signature fields. This is necessary for proper document timestamp support.

FORM_FILLING = 2

The only updates are extra signatures and updates to form field values or their appearance streams, in addition to the previous levels.

ANNOTATIONS = 3

In addition to the previous levels, manipulating annotations is also allowed at this level.

Note

This level is currently unused by the default diff policy, and modifications to annotations other than those permitted to fill in forms are treated as suspicious.

OTHER = 4

The document has been modified in ways that aren’t on the validator’s whitelist. This always invalidates the corresponding signature, irrespective of cryptographical integrity or /DocMDP settings.

exception pyhanko.sign.diff_analysis.policy_api.SuspiciousModification

Bases: ValueError

Error indicating a suspicious modification

class pyhanko.sign.diff_analysis.policy_api.DiffResult(modification_level: pyhanko.sign.diff_analysis.policy_api.ModificationLevel, changed_form_fields: Set[str])

Bases: object

Encodes the result of a difference analysis on two revisions.

Returned by DiffPolicy.apply().

modification_level: pyhanko.sign.diff_analysis.policy_api.ModificationLevel

The strictest modification level at which all changes pass muster.

changed_form_fields: Set[str]

Set containing the names of all changed form fields.

Note

For the purposes of this parameter, a change is defined as any FormUpdate where FormUpdate.valid_when_locked is False.

class pyhanko.sign.diff_analysis.policy_api.DiffPolicy

Bases: object

Analyse the differences between two revisions.

apply(old: pyhanko.pdf_utils.reader.HistoricalResolver, new: pyhanko.pdf_utils.reader.HistoricalResolver, field_mdp_spec: Optional[pyhanko.sign.fields.FieldMDPSpec] = None, doc_mdp: Optional[pyhanko.sign.fields.MDPPerm] = None) pyhanko.sign.diff_analysis.policy_api.DiffResult

Execute the policy on a pair of revisions, with the MDP values provided. SuspiciousModification exceptions should be propagated.

Parameters
  • old – The older, base revision.

  • new – The newer revision.

  • field_mdp_spec – The field MDP spec that’s currently active.

  • doc_mdp – The DocMDP spec that’s currently active.

Returns

A DiffResult object summarising the policy’s judgment.

review_file(reader: pyhanko.pdf_utils.reader.PdfFileReader, base_revision: Union[int, pyhanko.pdf_utils.reader.HistoricalResolver], field_mdp_spec: Optional[pyhanko.sign.fields.FieldMDPSpec] = None, doc_mdp: Optional[pyhanko.sign.fields.MDPPerm] = None) Union[pyhanko.sign.diff_analysis.policy_api.DiffResult, pyhanko.sign.diff_analysis.policy_api.SuspiciousModification]

Compare the current state of a file to an earlier version, with the MDP values provided. SuspiciousModification exceptions should be propagated.

If there are multiple revisions between the base revision and the current one, the precise manner in which the review is conducted is left up to the implementing class. In particular, subclasses may choose to review each intermediate revision individually, or handle them all at once.

Parameters
  • reader – PDF reader representing the current state of the file.

  • base_revision – The older, base revision. You can choose between providing it as a revision index, or a HistoricalResolver instance.

  • field_mdp_spec – The field MDP spec that’s currently active.

  • doc_mdp – The DocMDP spec that’s currently active.

Returns

A DiffResult object summarising the policy’s judgment.