pyhanko.sign.signers.pdf_byterange module

This module contains the low-level building blocks for dealing with bookkeeping around /ByteRange digests in PDF files.

class pyhanko.sign.signers.pdf_byterange.PreparedByteRangeDigest(document_digest: bytes, reserved_region_start: int, reserved_region_end: int)

Bases: object

New in version 0.7.0.

Changed in version 0.14.0: Removed md_algorithm attribute since it was unused.

Bookkeeping class that contains the digest of a document that is about to be signed (or otherwise authenticated) based on said digest. It also keeps track of the region in the output stream that is omitted in the byte range.

Instances of this class can easily be serialised, which allows for interrupting the signing process partway through.

document_digest: bytes

Digest of the document, computed over the appropriate /ByteRange.

reserved_region_start: int

Start of the reserved region in the output stream that is not part of the /ByteRange.

reserved_region_end: int

End of the reserved region in the output stream that is not part of the /ByteRange.

fill_with_cms(output: IO, cms_data: Union[bytes, ContentInfo])

Write a DER-encoded CMS object to the reserved region indicated by reserved_region_start and reserved_region_end in the output stream.

Parameters
  • output – Output stream to use. Must be writable and seekable.

  • cms_data – CMS object to write. Can be provided as an asn1crypto.cms.ContentInfo object, or as raw DER-encoded bytes.

Returns

A bytes object containing the contents that were written, plus any additional padding.

fill_reserved_region(output: IO, content_bytes: bytes)

Write hex-encoded contents to the reserved region indicated by reserved_region_start and reserved_region_end in the output stream.

Parameters
  • output – Output stream to use. Must be writable and seekable.

  • content_bytes – Content bytes. These will be padded, hexadecimally encoded and written to the appropriate location in output stream.

Returns

A bytes object containing the contents that were written, plus any additional padding.

class pyhanko.sign.signers.pdf_byterange.PdfByteRangeDigest(data_key='/Contents', *, bytes_reserved=None)

Bases: DictionaryObject

General class to model a PDF Dictionary that has a /ByteRange entry and a another data entry (named /Contents by default) that will contain a value based on a digest computed over said /ByteRange. The /ByteRange will cover the entire file, except for the value of the data entry itself.

Danger

This is internal API.

Parameters
  • data_key – Name of the data key, which is /Contents by default.

  • bytes_reserved – Number of bytes to reserve for the contents placeholder. If None, a generous default is applied, but you should try to estimate the size as accurately as possible.

fill(writer: BasePdfFileWriter, md_algorithm, in_place=False, output=None, chunk_size=4096)

Generator coroutine that handles the document hash computation and the actual filling of the placeholder data.

Danger

This is internal API; you should use use PdfSigner wherever possible. If you really need fine-grained control, use PdfCMSEmbedder instead.

class pyhanko.sign.signers.pdf_byterange.PdfSignedData(obj_type, subfilter: SigSeedSubFilter = SigSeedSubFilter.ADOBE_PKCS7_DETACHED, timestamp: Optional[datetime] = None, bytes_reserved=None)

Bases: PdfByteRangeDigest

Generic class to model signature dictionaries in a PDF file. See also SignatureObject and DocumentTimestamp.

Parameters
  • obj_type – The type of signature object.

  • subfilter – See SigSeedSubFilter.

  • timestamp – The timestamp to embed into the /M entry.

  • bytes_reserved

    The number of bytes to reserve for the signature. Defaults to 16 KiB.

    Warning

    Since the CMS object is written to the output file as a hexadecimal string, you should request twice the (estimated) number of bytes in the DER-encoded version of the CMS object.

class pyhanko.sign.signers.pdf_byterange.SignatureObject(timestamp: Optional[datetime] = None, subfilter: SigSeedSubFilter = SigSeedSubFilter.ADOBE_PKCS7_DETACHED, name=None, location=None, reason=None, app_build_props: Optional[BuildProps] = None, bytes_reserved=None)

Bases: PdfSignedData

Class modelling a (placeholder for) a regular PDF signature.

Parameters
  • timestamp – The (optional) timestamp to embed into the /M entry.

  • subfilter – See SigSeedSubFilter.

  • bytes_reserved

    The number of bytes to reserve for the signature. Defaults to 16 KiB.

    Warning

    Since the CMS object is written to the output file as a hexadecimal string, you should request twice the (estimated) number of bytes in the DER-encoded version of the CMS object.

  • name – Signer name. You probably want to leave this blank, viewers should default to the signer’s subject name.

  • location – Optional signing location.

  • reason – Optional signing reason. May be restricted by seed values.

class pyhanko.sign.signers.pdf_byterange.DocumentTimestamp(bytes_reserved=None)

Bases: PdfSignedData

Class modelling a (placeholder for) a regular PDF signature.

Parameters

bytes_reserved

The number of bytes to reserve for the signature. Defaults to 16 KiB.

Warning

Since the CMS object is written to the output file as a hexadecimal string, you should request twice the (estimated) number of bytes in the DER-encoded version of the CMS object.

class pyhanko.sign.signers.pdf_byterange.BuildProps(name: str, revision: Optional[str] = None)

Bases: object

Entries in a signature build properties dictionary; see Adobe PDF Signature Build Dictionary Specification.

name: str

The application’s name.

revision: Optional[str] = None

The application’s revision ID string.

Note

This corresponds to the REx entry in the build properties dictionary.

as_pdf_object() DictionaryObject

Render the build properties as a PDF object.

Returns

A PDF dictionary.