Additional Authenticode Structures

PKCS#7 objects

To help understand the specific SignedData and SignerInfo objects, the following graph may help:

http://yuml.me/f68f2b83.svg
class signify.authenticode.AuthenticodeSignature(asn1: cms.SignedData, signed_file: signed_file.AuthenticodeFile | None = None)

The signify.pkcs7.SignedData structure for Authenticode. It holds the same information as its superclass, with additionally the IndirectData.

__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 AuthenticodeSignature object.

property indirect_data: IndirectData

Alias for content

iter_recursive_nested() Iterator[AuthenticodeSignature]

Returns an iterator over AuthenticodeSignature objects, including the current one, but also any nested AuthenticodeSignature objects in the AuthenticodeSignerInfo structure.

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, AuthenticodeSignature and AuthenticodeSignerInfo must have the same)

  • Ensures that the hash in SpcInfo.digest matches the expected hash. If no expected hash is provided to this function, it is calculated using the Fingerprinter obtained from the AuthenticodeFile object.

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_file is available, this is relayed to AuthenticodeSignedFile.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.

property digest_algorithm: HashFunction

Digest algorithm of the digest.

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_type is moniker. Contains the class ID. Should be a6b586d5-b4a1-2466-ae05-a217da8e60d6.

property content: list[bytes]

Available if serialized_data_asn1_available is True.

property content_pairs: Iterable[tuple[str, list[bytes]]]

Available if serialized_data_asn1_available is True.

property content_type: str

Available if serialized_data_asn1_available is True.

property content_types: list[str]

Available if serialized_data_asn1_available is True.

property contents: list[list[bytes]]

Available if serialized_data_asn1_available is True.

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_type is url or file. Contains the information in the attribute in string form.

property serialized_data: bytes

Available if file_link_type is moniker. Raw serialized data as bytes.

property serialized_data_asn1: list[SpcAttributeTypeAndOptionalValue]

Available if serialized_data_asn1_available is True. Return the data in ASN.1 form.

property serialized_data_asn1_available: bool

Defines whether the property serialized_data_asn1 is 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 SignerInfo that is used by the verification of Authenticode. Note that this will contain the same attributes as SignerInfo, with some additions.

The countersigner attribute can hold the same as in the normal SignerInfo, but may also contain a RFC3161SignedData class.

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.SignedData objects. This is similar to including multiple SignedData structures in the signify.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 CounterSignerInfo that 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 content: TSTInfo

Contains the TSTInfo class for this SignedData.

property signing_time: datetime

Transparent attribute to ensure that the signing_time attribute is consistently available.

property tst_info: TSTInfo

Alias for content.

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 TSTInfo matches the SignerInfo.message_digest value. The remainder of the validation is done by calling SignerInfo.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 RFC3161SignedData class.