pyhanko.sign.signers module¶
-
class
pyhanko.sign.signers.
PdfSignatureMetadata
(field_name: Optional[str] = None, md_algorithm: Optional[str] = None, location: Optional[str] = None, reason: Optional[str] = None, name: Optional[str] = None, certify: bool = False, subfilter: Optional[pyhanko.sign.fields.SigSeedSubFilter] = None, embed_validation_info: bool = False, use_pades_lta: bool = False, timestamp_field_name: Optional[str] = None, validation_context: Optional[certvalidator.context.ValidationContext] = None, docmdp_permissions: pyhanko.sign.fields.MDPPerm = <MDPPerm.FILL_FORMS: 2>)¶ Bases:
object
Specification for a PDF signature.
-
field_name
: str = None¶ The name of the form field to contain the signature. If there is only one available signature field, the name may be inferred.
-
md_algorithm
: str = None¶ The name of the digest algorithm to use. It should be supported by
hashlib
.If
None
, this will ordinarily default to the value ofDEFAULT_MD
, unless a seed value dictionary and/or a prior certification signature happen to be available.
-
location
: str = None¶ Location of signing.
-
reason
: str = None¶ Reason for signing (textual).
-
name
: str = None¶ Name of the signer. This value is usually not necessary to set, since it should appear on the signer’s certificate, but there are cases where it might be useful to specify it here (e.g. in situations where signing is delegated to a trusted third party).
-
certify
: bool = False¶ Sign with an author (certification) signature, as opposed to an approval signature. A document can contain at most one such signature, and it must be the first one.
-
subfilter
: pyhanko.sign.fields.SigSeedSubFilter = None¶ Signature subfilter to use.
This should be one of
ADOBE_PKCS7_DETACHED
orPADES
. If not specified, the value may be inferred from the signature field’s seed value dictionary. Failing that,ADOBE_PKCS7_DETACHED
is used as the default value.
-
embed_validation_info
: bool = False¶ Flag indicating whether validation info (OCSP responses and/or CRLs) should be embedded or not. This is necessary to be able to validate signatures long after they have been made. This flag requires
validation_context
to be set.The precise manner in which the validation info is embedded depends on the (effective) value of
subfilter
:With
ADOBE_PKCS7_DETACHED
, the validation information will be embedded inside the CMS object containing the signature.With
PADES
, the validation information will be embedded into the document security store (DSS).
-
use_pades_lta
: bool = False¶ If
True
, the signer will append an additional document timestamp after writing the signature’s validation information to the document security store (DSS). This flag is only meaningful ifsubfilter
isPADES
.The PAdES B-LTA profile solves the long-term validation problem by adding a timestamp chain to the document after the regular signatures, which is updated with new timestamps at regular intervals. This provides an audit trail that ensures the long-term integrity of the validation information in the DSS, since OCSP responses and CRLs also have a finite lifetime.
-
timestamp_field_name
: str = None¶ Name of the timestamp field created when
use_pades_lta
isTrue
. If not specified, a unique name will be generated usinguuid
.
-
validation_context
: certvalidator.context.ValidationContext = None¶ The validation context to use when validating signatures. If provided, the signer’s certificate and any timestamp certificates will be validated before signing.
This parameter is mandatory when
embed_validation_info
isTrue
.
-
docmdp_permissions
: pyhanko.sign.fields.MDPPerm = 2¶ Indicates the document modification policy that will be in force after this signature is created.
Warning
For non-certification signatures, this is only explicitly allowed since PDF 2.0 (ISO 32000-2), so older software may not respect this setting on approval signatures.
-
-
class
pyhanko.sign.signers.
Signer
¶ Bases:
object
Abstract signer object that is agnostic as to where the cryptographic operations actually happen.
As of now, pyHanko provides two implementations:
SimpleSigner
implements the easy case where all the key material can be loaded into memory.PKCS11Signer
implements a signer that is capable of interfacing with a PKCS11 device (see alsoBEIDSigner
).
-
signing_cert
: asn1crypto.x509.Certificate¶ The certificate that will be used to create the signature.
-
cert_registry
: pyhanko.sign.general.CertificateStore¶ Collection of certificates associated with this signer. Note that this is simply a bookkeeping tool; in particular it doesn’t care about trust.
-
signature_mechanism
: asn1crypto.algos.SignedDigestAlgorithm¶ The (cryptographic) signature mechanism to use.
-
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.
-
property
subject_name
¶ - Returns
The subject’s common name as a string, extracted from
signing_cert
.
-
static
format_revinfo
(ocsp_responses: Optional[list] = None, crls: Optional[list] = None)¶ Format Adobe-style revocation information for inclusion into a CMS object.
- Parameters
ocsp_responses – A list of OCSP responses to include.
crls – A list of CRLs to include.
- Returns
A CMS attribute containing the relevant data.
-
signed_attrs
(data_digest: bytes, timestamp: Optional[datetime.datetime] = None, revocation_info=None, use_pades=False)¶ Format the signed attributes for a CMS signature.
- Parameters
data_digest – Raw digest of the data to be signed.
timestamp – Current timestamp (ignored when
use_pades
isTrue
).revocation_info – Revocation information to embed; this should be the output of a call to
Signer.format_revinfo()
(ignored whenuse_pades
isTrue
).use_pades – Respect PAdES requirements.
- Returns
An
asn1crypto.cms.CMSAttributes
object.
-
signer_info
(digest_algorithm: str, signed_attrs, signature)¶ Format the
SignerInfo
entry for a CMS signature.- Parameters
digest_algorithm – Digest algorithm to use.
signed_attrs – Signed attributes (see
signed_attrs()
).signature – The raw signature to embed (see
sign_raw()
).
- Returns
An
asn1crypto.cms.SignerInfo
object.
-
sign
(data_digest: bytes, digest_algorithm: str, timestamp: Optional[datetime.datetime] = None, dry_run=False, revocation_info=None, use_pades=False, timestamper=None) → asn1crypto.cms.ContentInfo¶ Produce a detached CMS signature from a raw data digest.
- Parameters
data_digest – Digest of the actual content being signed.
digest_algorithm – Digest algorithm to use. This should be the same digest method as the one used to hash the (external) content.
timestamp – Current timestamp (ignored when
use_pades
isTrue
).dry_run –
If
True
, the actual signing step will be replaced with a placeholder.In a PDF signing context, this is necessary to estimate the size of the signature container before computing the actual digest of the document.
revocation_info – Revocation information to embed; this should be the output of a call to
Signer.format_revinfo()
(ignored whenuse_pades
isTrue
).use_pades – Respect PAdES requirements.
timestamper –
TimeStamper
used to obtain a trusted timestamp token that can be embedded into the signature container.Note
If
dry_run
is true, the timestamper’sdummy_response()
method will be called to obtain a placeholder token. Note that with a standardHTTPTimeStamper
, this might still hit the timestamping server (in order to produce a realistic size estimate), but the dummy response will be cached.
- Returns
An
ContentInfo
object.
-
class
pyhanko.sign.signers.
SimpleSigner
(signing_cert: asn1crypto.x509.Certificate, signing_key: asn1crypto.keys.PrivateKeyInfo, cert_registry: pyhanko.sign.general.CertificateStore, signature_mechanism: Optional[asn1crypto.algos.SignedDigestAlgorithm] = None)¶ Bases:
pyhanko.sign.signers.Signer
Simple signer implementation where the key material is available in local memory.
-
signing_key
: asn1crypto.keys.PrivateKeyInfo¶ Private key associated with the certificate in
signing_cert
.
-
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.
-
classmethod
load_pkcs12
(pfx_file, ca_chain_files=None, passphrase=None, signature_mechanism=None)¶ Load certificates and key material from a PCKS#12 archive (usually
.pfx
or.p12
files).- Parameters
pfx_file – Path to the PKCS#12 archive.
ca_chain_files – Path to (PEM/DER) files containing other relevant certificates not included in the PKCS#12 file.
passphrase – Passphrase to decrypt the PKCS#12 archive, if required.
signature_mechanism – Override the signature mechanism to use.
- Returns
A
SimpleSigner
object initialised with key material loaded from the PKCS#12 file provided.
-
classmethod
load
(key_file, cert_file, ca_chain_files=None, key_passphrase=None, other_certs=None, signature_mechanism=None)¶ Load certificates and key material from PEM/DER files.
- Parameters
key_file – File containing the signer’s private key.
cert_file – File containing the signer’s certificate.
ca_chain_files – File containing other relevant certificates.
key_passphrase – Passphrase to decrypt the private key (if required).
other_certs – Other relevant certificates, specified as a list of
asn1crypto.x509.Certificate
objects.signature_mechanism – Override the signature mechanism to use.
- Returns
A
SimpleSigner
object initialised with key material loaded from the files provided.
-
-
class
pyhanko.sign.signers.
PdfTimeStamper
(timestamper: pyhanko.sign.timestamps.TimeStamper)¶ Bases:
object
Class to encapsulate the process of appending document timestamps to PDF files.
-
generate_timestamp_field_name
() → str¶ Generate a unique name for a document timestamp field using
uuid
.- Returns
The field name, as a (Python) string.
-
timestamp_pdf
(pdf_out: pyhanko.pdf_utils.incremental_writer.IncrementalPdfFileWriter, md_algorithm, validation_context, bytes_reserved=None, validation_paths=None, in_place=False, timestamper: Optional[pyhanko.sign.timestamps.TimeStamper] = None)¶ Timestamp the contents of
pdf_out
. Note thatpdf_out
should not be written to after this operation.- Parameters
pdf_out – An
IncrementalPdfFileWriter
.md_algorithm – The hash algorithm to use when computing message digests.
validation_context – The
certvalidator.ValidationContext
against which the TSA response should be validated. This validation context will also be used to update the DSS.bytes_reserved – Bytes to reserve for the CMS object in the PDF file. If not specified, make an estimate based on a dummy signature.
validation_paths – If the validation path(s) for the TSA’s certificate are already known, you can pass them using this parameter to avoid having to run the validation logic again.
in_place – Sign the input in-place. If
False
, write output to aBytesIO
object.timestamper – Override the default
TimeStamper
associated with thisPdfTimeStamper
.
- Returns
The output stream containing the signed output.
-
update_archival_timestamp_chain
(reader: pyhanko.pdf_utils.reader.PdfFileReader, validation_context, in_place=True)¶ Validate the last timestamp in the timestamp chain on a PDF file, and write an updated version to an output stream.
- Parameters
reader – A
PdfReader
encapsulating the input file.validation_context –
certvalidator.ValidationContext
object to validate the last timestamp.in_place – Sign the input in-place. If
False
, write output to aBytesIO
object.
- Returns
The output stream containing the signed output.
-
-
class
pyhanko.sign.signers.
PdfSigner
(signature_meta: pyhanko.sign.signers.PdfSignatureMetadata, signer: pyhanko.sign.signers.Signer, *, timestamper: Optional[pyhanko.sign.timestamps.TimeStamper] = None, stamp_style: Optional[pyhanko.stamp.TextStampStyle] = None, new_field_spec: Optional[pyhanko.sign.fields.SigFieldSpec] = None)¶ Bases:
pyhanko.sign.signers.PdfTimeStamper
Class to handle PDF signatures in general.
- Parameters
signature_meta – The specification of the signature to add.
signer –
Signer
object to use to produce the signature object.timestamper –
TimeStamper
object to use to produce any time stamp tokens that might be required.stamp_style – Stamp style specification to determine the visible style of the signature, typically an object of type
TextStampStyle
orQRStampStyle
. Defaults toDEFAULT_SIGNING_STAMP_STYLE
.new_field_spec – If a new field is to be created, this parameter allows the caller to specify the field’s properties in the form of a
SigFieldSpec
. This parameter is only meaningful ifexisting_fields_only
isFalse
.
-
generate_timestamp_field_name
() → str¶ Look up the timestamp field name in the
PdfSignatureMetadata
object associated with thisPdfSigner
. If not specified, generate a unique field name usinguuid
.- Returns
The field name, as a (Python) string.
-
sign_pdf
(pdf_out: pyhanko.pdf_utils.incremental_writer.IncrementalPdfFileWriter, existing_fields_only=False, bytes_reserved=None, in_place=False, appearance_text_params=None)¶ Sign a PDF file using the provided output writer.
- Parameters
pdf_out – An
IncrementalPdfFileWriter
containing the data to sign.existing_fields_only – If
True
, never create a new empty signature field to contain the signature. IfFalse
, a new field may be created if no field matchingfield_name
exists.bytes_reserved – Bytes to reserve for the CMS object in the PDF file. If not specified, make an estimate based on a dummy signature.
in_place – Sign the input in-place. If
False
, write output to aBytesIO
object.appearance_text_params – Dictionary with text parameters that will be passed to the signature appearance constructor (if applicable).
- Returns
The output stream containing the signed data.
-
pyhanko.sign.signers.
sign_pdf
(pdf_out: pyhanko.pdf_utils.incremental_writer.IncrementalPdfFileWriter, signature_meta: pyhanko.sign.signers.PdfSignatureMetadata, signer: pyhanko.sign.signers.Signer, timestamper: Optional[pyhanko.sign.timestamps.TimeStamper] = None, new_field_spec: Optional[pyhanko.sign.fields.SigFieldSpec] = None, existing_fields_only=False, bytes_reserved=None, in_place=False)¶ Thin convenience wrapper around
PdfSigner.sign_pdf()
.- Parameters
pdf_out – An
IncrementalPdfFileWriter
.bytes_reserved – Bytes to reserve for the CMS object in the PDF file. If not specified, make an estimate based on a dummy signature.
signature_meta – The specification of the signature to add.
signer –
Signer
object to use to produce the signature object.timestamper –
TimeStamper
object to use to produce any time stamp tokens that might be required.in_place – Sign the input in-place. If
False
, write output to aBytesIO
object.existing_fields_only – If
True
, never create a new empty signature field to contain the signature. IfFalse
, a new field may be created if no field matchingfield_name
exists.new_field_spec – If a new field is to be created, this parameter allows the caller to specify the field’s properties in the form of a
SigFieldSpec
. This parameter is only meaningful ifexisting_fields_only
isFalse
.
- Returns
The output stream containing the signed output.
-
pyhanko.sign.signers.
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.signers.
DEFAULT_MD
= 'sha256'¶ Default message digest algorithm used when computing digests for use in signatures.
-
pyhanko.sign.signers.
DEFAULT_SIGNING_STAMP_STYLE
= TextStampStyle(text_box_style=TextBoxStyle(font=<pyhanko.pdf_utils.font.SimpleFontEngine object>, font_size=10, leading=None, text_sep=10, border_width=0, vertical_center=True), border_width=3, stamp_text='Digitally signed by %(signer)s.\nTimestamp: %(ts)s.', timestamp_format='%Y-%m-%d %H:%M:%S %Z', background=<pyhanko.pdf_utils.content.RawContent object>, background_opacity=0.6)¶ Default stamp style used for visible signatures.