pyhanko.sign package
Subpackages
- pyhanko.sign.ades package
- pyhanko.sign.diff_analysis package
- Guidelines for developing rules for use with
StandardDiffPolicy
- Subpackages
- Submodules
- pyhanko.sign.diff_analysis.commons module
- pyhanko.sign.diff_analysis.constants module
- pyhanko.sign.diff_analysis.form_rules_api module
- pyhanko.sign.diff_analysis.policies module
- pyhanko.sign.diff_analysis.policy_api module
- pyhanko.sign.diff_analysis.rules_api module
- Guidelines for developing rules for use with
- pyhanko.sign.signers package
- pyhanko.sign.timestamps package
- pyhanko.sign.validation package
- Subpackages
- Submodules
- pyhanko.sign.validation.ades module
- pyhanko.sign.validation.dss module
- pyhanko.sign.validation.errors module
- pyhanko.sign.validation.generic_cms module
- pyhanko.sign.validation.ltv module
- pyhanko.sign.validation.pdf_embedded module
- pyhanko.sign.validation.policy_decl module
- pyhanko.sign.validation.settings module
- pyhanko.sign.validation.status module
- pyhanko.sign.validation.utils module
- Module contents
Submodules
pyhanko.sign.attributes module
- class pyhanko.sign.attributes.SignedAttributeProviderSpec
Bases:
ABC
Added in version 0.14.0.
Interface for setting up signed attributes, independently of the
Signer
hierarchy.- signed_attr_providers(data_digest: bytes, digest_algorithm: str) Iterable[CMSAttributeProvider]
Lazily set up signed attribute providers.
- Parameters:
data_digest – The digest of the data to be signed.
digest_algorithm – The digest algorithm used.
- class pyhanko.sign.attributes.UnsignedAttributeProviderSpec
Bases:
ABC
Added in version 0.14.0.
Interface for setting up unsigned attributes, independently of the
Signer
hierarchy.- unsigned_attr_providers(signature: bytes, signed_attrs: CMSAttributes, digest_algorithm: str) Iterable[CMSAttributeProvider]
Lazily set up unsigned attribute providers.
- Parameters:
signature – The signature computed over the signed attributes.
signed_attrs – Signed attributes over which the signature was taken.
digest_algorithm – The digest algorithm used.
- class pyhanko.sign.attributes.CMSAttributeProvider
Bases:
object
Base class to provide asynchronous CMS attribute values.
- attribute_type: str
Name of the CMS attribute type this provider supplies. See
cms.CMSAttributeType
.
- async build_attr_value(dry_run=False)
Build the attribute value asynchronously.
- Parameters:
dry_run –
True
if the signer is operating in dry-run (size estimation) mode.- Returns:
An attribute value appropriate for the attribute type.
- async get_attribute(dry_run=False) CMSAttribute | None
- class pyhanko.sign.attributes.SigningTimeProvider(timestamp: datetime)
Bases:
CMSAttributeProvider
Provide a value for the signing-time attribute (i.e. an otherwise unauthenticated timestamp).
- Parameters:
timestamp – Datetime object to include.
- attribute_type: str = 'signing_time'
Name of the CMS attribute type this provider supplies. See
cms.CMSAttributeType
.
- async build_attr_value(dry_run=False) Time
Build the attribute value asynchronously.
- Parameters:
dry_run –
True
if the signer is operating in dry-run (size estimation) mode.- Returns:
An attribute value appropriate for the attribute type.
- class pyhanko.sign.attributes.SigningCertificateV2Provider(signing_cert: Certificate)
Bases:
CMSAttributeProvider
Provide a value for the signing-certificate-v2 attribute.
- Parameters:
signing_cert – Certificate containing the signer’s public key.
- attribute_type: str = 'signing_certificate_v2'
Name of the CMS attribute type this provider supplies. See
cms.CMSAttributeType
.
- async build_attr_value(dry_run=False) SigningCertificateV2
Build the attribute value asynchronously.
- Parameters:
dry_run –
True
if the signer is operating in dry-run (size estimation) mode.- Returns:
An attribute value appropriate for the attribute type.
- class pyhanko.sign.attributes.AdobeRevinfoProvider(value: RevocationInfoArchival)
Bases:
CMSAttributeProvider
Yield Adobe-style revocation information for inclusion into a CMS object.
- Parameters:
value – A (pre-formatted) RevocationInfoArchival object.
- attribute_type: str = 'adobe_revocation_info_archival'
Name of the CMS attribute type this provider supplies. See
cms.CMSAttributeType
.
- async build_attr_value(dry_run=False) RevocationInfoArchival | None
Build the attribute value asynchronously.
- Parameters:
dry_run –
True
if the signer is operating in dry-run (size estimation) mode.- Returns:
An attribute value appropriate for the attribute type.
- class pyhanko.sign.attributes.CMSAlgorithmProtectionProvider(digest_algo: str, signature_algo: SignedDigestAlgorithm)
Bases:
CMSAttributeProvider
- attribute_type: str = 'cms_algorithm_protection'
Name of the CMS attribute type this provider supplies. See
cms.CMSAttributeType
.
- async build_attr_value(dry_run=False) CMSAlgorithmProtection
Build the attribute value asynchronously.
- Parameters:
dry_run –
True
if the signer is operating in dry-run (size estimation) mode.- Returns:
An attribute value appropriate for the attribute type.
- class pyhanko.sign.attributes.TSTProvider(digest_algorithm: str, data_to_ts: bytes, timestamper: TimeStamper, attr_type: str = 'signature_time_stamp_token', prehashed=False)
Bases:
CMSAttributeProvider
- async build_attr_value(dry_run=False) ContentInfo
Build the attribute value asynchronously.
- Parameters:
dry_run –
True
if the signer is operating in dry-run (size estimation) mode.- Returns:
An attribute value appropriate for the attribute type.
pyhanko.sign.fields module
Utilities to deal with signature form fields and their properties in PDF files.
- class pyhanko.sign.fields.SigFieldSpec(sig_field_name: str, on_page: int = 0, box: Tuple[int, int, int, int] | None = None, seed_value_dict: SigSeedValueSpec | None = None, field_mdp_spec: FieldMDPSpec | None = None, doc_mdp_update_value: MDPPerm | None = None, combine_annotation: bool = True, empty_field_appearance: bool = False, invis_sig_settings: InvisSigSettings = InvisSigSettings(set_print_flag=True, set_hidden_flag=False, box_out_of_bounds=False), readable_field_name: str | None = None, visible_sig_settings: VisibleSigSettings = VisibleSigSettings(rotate_with_page=True, scale_with_page_zoom=True, print_signature=True))
Bases:
object
Description of a signature field to be created.
- sig_field_name: str
Name of the signature field.
- on_page: int = 0
Index of the page on which the signature field should be included (starting at 0). A negative number counts pages from the back of the document, with index
-1
referring to the last page.Note
This is essentially only relevant for visible signature fields, i.e. those that have a widget associated with them.
- box: Tuple[int, int, int, int] | None = None
Bounding box of the signature field, if applicable.
Typically specified in
ll_x
,ll_y
,ur_x
,ur_y
format, wherell_*
refers to the lower left andur_*
to the upper right corner.
- seed_value_dict: SigSeedValueSpec | None = None
Specification for the seed value dictionary, if applicable.
- field_mdp_spec: FieldMDPSpec | None = None
Specification for the field lock dictionary, if applicable.
- doc_mdp_update_value: MDPPerm | None = None
Value to use for the document modification policy associated with the signature in this field.
This value will be embedded into the field lock dictionary if specified, and is meaningless if
field_mdp_spec
is not specified.Warning
DocMDP entries for approval signatures are a PDF 2.0 feature. Older PDF software will likely ignore this part of the field lock dictionary.
- combine_annotation: bool = True
Flag controlling whether the field should be combined with its annotation dictionary;
True
by default.
- empty_field_appearance: bool = False
Generate a neutral appearance stream for empty, visible signature fields. If
False
, an empty appearance stream will be put in.Note
We use an empty appearance stream to satisfy the appearance requirements for widget annotations in ISO 32000-2. However, even when a nontrivial appearance stream is present on an empty signature field, many viewers will not use it to render the appearance of the empty field on-screen.
Instead, these viewers typically substitute their own native widget.
- invis_sig_settings: InvisSigSettings = InvisSigSettings(set_print_flag=True, set_hidden_flag=False, box_out_of_bounds=False)
Advanced settings to control invisible signature field generation.
- readable_field_name: str | None = None
Human-readable field name (
/TU
entry).Note
This value is commonly rendered as a tooltip in viewers, but also serves an accessibility purpose.
- visible_sig_settings: VisibleSigSettings = VisibleSigSettings(rotate_with_page=True, scale_with_page_zoom=True, print_signature=True)
Advanced settings to control the generation of visible signature fields.
- format_lock_dictionary() DictionaryObject | None
- class pyhanko.sign.fields.SigSeedValFlags(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Flag
Flags for the
/Ff
entry in the seed value dictionary for a signature field. These mark which of the constraints are to be strictly enforced, as opposed to optional ones.Warning
The flags
LEGAL_ATTESTATION
andAPPEARANCE_FILTER
are processed in accordance with the specification when creating a signature, but support is nevertheless limited.PyHanko does not support legal attestations at all, so given that the
LEGAL_ATTESTATION
requirement flag only restricts the legal attestations that can be used by the signer, pyHanko can safely ignore it when signing.On the other hand, since the validator is not aware of legal attestations either, it cannot validate signatures that make
legal_attestations
a mandatory constraint.Since pyHanko does not define any named appearances, setting the
APPEARANCE_FILTER
flag and theappearance
entry in the seed value dictionary will make pyHanko refuse to sign the document.When validating, the situation is different: since pyHanko has no way of knowing whether the signer used the named appearance imposed by the seed value dictionary, it will simply emit a warning and continue validating the signature.
- FILTER = 1
Makes the signature handler setting mandatory. PyHanko only supports
/Adobe.PPKLite
.
- SUBFILTER = 2
See
subfilters
.
- V = 4
See
sv_dict_version
.
- LEGAL_ATTESTATION = 16
See
legal_attestations
.
- ADD_REV_INFO = 32
See
add_rev_info
.
- DIGEST_METHOD = 64
See
digest_method
.
- LOCK_DOCUMENT = 128
See
lock_document
.
- APPEARANCE_FILTER = 256
See
appearance
.
- class pyhanko.sign.fields.SigCertConstraints(flags: ~pyhanko.sign.fields.SigCertConstraintFlags = <SigCertConstraintFlags: 0>, subjects: ~typing.List[~asn1crypto.x509.Certificate] | None = None, subject_dn: ~asn1crypto.x509.Name | None = None, issuers: ~typing.List[~asn1crypto.x509.Certificate] | None = None, info_url: str | None = None, url_type: ~pyhanko.pdf_utils.generic.NameObject = '/Browser', key_usage: ~typing.List[~pyhanko.sign.fields.SigCertKeyUsage] | None = None)
Bases:
object
This part of the seed value dictionary allows the document author to set constraints on the signer’s certificate.
See Table 235 in ISO 32000-1.
- flags: SigCertConstraintFlags = 0
Enforcement flags. By default, all entries are optional.
- subjects: List[Certificate] | None = None
Explicit list of certificates that can be used to sign a signature field.
- subject_dn: Name | None = None
Certificate subject names that can be used to sign a signature field. Subject DN entries that are not mentioned are unconstrained.
- issuers: List[Certificate] | None = None
List of issuer certificates that the signer certificate can be issued by. Note that these issuers do not need to be the direct issuer of the signer’s certificate; any descendant relationship will do.
- info_url: str | None = None
Informational URL that should be opened when an appropriate certificate cannot be found (if
url_type
is/Browser
, that is).Note
PyHanko ignores this value, but we include it for compatibility.
- url_type: NameObject = '/Browser'
Handler that should be used to open
info_url
./Browser
is the only implementation-independent value.
- key_usage: List[SigCertKeyUsage] | None = None
Specify the key usage extensions that should (or should not) be present on the signer’s certificate.
- classmethod from_pdf_object(pdf_dict)
Read a PDF dictionary into a
SigCertConstraints
object.- Parameters:
pdf_dict – A
DictionaryObject
.- Returns:
A
SigCertConstraints
object.
- as_pdf_object()
Render this
SigCertConstraints
object to a PDF dictionary.- Returns:
- satisfied_by(signer: Certificate, validation_path: ValidationPath | None)
Evaluate whether a signing certificate satisfies the required constraints of this
SigCertConstraints
object.- Parameters:
signer – The candidate signer’s certificate.
validation_path – Validation path of the signer’s certificate.
- Raises:
UnacceptableSignerError – Raised if the conditions are not met.
- class pyhanko.sign.fields.SigSeedValueSpec(flags: ~pyhanko.sign.fields.SigSeedValFlags = <SigSeedValFlags: 0>, reasons: ~typing.List[str] | None = None, timestamp_server_url: str | None = None, timestamp_required: bool = False, cert: ~pyhanko.sign.fields.SigCertConstraints | None = None, subfilters: ~typing.List[~pyhanko.sign.fields.SigSeedSubFilter] | None = None, digest_methods: ~typing.List[str] | None = None, add_rev_info: bool | None = None, seed_signature_type: ~pyhanko.sign.fields.SeedSignatureType | None = None, sv_dict_version: ~pyhanko.sign.fields.SeedValueDictVersion | int | None = None, legal_attestations: ~typing.List[str] | None = None, lock_document: ~pyhanko.sign.fields.SeedLockDocument | None = None, appearance: str | None = None)
Bases:
object
Python representation of a PDF seed value dictionary.
- flags: SigSeedValFlags = 0
Enforcement flags. By default, all entries are optional.
- reasons: List[str] | None = None
Acceptable reasons for signing.
- timestamp_server_url: str | None = None
RFC 3161 timestamp server endpoint suggestion.
- timestamp_required: bool = False
Flags whether a timestamp is required. This flag is only meaningful if
timestamp_server_url
is specified.
- cert: SigCertConstraints | None = None
Constraints on the signer’s certificate.
- subfilters: List[SigSeedSubFilter] | None = None
Acceptable
/SubFilter
values.
- digest_methods: List[str] | None = None
Acceptable digest methods.
- add_rev_info: bool | None = None
Indicates whether revocation information should be embedded.
Warning
This flag exclusively refers to the Adobe-style revocation information embedded within the CMS object that is written to the signature field. PAdES-style revocation information that is saved to the document security store (DSS) does not satisfy the requirement. Additionally, the standard mandates that
/SubFilter
be equal to/adbe.pkcs7.detached
if this flag isTrue
.
- seed_signature_type: SeedSignatureType | None = None
Specifies the type of signature that should occupy a signature field; this represents the
/MDP
entry in the seed value dictionary. SeeSeedSignatureType
for details.Caution
Since a certification-type signature is by definition the first signature applied to a document, compliance with this requirement cannot be cryptographically enforced.
- sv_dict_version: SeedValueDictVersion | int | None = None
Specifies the compliance level required of a seed value dictionary processor. If
None
, pyHanko will compute an appropriate value.Note
You may also specify this value directly as an integer. This covers potential future versions of the standard that pyHanko does not support out of the box.
- legal_attestations: List[str] | None = None
Specifies the possible legal attestations that a certification signature occupying this signature field can supply. The corresponding flag in
flags
indicates whether this is a mandatory constraint.Caution
Since
legal_attestations
is only relevant for certification signatures, compliance with this requirement cannot be reliably enforced. Regardless, since pyHanko’s validator is also unaware of legal attestation settings, it will refuse to validate signatures where this seed value constitutes a mandatory constraint.Additionally, since pyHanko does not support legal attestation specifications at all, it vacuously satisfies the requirements of this entry no matter what, and will therefore ignore it when signing.
- lock_document: SeedLockDocument | None = None
Tell the signer whether or not the document should be locked after signing this field; see
SeedLockDocument
for details.The corresponding flag in
flags
indicates whether this constraint is mandatory.
- appearance: str | None = None
Specify a named appearance to use when generating the signature. The corresponding flag in
flags
indicates whether this constraint is mandatory.Caution
There is no standard registry of named appearances, so these constraints are not portable, and cannot be validated.
PyHanko currently does not define any named appearances.
- as_pdf_object()
Render this
SigSeedValueSpec
object to a PDF dictionary.- Returns:
- classmethod from_pdf_object(pdf_dict)
Read from a seed value dictionary.
- Parameters:
pdf_dict – A
DictionaryObject
.- Returns:
A
SigSeedValueSpec
object.
- build_timestamper()
Return a timestamper object based on the
timestamp_server_url
attribute of thisSigSeedValueSpec
object.- Returns:
A
HTTPTimeStamper
.
- class pyhanko.sign.fields.SigCertConstraintFlags(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Flag
Flags for the
/Ff
entry in the certificate seed value dictionary for a dictionary field. These mark which of the constraints are to be strictly enforced, as opposed to optional ones.Warning
While this enum records values for all flags, not all corresponding constraint types have been implemented yet.
- SUBJECT = 1
- ISSUER = 2
- OID = 4
Currently not supported.
- SUBJECT_DN = 8
- RESERVED = 16
Currently not supported (reserved).
- KEY_USAGE = 32
- URL = 64
See
SigCertConstraints.info_url
.Note
As specified in the standard, this enforcement bit is supposed to be ignored by default. We include it for compatibility reasons.
- UNSUPPORTED = 20
Flags for which the corresponding constraint is unsupported.
- class pyhanko.sign.fields.SigSeedSubFilter(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
Enum declaring all supported
/SubFilter
values.- ADOBE_PKCS7_DETACHED = '/adbe.pkcs7.detached'
- PADES = '/ETSI.CAdES.detached'
- ETSI_RFC3161 = '/ETSI.RFC3161'
- class pyhanko.sign.fields.SeedValueDictVersion(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
OrderedEnum
Specify the minimal compliance level for a seed value dictionary processor.
- PDF_1_5 = 1
Require the reader to understand all keys defined in PDF 1.5.
- PDF_1_7 = 2
Require the reader to understand all keys defined in PDF 1.7.
- PDF_2_0 = 3
Require the reader to understand all keys defined in PDF 2.0.
- class pyhanko.sign.fields.SeedLockDocument(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
Provides a recommendation to the signer as to whether the document should be locked after signing. The corresponding flag in
SigSeedValueSpec.flags
determines whether this constraint is a required constraint.- LOCK = '/true'
Lock the document after signing.
- DO_NOT_LOCK = '/false'
Lock the document after signing.
- SIGNER_DISCRETION = '/auto'
Leave the decision up to the signer.
Note
This is functionally equivalent to not specifying any value.
- class pyhanko.sign.fields.SigCertKeyUsage(must_have: KeyUsage | None = None, forbidden: KeyUsage | None = None)
Bases:
object
Encodes the key usage bits that must (resp. must not) be active on the signer’s certificate.
Note
See § 4.2.1.3 in RFC 5280 and
KeyUsage
for more information on key usage extensions.Note
The human-readable names of the key usage extensions are recorded in
camelCase
in RFC 5280, but this class uses the naming convention ofKeyUsage
inasn1crypto
. The conversion is done by replacingcamelCase
withsnake_case
. For example,nonRepudiation
becomesnon_repudiation
, anddigitalSignature
turns intodigital_signature
.Note
This class is intended to closely replicate the definition of the KeyUsage entry Table 235 in ISO 32000-1. In particular, it does not provide a mechanism to deal with extended key usage extensions (cf. § 4.2.1.12 in RFC 5280).
- Parameters:
must_have – The
KeyUsage
object encoding the key usage extensions that must be present on the signer’s certificate.forbidden – The
KeyUsage
object encoding the key usage extensions that must not be present on the signer’s certificate.
- encode_to_sv_string()
Encode the key usage requirements in the format specified in the PDF specification.
- Returns:
A string.
- classmethod read_from_sv_string(ku_str)
Parse a PDF KeyUsage string into an instance of
SigCertKeyUsage
. See Table 235 in ISO 32000-1.- Parameters:
ku_str – A PDF KeyUsage string.
- Returns:
An instance of
SigCertKeyUsage
.
- classmethod from_sets(must_have: Set[str] | None = None, forbidden: Set[str] | None = None)
Initialise a
SigCertKeyUsage
object from two sets.- Parameters:
must_have – The key usage extensions that must be present on the signer’s certificate.
forbidden – The key usage extensions that must not be present on the signer’s certificate.
- Returns:
A
SigCertKeyUsage
object encoding these.
- must_have_set() Set[str]
Return the set of key usage extensions that must be present on the signer’s certificate.
- forbidden_set() Set[str]
Return the set of key usage extensions that must not be present on the signer’s certificate.
- class pyhanko.sign.fields.MDPPerm(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
OrderedEnum
Indicates a
/DocMDP
level.Cf. Table 254 in ISO 32000-1.
- NO_CHANGES = 1
No changes to the document are allowed.
Warning
This does not apply to DSS updates and the addition of document time stamps.
- FILL_FORMS = 2
Form filling & signing is allowed.
- ANNOTATE = 3
Form filling, signing and commenting are allowed.
Warning
Validating this
/DocMDP
level is not currently supported, but included in the list for completeness.
- class pyhanko.sign.fields.FieldMDPAction(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
Marker for the scope of a
/FieldMDP
policy.- ALL = '/All'
The policy locks all form fields.
- INCLUDE = '/Include'
The policy locks all fields in the list (see
FieldMDPSpec.fields
).
- EXCLUDE = '/Exclude'
The policy locks all fields except those specified in the list (see
FieldMDPSpec.fields
).
- class pyhanko.sign.fields.FieldMDPSpec(action: FieldMDPAction, fields: List[str] | None = None)
Bases:
object
/FieldMDP
policy description.This class models both field lock dictionaries and
/FieldMDP
transformation parameters.- action: FieldMDPAction
Indicates the scope of the policy.
- fields: List[str] | None = None
Indicates the fields subject to the policy, unless
action
isFieldMDPAction.ALL
.
- as_pdf_object() DictionaryObject
Render this
/FieldMDP
policy description as a PDF dictionary.- Returns:
- as_transform_params() DictionaryObject
Render this
/FieldMDP
policy description as a PDF dictionary, ready for inclusion into the/TransformParams
entry of a/FieldMDP
dictionary associated with a signature object.- Returns:
- as_sig_field_lock() DictionaryObject
Render this
/FieldMDP
policy description as a PDF dictionary, ready for inclusion into the/Lock
dictionary of a signature field.- Returns:
- classmethod from_pdf_object(pdf_dict) FieldMDPSpec
Read a PDF dictionary into a
FieldMDPSpec
object.- Parameters:
pdf_dict – A
DictionaryObject
.- Returns:
A
FieldMDPSpec
object.
- is_locked(field_name: str) bool
Adjudicate whether a field should be locked by the policy described by this
FieldMDPSpec
object.- Parameters:
field_name – The name of a form field.
- Returns:
True
if the field should be locked,False
otherwise.
- class pyhanko.sign.fields.SignatureFormField(field_name, *, box=None, include_on_page=None, combine_annotation=True, invis_settings: InvisSigSettings = InvisSigSettings(set_print_flag=True, set_hidden_flag=False, box_out_of_bounds=False), visible_settings: VisibleSigSettings = VisibleSigSettings(rotate_with_page=True, scale_with_page_zoom=True, print_signature=True), annot_flags=None)
Bases:
DictionaryObject
- register_widget_annotation(writer: BasePdfFileWriter, sig_field_ref)
- class pyhanko.sign.fields.InvisSigSettings(set_print_flag: bool = True, set_hidden_flag: bool = False, box_out_of_bounds: bool = False)
Bases:
object
Invisible signature widget generation settings.
These settings exist because there is no real way of including an untagged invisible signature in a document that complies with the requirements of both PDF/A-2 (or -3) and PDF/UA-1.
Compatibility with PDF/A (the default) requires the print flag to be set. Compatibility with PDF/UA requires the hidden flag to be set (which is banned in PDF/A) or the box to be outside the crop box.
- set_print_flag: bool = True
Set the print flag. Required in PDF/A.
Set the hidden flag. Required in PDF/UA.
- box_out_of_bounds: bool = False
Put the box out of bounds (technically, this just makes the box zero-sized with large negative coordinates).
This is a hack to get around the fact that PDF/UA requires the hidden flag to be set on all in-bounds untagged annotations, and some validators consider [0, 0, 0, 0] to be an in-bounds rectangle if (0, 0) is a point that falls within the crop box.
- class pyhanko.sign.fields.VisibleSigSettings(rotate_with_page: bool = True, scale_with_page_zoom: bool = True, print_signature: bool = True)
Bases:
object
Added in version 0.14.0.
Additional flags used when setting up visible signature widgets.
- rotate_with_page: bool = True
Allow the signature widget to rotate with the page if rotation is applied (e.g. by way of the page’s
/Rotate
entry). Default isTrue
.Note
If
False
, this will cause theNoRotate
flag to be set.
- scale_with_page_zoom: bool = True
Allow the signature widget to scale with the page’s zoom level. Default is
True
.Note
If
False
, this will cause theNoZoom
flag to be set.
- print_signature: bool = True
Render the signature when the document is printed. Default
True
.
- pyhanko.sign.fields.enumerate_sig_fields(handler: PdfHandler, filled_status: bool | None = None, with_name: str | None = None)
Enumerate signature fields.
- Parameters:
handler – The
PdfHandler
to operate on.filled_status – Optional boolean. If
True
(resp.False
) then all filled (resp. empty) fields are returned. If leftNone
(the default), then all fields are returned.with_name – If not
None
, only look for fields with the specified name.
- Returns:
A generator producing signature fields.
- pyhanko.sign.fields.append_signature_field(pdf_out: BasePdfFileWriter, sig_field_spec: SigFieldSpec)
Append signature fields to a PDF file.
- Parameters:
pdf_out – Incremental writer to house the objects.
sig_field_spec – A
SigFieldSpec
object describing the signature field to add.
- pyhanko.sign.fields.ensure_sig_flags(writer: BasePdfFileWriter, lock_sig_flags: bool = True)
Ensure the SigFlags setting is present in the AcroForm dictionary.
- Parameters:
writer – A PDF writer.
lock_sig_flags – Whether to flag the document as append-only.
- pyhanko.sign.fields.prepare_sig_field(sig_field_name, root, update_writer: BasePdfFileWriter, existing_fields_only=False, **kwargs)
Returns a tuple of a boolean and a reference to a signature field. The boolean is
True
if the field was created, andFalse
otherwise.Danger
This function is internal API.
- pyhanko.sign.fields.apply_sig_field_spec_properties(pdf_out: BasePdfFileWriter, sig_field: DictionaryObject, sig_field_spec: SigFieldSpec)
Internal function to apply field spec properties to a newly created field.
- pyhanko.sign.fields.annot_width_height(annot_dict: DictionaryObject) Tuple[float, float]
Internal function to compute the width and height of an annotation.
- Parameters:
annot_dict – Annotation dictionary.
- Returns:
a (width, height) tuple
- pyhanko.sign.fields.get_sig_field_annot(sig_field: DictionaryObject) DictionaryObject
Internal function to get the annotation of a signature field.
- Parameters:
sig_field – A signature field dictionary.
- Returns:
The dictionary of the corresponding annotation.
pyhanko.sign.general module
General tools related to Cryptographic Message Syntax (CMS) signatures, not necessarily to the extent implemented in the PDF specification.
CMS is defined in RFC 5652. To parse CMS messages, pyHanko relies heavily on asn1crypto.
- pyhanko.sign.general.simple_cms_attribute(attr_type, value)
Convenience method to quickly construct a CMS attribute object with one value.
- Parameters:
attr_type – The attribute type, as a string or OID.
value – The value.
- Returns:
A
cms.CMSAttribute
object.
- pyhanko.sign.general.find_cms_attribute(attrs, name)
Find and return CMS attribute values of a given type.
Note
This function will also check for duplicates, but not in the sense of multivalued attributes. In other words: multivalued attributes are allowed; listing the same attribute OID more than once is not.
- Parameters:
attrs – The
cms.CMSAttributes
object.name – The attribute type as a string (as defined in
asn1crypto
).
- Returns:
The values associated with the requested type, if present.
- Raises:
NonexistentAttributeError – Raised when no such type entry could be found in the
cms.CMSAttributes
object.CMSStructuralError – Raised if the given OID occurs more than once.
- pyhanko.sign.general.find_unique_cms_attribute(attrs, name)
Find and return a unique CMS attribute value of a given type.
- Parameters:
attrs – The
cms.CMSAttributes
object.name – The attribute type as a string (as defined in
asn1crypto
).
- Returns:
The value associated with the requested type, if present.
- Raises:
NonexistentAttributeError – Raised when no such type entry could be found in the
cms.CMSAttributes
object.MultivaluedAttributeError – Raised when the attribute’s cardinality is not 1.
- exception pyhanko.sign.general.NonexistentAttributeError
Bases:
KeyError
- exception pyhanko.sign.general.MultivaluedAttributeError
Bases:
ValueError
- exception pyhanko.sign.general.SigningError(msg: str, *args)
Bases:
ValueError
Error encountered while signing a file.
- exception pyhanko.sign.general.UnacceptableSignerError(msg: str, *args)
Bases:
SigningError
Error raised when a signer was judged unacceptable.
- class pyhanko.sign.general.SignedDataCerts(signer_cert: Certificate, other_certs: List[Certificate], attribute_certs: List[AttributeCertificateV2])
Bases:
object
Value type to describe certificates included in a CMS signed data payload.
- signer_cert: Certificate
The certificate identified as the signer’s certificate.
- other_certs: List[Certificate]
Other (public-key) certificates included in the signed data object.
- attribute_certs: List[AttributeCertificateV2]
Attribute certificates included in the signed data object.
- pyhanko.sign.general.extract_signer_info(signed_data: SignedData) SignerInfo
Extract the unique
SignerInfo
entry of a CMS signed data value, or throw aValueError
.- Parameters:
signed_data – A CMS
SignedData
value.- Returns:
A CMS
SignerInfo
value.- Raises:
ValueError – If the number of
SignerInfo
values is not exactly one.
- pyhanko.sign.general.extract_certificate_info(signed_data: SignedData) SignedDataCerts
Extract and classify embedded certificates found in the
certificates
field of the signed data value.- Parameters:
signed_data – A CMS
SignedData
value.- Returns:
A
SignedDataCerts
object containing the embedded certificates.
- pyhanko.sign.general.get_cms_hash_algo_for_mechanism(mech: SignedDigestAlgorithm) str
Internal function that takes a
SignedDigestAlgorithm
instance and returns the name of the digest algorithm that has to be used to compute themessageDigest
attribute.- Parameters:
mech – A signature mechanism.
- Returns:
A digest algorithm name.
- pyhanko.sign.general.get_pyca_cryptography_hash(algorithm) HashAlgorithm
- pyhanko.sign.general.get_pyca_cryptography_hash_for_signing(algorithm, prehashed=False) HashAlgorithm | Prehashed
- pyhanko.sign.general.optimal_pss_params(cert: Certificate, digest_algorithm: str) RSASSAPSSParams
Figure out the optimal RSASSA-PSS parameters for a given certificate. The subject’s public key must be an RSA key.
- Parameters:
cert – An RSA X.509 certificate.
digest_algorithm – The digest algorithm to use.
- Returns:
RSASSA-PSS parameters.
- pyhanko.sign.general.process_pss_params(params: RSASSAPSSParams, digest_algorithm, prehashed=False)
Extract PSS padding settings and message digest from an
RSASSAPSSParams
value.Internal API.
- pyhanko.sign.general.as_signing_certificate(cert: Certificate) SigningCertificate
Format an ASN.1
SigningCertificate
object, where the certificate is identified by its SHA-1 digest.- Parameters:
cert – An X.509 certificate.
- Returns:
A
tsp.SigningCertificate
object referring to the original certificate.
- pyhanko.sign.general.as_signing_certificate_v2(cert: Certificate, hash_algo='sha256') SigningCertificateV2
Format an ASN.1
SigningCertificateV2
value, where the certificate is identified by the hash algorithm specified.- Parameters:
cert – An X.509 certificate.
hash_algo – Hash algorithm to use to digest the certificate. Default is SHA-256.
- Returns:
A
tsp.SigningCertificateV2
object referring to the original certificate.
- pyhanko.sign.general.match_issuer_serial(expected_issuer_serial: IssuerAndSerialNumber | IssuerSerial, cert: Certificate) bool
Match the issuer and serial number of an X.509 certificate against some expected identifier.
- Parameters:
expected_issuer_serial – A certificate identifier, either
cms.IssuerAndSerialNumber
ortsp.IssuerSerial
.cert – An
x509.Certificate
.
- Returns:
True
if there’s a match,False
otherwise.
- pyhanko.sign.general.check_ess_certid(cert: Certificate, certid: ESSCertID | ESSCertIDv2)
Match an
ESSCertID
value against a certificate.- Parameters:
cert – The certificate to match against.
certid – The
ESSCertID
value.
- Returns:
True
if theESSCertID
matches the certificate,False
otherwise.
- exception pyhanko.sign.general.CMSExtractionError(failure_message)
Bases:
ValueErrorWithMessage
- pyhanko.sign.general.byte_range_digest(stream: IO, byte_range: Iterable[int], md_algorithm: str, chunk_size=4096) Tuple[int, bytes]
Internal API to compute byte range digests. Potentially dangerous if used without due caution.
- Parameters:
stream – Stream over which to compute the digest. Must support seeking and reading.
byte_range – The byte range, as a list of (offset, length) pairs, flattened.
md_algorithm – The message digest algorithm to use.
chunk_size – The I/O chunk size to use.
- Returns:
A tuple of the total digested length, and the actual digest.
- exception pyhanko.sign.general.ValueErrorWithMessage(failure_message)
Bases:
ValueError
Value error with a failure message attribute that can be conveniently extracted, instead of having to rely on extracting exception args generically.
- exception pyhanko.sign.general.CMSStructuralError(failure_message)
Bases:
ValueErrorWithMessage
Structural error in a CMS object.
- pyhanko.sign.general.load_cert_from_pemder(cert_file)
A convenience function to load a single PEM/DER-encoded certificate from a file.
- Parameters:
cert_file – A file name.
- Returns:
An
asn1crypto.x509.Certificate
object.
- pyhanko.sign.general.load_certs_from_pemder(cert_files)
A convenience function to load PEM/DER-encoded certificates from files.
- Parameters:
cert_files – An iterable of file names.
- Returns:
A generator producing
asn1crypto.x509.Certificate
objects.
- pyhanko.sign.general.load_certs_from_pemder_data(cert_data_bytes: bytes)
A convenience function to load PEM/DER-encoded certificates from binary data.
- Parameters:
cert_data_bytes –
bytes
object from which to extract certificates.- Returns:
A generator producing
asn1crypto.x509.Certificate
objects.
- pyhanko.sign.general.load_private_key_from_pemder(key_file, passphrase: bytes | None) PrivateKeyInfo
A convenience function to load PEM/DER-encoded keys from files.
- Parameters:
key_file – File to read the key from.
passphrase – Key passphrase.
- Returns:
A private key encoded as an unencrypted PKCS#8 PrivateKeyInfo object.
- pyhanko.sign.general.load_private_key_from_pemder_data(key_bytes: bytes, passphrase: bytes | None) PrivateKeyInfo
A convenience function to load PEM/DER-encoded keys from binary data.
- Parameters:
key_bytes –
bytes
object to read the key from.passphrase – Key passphrase.
- Returns:
A private key encoded as an unencrypted PKCS#8 PrivateKeyInfo object.
pyhanko.sign.pkcs11 module
This module provides PKCS#11 integration for pyHanko, by providing a wrapper
for python-pkcs11 that can be
seamlessly plugged into a PdfSigner
.
- class pyhanko.sign.pkcs11.PKCS11Signer(pkcs11_session: Session, cert_label: str | None = None, signing_cert: Certificate | None = None, ca_chain=None, key_label: str | None = None, prefer_pss=False, embed_roots=True, other_certs_to_pull=(), bulk_fetch=True, key_id: bytes | None = None, cert_id: bytes | None = None, use_raw_mechanism=False)
Bases:
Signer
Signer implementation for PKCS11 devices.
- Parameters:
pkcs11_session – The PKCS11 session object to use.
cert_label – The label of the certificate that will be used for signing, to be pulled from the PKCS#11 token.
cert_id – ID of the certificate object that will be used for signing, to be pulled from the PKCS#11 token.
signing_cert – The signer’s certificate. If the signer’s certificate is provided via this parameter, the
cert_label
andcert_id
parameters will not be used to retrieve the signer’s certificate.ca_chain – Set of other relevant certificates (as
asn1crypto.x509.Certificate
objects).key_label –
The label of the key that will be used for signing. Defaults to the value of
cert_label
if left unspecified andkey_id
is also unspecified.Note
At least one of
key_id
,key_label
andcert_label
must be supplied.key_id – ID of the private key object (optional).
other_certs_to_pull – List labels of other certificates to pull from the PKCS#11 device. Defaults to the empty tuple. If
None
, pull all certificates.bulk_fetch – Boolean indicating the fetching strategy. If
True
, fetch all certs and filter the unneeded ones. IfFalse
, fetch the requested certs one by one. Default value isTrue
, unlessother_certs_to_pull
has one or fewer elements, in which case it is always treated asFalse
.use_raw_mechanism –
Use the ‘raw’ equivalent of the selected signature mechanism. This is useful when working with tokens that do not support a hash-then-sign mode of operation.
Note
This functionality is only available for ECDSA at this time. Support for other signature schemes will be added on an as-needed basis.
- property cert_registry: CertificateStore
Changed in version 0.18.0: Turned into a property instead of a class attribute.
Collection of certificates associated with this signer. Note that this is simply a bookkeeping tool; in particular it doesn’t care about trust.
- property signing_cert
Changed in version 0.14.0: Made optional (see note)
Changed in version 0.18.0: Turned into a property instead of a class attribute.
The certificate that will be used to create the signature.
Note
This is an optional field only to a limited extent. Subclasses may require it to be present, and not setting it at the beginning of the signing process implies that certain high-level convenience features will no longer work or be limited in function (e.g., automatic hash selection, appearance generation, revocation information collection, …).
However, making
signing_cert
optional enables certain signing workflows where the certificate of the signer is not known until the signature has actually been produced. This is most relevant in certain types of remote signing scenarios.
- async async_sign_raw(data: bytes, digest_algorithm: str, dry_run=False) bytes
Compute the raw cryptographic signature of the data provided, hashed using the digest algorithm provided.
- Parameters:
data – Data to sign.
digest_algorithm –
Digest algorithm to use.
Warning
If
signature_mechanism
also specifies a digest, they should match.dry_run – Do not actually create a signature, but merely output placeholder bytes that would suffice to contain an actual signature.
- Returns:
Signature bytes.
- async ensure_objects_loaded()
Async method that, when awaited, ensures that objects (relevant certificates, key handles, …) are loaded.
This coroutine is guaranteed to be called & awaited in
sign_raw()
, but some property implementations may cause object loading to be triggered synchronously (for backwards compatibility reasons). This blocks the event loop the first time it happens.To avoid this behaviour, asynchronous code should ideally perform await signer.ensure_objects_loaded() after instantiating the signer.
Note
The asynchronous context manager on
PKCS11SigningContext
takes care of that automatically.
- pyhanko.sign.pkcs11.open_pkcs11_session(lib_location: str, slot_no: int | None = None, token_label: str | None = None, token_criteria: TokenCriteria | None = None, user_pin: str | object | None = None) Session
Open a PKCS#11 session
- Parameters:
lib_location – Path to the PKCS#11 module.
slot_no – Slot number to use. If not specified, the first slot containing a token labelled
token_label
will be used.token_label –
Deprecated since version 0.14.0: Use
token_criteria
instead.Label of the token to use. If
None
, there is no constraint.token_criteria – Criteria that the token should match.
user_pin –
User PIN to use, or
PROTECTED_AUTH
. IfNone
, authentication is skipped.Note
Some PKCS#11 implementations do not require PIN when the token is opened, but will prompt for it out-of-band when signing. Whether
PROTECTED_AUTH
orNone
is used in this case depends on the implementation.
- Returns:
An open PKCS#11 session object.
- class pyhanko.sign.pkcs11.PKCS11SigningContext(config: PKCS11SignatureConfig, user_pin: str | None = None)
Bases:
object
Context manager for PKCS#11 configurations.
- pyhanko.sign.pkcs11.find_token(slots: List[Slot], slot_no: int | None = None, token_criteria: TokenCriteria | None = None) Token | None
Internal helper method to find a token.
- Parameters:
slots – The list of slots.
slot_no – Slot number to use. If not specified, the first slot containing a token satisfying the criteria will be used
token_criteria – Criteria the token must satisfy.
- Returns:
A PKCS#11 token object, or
None
if none was found.
- pyhanko.sign.pkcs11.select_pkcs11_signing_params(signature_mechanism: SignedDigestAlgorithm, digest_algorithm: str, use_raw_mechanism: bool) PKCS11SignatureOperationSpec
Internal helper function to set up a PKCS #11 signing operation.
- Parameters:
signature_mechanism – The signature mechanism to use (as an ASN.1 value)
digest_algorithm – The digest algorithm to use
use_raw_mechanism – Whether to attempt to use the raw mechanism on pre-hashed data.
- Returns: