pyhanko.sign.validation package
Subpackages
Submodules
pyhanko.sign.validation.ades module
This module contains a number of functions to handle AdES signature validation.
Danger
This API is incubating, and not all features of the spec have been fully implemented at this stage. There will be bugs, and API changes may still occur.
- async pyhanko.sign.validation.ades.ades_basic_validation(signed_data: SignedData, validation_spec: SignatureValidationSpec, *, status_cls: Type[StatusType], timing_info: ValidationTimingInfo | None = None, raw_digest: bytes | None = None, validation_data_handlers: ValidationDataHandlers | None = None, signature_not_before_time: datetime | None = None, extra_status_kwargs: Dict[str, Any] | None = None) AdESBasicValidationResult
- async pyhanko.sign.validation.ades.ades_basic_validation(signed_data: SignedData, validation_spec: SignatureValidationSpec, *, timing_info: ValidationTimingInfo | None = None, raw_digest: bytes | None = None, validation_data_handlers: ValidationDataHandlers | None = None, signature_not_before_time: datetime | None = None, extra_status_kwargs: Dict[str, Any] | None = None) AdESBasicValidationResult
Validate a CMS signature according to ETSI EN 319 102-1 § 5.3.
- Parameters:
signed_data – The
SignedData
value.validation_spec – Validation settings to apply.
raw_digest – The expected message digest attribute value.
timing_info – Data object describing the timing of the validation. Defaults to
ValidationTimingInfo.now()
.validation_data_handlers – Data handlers to manage validation data.
extra_status_kwargs – Extra keyword arguments to pass to the signature status object’s
__init__
function.status_cls – The class of the resulting status object in pyHanko’s internal validation API.
signature_not_before_time – Time when the signature was known _not_ to exist.
- Returns:
- async pyhanko.sign.validation.ades.ades_with_time_validation(signed_data: SignedData, validation_spec: SignatureValidationSpec, *, timing_info: ValidationTimingInfo | None = None, raw_digest: bytes | None = None, validation_data_handlers: ValidationDataHandlers | None = None, signature_not_before_time: datetime | None = None, extra_status_kwargs: Dict[str, Any] | None = None) AdESWithTimeValidationResult
- async pyhanko.sign.validation.ades.ades_with_time_validation(signed_data: SignedData, validation_spec: SignatureValidationSpec, *, status_cls: Type[StatusType], timing_info: ValidationTimingInfo | None = None, raw_digest: bytes | None = None, validation_data_handlers: ValidationDataHandlers | None = None, signature_not_before_time: datetime | None = None, extra_status_kwargs: Dict[str, Any] | None = None) AdESWithTimeValidationResult
Validate a CMS signature with time according to ETSI EN 319 102-1 § 5.5.
- Parameters:
signed_data – The
SignedData
value.validation_spec – Validation settings to apply.
raw_digest – The expected message digest attribute value.
timing_info – Data object describing the timing of the validation. Defaults to
ValidationTimingInfo.now()
.validation_data_handlers – Data handlers to manage validation data.
extra_status_kwargs – Extra keyword arguments to pass to the signature status object’s
__init__
function.status_cls – The class of the resulting status object in pyHanko’s internal validation API.
signature_not_before_time – Time when the signature was known _not_ to exist.
- Returns:
- async pyhanko.sign.validation.ades.ades_lta_validation(embedded_sig: EmbeddedPdfSignature, pdf_validation_spec: PdfSignatureValidationSpec, timing_info: ValidationTimingInfo | None = None, signature_not_before_time: datetime | None = None) AdESLTAValidationResult
Validate a PAdES signature providing long-term availability and integrity of validation material. See ETSI EN 319 102-1, § 5.6.3.
For the purposes of PAdES validation, the chain of document time stamps in the document serves as the unique Evidence Record (ER).
- Parameters:
embedded_sig – The PDF signature to validate.
pdf_validation_spec – PDF signature validation settings.
timing_info – Data object describing the timing of the validation. Defaults to
ValidationTimingInfo.now()
.signature_not_before_time – Time when the signature was known _not_ to exist.
- Returns:
A validation result.
- async pyhanko.sign.validation.ades.ades_timestamp_validation(tst_signed_data: SignedData, validation_spec: SignatureValidationSpec, expected_tst_imprint: bytes, *, status_cls: Type[StatusType], timing_info: ValidationTimingInfo | None = None, validation_data_handlers: ValidationDataHandlers | None = None, extra_status_kwargs: Dict[str, Any] | None = None) AdESBasicValidationResult
- async pyhanko.sign.validation.ades.ades_timestamp_validation(tst_signed_data: SignedData, validation_spec: SignatureValidationSpec, expected_tst_imprint: bytes, *, timing_info: ValidationTimingInfo | None = None, validation_data_handlers: ValidationDataHandlers | None = None, extra_status_kwargs: Dict[str, Any] | None = None) AdESBasicValidationResult
Validate a timestamp token according to ETSI EN 319 102-1 § 5.4.
- Parameters:
tst_signed_data – The
SignedData
value of the timestamp.validation_spec – Validation settings to apply.
expected_tst_imprint – The expected message imprint in the timestamp token.
timing_info – Data object describing the timing of the validation. Defaults to
ValidationTimingInfo.now()
.validation_data_handlers – Data handlers to manage validation data.
extra_status_kwargs – Extra keyword arguments to pass to the signature status object’s
__init__
function.status_cls – The class of the resulting status object in pyHanko’s internal validation API.
- Returns:
- async pyhanko.sign.validation.ades.simulate_future_ades_lta_validation(embedded_sig: EmbeddedPdfSignature, pdf_validation_spec: PdfSignatureValidationSpec, future_validation_time: datetime, current_reference_time: datetime | None = None) AdESLTAValidationResult
Added in version 0.21.0.
Simulate a future LTA validation of a PDF signature, assuming perfect timestamp maintenance until the specified point in time.
Warning
This is experimental API.
The purpose of this utility function is to act as a sanity check for signers and signature archivists. It takes validation spec, a future validation time and a current reference time (defaults to the current time), and, by fiat, generates proofs of existence for all relevant objects in the PDF for that reference time. It then executes the PAdES LTA validation algorithm with that set of PoEs against the future validation time, with all remote fetching functionality disabled.
The idea is that this allows the caller to assess whether a signature is “LTA maintainable”, i.e. whether it contains the necessary information for the signature to remain validatable if the timestamp chain is extended properly. If this check fails but the signature validates at the current time, it may indicate a lack of contemporaneous revocation information.
- Parameters:
embedded_sig – The signature under scrutiny.
pdf_validation_spec – The validation spec against which the simulated validation should be executed.
future_validation_time – The future validation time at which the validation should be simulated.
current_reference_time – The reference time at which all relevant objects in the PDF are presumed to have been proven to exist for the purposes of the (future) validation being simulated. Defaults to the current time.
- Returns:
An AdES LTA validation result.
- class pyhanko.sign.validation.ades.AdESBasicValidationResult(ades_subindic: AdESSubIndic, api_status: StatusType | None, failure_msg: str | None, validation_objects: ValidationObjectSet)
Bases:
Generic
[StatusType
]Result of validation of basic signatures.
ETSI EN 319 102-1, § 5.3
- ades_subindic: AdESSubIndic
AdES subindication.
- api_status: StatusType | None
A status descriptor object from pyHanko’s own validation API. Will be an instance of
SignatureStatus
or a subclass thereof.
- failure_msg: str | None
A string describing the reason why validation failed, if applicable.
- validation_objects: ValidationObjectSet
Validation objects that were potentially relevant for the validation process.
- class pyhanko.sign.validation.ades.AdESWithTimeValidationResult(ades_subindic: pyhanko.sign.ades.report.AdESSubIndic, api_status: Optional[+StatusType], failure_msg: str | None, validation_objects: pyhanko.sign.validation.ades.ValidationObjectSet, best_signature_time: datetime.datetime, signature_not_before_time: datetime.datetime | None)
Bases:
AdESBasicValidationResult
- best_signature_time: datetime
- signature_not_before_time: datetime | None
- class pyhanko.sign.validation.ades.AdESLTAValidationResult(ades_subindic: AdESSubIndic, api_status: StatusType | None, failure_msg: str | None, validation_objects: ValidationObjectSet, best_signature_time: datetime, signature_not_before_time: datetime | None, oldest_evidence_record_timestamp: datetime | None, signature_timestamp_status: AdESBasicValidationResult | None)
Bases:
AdESWithTimeValidationResult
Result of a PAdES validation for a signature providing long-term availability and integrity of validation material. See ETSI EN 319 102-1, § 5.6.3.
- oldest_evidence_record_timestamp: datetime | None
The oldest timestamp in the evidence record, after validation.
Note
For PAdES, this refers to the chain of document timestamp signatures after signing.
- signature_timestamp_status: AdESBasicValidationResult | None
The validation result for the signature time stamp, if applicable.
- pyhanko.sign.validation.ades.derive_validation_object_identifier(vo: ValidationObject) str | None
pyhanko.sign.validation.dss module
- class pyhanko.sign.validation.dss.VRI(certs: set = <factory>, ocsps: set = <factory>, crls: set = <factory>)
Bases:
object
VRI dictionary as defined in PAdES / ISO 32000-2. These dictionaries collect data that may be relevant for the validation of a specific signature.
Note
The data are stored as PDF indirect objects, not asn1crypto values. In particular, values are tied to a specific PDF handler.
- certs: set
Relevant certificates.
- ocsps: set
Relevant OCSP responses.
- crls: set
Relevant CRLs.
- as_pdf_object() DictionaryObject
- Returns:
A PDF dictionary representing this VRI entry.
- class pyhanko.sign.validation.dss.DocumentSecurityStore(writer: BasePdfFileWriter | None, certs=None, ocsps=None, crls=None, vri_entries=None, backing_pdf_object=None)
Bases:
object
Representation of a DSS in Python.
- property modified
- static sig_content_identifier(contents) NameObject
Hash the contents of a signature object to get the corresponding VRI identifier.
This is internal API.
- Parameters:
contents – Signature contents.
- Returns:
A name object to put into the DSS.
- register_vri(identifier, *, certs=(), ocsps=(), crls=())
Register validation information for a set of signing certificates associated with a particular signature.
- Parameters:
identifier – Identifier of the signature object (see sig_content_identifier). If
None
, only embed the data into the DSS without associating it with any VRI.certs – Certificates to add.
ocsps – OCSP responses to add.
crls – CRLs to add.
- as_pdf_object()
Convert the
DocumentSecurityStore
object to a python dictionary. This method also handles DSS updates.- Returns:
A PDF object representing this DSS.
- load_certs() Iterable[Certificate]
Return a generator that parses and yields all certificates in the DSS.
- Returns:
A generator yielding
Certificate
objects.
- as_validation_context(validation_context_kwargs, include_revinfo=True) ValidationContext
Construct a validation context from the data in this DSS.
- Parameters:
validation_context_kwargs – Extra kwargs to pass to the
__init__
function.include_revinfo – If
False
, revocation info is skipped.
- Returns:
A validation context preloaded with information from this DSS.
- classmethod read_dss(handler: PdfHandler) DocumentSecurityStore
Read a DSS record from a file and add the data to a validation context.
- Parameters:
handler – PDF handler from which to read the DSS.
- Returns:
A DocumentSecurityStore object describing the current state of the DSS.
- classmethod supply_dss_in_writer(pdf_out: BasePdfFileWriter, sig_contents, *, certs=None, ocsps=None, crls=None, paths=None, validation_context=None, embed_roots: bool = True) DocumentSecurityStore
Add or update a DSS, and optionally associate the new information with a VRI entry tied to a signature object.
You can either specify the CMS objects to include directly, or pass them in as output from pyhanko_certvalidator.
- Parameters:
pdf_out – PDF writer to write to.
sig_contents – Contents of the new signature (used to compute the VRI hash), as a hexadecimal string, including any padding. If
None
, the information will not be added to any VRI dictionary.certs – Certificates to include in the VRI entry.
ocsps – OCSP responses to include in the VRI entry.
crls – CRLs to include in the VRI entry.
paths – Validation paths that have been established, and need to be added to the DSS.
validation_context – Validation context from which to draw OCSP responses and CRLs.
embed_roots –
Added in version 0.9.0.
Option that controls whether the root certificate of each validation path should be embedded into the DSS. The default is
True
.Note
Trust roots are configured by the validator, so embedding them typically does nothing in a typical validation process. Therefore they can be safely omitted in most cases. Nonetheless, embedding the roots can be useful for documentation purposes.
Warning
This only applies to paths, not the
certs
parameter.
- Returns:
a
DocumentSecurityStore
object containing both the new and existing contents of the DSS (if any).
- classmethod add_dss(output_stream, sig_contents, *, certs=None, ocsps=None, crls=None, paths=None, validation_context=None, force_write: bool = False, embed_roots: bool = True, file_credential: SerialisedCredential | None = None, strict: bool = True)
Wrapper around
supply_dss_in_writer()
.The result is applied to the output stream as an incremental update.
- Parameters:
output_stream – Output stream to write to.
sig_contents – Contents of the new signature (used to compute the VRI hash), as a hexadecimal string, including any padding. If
None
, the information will not be added to any VRI dictionary.certs – Certificates to include in the VRI entry.
ocsps – OCSP responses to include in the VRI entry.
crls – CRLs to include in the VRI entry.
paths – Validation paths that have been established, and need to be added to the DSS.
force_write – Force a write even if the DSS doesn’t have any new content.
validation_context – Validation context from which to draw OCSP responses and CRLs.
embed_roots –
Added in version 0.9.0.
Option that controls whether the root certificate of each validation path should be embedded into the DSS. The default is
True
.Note
Trust roots are configured by the validator, so embedding them typically does nothing in a typical validation process. Therefore they can be safely omitted in most cases. Nonetheless, embedding the roots can be useful for documentation purposes.
Warning
This only applies to paths, not the
certs
parameter.file_credential –
Added in version 0.13.0.
Serialised file credential, to update encrypted files.
strict – If
True
, enforce strict validation of the input stream. Default isTrue
.
- async pyhanko.sign.validation.dss.async_add_validation_info(embedded_sig: EmbeddedPdfSignature, validation_context: ValidationContext, skip_timestamp=False, add_vri_entry=True, in_place=False, output=None, force_write=False, chunk_size=4096, embed_roots: bool = True)
Add validation info (CRLs, OCSP responses, extra certificates) for a signature to the DSS of a document in an incremental update. This is a wrapper around
collect_validation_info()
.- Parameters:
embedded_sig – The signature for which the revocation information needs to be collected.
validation_context – The validation context to use.
skip_timestamp – If
True
, do not attempt to validate the timestamp attached to the signature, if one is present.add_vri_entry – Add a
/VRI
entry for this signature to the document security store. Default isTrue
.output – Write the output to the specified output stream. If
None
, write to a newBytesIO
object. Default isNone
.in_place – Sign the original input stream in-place. This parameter overrides
output
.chunk_size – Chunk size parameter to use when copying output to a new stream (irrelevant if
in_place
isTrue
).force_write – Force a new revision to be written, even if not necessary (i.e. when all data in the validation context is already present in the DSS).
embed_roots –
Option that controls whether the root certificate of each validation path should be embedded into the DSS. The default is
True
.Note
Trust roots are configured by the validator, so embedding them typically does nothing in a typical validation process. Therefore they can be safely omitted in most cases. Nonetheless, embedding the roots can be useful for documentation purposes.
- Returns:
The (file-like) output object to which the result was written.
- async pyhanko.sign.validation.dss.collect_validation_info(embedded_sig: EmbeddedPdfSignature, validation_context: ValidationContext, skip_timestamp=False)
Query revocation info for a PDF signature using a validation context, and store the results in a validation context.
This works by validating the signer’s certificate against the provided validation context, which causes revocation info to be cached for later retrieval.
Warning
This function does not actually validate the signature, but merely checks the signer certificate’s chain of trust.
- Parameters:
embedded_sig – Embedded PDF signature to operate on.
validation_context – Validation context to use.
skip_timestamp – If the signature has a time stamp token attached to it, also collect revocation information for the timestamp.
- Returns:
A list of validation paths.
- pyhanko.sign.validation.dss.enumerate_ocsp_certs(ocsp_response)
Essentially nabbed from _extract_ocsp_certs in ValidationContext
pyhanko.sign.validation.errors module
- exception pyhanko.sign.validation.errors.SignatureValidationError(failure_message, ades_subindication: AdESSubIndic | None = None)
Bases:
ValueErrorWithMessage
Error validating a signature.
- property ades_status: AdESStatus | None
- exception pyhanko.sign.validation.errors.DisallowedAlgorithmError(failure_message, permanent: bool, oid_type: Type[ObjectIdentifier] | None = None)
Bases:
SignatureValidationError
- exception pyhanko.sign.validation.errors.ValidationInfoReadingError(failure_message)
Bases:
ValueErrorWithMessage
Error reading validation info.
- exception pyhanko.sign.validation.errors.NoDSSFoundError
Bases:
ValidationInfoReadingError
- exception pyhanko.sign.validation.errors.SigSeedValueValidationError(failure_message, ades_subindication: AdESSubIndic | None = None)
Bases:
SignatureValidationError
Error validating a signature’s seed value constraints.
- exception pyhanko.sign.validation.errors.CMSAlgorithmProtectionError(failure_message)
Bases:
ValueErrorWithMessage
Error related to CMS algorithm protection checks.
pyhanko.sign.validation.generic_cms module
- pyhanko.sign.validation.generic_cms.validate_sig_integrity(signer_info: SignerInfo, cert: Certificate, expected_content_type: str, actual_digest: bytes, algorithm_usage_policy: CMSAlgorithmUsagePolicy | None = None, time_indic: datetime | None = None) Tuple[bool, bool]
Validate the integrity of a signature for a particular signerInfo object inside a CMS signed data container.
Warning
This function does not do any trust checks, and is considered “dangerous” API because it is easy to misuse.
- Parameters:
signer_info – A
cms.SignerInfo
object.cert –
The signer’s certificate.
Note
This function will not attempt to extract certificates from the signed data.
expected_content_type – The expected value for the content type attribute (as a Python string, see
cms.ContentType
).actual_digest – The actual digest to be matched to the message digest attribute.
algorithm_usage_policy – Algorithm usage policy.
time_indic – Time indication for the production of the signature.
- Returns:
A tuple of two booleans. The first indicates whether the provided digest matches the value in the signed attributes. The second indicates whether the signature of the digest is valid.
- async pyhanko.sign.validation.generic_cms.async_validate_cms_signature(signed_data: SignedData, *, status_cls: Type[StatusType], raw_digest: bytes | None = None, validation_context: ValidationContext | None = None, status_kwargs: dict | None = None, key_usage_settings: KeyUsageConstraints | None = None) StatusType
- async pyhanko.sign.validation.generic_cms.async_validate_cms_signature(signed_data: SignedData, *, raw_digest: bytes | None = None, validation_context: ValidationContext | None = None, status_kwargs: dict | None = None, key_usage_settings: KeyUsageConstraints | None = None) SignatureStatus
Validate a CMS signature (i.e. a
SignedData
object).- Parameters:
signed_data – The
asn1crypto.cms.SignedData
object to validate.status_cls – Status class to use for the validation result.
raw_digest – Raw digest, computed from context.
validation_context – Validation context to validate the signer’s certificate.
status_kwargs – Other keyword arguments to pass to the
status_class
when reporting validation results.key_usage_settings – A
KeyUsageConstraints
object specifying which key usages must or must not be present in the signer’s certificate.algorithm_policy –
The algorithm usage policy for the signature validation.
Warning
This is distinct from the algorithm usage policy used for certificate validation, but the latter will be used as a fallback if this parameter is not specified.
It is nonetheless recommended to align both policies unless there is a clear reason to do otherwise.
- Returns:
A
SignatureStatus
object (or an instance of a proper subclass)
- async pyhanko.sign.validation.generic_cms.collect_timing_info(signer_info: SignerInfo, ts_validation_context: ValidationContext | None, raw_digest: bytes)
Collect and validate timing information in a
SignerInfo
value. This includes thesigningTime
attribute, content timestamp information and signature timestamp information.- Parameters:
signer_info – A
SignerInfo
value.ts_validation_context – The timestamp validation context to validate against.
raw_digest – The raw external message digest bytes (only relevant for the validation of the content timestamp token, if there is one)
- async pyhanko.sign.validation.generic_cms.validate_tst_signed_data(tst_signed_data: SignedData, validation_context: ValidationContext | None, expected_tst_imprint: bytes, algorithm_policy: CMSAlgorithmUsagePolicy | None = None)
Validate the
SignedData
of a time stamp token.- Parameters:
tst_signed_data – The
SignedData
value to validate; must encapsulate aTSTInfo
value.validation_context – The validation context to validate against.
expected_tst_imprint – The expected message imprint value that should be contained in the encapsulated
TSTInfo
.algorithm_policy –
The algorithm usage policy for the signature validation.
Warning
This is distinct from the algorithm usage policy used for certificate validation, but the latter will be used as a fallback if this parameter is not specified.
It is nonetheless recommended to align both policies unless there is a clear reason to do otherwise.
- Returns:
Keyword arguments for a
TimeStampSignatureStatus
.
- async pyhanko.sign.validation.generic_cms.async_validate_detached_cms(input_data: bytes | IO | ContentInfo | EncapsulatedContentInfo, signed_data: SignedData, signer_validation_context: ValidationContext | None = None, ts_validation_context: ValidationContext | None = None, ac_validation_context: ValidationContext | None = None, key_usage_settings: KeyUsageConstraints | None = None, algorithm_policy: CMSAlgorithmUsagePolicy | None = None, chunk_size=4096, max_read=None) StandardCMSSignatureStatus
Validate a detached CMS signature.
- Parameters:
input_data –
The input data to sign. This can be either a
bytes
object, a file-like object or acms.ContentInfo
/cms.EncapsulatedContentInfo
object.If a CMS content info object is passed in, the content field will be extracted.
signed_data – The
cms.SignedData
object containing the signature to verify.signer_validation_context – Validation context to use to verify the signer certificate’s trust.
ts_validation_context – Validation context to use to verify the TSA certificate’s trust, if a timestamp token is present. By default, the same validation context as that of the signer is used.
ac_validation_context –
Validation context to use to validate attribute certificates. If not supplied, no AC validation will be performed.
Note
RFC 5755 requires attribute authority trust roots to be specified explicitly; hence why there’s no default.
algorithm_policy –
The algorithm usage policy for the signature validation.
Warning
This is distinct from the algorithm usage policy used for certificate validation, but the latter will be used as a fallback if this parameter is not specified.
It is nonetheless recommended to align both policies unless there is a clear reason to do otherwise.
key_usage_settings – Key usage parameters for the signer.
chunk_size – Chunk size to use when consuming input data.
max_read – Maximal number of bytes to read from the input stream.
- Returns:
A description of the signature’s status.
- async pyhanko.sign.validation.generic_cms.cms_basic_validation(signed_data: SignedData, raw_digest: bytes | None = None, validation_context: ValidationContext | None = None, status_kwargs: dict | None = None, validation_path: ValidationPath | None = None, pkix_validation_params: PKIXValidationParams | None = None, algorithm_policy: CMSAlgorithmUsagePolicy | None = None, *, key_usage_settings: KeyUsageConstraints) Dict[str, Any]
Perform basic validation of CMS and PKCS#7 signatures in isolation (i.e. integrity and trust checks).
Internal API.
- pyhanko.sign.validation.generic_cms.compute_signature_tst_digest(signer_info: SignerInfo) bytes | None
Compute the digest of the signature according to the message imprint algorithm information in a signature timestamp token.
Internal API.
- Parameters:
signer_info – A
SignerInfo
value.- Returns:
The computed digest, or
None
if there is no signature timestamp.
- pyhanko.sign.validation.generic_cms.extract_tst_data(signer_info: SignerInfo, signed: bool = False) SignedData | None
Extract signed data associated with a timestamp token.
Internal API.
- Parameters:
signer_info – A
SignerInfo
value.signed – If
True
, look for a content timestamp (among the signed attributes), else look for a signature timestamp (among the unsigned attributes).
- Returns:
The
SignedData
value found, orNone
.
- pyhanko.sign.validation.generic_cms.extract_self_reported_ts(signer_info: SignerInfo) datetime | None
Extract self-reported timestamp (from the
signingTime
attribute)Internal API.
- Parameters:
signer_info – A
SignerInfo
value.- Returns:
The value of the
signingTime
attribute as adatetime
, orNone
.
- pyhanko.sign.validation.generic_cms.extract_certs_for_validation(signed_data: SignedData) SignedDataCerts
Extract certificates from a CMS signed data object for validation purposes, identifying the signer’s certificate in accordance with ETSI EN 319 102-1, 5.2.3.4.
- Parameters:
signed_data – The CMS payload.
- Returns:
The extracted certificates.
- async pyhanko.sign.validation.generic_cms.collect_signer_attr_status(sd_attr_certificates: Iterable[AttributeCertificateV2], signer_cert: Certificate, validation_context: ValidationContext | None, sd_signed_attrs: CMSAttributes)
- pyhanko.sign.validation.generic_cms.validate_algorithm_protection(attrs: CMSAttributes, claimed_digest_algorithm_obj: DigestAlgorithm, claimed_signature_algorithm_obj: SignedDigestAlgorithm | None, claimed_mac_algorithm_obj: HmacAlgorithm | None)
Internal API to validate the CMS algorithm protection attribute defined in RFC 6211, if present.
- Parameters:
attrs – A CMS attribute list.
claimed_digest_algorithm_obj – The claimed (i.e. unprotected) digest algorithm value.
claimed_signature_algorithm_obj – The claimed (i.e. unprotected) signature algorithm value.
claimed_mac_algorithm_obj – The claimed (i.e. unprotected) MAC algorithm value.
- Raises:
errors.CMSStructuralError – if multiple CMS protection attributes are present
errors.CMSAlgorithmProtectionError – if a mismatch is detected
- pyhanko.sign.validation.generic_cms.get_signing_cert_attr(signed_attrs: CMSAttributes) SigningCertificate | SigningCertificateV2 | None
Retrieve the
signingCertificate
orsigningCertificateV2
attribute (giving preference to the latter) from a signature’s signed attributes.- Parameters:
signed_attrs – Signed attributes.
- Returns:
The value of the attribute, if present, else
None
.
pyhanko.sign.validation.ltv module
- class pyhanko.sign.validation.ltv.RevocationInfoValidationType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
Indicates a validation profile to use when validating revocation info.
- ADOBE_STYLE = 'adobe'
Retrieve validation information from the CMS object, using Adobe’s revocation info archival attribute.
- PADES_LT = 'pades'
Retrieve validation information from the DSS, and require the signature’s embedded timestamp to still be valid.
- PADES_LTA = 'pades-lta'
Retrieve validation information from the DSS, but read & validate the chain of document timestamps leading up to the signature to establish the integrity of the validation information at the time of signing.
- classmethod as_tuple()
- pyhanko.sign.validation.ltv.apply_adobe_revocation_info(signer_info: SignerInfo, validation_context_kwargs=None) ValidationContext
Read Adobe-style revocation information from a CMS object, and load it into a validation context.
- Parameters:
signer_info – Signer info CMS object.
validation_context_kwargs – Extra kwargs to pass to the
__init__
function.
- Returns:
A validation context preloaded with the relevant revocation information.
- pyhanko.sign.validation.ltv.retrieve_adobe_revocation_info(signer_info: SignerInfo)
Retrieve Adobe-style revocation information from a
SignerInfo
value, if present.Internal API.
- Parameters:
signer_info – A
SignerInfo
value.- Returns:
A tuple of two (potentially empty) lists, containing OCSP responses and CRLs, respectively.
- pyhanko.sign.validation.ltv.get_timestamp_chain(reader: PdfFileReader) Iterator[EmbeddedPdfSignature]
Get the document timestamp chain of the associated reader, ordered from new to old.
- Parameters:
reader – A
PdfFileReader
.- Returns:
An iterable of
EmbeddedPdfSignature
objects representing document timestamps.
- async pyhanko.sign.validation.ltv.async_validate_pdf_ltv_signature(embedded_sig: EmbeddedPdfSignature, validation_type: RevocationInfoValidationType, validation_context_kwargs: dict | None = None, bootstrap_validation_context: ValidationContext | None = None, ac_validation_context_kwargs=None, force_revinfo=False, diff_policy: DiffPolicy | None = None, key_usage_settings: KeyUsageConstraints | None = None, skip_diff: bool = False) PdfSignatureStatus
Added in version 0.9.0.
Validate a PDF LTV signature according to a particular profile.
- Parameters:
embedded_sig – Embedded signature to evaluate.
validation_type – Validation profile to use.
validation_context_kwargs – Keyword args to instantiate
pyhanko_certvalidator.ValidationContext
objects needed over the course of the validation.ac_validation_context_kwargs –
Keyword arguments for the validation context to use to validate attribute certificates. If not supplied, no AC validation will be performed.
Note
RFC 5755 requires attribute authority trust roots to be specified explicitly; hence why there’s no default.
bootstrap_validation_context – Validation context used to validate the current timestamp.
force_revinfo – Require all certificates encountered to have some form of live revocation checking provisions.
diff_policy – Policy to evaluate potential incremental updates that were appended to the signed revision of the document. Defaults to
DEFAULT_DIFF_POLICY
.key_usage_settings – A
KeyUsageConstraints
object specifying which key usages must or must not be present in the signer’s certificate.skip_diff – If
True
, skip the difference analysis step entirely.
- Returns:
The status of the signature.
- async pyhanko.sign.validation.ltv.establish_timestamp_trust(tst_signed_data: SignedData, validation_context: ValidationContext, expected_tst_imprint: bytes)
Wrapper around
validate_tst_signed_data()
for use when analysing timestamps for the purpose of establishing a timestamp chain. Its main purpose is throwing/logging an error if validation fails, since that amounts to lack of trust in the purported validation time.This is internal API.
- Parameters:
tst_signed_data – The
SignedData
value to validate; must encapsulate aTSTInfo
value.validation_context – The validation context to apply to the timestamp.
expected_tst_imprint – The expected message imprint for the
TSTInfo
value.
- Returns:
A
TimestampSignatureStatus
if validation is successful.- Raises:
SignatureValidationError
if validation fails.
pyhanko.sign.validation.pdf_embedded module
- class pyhanko.sign.validation.pdf_embedded.EmbeddedPdfSignature(reader: PdfFileReader, sig_field: DictionaryObject, fq_name: str)
Bases:
object
Class modelling a signature embedded in a PDF document.
- sig_object: DictionaryObject
The signature dictionary.
- sig_field: DictionaryObject
The field dictionary of the form field containing the signature.
- signed_data: SignedData
CMS signed data in the signature.
- property embedded_attr_certs: List[AttributeCertificateV2]
Embedded attribute certificates.
- property other_embedded_certs: List[Certificate]
Embedded X.509 certificates, excluding than that of the signer.
- property signer_cert: Certificate
Certificate of the signer.
- property sig_object_type: NameObject
Returns the type of the embedded signature object. For ordinary signatures, this will be
/Sig
. In the case of a document timestamp,/DocTimeStamp
is returned.- Returns:
A PDF name object describing the type of signature.
- property field_name
- Returns:
Name of the signature field.
- property self_reported_timestamp: datetime | None
- Returns:
The signing time as reported by the signer, if embedded in the signature’s signed attributes or provided as part of the signature object in the PDF document.
- property attached_timestamp_data: SignedData | None
- Returns:
The signed data component of the timestamp token embedded in this signature, if present.
- compute_integrity_info(diff_policy=None, skip_diff=False)
Compute the various integrity indicators of this signature.
- Parameters:
diff_policy – Policy to evaluate potential incremental updates that were appended to the signed revision of the document. Defaults to
DEFAULT_DIFF_POLICY
.skip_diff – If
True
, skip the difference analysis step entirely.
- summarise_integrity_info() dict
Compile the integrity information for this signature into a dictionary that can later be passed to
PdfSignatureStatus
as kwargs.This method is only available after calling
EmbeddedPdfSignature.compute_integrity_info()
.
- property seed_value_spec: SigSeedValueSpec | None
- property docmdp_level: MDPPerm | None
- Returns:
The document modification policy required by this signature or its Lock dictionary.
Warning
This does not take into account the DocMDP requirements of earlier signatures (if present).
The specification forbids signing with a more lenient DocMDP than the one currently in force, so this should not happen in a compliant document. That being said, any potential violations will still invalidate the earlier signature with the stricter DocMDP policy.
- property fieldmdp: FieldMDPSpec | None
- Returns:
Read the field locking policy of this signature, if applicable. See also
FieldMDPSpec
.
- compute_digest() bytes
Compute the
/ByteRange
digest of this signature. The result will be cached.- Returns:
The digest value.
- compute_tst_digest() bytes | None
Compute the digest of the signature needed to validate its timestamp token (if present).
Warning
This computation is only relevant for timestamp tokens embedded inside a regular signature. If the signature in question is a document timestamp (where the entire signature object is a timestamp token), this method does not apply.
- Returns:
The digest value, or
None
if there is no timestamp token.
- evaluate_signature_coverage() SignatureCoverageLevel
Internal method used to evaluate the coverage level of a signature.
- Returns:
The coverage level of the signature.
- evaluate_modifications(diff_policy: DiffPolicy) DiffResult | SuspiciousModification
Internal method used to evaluate the modification level of a signature.
- class pyhanko.sign.validation.pdf_embedded.DocMDPInfo(permission, author_sig)
Bases:
tuple
Encodes certification information for a signed document, consisting of a reference to the author signature, together with the associated DocMDP policy.
- author_sig
Alias for field number 1
- permission
Alias for field number 0
- pyhanko.sign.validation.pdf_embedded.read_certification_data(reader: PdfFileReader) DocMDPInfo | None
Read the certification information for a PDF document, if present.
- Parameters:
reader – Reader representing the input document.
- Returns:
A
DocMDPInfo
object containing the relevant data, orNone
.
- async pyhanko.sign.validation.pdf_embedded.async_validate_pdf_signature(embedded_sig: EmbeddedPdfSignature, signer_validation_context: ValidationContext | None = None, ts_validation_context: ValidationContext | None = None, ac_validation_context: ValidationContext | None = None, diff_policy: DiffPolicy | None = None, key_usage_settings: KeyUsageConstraints | None = None, skip_diff: bool = False, algorithm_policy: CMSAlgorithmUsagePolicy | None = None) PdfSignatureStatus
Added in version 0.9.0.
Validate a PDF signature.
- Parameters:
embedded_sig – Embedded signature to evaluate.
signer_validation_context – Validation context to use to validate the signature’s chain of trust.
ts_validation_context – Validation context to use to validate the timestamp’s chain of trust (defaults to
signer_validation_context
).ac_validation_context –
Validation context to use to validate attribute certificates. If not supplied, no AC validation will be performed.
Note
RFC 5755 requires attribute authority trust roots to be specified explicitly; hence why there’s no default.
diff_policy – Policy to evaluate potential incremental updates that were appended to the signed revision of the document. Defaults to
DEFAULT_DIFF_POLICY
.key_usage_settings – A
KeyUsageConstraints
object specifying which key usages must or must not be present in the signer’s certificate.skip_diff – If
True
, skip the difference analysis step entirely.algorithm_policy –
The algorithm usage policy for the signature validation.
Warning
This is distinct from the algorithm usage policy used for certificate validation, but the latter will be used as a fallback if this parameter is not specified.
It is nonetheless recommended to align both policies unless there is a clear reason to do otherwise.
- Returns:
The status of the PDF signature in question.
- async pyhanko.sign.validation.pdf_embedded.async_validate_pdf_timestamp(embedded_sig: EmbeddedPdfSignature, validation_context: ValidationContext | None = None, diff_policy: DiffPolicy | None = None, skip_diff: bool = False) DocumentTimestampStatus
Added in version 0.9.0.
Validate a PDF document timestamp.
- Parameters:
embedded_sig – Embedded signature to evaluate.
validation_context – Validation context to use to validate the timestamp’s chain of trust.
diff_policy – Policy to evaluate potential incremental updates that were appended to the signed revision of the document. Defaults to
DEFAULT_DIFF_POLICY
.skip_diff – If
True
, skip the difference analysis step entirely.
- Returns:
The status of the PDF timestamp in question.
- pyhanko.sign.validation.pdf_embedded.report_seed_value_validation(embedded_sig: EmbeddedPdfSignature, validation_path: ValidationPath, timestamp_found: bool)
Internal API function to enforce seed value constraints (if present) and report on the result(s).
- Parameters:
embedded_sig – The embedded signature.
validation_path – The validation path for the signer’s certificate.
timestamp_found – Flag indicating whether a valid timestamp was found or not.
- Returns:
A
status_kwargs
dict.
- pyhanko.sign.validation.pdf_embedded.extract_contents(sig_object: DictionaryObject) bytes
Internal function to extract the (DER-encoded) signature bytes from a PDF signature dictionary.
- Parameters:
sig_object – A signature dictionary.
- Returns:
The extracted contents as a byte string.
pyhanko.sign.validation.policy_decl module
- class pyhanko.sign.validation.policy_decl.SignatureValidationSpec(cert_validation_policy: pyhanko_certvalidator.context.CertValidationPolicySpec, revinfo_gathering_policy: pyhanko.sign.validation.policy_decl.RevocationInfoGatheringSpec = RevocationInfoGatheringSpec(online_fetching_rule=<RevinfoOnlineFetchingRule.NO_HISTORICAL_FETCH: 2>, fetcher_backend=<pyhanko_certvalidator.fetchers.requests_fetchers.RequestsFetcherBackend object at 0x7fcd70e92d50>), ts_cert_validation_policy: Optional[pyhanko_certvalidator.context.CertValidationPolicySpec] = None, ac_validation_policy: Optional[pyhanko_certvalidator.context.CertValidationPolicySpec] = None, local_knowledge: pyhanko.sign.validation.policy_decl.LocalKnowledge = LocalKnowledge(known_ocsps=[], known_crls=[], known_certs=[], known_poes=[], nonrevoked_assertions=[]), key_usage_settings: pyhanko.sign.validation.settings.KeyUsageConstraints = KeyUsageConstraints(key_usage=None, key_usage_forbidden=None, extd_key_usage=None, explicit_extd_key_usage_required=True, match_all_key_usages=False), signature_algorithm_policy: Optional[pyhanko.sign.validation.utils.CMSAlgorithmUsagePolicy] = None)
Bases:
object
- cert_validation_policy: CertValidationPolicySpec
- revinfo_gathering_policy: RevocationInfoGatheringSpec = RevocationInfoGatheringSpec(online_fetching_rule=<RevinfoOnlineFetchingRule.NO_HISTORICAL_FETCH: 2>, fetcher_backend=<pyhanko_certvalidator.fetchers.requests_fetchers.RequestsFetcherBackend object>)
- ts_cert_validation_policy: CertValidationPolicySpec | None = None
- ac_validation_policy: CertValidationPolicySpec | None = None
- local_knowledge: LocalKnowledge = LocalKnowledge(known_ocsps=[], known_crls=[], known_certs=[], known_poes=[], nonrevoked_assertions=[])
- key_usage_settings: KeyUsageConstraints = KeyUsageConstraints(key_usage=None, key_usage_forbidden=None, extd_key_usage=None, explicit_extd_key_usage_required=True, match_all_key_usages=False)
- signature_algorithm_policy: CMSAlgorithmUsagePolicy | None = None
- class pyhanko.sign.validation.policy_decl.PdfSignatureValidationSpec(signature_validation_spec: pyhanko.sign.validation.policy_decl.SignatureValidationSpec, diff_policy: Optional[pyhanko.sign.diff_analysis.policy_api.DiffPolicy] = <pyhanko.sign.diff_analysis.policies.StandardDiffPolicy object at 0x7fcd76b9f2d0>)
Bases:
object
- signature_validation_spec: SignatureValidationSpec
- diff_policy: DiffPolicy | None = <pyhanko.sign.diff_analysis.policies.StandardDiffPolicy object>
- class pyhanko.sign.validation.policy_decl.RevinfoOnlineFetchingRule(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
- ALWAYS_FETCH = 1
Always permit fetching revocation information from online sources.
- NO_HISTORICAL_FETCH = 2
Only attempt to fetch revocation information when performing validation of a signature at the current time, and use the local cache in past validation evaluation.
- LOCAL_ONLY = 3
Only use locally cached revocation information.
- class pyhanko.sign.validation.policy_decl.LocalKnowledge(known_ocsps: List[pyhanko_certvalidator.revinfo.archival.OCSPContainer] = <factory>, known_crls: List[pyhanko_certvalidator.revinfo.archival.CRLContainer] = <factory>, known_certs: List[asn1crypto.x509.Certificate] = <factory>, known_poes: List[pyhanko_certvalidator.ltv.poe.KnownPOE] = <factory>, nonrevoked_assertions: List[pyhanko_certvalidator.policy_decl.NonRevokedStatusAssertion] = <factory>)
Bases:
object
- known_ocsps: List[OCSPContainer]
- known_crls: List[CRLContainer]
- known_certs: List[Certificate]
- nonrevoked_assertions: List[NonRevokedStatusAssertion]
- add_to_poe_manager(poe_manager: POEManager)
- class pyhanko.sign.validation.policy_decl.RevocationInfoGatheringSpec(online_fetching_rule: pyhanko.sign.validation.policy_decl.RevinfoOnlineFetchingRule = <RevinfoOnlineFetchingRule.NO_HISTORICAL_FETCH: 2>, fetcher_backend: pyhanko_certvalidator.fetchers.api.FetcherBackend = <factory>)
Bases:
object
- online_fetching_rule: RevinfoOnlineFetchingRule = 2
- fetcher_backend: FetcherBackend
- class pyhanko.sign.validation.policy_decl.CMSAlgorithmUsagePolicy
Bases:
AlgorithmUsagePolicy
,ABC
Algorithm usage policy for CMS signatures.
- digest_combination_allowed(signature_algo: SignedDigestAlgorithm, message_digest_algo: DigestAlgorithm, moment: datetime | None) AlgorithmUsageConstraint
Verify whether a digest algorithm is compatible with the digest algorithm implied by the provided signature algorithm, if any.
By default, this enforces the convention (requirement in RFC 8933) that the message digest must be computed using the same digest algorithm as the one used by the signature, if applicable.
Checking whether the individual algorithms are allowed is not the responsibility of this method.
- Parameters:
signature_algo – A signature mechanism to use
message_digest_algo – The digest algorithm used for the message digest
moment – The point in time for which the assessment needs to be made.
- Returns:
A usage constraint.
- static lift_policy(policy: AlgorithmUsagePolicy) CMSAlgorithmUsagePolicy
Lift a ‘base’
AlgorithmUsagePolicy
to a CMS usage algorithm policy with default settings. If the policy passed in is already aCMSAlgorithmUsagePolicy
, return it as-is.- Parameters:
policy – The underlying original policy
- Returns:
The lifted policy
- pyhanko.sign.validation.policy_decl.bootstrap_validation_data_handlers(spec: SignatureValidationSpec, timing_info: ValidationTimingInfo | None = None, is_historical: bool | None = None, poe_manager_override: POEManager | None = None) ValidationDataHandlers
pyhanko.sign.validation.settings module
- class pyhanko.sign.validation.settings.KeyUsageConstraints(key_usage: Set[str] | None = None, key_usage_forbidden: Set[str] | None = None, extd_key_usage: Set[str] | None = None, explicit_extd_key_usage_required: bool = True, match_all_key_usages: bool = False)
Bases:
ConfigurableMixin
Convenience class to pass around key usage requirements and validate them. Intended to be flexible enough to handle both PKIX and ISO 32000 certificate seed value constraint semantics.
Changed in version 0.6.0: Bring extended key usage semantics in line with RFC 5280 (PKIX).
- key_usage: Set[str] | None = None
All or some (depending on
match_all_key_usage
) of these key usage extensions must be present in the signer’s certificate. If not set or empty, all key usages are considered acceptable.
- key_usage_forbidden: Set[str] | None = None
These key usages must not be present in the signer’s certificate.
Note
This behaviour is undefined in RFC 5280 (PKIX), but included for compatibility with certificate seed value settings in ISO 32000.
- extd_key_usage: Set[str] | None = None
List of acceptable key purposes that can appear in an extended key usage extension in the signer’s certificate, if such an extension is at all present. If not set, all extended key usages are considered acceptable.
If no extended key usage extension is present, or if the
anyExtendedKeyUsage
key purpose ID is present, the resulting behaviour depends onexplicit_extd_key_usage_required
.Setting this option to the empty set (as opposed to
None
) effectively bans all (presumably unrecognised) extended key usages.Warning
Note the difference in behaviour with
key_usage
for empty sets of valid usages.Warning
Contrary to what some CAs seem to believe, the criticality of the extended key usage extension is irrelevant here. Even a non-critical EKU extension must be enforced according to RFC 5280 § 4.2.1.12.
In practice, many certificate authorities issue non-repudiation certs that can also be used for TLS authentication by only including the TLS client authentication key purpose ID in the EKU extension. Interpreted strictly, RFC 5280 bans such certificates from being used to sign documents, and pyHanko will enforce these semantics if
extd_key_usage
is notNone
.
- explicit_extd_key_usage_required: bool = True
Added in version 0.6.0.
Require an extended key usage extension with the right key usages to be present if
extd_key_usage
is non-empty.If this flag is
True
, at least one key purpose inextd_key_usage
must appear in the certificate’s extended key usage, andanyExtendedKeyUsage
will be ignored.
- match_all_key_usages: bool = False
Added in version 0.6.0.
If
True
, all key usages indicated inkey_usage
must be present in the certificate. IfFalse
, one match suffices.If
key_usage
is empty orNone
, this option has no effect.
- validate(cert: Certificate)
- classmethod process_entries(config_dict)
Hook method that can modify the configuration dictionary to overwrite or tweak some of their values (e.g. to convert string parameters into more complex Python objects)
Subclasses that override this method should call
super().process_entries()
, and leave keys that they do not recognise untouched.- Parameters:
config_dict – A dictionary containing configuration values.
- Raises:
ConfigurationError – when there is a problem processing a relevant entry.
pyhanko.sign.validation.status module
- class pyhanko.sign.validation.status.SignatureStatus(intact: bool, valid: bool, trust_problem_indic: AdESSubIndic | None, signing_cert: Certificate, pkcs7_signature_mechanism: str, md_algorithm: str, validation_path: ValidationPath | None, revocation_details: RevocationDetails | None, error_time_horizon: datetime | None, validation_time: datetime | None)
Bases:
object
Class describing the validity of a (general) CMS signature.
- intact: bool
Reports whether the signature is intact, i.e. whether the hash of the message content (which may or may not be embedded inside the CMS object itself) matches the hash value that was signed.
If there are no signed attributes, this is equal to
valid
.
- valid: bool
Reports whether the signature is valid, i.e. whether the signature in the CMS object itself (usually computed over a hash of the signed attributes) is cryptographically valid.
- trust_problem_indic: AdESSubIndic | None
If not
None
, provides the AdES subindication indication what went wrong when validating the signer’s certificate.
- signing_cert: Certificate
Contains the certificate of the signer, as embedded in the CMS object.
- pkcs7_signature_mechanism: str
CMS signature mechanism used.
- md_algorithm: str
Message digest algorithm used.
- validation_path: ValidationPath | None
Validation path providing a valid chain of trust from the signer’s certificate to a trusted root certificate.
- revocation_details: RevocationDetails | None
Details on why and when the signer’s certificate (or another certificate in the chain) was revoked.
- error_time_horizon: datetime | None
Informational timestamp indicating a point in time where the validation behaviour potentially changed (e.g. expiration, revocation, etc.).
The presence of this value by itself should not be taken as an assertion that validation would have succeeded if executed before that point in time.
- key_usage: ClassVar[Set[str]] = {'non_repudiation'}
Class property indicating which key usages are accepted on the signer’s certificate. The default is
non_repudiation
only.
- extd_key_usage: ClassVar[Set[str] | None] = None
Class property indicating which extended key usage key purposes are accepted to be present on the signer’s certificate.
- validation_time: datetime | None
Reference time for validation purposes.
- summary_fields()
- property revoked: bool
Reports whether the signer’s certificate has been revoked or not. If this field is
True
, then obviouslytrusted
will beFalse
.
- property trusted: bool
Reports whether the signer’s certificate is trusted w.r.t. the currently relevant validation context and key usage requirements.
- summary(delimiter=',') str
Provide a textual but machine-parsable summary of the validity.
- classmethod default_usage_constraints(key_usage_settings: KeyUsageConstraints | None = None) KeyUsageConstraints
- class pyhanko.sign.validation.status.TimestampSignatureStatus(intact: bool, valid: bool, trust_problem_indic: AdESSubIndic | None, signing_cert: Certificate, pkcs7_signature_mechanism: str, md_algorithm: str, validation_path: ValidationPath | None, revocation_details: RevocationDetails | None, error_time_horizon: datetime | None, validation_time: datetime | None, timestamp: datetime)
Bases:
SignatureStatus
Signature status class used when validating timestamp tokens.
- key_usage: ClassVar[Set[str]] = {}
There are no (non-extended) key usage requirements for TSA certificates.
- extd_key_usage: ClassVar[Set[str] | None] = {'time_stamping'}
TSA certificates must have the
time_stamping
extended key usage extension (OID 1.3.6.1.5.5.7.3.8).
- timestamp: datetime
Value of the timestamp token as a datetime object.
- describe_timestamp_trust()
- class pyhanko.sign.validation.status.X509AttributeInfo(attr_type: AttCertAttributeType, attr_values: Iterable[Asn1Value])
Bases:
object
Info on an X.509 attribute.
- attr_type: AttCertAttributeType
The certified attribute’s type.
- attr_values: Iterable[Asn1Value]
The certified attribute’s values.
- class pyhanko.sign.validation.status.CertifiedAttributeInfo(attr_type: AttCertAttributeType, attr_values: Iterable[Asn1Value], validation_results: Iterable[ACValidationResult])
Bases:
X509AttributeInfo
Info on a certified attribute, including AC validation results.
- validation_results: Iterable[ACValidationResult]
The validation details for the attribute in question (possibly several if values for the same attribute were sourced from several different ACs).
- class pyhanko.sign.validation.status.ClaimedAttributes
Bases:
object
Container class for extracted information on attributes asserted by a signer without an attribute certificate.
- classmethod from_iterable(attrs: Iterable[AttCertAttribute], parse_error_fatal=False)
- class pyhanko.sign.validation.status.CertifiedAttributes
Bases:
object
Container class for extracted attribute certificate information.
- classmethod from_results(results: Iterable[ACValidationResult], parse_error_fatal=False)
- class pyhanko.sign.validation.status.CAdESSignerAttributeAssertions(claimed_attrs: ClaimedAttributes, certified_attrs: CertifiedAttributes | None = None, ac_validation_errs: Collection[ValidationError | PathBuildingError] | None = None, unknown_attrs_present: bool = False)
Bases:
object
Value type describing information extracted (and, if relevant, validated) from a
signer-attrs-v2
signed attribute.- claimed_attrs: ClaimedAttributes
Attributes claimed by the signer without additional justification. May be empty.
- certified_attrs: CertifiedAttributes | None = None
Attributes claimed by the signer using an attribute certificate.
This field will only be populated if an attribute certificate validation context is available, otherwise its value will be
None
, even if there are no attribute certificates present.
- ac_validation_errs: Collection[ValidationError | PathBuildingError] | None = None
Attribute certificate validation errors.
This field will only be populated if an attribute certificate validation context is available, otherwise its value will be
None
, even if there are no attribute certificates present.
- unknown_attrs_present: bool = False
Records if the
signer-attrs-v2
attribute contained certificate types or signed assertions that could not be processed.This does not affect the validation process by default, but will trigger a warning.
- property valid
- class pyhanko.sign.validation.status.StandardCMSSignatureStatus(intact: bool, valid: bool, trust_problem_indic: AdESSubIndic | None, signing_cert: Certificate, pkcs7_signature_mechanism: str, md_algorithm: str, validation_path: ValidationPath | None, revocation_details: RevocationDetails | None, error_time_horizon: datetime | None, validation_time: datetime | None, ac_attrs: CertifiedAttributes | None = None, ac_validation_errs: Collection[PathValidationError | PathBuildingError] | None = None, cades_signer_attrs: CAdESSignerAttributeAssertions | None = None, signer_reported_dt: datetime | None = None, timestamp_validity: TimestampSignatureStatus | None = None, content_timestamp_validity: TimestampSignatureStatus | None = None)
Bases:
SignerAttributeStatus
,SignatureStatus
Status of a standard “end-entity” CMS signature, potentially with timing information embedded inside.
- signer_reported_dt: datetime | None = None
Signer-reported signing time, if present in the signature.
Generally speaking, this timestamp should not be taken as fact.
- timestamp_validity: TimestampSignatureStatus | None = None
Validation status of the signature timestamp token embedded in this signature, if present.
- content_timestamp_validity: TimestampSignatureStatus | None = None
Validation status of the content timestamp token embedded in this signature, if present.
- property bottom_line: bool
Formulates a general judgment on the validity of this signature. This takes into account the cryptographic validity of the signature, the signature’s chain of trust and the validity of the timestamp token (if present).
- Returns:
True
if all constraints are satisfied,False
otherwise.
- summary_fields()
- pretty_print_details()
- pretty_print_sections() List[Tuple[str, str]]
- class pyhanko.sign.validation.status.SignatureCoverageLevel(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
OrderedEnum
Indicate the extent to which a PDF signature (cryptographically) covers a document. Note that this does not pass judgment on whether uncovered updates are legitimate or not, but as a general rule, a legitimate signature will satisfy at least
ENTIRE_REVISION
.- UNCLEAR = 0
The signature’s coverage is unclear and/or disconnected. In standard PDF signatures, this is usually a bad sign.
- CONTIGUOUS_BLOCK_FROM_START = 1
The signature covers a contiguous block in the PDF file stretching from the first byte of the file to the last byte in the indicated
/ByteRange
. In other words, the only interruption in the byte range is fully occupied by the signature data itself.
- ENTIRE_REVISION = 2
The signature covers the entire revision in which it occurs, but incremental updates may have been added later. This is not necessarily evidence of tampering. In particular, it is expected when a file contains multiple signatures. Nonetheless, caution is required.
- ENTIRE_FILE = 3
The entire file is covered by the signature.
- class pyhanko.sign.validation.status.ModificationInfo(coverage: pyhanko.sign.validation.status.SignatureCoverageLevel | None = None, diff_result: pyhanko.sign.diff_analysis.policy_api.DiffResult | pyhanko.sign.diff_analysis.policy_api.SuspiciousModification | NoneType = None, docmdp_ok: bool | None = None)
Bases:
object
- coverage: SignatureCoverageLevel | None = None
Indicates how much of the document is covered by the signature.
- diff_result: DiffResult | SuspiciousModification | None = None
Result of the difference analysis run on the file:
If
None
, no difference analysis was run.If the difference analysis was successful, this attribute will contain a
DiffResult
object.If the difference analysis failed due to unforeseen or suspicious modifications, the
SuspiciousModification
exception thrown by the difference policy will be stored in this attribute.
- docmdp_ok: bool | None = None
Indicates whether the signature’s
modification_level
is in line with the document signature policy in force.If
None
, compliance could not be determined.
- property modification_level: ModificationLevel | None
Indicates the degree to which the document was modified after the signature was applied.
Will be
None
if difference analysis results are not available; an instance ofModificationLevel
otherwise.
- class pyhanko.sign.validation.status.PdfSignatureStatus(intact: bool, valid: bool, trust_problem_indic: AdESSubIndic | None, signing_cert: Certificate, pkcs7_signature_mechanism: str, md_algorithm: str, validation_path: ValidationPath | None, revocation_details: RevocationDetails | None, error_time_horizon: datetime | None, validation_time: datetime | None, ac_attrs: CertifiedAttributes | None = None, ac_validation_errs: Collection[PathValidationError | PathBuildingError] | None = None, cades_signer_attrs: CAdESSignerAttributeAssertions | None = None, signer_reported_dt: datetime | None = None, timestamp_validity: TimestampSignatureStatus | None = None, content_timestamp_validity: TimestampSignatureStatus | None = None, coverage: SignatureCoverageLevel | None = None, diff_result: DiffResult | SuspiciousModification | None = None, docmdp_ok: bool | None = None, has_seed_values: bool = False, seed_value_constraint_error: SigSeedValueValidationError | None = None)
Bases:
ModificationInfo
,StandardCMSSignatureStatus
Class to indicate the validation status of a PDF signature.
- has_seed_values: bool = False
Records whether the signature form field has seed values.
- seed_value_constraint_error: SigSeedValueValidationError | None = None
Records the reason for failure if the signature field’s seed value constraints didn’t validate.
- property bottom_line: bool
Formulates a general judgment on the validity of this signature. This takes into account the cryptographic validity of the signature, the signature’s chain of trust, compliance with the document modification policy, seed value constraint compliance and the validity of the timestamp token (if present).
- Returns:
True
if all constraints are satisfied,False
otherwise.
- property seed_value_ok: bool
Indicates whether the signature satisfies all mandatory constraints in the seed value dictionary of the associated form field.
Warning
Currently, not all seed value entries are recognised by the signer and/or the validator, so this judgment may not be entirely accurate in some cases.
See
SigSeedValueSpec
.
- summary_fields()
- pretty_print_sections()
- class pyhanko.sign.validation.status.DocumentTimestampStatus(intact: bool, valid: bool, trust_problem_indic: AdESSubIndic | None, signing_cert: Certificate, pkcs7_signature_mechanism: str, md_algorithm: str, validation_path: ValidationPath | None, revocation_details: RevocationDetails | None, error_time_horizon: datetime | None, validation_time: datetime | None, timestamp: datetime, coverage: SignatureCoverageLevel | None = None, diff_result: DiffResult | SuspiciousModification | None = None, docmdp_ok: bool | None = None)
Bases:
ModificationInfo
,TimestampSignatureStatus
Class to indicate the validation status of a PDF document timestamp.
- class pyhanko.sign.validation.status.RevocationDetails(ca_revoked: bool, revocation_date: datetime, revocation_reason: CRLReason)
Bases:
object
Contains details about a certificate revocation related to a signature.
- ca_revoked: bool
If
False
, the revoked certificate is the signer’s. IfTrue
, there’s a revoked CA certificate higher up the chain.
- revocation_date: datetime
The date and time of revocation.
- revocation_reason: CRLReason
The reason why the certificate was revoked.
- class pyhanko.sign.validation.status.SignerAttributeStatus(ac_attrs: pyhanko.sign.validation.status.CertifiedAttributes | None = None, ac_validation_errs: Collection[pyhanko_certvalidator.errors.PathValidationError | pyhanko_certvalidator.errors.PathBuildingError] | None = None, cades_signer_attrs: pyhanko.sign.validation.status.CAdESSignerAttributeAssertions | None = None)
Bases:
object
- ac_attrs: CertifiedAttributes | None = None
Certified attributes sourced from valid attribute certificates embedded into the
SignedData
’scertificates
field and the CAdES-stylesigner-attrs-v2
attribute (if present).Will be
None
if no validation context for attribute certificate validation was provided.Note
There is a semantic difference between attribute certificates extracted from the
certificates
field and those extracted from thesigner-attrs-v2
attribute. In the former case, the ACs are not covered by the signature. However, a CAdES-stylesigner-attrs-v2
attribute is signed, so the signer is expected to have explicitly _acknowledged_ all attributes, in the AC. See alsocades_signer_attrs
.
- ac_validation_errs: Collection[PathValidationError | PathBuildingError] | None = None
Errors encountered while validating attribute certificates embedded into the
SignedData
’scertificates
field and the CAdES-stylesigner-attrs-v2
attribute (if present).Will be
None
if no validation context for attribute certificate validation was provided.
- cades_signer_attrs: CAdESSignerAttributeAssertions | None = None
Information extracted and validated from the signed
signer-attrs-v2
attribute defined in CAdES.
pyhanko.sign.validation.utils module
- class pyhanko.sign.validation.utils.CMSAlgorithmUsagePolicy
Bases:
AlgorithmUsagePolicy
,ABC
Algorithm usage policy for CMS signatures.
- digest_combination_allowed(signature_algo: SignedDigestAlgorithm, message_digest_algo: DigestAlgorithm, moment: datetime | None) AlgorithmUsageConstraint
Verify whether a digest algorithm is compatible with the digest algorithm implied by the provided signature algorithm, if any.
By default, this enforces the convention (requirement in RFC 8933) that the message digest must be computed using the same digest algorithm as the one used by the signature, if applicable.
Checking whether the individual algorithms are allowed is not the responsibility of this method.
- Parameters:
signature_algo – A signature mechanism to use
message_digest_algo – The digest algorithm used for the message digest
moment – The point in time for which the assessment needs to be made.
- Returns:
A usage constraint.
- static lift_policy(policy: AlgorithmUsagePolicy) CMSAlgorithmUsagePolicy
Lift a ‘base’
AlgorithmUsagePolicy
to a CMS usage algorithm policy with default settings. If the policy passed in is already aCMSAlgorithmUsagePolicy
, return it as-is.- Parameters:
policy – The underlying original policy
- Returns:
The lifted policy
- pyhanko.sign.validation.utils.validate_raw(signature: bytes, signed_data: bytes, cert: ~asn1crypto.x509.Certificate, signature_algorithm: ~asn1crypto.algos.SignedDigestAlgorithm, md_algorithm: str, prehashed=False, algorithm_policy: ~pyhanko.sign.validation.utils.CMSAlgorithmUsagePolicy | None = <pyhanko.sign.validation.utils._DefaultPolicyMixin object>, time_indic: ~datetime.datetime | None = None)
Validate a raw signature. Internal API.
- pyhanko.sign.validation.utils.extract_message_digest(signer_info: SignerInfo)
Module contents
- pyhanko.sign.validation.validate_pdf_signature(embedded_sig: EmbeddedPdfSignature, signer_validation_context: ValidationContext | None = None, ts_validation_context: ValidationContext | None = None, diff_policy: DiffPolicy | None = None, key_usage_settings: KeyUsageConstraints | None = None, skip_diff: bool = False) PdfSignatureStatus
Changed in version 0.9.0: Wrapper around
async_validate_pdf_signature()
.Validate a PDF signature.
- Parameters:
embedded_sig – Embedded signature to evaluate.
signer_validation_context – Validation context to use to validate the signature’s chain of trust.
ts_validation_context – Validation context to use to validate the timestamp’s chain of trust (defaults to
signer_validation_context
).diff_policy – Policy to evaluate potential incremental updates that were appended to the signed revision of the document. Defaults to
DEFAULT_DIFF_POLICY
.key_usage_settings – A
KeyUsageConstraints
object specifying which key usages must or must not be present in the signer’s certificate.skip_diff – If
True
, skip the difference analysis step entirely.
- Returns:
The status of the PDF signature in question.
- pyhanko.sign.validation.validate_cms_signature(signed_data: ~asn1crypto.cms.SignedData, status_cls=<class 'pyhanko.sign.validation.status.SignatureStatus'>, raw_digest: bytes | None = None, validation_context: ~pyhanko_certvalidator.context.ValidationContext | None = None, status_kwargs: dict | None = None, key_usage_settings: ~pyhanko.sign.validation.settings.KeyUsageConstraints | None = None, encap_data_invalid=False)
Deprecated since version 0.9.0: Use
async_validate_cms_signature()
instead.Changed in version 0.7.0: Now handles both detached and enveloping signatures.
Changed in version 0.17.0: The
encap_data_invalid
parameter is ignored.Validate a CMS signature (i.e. a
SignedData
object).- Parameters:
signed_data – The
asn1crypto.cms.SignedData
object to validate.status_cls – Status class to use for the validation result.
raw_digest – Raw digest, computed from context.
validation_context – Validation context to validate the signer’s certificate.
status_kwargs – Other keyword arguments to pass to the
status_class
when reporting validation results.key_usage_settings – A
KeyUsageConstraints
object specifying which key usages must or must not be present in the signer’s certificate.encap_data_invalid – As of version
0.17.0
, this parameter is ignored.
- Returns:
A
SignatureStatus
object (or an instance of a proper subclass)
- pyhanko.sign.validation.validate_detached_cms(input_data: bytes | IO | ContentInfo | EncapsulatedContentInfo, signed_data: SignedData, signer_validation_context: ValidationContext | None = None, ts_validation_context: ValidationContext | None = None, key_usage_settings: KeyUsageConstraints | None = None, chunk_size=4096, max_read=None) StandardCMSSignatureStatus
Deprecated since version 0.9.0: Use
generic_cms.async_validate_detached_cms()
instead.Validate a detached CMS signature.
- Parameters:
input_data –
The input data to sign. This can be either a
bytes
object, a file-like object or acms.ContentInfo
/cms.EncapsulatedContentInfo
object.If a CMS content info object is passed in, the content field will be extracted.
signed_data – The
cms.SignedData
object containing the signature to verify.signer_validation_context – Validation context to use to verify the signer certificate’s trust.
ts_validation_context – Validation context to use to verify the TSA certificate’s trust, if a timestamp token is present. By default, the same validation context as that of the signer is used.
key_usage_settings – Key usage parameters for the signer.
chunk_size – Chunk size to use when consuming input data.
max_read – Maximal number of bytes to read from the input stream.
- Returns:
A description of the signature’s status.
- pyhanko.sign.validation.validate_pdf_timestamp(embedded_sig: EmbeddedPdfSignature, validation_context: ValidationContext | None = None, diff_policy: DiffPolicy | None = None, skip_diff: bool = False) DocumentTimestampStatus
Changed in version 0.9.0: Wrapper around
async_validate_pdf_timestamp()
.Validate a PDF document timestamp.
- Parameters:
embedded_sig – Embedded signature to evaluate.
validation_context – Validation context to use to validate the timestamp’s chain of trust.
diff_policy – Policy to evaluate potential incremental updates that were appended to the signed revision of the document. Defaults to
DEFAULT_DIFF_POLICY
.skip_diff – If
True
, skip the difference analysis step entirely.
- Returns:
The status of the PDF timestamp in question.
- pyhanko.sign.validation.validate_pdf_ltv_signature(embedded_sig: EmbeddedPdfSignature, validation_type: RevocationInfoValidationType, validation_context_kwargs=None, bootstrap_validation_context=None, force_revinfo=False, diff_policy: DiffPolicy | None = None, key_usage_settings: KeyUsageConstraints | None = None, skip_diff: bool = False) PdfSignatureStatus
Changed in version 0.9.0: Wrapper around
async_validate_pdf_ltv_signature()
.Validate a PDF LTV signature according to a particular profile.
- Parameters:
embedded_sig – Embedded signature to evaluate.
validation_type – Validation profile to use.
validation_context_kwargs – Keyword args to instantiate
pyhanko_certvalidator.ValidationContext
objects needed over the course of the validation.bootstrap_validation_context – Validation context used to validate the current timestamp.
force_revinfo – Require all certificates encountered to have some form of live revocation checking provisions.
diff_policy – Policy to evaluate potential incremental updates that were appended to the signed revision of the document. Defaults to
DEFAULT_DIFF_POLICY
.key_usage_settings – A
KeyUsageConstraints
object specifying which key usages must or must not be present in the signer’s certificate.skip_diff – If
True
, skip the difference analysis step entirely.
- Returns:
The status of the signature.
- pyhanko.sign.validation.add_validation_info(embedded_sig: EmbeddedPdfSignature, validation_context: ValidationContext, skip_timestamp=False, add_vri_entry=True, in_place=False, output=None, force_write=False, chunk_size=4096)
Changed in version 0.9.0: Wrapper around
async_add_validation_info()
Add validation info (CRLs, OCSP responses, extra certificates) for a signature to the DSS of a document in an incremental update.
- Parameters:
embedded_sig – The signature for which the revocation information needs to be collected.
validation_context – The validation context to use.
skip_timestamp – If
True
, do not attempt to validate the timestamp attached to the signature, if one is present.add_vri_entry – Add a
/VRI
entry for this signature to the document security store. Default isTrue
.output – Write the output to the specified output stream. If
None
, write to a newBytesIO
object. Default isNone
.in_place – Sign the original input stream in-place. This parameter overrides
output
.chunk_size – Chunk size parameter to use when copying output to a new stream (irrelevant if
in_place
isTrue
).force_write – Force a new revision to be written, even if not necessary (i.e. when all data in the validation context is already present in the DSS).
- Returns:
The (file-like) output object to which the result was written.