Authenticode
The Authenticode support of Signify allows you to easily verify a PE or MSI File’s Authenticode signature:
with open("file.exe", "rb") as f:
signed_file = AuthenticodeFile.detect(f)
signed_file.verify()
This method will raise an error if it is invalid. A simpler API is also available, allowing you to interpret the error if one happens:
with open("file.exe", "rb") as f:
signed_file = AuthenticodeFile.detect(f)
status, err = signed_file.explain_verify()
if status != AuthenticodeVerificationResult.OK:
print(f"Invalid: {err}")
If you need to get more information about the signature, you can use this:
with open("file.exe", "rb") as f:
pefile = SignedPEFile(f)
for signed_data in pefile.signed_datas:
print(signed_data.signer_info.program_name)
if signed_data.signer_info.countersigner is not None:
print(signed_data.signer_info.countersigner.signing_time)
A more thorough example is available in the examples directory of the Signify repository.
Note that the file must remain open as long as not all SignedData objects have been parsed or verified.
Authenticode overview
Most of the specification of Authenticode is properly documented in a 2008 paper Windows Authenticode Portable Executable Signature Format and still available to download. The specification mostly follows the PKCS#7: SignedData and SignerInfo specification, although most structures have since been updated in more recent RFCs. Of particular note is that the specification defines various “must” and “must not” phrases, which has not been adhered to in more recent uses.
At its core, it defines how the certificate table of a PE file (a normal Windows executable) contains PKCS#7 SignedData objects. Note that the specification allows for multiple of such objects, perhaps including other signers or signatures.
Authenticode SignedData objects contain SpcIndirectDataContent contents
(microsoft_spc_indirect_data_content, OID 1.3.6.1.4.1.311.2.1.4), which
(amongst others) define the hash of the PE file. The
PE file is hashed particularly, as we need to skip the PE file checksum, the
pointer to the certificate table in the data directory, and the certificate table
itself.
The signature is valid, in principle, if the hash we calculate is the same as in
SpcIndirectDataContent, and the SignerInfo contains a hash over this content.
See also
There are various other projects that also deal with Authenticode, which also provide useful insights. These include:
Other useful references include:
Additional gotcha’s
There are a few additional gotcha’s when verifying Authenticode signatures, which are not very well defined in the original specification, but we have been able to reverse-engineer or otherwise use to our advantage.
RFC3161 countersignatures
There are two types of countersignature: a regular countersignature, as used in PKCS#7,
or a nested Time-Stamp Protocol response (RFC3161). This response, available as
unauthenticated attribute with microsoft_time_stamp_token (OID 1.3.6.1.4.1.311.3.3.1),
is added as nested authenticode.pkcs7.SignedData object.
This is transparently handled by the AuthenticodeSignedData.countersigner
attribute, but note that this attribute can return two different types.
Nested signatures
Instead of adding multiple signatures to the certificate table, SignedData objects can also be nested in others as unauthenticated attributes with microsoft_nested_signature (OID 1.3.6.1.4.1.311.2.4.1).
This is transparently handled by the SignedPEFile class.
Page hashes
The SpcIndirectDataContent class may contain a binary structure that defines
hashes for portions of the file (in the SpcLink.moniker field). If this is the case,
the moniker will use class ID a6b586d5-b4a1-2466-ae05-a217da8e60d6, and its
serialized data will contain another SpcAttributeTypeAndOptionalValue with OIDs
microsoft_spc_pe_image_page_hashes_v1 (1.3.6.1.4.1.311.2.3.1) for SHA-1 or
microsoft_spc_pe_image_page_hashes_v2 (1.3.6.1.4.1.311.2.3.2) for SHA-256.
The value will be a binary structure that describes offsets (4 bytes integer) and hash digest (digest length of the algorithm) of parts of the binary. These offsets appear to be relative to the entire file, and the final offset is always at the end of the file (describing the end of the previous hash), and the final hash is ignored:
0000000 08d88d96cb3fddf7a7c73598e95388ce60432c2c5ff17b8c558ce599645db73e
0001024 5ebe1d0255524e4291105759b80abad8294e269e3e11fce76ed6b2e005a79df0
0005120 255d7a5768ac44963184e0b5281d64fd9282f953211d03fd49a3d8190044dc35
...
1436160 35c36ac4c657e82cc3aa1311373c1b17552780f64e000a2c31742125365145cd
1438720 0000000000000000000000000000000000000000000000000000000000000000
Each hash is then calculated between the two defined offsets, using the same omissions as for normal Authenticode validation. The hashes are filled with NULL bytes when the hash would be shorter than the page size (typically 4096), ignoring omissions.
In the example above, for the first hash, we would calculate the hash over the first 1024 bytes of the PE file, skipping the checksum and table locations located in the PE header file, and then add 3072 NULL bytes to complete a full PE page. Note that the actual digest is calculated over less than 4096 bytes due to the omissions.
Additional attributes, extensions
Some attributes are present on SignerInfo objects that have additional meanings:
- microsoft_spc_sp_opus_info (1.3.6.1.4.1.311.2.1.12)
Contains the program name and URL
- microsoft_spc_statement_type (1.3.6.1.4.1.311.2.1.11)
Defines that the key purpose is individual (1.3.6.1.4.1.311.2.1.21) or commercial (1.3.6.1.4.1.311.2.1.22), but unused in practice.
- microsoft_spc_relaxed_pe_marker_check (1.3.6.1.4.1.311.2.6.1)
Purpose unknown
- microsoft_platform_manifest_binary_id (1.3.6.1.4.1.311.10.3.28)
Purpose unknown
For certificates, these extensions are known:
- microsoft_spc_sp_agency_info (1.3.6.1.4.1.311.2.1.10)
Purpose unknown
- microsoft_spc_financial_criteria (1.3.6.1.4.1.311.2.1.27)
Purpose unknown
The following key purpose is relevant for Authenticode:
- microsoft_lifetime_signing (1.3.6.1.4.1.311.10.3.13)
The certificate is only valid for it’s lifetime, and cannot be extend with a counter signature.
All these attributes and extensions are defined in the ASN.1 spec of this library, but not all of them are used.
Future work:
1.3.6.1.4.1.311.2.5.1 (enhanced_hash)
Authenticode-signed File Objects
To support both PE and MSI files, a generic interface exists. When you call
AuthenticodeFile.detect(), either a SignedPeFile or
SignedMsiFile will be returned, both implementing the same interface. This
generic interface allows access to zero or more AuthenticodeSignedData objects,
and allows validation of the signature.
- class signify.authenticode.AuthenticodeFile
An Authenticode-signed file that is to be parsed to find the relevant sections for Authenticode parsing.
- classmethod detect(file_obj: BinaryIO) AuthenticodeFile
This initializer will return either
SignedMsiFileorSignedPEFile, and otherwise throw an error.
- explain_verify(*args: Any, **kwargs: Any) tuple[AuthenticodeVerificationResult, Exception | None]
This will return a value indicating the signature status of this PE file. This will not raise an error when the verification fails, but rather indicate this through the resulting enum
- Return type:
(signify.authenticode.AuthenticodeVerificationResult, Exception)
- Returns:
The verification result, and the exception containing more details (if available or None)
- get_fingerprint(digest_algorithm: HashFunction) bytes
Gets the fingerprint for this file
- iter_signed_datas(*, include_nested: bool = True, ignore_parse_errors: bool = True) Iterator[AuthenticodeSignedData]
Returns an iterator over
AuthenticodeSignedDataobjects relevant for this Authenticode-signed file.- Parameters:
include_nested – Boolean, if True, will also iterate over all nested SignedData structures
ignore_parse_errors –
Indicates how to handle
ParseErrorthat may be raised while fetching embeddedAuthenticodeSignedDatastructures.When
True, which is the default and seems to be how Windows handles this as well, this will fetch as many validAuthenticodeSignedDatastructures until an exception occurs.Note that this will also silence the
ParseErrorthat occurs when there’s no validAuthenticodeSignedDatato fetch.When
False, this will raise theParseErroras soon as one occurs.
- Raises:
ParseError – For parse errors in the signed file
signify.authenticode.AuthenticodeParseError – For parse errors in the SignedData
- Returns:
iterator of signify.authenticode.SignedData
- property signed_datas: Iterator[AuthenticodeSignedData]
Returns an iterator over
AuthenticodeSignedDataobjects relevant for this file. Seeiter_signed_datas()
- verify(*, multi_verify_mode: Literal['any', 'first', 'all', 'best'] = 'any', expected_hashes: dict[str, bytes] | None = None, ignore_parse_errors: bool = True, **kwargs: Any) list[tuple[AuthenticodeSignedData, Iterable[list[Certificate]]]]
Verifies the SignedData structures. This is a little bit more efficient than calling all verify-methods separately.
- Parameters:
expected_hashes – When provided, should be a mapping of hash names to digests. This could speed up the verification process.
multi_verify_mode –
Indicates how to verify when there are multiple
AuthenticodeSignedDataobjects in this file. Can be:’any’ (default) to indicate that any of the signatures must validate correctly.
’first’ to indicate that the first signature must verify correctly (the default of tools such as sigcheck.exe)
’all’ to indicate that all signatures must verify
’best’ to indicate that the signature using the best hashing algorithm must verify (e.g. if both SHA-1 and SHA-256 are present, only SHA-256 is checked); if multiple signatures exist with the same algorithm, any may verify
This argument has no effect when only one signature is present.
ignore_parse_errors –
Indicates how to handle
ParseErrorthat may be raised during parsing of the signed file’s certificate table.When
True, which is the default and seems to be how Windows handles this as well, this will verify based on all availableAuthenticodeSignedDatabefore a parse error occurs.AuthenticodeNotSignedErrorwill be raised when no validAuthenticodeSignedDataexists.When
False, this will raise theParseErroras soon as one occurs. This often occurs beforeAuthenticodeNotSignedErroris potentially raised.
- Returns:
the used structure(s) in validation, as a list of tuples, in the form (signed data object, certificate chain)
- Raises:
AuthenticodeVerificationError – when the verification failed
ParseError – for parse errors in the signed file
- verify_additional_hashes(signed_data: AuthenticodeSignedData) None
Verifies additional hashes that may be present in the
AuthenticodeSignedDatareferencing this data. ReturnNonewhen the verification succeeds, or raises an error otherwise.The default implementation is to do nothing.
- class signify.authenticode.AuthenticodeVerificationResult(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
This represents the result of an Authenticode verification. If everything is OK, it will equal to
AuthenticodeVerificationResult.OK, otherwise one of the other enum items will be returned. Remember that onl the first exception is processed - there may be more wrong.- CERTIFICATE_ERROR = 6
An error occurred during the processing of a certificate (e.g. during chain building), or when verifying the certificate’s signature.
- COUNTERSIGNER_ERROR = 9
Something went wrong when verifying the countersignature.
- INCONSISTENT_DIGEST_ALGORITHM = 7
A highly specific error raised when different digest algorithms are used in SignedData, SpcInfo or SignerInfo.
- INVALID_ADDITIONAL_HASH = 10
The additional file hash, such as the page hash for PE files, or the extended digest for MSI files, does not match the calculated hash.
- INVALID_DIGEST = 8
The verified digest does not match the calculated digest of the file. This is a tell-tale sign that the file may have been tampered with.
- NOT_SIGNED = 2
The provided PE file is not signed.
- OK = 1
The signature is valid.
- PARSE_ERROR = 3
The Authenticode signature could not be parsed.
- UNKNOWN_ERROR = 5
An unknown error occurred during parsing or verifying.
- VERIFY_ERROR = 4
The Authenticode signature could not be verified. This is a more generic error than other possible statuses and is used as a catch-all.
Signed PE File
This class is used for the verification of PE files.
- class signify.authenticode.SignedPEFile(file_obj: BinaryIO)
- __init__(file_obj: BinaryIO)
A PE file that is to be parsed to find the relevant sections for Authenticode parsing.
- Parameters:
file_obj – A PE file opened in binary file
- get_authenticode_omit_sections() dict[str, RelRange] | None
Returns all ranges of the raw file that are relevant for exclusion for the calculation of the hash function used in Authenticode.
The relevant sections are (as per http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx, chapter Calculating the PE Image Hash):
The location of the checksum
The location of the entry of the Certificate Table in the Data Directory
The location of the Certificate Table.
- Returns:
dict if successful, or None if not successful
- get_fingerprint(digest_algorithm: HashFunction, start: int = 0, end: int = -1, aligned: bool = False) bytes
Gets the fingerprint for this file, with the provided start and end, and optionally aligned to the PE file’s alignment.
- get_fingerprinter() SignedPEFingerprinter
Returns a fingerprinter object for this file.
- Return type:
signify.fingerprinter.SignedPEFingerprinter
- iter_signed_datas(*, include_nested: bool = True, ignore_parse_errors: bool = True) Iterator[AuthenticodeSignedData]
Returns an iterator over
AuthenticodeSignedDataobjects relevant for this Authenticode-signed file.- Parameters:
include_nested – Boolean, if True, will also iterate over all nested SignedData structures
ignore_parse_errors –
Indicates how to handle
ParseErrorthat may be raised while fetching embeddedAuthenticodeSignedDatastructures.When
True, which is the default and seems to be how Windows handles this as well, this will fetch as many validAuthenticodeSignedDatastructures until an exception occurs.Note that this will also silence the
ParseErrorthat occurs when there’s no validAuthenticodeSignedDatato fetch.When
False, this will raise theParseErroras soon as one occurs.
- Raises:
ParseError – For parse errors in the signed file
signify.authenticode.AuthenticodeParseError – For parse errors in the SignedData
- Returns:
iterator of signify.authenticode.SignedData
- property page_size: int
Gets the page size from the optional COFF header, or if not available, returns 4096 as best guess.
- verify_additional_hashes(signed_data: AuthenticodeSignedData) None
Verifies the page hashes (if available) in the SpcPeImageData field.
- class signify.authenticode.SignedPEFingerprinter(file_obj: BinaryIO, block_size: int = 1000000)
An extension of the
Fingerprinterclass that enables the calculation of authentihashes of PE Files.- add_signed_pe_hashers(*hashers: HashFunction, start: int = 0, end: int = -1, block_size: int | None = None) bool
Specialized method of
add_hashers()to add hashers with ranges limited to those that are needed to calculate the hash of signed PE Files.
Signed MSI File
This class is used for the verification of MSI files.
Signed Data File
This class is used for the verification of simple P7X files with Authenticode signatures.
PKCS7 objects
To help understand the specific SignedData and SignerInfo objects, the following graph may help:
- class signify.authenticode.AuthenticodeSignedData(asn1: cms.SignedData, signed_file: signed_file.AuthenticodeFile | None = None)
The
signify.pkcs7.SignedDatastructure for Authenticode. It holds the same information as its superclass, with additionally theIndirectData.- __init__(asn1: cms.SignedData, signed_file: signed_file.AuthenticodeFile | None = None)
- Parameters:
asn1 (asn1.pkcs7.SignedData) – The ASN.1 structure of the SignedData object
signed_file – The related AuthenticodeFile.
- property content: IndirectData
The indirect data content of this
AuthenticodeSignedDataobject.
- explain_verify(*args: Any, **kwargs: Any) tuple[AuthenticodeVerificationResult, Exception | None]
This will return a value indicating the signature status of this object. This will not raise an error when the verification fails, but rather indicate this through the resulting enum
- Return type:
Tuple[AuthenticodeVerificationResult, Exception]
- Returns:
The verification result, and the exception containing more details (if available or None)
- property indirect_data: IndirectData
Alias for
content
- iter_recursive_nested() Iterator[AuthenticodeSignedData]
Returns an iterator over
AuthenticodeSignedDataobjects, including the current one, but also any nestedAuthenticodeSignedDataobjects in theAuthenticodeSignerInfostructure.
- verify(verification_context: ~signify.x509.context.VerificationContext | None = None, *, expected_hash: bytes | None = None, verify_additional_hashes: bool = True, cs_verification_context: ~signify.x509.context.VerificationContext | None = None, trusted_certificate_store: ~signify.x509.context.CertificateStore = <signify.x509.context.FileSystemCertificateStore object>, verification_context_kwargs: dict[str, ~typing.Any] | None = None, countersignature_mode: ~typing.Literal['strict', 'permit', 'ignore'] = 'strict') Iterable[list[Certificate]]
Verifies the SignedData structure, adds this to the base methods of
SignedData:Verifies that the digest algorithms match across the structure (
SpcInfo,AuthenticodeSignedDataandAuthenticodeSignerInfomust have the same)Ensures that the hash in
SpcInfo.digestmatches the expected hash. If no expected hash is provided to this function, it is calculated using theFingerprinterobtained from theAuthenticodeFileobject.
- Parameters:
expected_hash – The expected hash digest of the
AuthenticodeFile.verify_additional_hashes – Defines whether additional hashes, should be verified, such as page hashes for PE files and extended digests for MSI files.
verification_context – See
SignedData.verify()cs_verification_context – See
SignedData.verify()trusted_certificate_store – See
SignedData.verify()verification_context_kwargs – See
SignedData.verify()countersignature_mode – See
SignedData.verify()
- Raises:
AuthenticodeVerificationError – when the verification failed
- Returns:
A list of valid certificate chains for this SignedData.
- class signify.authenticode.IndirectData(asn1: SpcIndirectDataContent)
The Authenticode’s SpcIndirectDataContent information, and their children. This is expected to be part of the content of the SignedData structure in Authenticode.
Note that this structure is completely flattened out from this ASN.1 spec:
SpcIndirectDataContent ::= SEQUENCE { data SpcAttributeTypeAndOptionalValue, messageDigest DigestInfo } SpcAttributeTypeAndOptionalValue ::= SEQUENCE { type ObjectID, value [0] EXPLICIT ANY OPTIONAL }
- asn1
The underlying ASN.1 data object
- property content: PeImageData | SigInfo | None
Nested content of this
IndirectData.
- property content_asn1: Asn1Value
ASN.1 structure of the content.
- property content_type: str
The contenttype string
- property digest: bytes
The (signed) digest as present in this structure. This should match the digest calculated over the data itself.
- class signify.authenticode.PeImageData(asn1: SpcPeImageData)
Information about the PE file, as provided in the
IndirectData. It is based on the following structure:SpcPeImageData ::= SEQUENCE { flags SpcPeImageFlags DEFAULT { includeResources }, file SpcLink } SpcPeImageFlags ::= BIT STRING { includeResources (0), includeDebugInfo (1), includeImportAddressTable (2) } SpcLink ::= CHOICE { url [0] IMPLICIT IA5STRING, moniker [1] IMPLICIT SpcSerializedObject, file [2] EXPLICIT SpcString } SpcSerializedObject ::= SEQUENCE { classId SpcUuid, serializedData OCTETSTRING }
This structure contains flags, which define which parts of the PE file are hashed. It is always ignored.
The file attribute originally contained information that describes the software publisher, but can now be a URL (which is ignored), a file, which is set to a SpcString set to
<<<Obsolete>>>, or the moniker setting a SpcSerializedObject.If used, the moniker always has UUID a6b586d5-b4a1-2466-ae05-a217da8e60d6 (bytes
a6 b5 86 d5 b4 a1 24 66 ae 05 a2 17 da 8e 60 d6), and a binary structure. Ominously, this is left outside of scope of the Authenticode documentation, noting that it contains a binary structure that contains page hashes.- property class_id: str
Available if
file_link_typeismoniker. Contains the class ID. Should be a6b586d5-b4a1-2466-ae05-a217da8e60d6.
- property content: list[bytes]
Available if
serialized_data_asn1_availableisTrue.
- property content_pairs: Iterable[tuple[str, list[bytes]]]
Available if
serialized_data_asn1_availableisTrue.
- property content_type: str
Available if
serialized_data_asn1_availableisTrue.
- property content_types: list[str]
Available if
serialized_data_asn1_availableisTrue.
- property contents: list[list[bytes]]
Available if
serialized_data_asn1_availableisTrue.
- property file_link_type: Literal['url', 'moniker', 'file']
Describes which of the options is used in this content.
- property flags: set[str]
Defines which parts of the PE file are hashed. It is always ignored.
- classmethod page_hash_algorithm(content_type: str) HashFunction
Returns the used page hash algorithm for the provided content type.
- property page_hash_algorithms: list[HashFunction]
Returns all used page hash algorithms in this structure.
- property page_hashes: Iterable[tuple[int, int, bytes, HashFunction]]
Iterates over all page hash ranges, and their hash digests, as defined in the SpcSerializedObject. If not available, will simply return an empty list.
- classmethod parse_page_hash_content(hash_algorithm: HashFunction, content: bytes) Iterable[tuple[int, int, bytes]]
Parses the content in the page hash content blob. It is constructed as 4 bytes offset, and the hash digest. The final entry will be the final offset and a zero hash (0000…).
This method yields tuples of start offset, end offset, and the hash digest.
- property publisher: str
Available if
file_link_typeisurlorfile. Contains the information in the attribute in string form.
- property serialized_data: bytes
Available if
file_link_typeismoniker. Raw serialized data as bytes.
- property serialized_data_asn1: list[SpcAttributeTypeAndOptionalValue]
Available if
serialized_data_asn1_availableisTrue. Return the data in ASN.1 form.
- property serialized_data_asn1_available: bool
Defines whether the property
serialized_data_asn1is available.
- class signify.authenticode.SigInfo(asn1: SpcSigInfo)
SigInfo, mostly used in MSI files. It defines information about the SIP, which is the Subject Interface Package: A Microsoft proprietary specification for a software layer that enables applications to create, store, retrieve, and verify a subject signature.
- property sip_guid: str
The SIP GUID.
- property sip_version: int
The SIP version.
- class signify.authenticode.AuthenticodeSignerInfo(asn1: SignerInfo, parent: SignedData | None = None)
Subclass of
SignerInfothat is used by the verification of Authenticode. Note that this will contain the same attributes asSignerInfo, with some additions.The
countersignerattribute can hold the same as in the normalSignerInfo, but may also contain aRFC3161SignedDataclass.- property countersigner: AuthenticodeCounterSignerInfo | RFC3161SignedData | None
Authenticode may use a different countersigning mechanism, rather than using a nested
AuthenticodeCounterSignerInfo, it may use a nested RFC-3161 response, which is a nestedsignify.pkcs7.SignedDatastructure (of typeRFC3161SignedData). This is also assigned to the countersigner attribute if this is available.
- property more_info: str | None
This information is extracted from the SpcSpOpusInfo authenticated attribute, containing the URL with more information.
- property nested_signed_datas: list[AuthenticodeSignedData]
It is possible for Authenticode SignerInfo objects to contain nested
signify.pkcs7.SignedDataobjects. This is similar to including multiple SignedData structures in thesignify.authenticode.AuthenticodeFile.This field is extracted from the unauthenticated attributes.
- property program_name: str | None
This information is extracted from the SpcSpOpusInfo authenticated attribute, containing the program’s name.
- property publisher_info: str | None
This information is extracted from the SpcSpOpusInfo authenticated attribute, containing the publisher_info. It is almost never set, but is defined in the ASN.1 structure.
- property statement_types: list[str] | None
Defines the key purpose of the signer. This is ignored by the verification.
Countersignature
The countersignature is used to verify the timestamp of the signature. This is usually done by sending the signature to a time-stamping service, that provides the countersignature. This allows the signature to continue to be valid, even after the original certificate chain expiring.
There are two types of countersignature: a regular countersignature, as used in PKCS7,
or a nested RFC3161 response. This nested object is basically a
authenticode.pkcs7.SignedData object, which holds its own set of certificates.
Regular
- class signify.authenticode.AuthenticodeCounterSignerInfo(asn1: SignerInfo, parent: SignedData | None = None)
Subclass of
CounterSignerInfothat is used to contain the countersignerinfo for Authenticode.
RFC3161
- class signify.authenticode.RFC3161SignedData(asn1: SignedData)
Some samples have shown to include a RFC-3161 countersignature in the unauthenticated attributes (as OID 1.3.6.1.4.1.311.3.3.1, which is in the Microsoft private namespace). This attribute contains its own signed data structure.
This is a subclass of
signify.pkcs7.SignedData, containing a RFC3161 TSTInfo in its content field.- check_message_digest(data: bytes) bool
Given the data, returns whether the hash_algorithm and message_digest match the data provided.
- property signing_time: datetime
Transparent attribute to ensure that the signing_time attribute is consistently available.
- verify(verification_context: VerificationContext | None = None, *, trusted_certificate_store: CertificateStore | None = None, verification_context_kwargs: dict[str, Any] | None = None) Iterable[Iterable[Certificate]]
Verifies the RFC3161 SignedData object. The context that is passed in must account for the certificate store of this object, or be left None.
The object is verified by verifying that the hash of the
TSTInfomatches theSignerInfo.message_digestvalue. The remainder of the validation is done by callingSignerInfo.verify()
- class signify.authenticode.TSTInfo(asn1: TSTInfo)
This is an implementation of the TSTInfo class as defined by RFC3161, used as content for a SignedData structure.
- property hash_algorithm: HashFunction
The hash algorithm of the message imprint.
- property message_digest: bytes
The hashed message
- property policy: str
Policy attribute
- property serial_number: int
The serial number of this signature
- property signing_authority: CertificateName | None
The authority generating this signature
- property signing_time: datetime
The time this signature was generated
- property signing_time_accuracy: timedelta | None
The accuracy of the above time
- property signing_time_ordering: bool
Indicates whether the signing time can be ordered.
- class signify.authenticode.RFC3161SignerInfo(asn1: SignerInfo, parent: SignedData | None = None)
Subclass of SignerInfo that is used to contain the signerinfo for the RFC3161SignedData option.