Module fpdf.sign
Module dedicated to document signature generation.
The contents of this module are internal to fpdf2, and not part of the public API. They may change at any time without prior warning or any deprecation period, in non-backward-compatible ways.
Functions
def sign_content(signer, buffer, key, cert, extra_certs, hashalgo, sign_time)
-
Expand source code Browse git
def sign_content(signer, buffer, key, cert, extra_certs, hashalgo, sign_time): """ Perform PDF signing based on the content of the buffer, performing substitutions on it. The signing operation does not alter the buffer size """ # We start by substituting the ByteRange, # that defines which part of the document content the signature is based on. # This is basically ALL the content EXCEPT the signature content itself. sig_placeholder = _SIGNATURE_CONTENTS_PLACEHOLDER.encode("latin1") start_index = buffer.find(sig_placeholder) end_index = start_index + len(sig_placeholder) content_range = (0, start_index - 1, end_index + 1, len(buffer) - end_index - 1) # pylint: disable=consider-using-f-string buffer = buffer_subst( buffer, _SIGNATURE_BYTERANGE_PLACEHOLDER, "[%010d %010d %010d %010d]" % content_range, ) # We compute the ByteRange hash, of everything before & after the placeholder: content_hash = hashlib.new(hashalgo) content_hash.update(buffer[: content_range[1]]) # before content_hash.update(buffer[content_range[2] :]) # after # This monkey-patching is needed, at the time of endesive v2.0.9, # to get control over signed_time, initialized by endesive.signer.sign() to be datetime.now(): class mock_datetime: @staticmethod def now(tz): # pylint: disable=unused-argument return sign_time.astimezone(timezone.utc) sign = patch("endesive.signer.datetime", mock_datetime)(signer.sign) contents = sign( datau=None, key=key, cert=cert, othercerts=extra_certs, hashalgo=hashalgo, attrs=True, signed_value=content_hash.digest(), ) contents = _pkcs11_aligned(contents).encode("latin1") # Sanity check, otherwise we will break the xref table: assert len(sig_placeholder) == len(contents) return buffer.replace(sig_placeholder, contents, 1)
Perform PDF signing based on the content of the buffer, performing substitutions on it. The signing operation does not alter the buffer size
Classes
class Signature (contact_info=None, location=None, m=None, reason=None)
-
Expand source code Browse git
class Signature: def __init__(self, contact_info=None, location=None, m=None, reason=None): self.type = Name("Sig") self.filter = Name("Adobe.PPKLite") self.sub_filter = Name("adbe.pkcs7.detached") self.contact_info = contact_info "Information provided by the signer to enable a recipient to contact the signer to verify the signature" self.location = location "The CPU host name or physical location of the signing" self.m = m "The time of signing" self.reason = reason "The reason for the signing" self.byte_range = _SIGNATURE_BYTERANGE_PLACEHOLDER self.contents = "<" + _SIGNATURE_CONTENTS_PLACEHOLDER + ">" def serialize(self, _security_handler=None, _obj_id=None): obj_dict = build_obj_dict( {key: getattr(self, key) for key in dir(self)}, _security_handler=_security_handler, _obj_id=_obj_id, ) return pdf_dict(obj_dict)
Instance variables
var contact_info
-
Information provided by the signer to enable a recipient to contact the signer to verify the signature
var location
-
The CPU host name or physical location of the signing
var m
-
The time of signing
var reason
-
The reason for the signing
Methods
def serialize(self)
-
Expand source code Browse git
def serialize(self, _security_handler=None, _obj_id=None): obj_dict = build_obj_dict( {key: getattr(self, key) for key in dir(self)}, _security_handler=_security_handler, _obj_id=_obj_id, ) return pdf_dict(obj_dict)