Additional Authenticode Structures
PKCS#7 objects
To help understand the specific SignedData and SignerInfo objects, the following graph may help:
- class signify.authenticode.AuthenticodeSignature(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
AuthenticodeSignatureobject.
- property indirect_data: IndirectData
Alias for
content
- iter_recursive_nested() Iterator[AuthenticodeSignature]
Returns an iterator over
AuthenticodeSignatureobjects, including the current one, but also any nestedAuthenticodeSignatureobjects in theAuthenticodeSignerInfostructure.See
AuthenticodeSignerInfo.nested_signed_datas
- 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.CombinedCertificateStore 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,AuthenticodeSignatureandAuthenticodeSignerInfomust 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.
- verify_indirect_data(indirect_data: IndirectData, *, expected_hash: bytes | None = None, verify_additional_hashes: bool = True) None
Verifies the provided IndirectData against the expected hash.
If a
signed_fileis available, this is relayed toAuthenticodeSignedFile.verify_indirect_data().If such file is not available, this simply checks whether the provided hash matches the hash in the
indirect_data.- 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.
- class signify.authenticode.indirect_data.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.indirect_data.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.indirect_data.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.signer_info.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 more_info: str | None
This information is extracted from the SpcSpOpusInfo authenticated attribute, containing the URL with more information.
- property nested_signed_datas: list[AuthenticodeSignature]
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.signer_info.AuthenticodeCounterSignerInfo(asn1: SignerInfo, parent: SignedData | None = None)
Subclass of
CounterSignerInfothat is used to contain the countersignerinfo for Authenticode.
RFC3161
- class signify.authenticode.tsp.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.tsp.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.tsp.RFC3161SignerInfo(asn1: SignerInfo, parent: SignedData | None = None)
Subclass of SignerInfo that is used to contain the signerinfo for the
RFC3161SignedDataclass.