Add reusable certificate and file validation helpers

Fix process-name ownership and module lookup outputs, add explicit SPKI hashing and bounded chain access, and improve WDM integration. Deprecate superseded entry points with migration guidance and align branch code and tests with the library style.
This commit is contained in:
nefarius committed 2026-10-27 00:16:42 +01:00
1 parent 1f4d62ae95
commit a491bbd3f8
32 files changed
+5404 -1136

No files matched your search

+122 -67
View File
@@ -13,18 +13,22 @@
#endif
#pragma pack(push, 8)
typedef struct _DOMITO_CI26100_BLOB {
typedef struct _DOMITO_CI26100_BLOB
{
ULONG Size;
UCHAR *Data;
UCHAR* Data;
} DOMITO_CI26100_BLOB;
typedef struct _DOMITO_CI26100_NAME_BLOB {
UCHAR *Data; /* Borrowed, length-delimited encoded bytes. */
USHORT Size; /* Bytes, not characters. */
UCHAR Asn1StringTag; /* Observed: 0x0c UTF8String, 0x1e BMPString. */
typedef struct _DOMITO_CI26100_NAME_BLOB
{
UCHAR* Data; /* Borrowed, length-delimited encoded bytes. */
USHORT Size; /* Bytes, not characters. */
UCHAR Asn1StringTag; /* Observed: 0x0c UTF8String, 0x1e BMPString. */
} DOMITO_CI26100_NAME_BLOB;
typedef struct _DOMITO_CI26100_CHAIN_ELEMENT {
typedef struct _DOMITO_CI26100_CHAIN_ELEMENT
{
ULONG HashAlgId;
ULONG HashSize;
UCHAR Hash[64];
@@ -33,72 +37,121 @@ typedef struct _DOMITO_CI26100_CHAIN_ELEMENT {
DOMITO_CI26100_BLOB Certificate;
} DOMITO_CI26100_CHAIN_ELEMENT;
typedef struct _DOMITO_CI26100_CHAIN_INFO {
ULONG Size; /* Entire allocation, including trailing data. */
DOMITO_CI26100_BLOB *PublicKeys;
typedef struct _DOMITO_CI26100_CHAIN_INFO
{
ULONG Size; /* Entire allocation, including trailing data. */
DOMITO_CI26100_BLOB* PublicKeys;
ULONG NumberOfPublicKeys;
DOMITO_CI26100_BLOB *EKUs;
DOMITO_CI26100_BLOB* EKUs;
ULONG NumberOfEKUs;
DOMITO_CI26100_CHAIN_ELEMENT *ChainElements;
DOMITO_CI26100_CHAIN_ELEMENT* ChainElements;
ULONG NumberOfChainElements;
ULONG RootId; /* Opaque classification, NOT policy bits. */
ULONG RootId; /* Opaque classification, NOT policy bits. */
DOMITO_CI26100_BLOB AuthenticodeAttributes;
UCHAR PlatformManifestBinaryId[32]; /* NOT a file or certificate hash. */
} DOMITO_CI26100_CHAIN_INFO;
typedef struct _DOMITO_CI26100_POLICY_INFO {
typedef struct _DOMITO_CI26100_POLICY_INFO
{
ULONG Size;
NTSTATUS VerificationStatus; /* Does not replace the API return status. */
ULONG PolicyBits;
DOMITO_CI26100_CHAIN_INFO *ChainInfo;
DOMITO_CI26100_CHAIN_INFO* ChainInfo;
LARGE_INTEGER RevocationTime;
LARGE_INTEGER NotBefore;
LARGE_INTEGER NotAfter;
} DOMITO_CI26100_POLICY_INFO, *PDOMITO_CI26100_POLICY_INFO;
#pragma pack(pop)
C_ASSERT(sizeof(DOMITO_CI26100_BLOB) == 16);
C_ASSERT(sizeof(DOMITO_CI26100_NAME_BLOB) == 16);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_NAME_BLOB, Asn1StringTag) == 10);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_NAME_BLOB,
Asn1StringTag
) == 10
);
C_ASSERT(sizeof(DOMITO_CI26100_CHAIN_ELEMENT) == 120);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_CHAIN_ELEMENT, Certificate) == 104);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_CHAIN_INFO, RootId) == 52);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_CHAIN_INFO, AuthenticodeAttributes) == 56);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_CHAIN_INFO, PlatformManifestBinaryId) == 72);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_CHAIN_ELEMENT,
Certificate
) == 104
);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_CHAIN_INFO,
RootId
) == 52
);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_CHAIN_INFO,
AuthenticodeAttributes
) == 56
);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_CHAIN_INFO,
PlatformManifestBinaryId
) == 72
);
C_ASSERT(sizeof(DOMITO_CI26100_CHAIN_INFO) == 104);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_POLICY_INFO, ChainInfo) == 16);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_POLICY_INFO, RevocationTime) == 24);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_POLICY_INFO, NotBefore) == 32);
C_ASSERT(FIELD_OFFSET(DOMITO_CI26100_POLICY_INFO, NotAfter) == 40);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_POLICY_INFO,
ChainInfo
) == 16
);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_POLICY_INFO,
RevocationTime
) == 24
);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_POLICY_INFO,
NotBefore
) == 32
);
C_ASSERT(
FIELD_OFFSET(
DOMITO_CI26100_POLICY_INFO,
NotAfter
) == 40
);
C_ASSERT(sizeof(DOMITO_CI26100_POLICY_INFO) == 48);
/* Zero-initialize policies before first use. Free existing owned chains before
* reuse. Never copy these structs as independently owned objects with memcpy.
* Size is an output/initialization marker here, not runtime ABI negotiation.
*/
typedef VOID (NTAPI *DOMITO_CI26100_FREE_POLICY_INFO)(
DOMITO_CI26100_POLICY_INFO *PolicyInfo);
typedef VOID(NTAPI* DOMITO_CI26100_FREE_POLICY_INFO)(DOMITO_CI26100_POLICY_INFO* PolicyInfo);
typedef NTSTATUS (NTAPI *DOMITO_CI26100_VALIDATE_FILE_OBJECT)(
typedef NTSTATUS(NTAPI* DOMITO_CI26100_VALIDATE_FILE_OBJECT)(
PFILE_OBJECT FileObject,
ULONG ValidationFlags,
UCHAR RequestedSigningLevel,
DOMITO_CI26100_POLICY_INFO *PolicyInfo,
DOMITO_CI26100_POLICY_INFO *TimeStampPolicyInfo,
LARGE_INTEGER *SigningTime,
UCHAR *Hash, /* Provide 64-byte capacity, even for SHA-1. */
ULONG *HashSize, /* In: capacity >=64. Out success: actual size. */
ULONG *HashAlgId);
DOMITO_CI26100_POLICY_INFO* PolicyInfo,
DOMITO_CI26100_POLICY_INFO* TimeStampPolicyInfo,
LARGE_INTEGER* SigningTime,
UCHAR* Hash, /* Provide 64-byte capacity, even for SHA-1. */
ULONG* HashSize, /* In: capacity >=64. Out success: actual size. */
ULONG* HashAlgId
);
typedef NTSTATUS (NTAPI *DOMITO_CI26100_CHECK_SIGNED_FILE)(
typedef NTSTATUS(NTAPI* DOMITO_CI26100_CHECK_SIGNED_FILE)(
PVOID Hash,
ULONG HashSize,
ULONG HashAlgId,
PVOID WinCertificate, /* WIN_CERTIFICATE header, not bCertificate. */
PVOID WinCertificate, /* WIN_CERTIFICATE header, not bCertificate. */
ULONG SizeOfSecurityDirectory,
DOMITO_CI26100_POLICY_INFO *PolicyInfo,
LARGE_INTEGER *SigningTime,
DOMITO_CI26100_POLICY_INFO *TimeStampPolicyInfo);
DOMITO_CI26100_POLICY_INFO* PolicyInfo,
LARGE_INTEGER* SigningTime,
DOMITO_CI26100_POLICY_INFO* TimeStampPolicyInfo
);
/* The existing BOOLEAN reload parameter ABI was not independently resolved
* beyond the full-width use in this build; retain Domito's declaration until
@@ -106,49 +159,51 @@ typedef NTSTATUS (NTAPI *DOMITO_CI26100_CHECK_SIGNED_FILE)(
* Fifth argument nonzero filters on the catalog TRUSTED marker.
* Sixth argument requires ANY overlap with catalog PolicyInfo.PolicyBits.
*/
typedef NTSTATUS (NTAPI *DOMITO_CI26100_VERIFY_HASH_IN_CATALOG)(
typedef NTSTATUS(NTAPI* DOMITO_CI26100_VERIFY_HASH_IN_CATALOG)(
PVOID Hash,
ULONG HashSize,
ULONG HashAlgId,
BOOLEAN ReloadCatalogs,
ULONG RequireTrustedCatalog,
ULONG AcceptedCatalogPolicyBits,
DOMITO_CI26100_POLICY_INFO *PolicyInfo,
UNICODE_STRING *CatalogName, /* Optional; separate RtlFreeUnicodeString. */
LARGE_INTEGER *SigningTime,
DOMITO_CI26100_POLICY_INFO *TimeStampPolicyInfo);
DOMITO_CI26100_POLICY_INFO* PolicyInfo,
UNICODE_STRING* CatalogName, /* Optional; separate RtlFreeUnicodeString. */
LARGE_INTEGER* SigningTime,
DOMITO_CI26100_POLICY_INFO* TimeStampPolicyInfo
);
typedef PVOID (NTAPI *DOMITO_CI26100_ALLOCATE)(SIZE_T ByteSize);
typedef NTSTATUS (NTAPI *DOMITO_CI26100_GET_CERT_PUBLISHER_NAME)(
DOMITO_CI26100_BLOB *Certificate,
typedef PVOID(NTAPI* DOMITO_CI26100_ALLOCATE)(SIZE_T ByteSize);
typedef NTSTATUS(NTAPI* DOMITO_CI26100_GET_CERT_PUBLISHER_NAME)(
DOMITO_CI26100_BLOB* Certificate,
DOMITO_CI26100_ALLOCATE AllocateRoutine,
UNICODE_STRING *PublisherName); /* Free with callback's allocator pair. */
UNICODE_STRING* PublisherName
); /* Free with callback's allocator pair. */
/* Proposed descriptive diagnostic names. Not official Microsoft names, not
* an exhaustive dictionary, and not accepted-input validation flags.
* See the report for narrower branch conditions and composite values.
*/
#define DOMITO_CI26100_POLICY_SELF_ISSUED_TERMINAL 0x00000001UL
#define DOMITO_CI26100_POLICY_SELF_ISSUED_TERMINAL 0x00000001UL
// Also present on rgbMicrosoftRoot4 together with bit 0x800.
#define DOMITO_CI26100_POLICY_MICROSOFT_ROOT_0_1_2 0x00000002UL
#define DOMITO_CI26100_POLICY_TEST_ROOT 0x00000004UL
#define DOMITO_CI26100_POLICY_MICROSOFT_ROOT_3 0x00000008UL
#define DOMITO_CI26100_POLICY_DMD_ROOT 0x00000020UL
#define DOMITO_CI26100_POLICY_DMD_TEST_ROOT 0x00000040UL
#define DOMITO_CI26100_POLICY_MICROSOFT_ROOT_5 0x00000080UL
#define DOMITO_CI26100_POLICY_FLIGHT_ROOT 0x00000400UL
#define DOMITO_CI26100_POLICY_MARKETPLACE_ROOT 0x00002000UL
#define DOMITO_CI26100_POLICY_SUPPLIED_CERT_OR_KEY 0x00004000UL
#define DOMITO_CI26100_POLICY_IDENTITY_ROOT_2020 0x00008000UL
#define DOMITO_CI26100_POLICY_PARTIAL_CHAIN 0x00000010UL
#define DOMITO_CI26100_POLICY_CHAIN_FAILURE 0x00020000UL
#define DOMITO_CI26100_POLICY_CRYPTO_FAILURE 0x00040000UL
#define DOMITO_CI26100_POLICY_EKU_FAILURE 0x00080000UL
#define DOMITO_CI26100_POLICY_PAGE_HASH_FAILURE 0x00100000UL
#define DOMITO_CI26100_POLICY_CERT_REVOKED 0x00200000UL
#define DOMITO_CI26100_POLICY_CERT_VALIDITY_FAILURE 0x00400000UL
#define DOMITO_CI26100_POLICY_PATH_LENGTH_FAILURE 0x08000000UL
#define DOMITO_CI26100_POLICY_GENERIC_FAILURE 0x10000000UL
#define DOMITO_CI26100_POLICY_MICROSOFT_ROOT_0_1_2 0x00000002UL
#define DOMITO_CI26100_POLICY_TEST_ROOT 0x00000004UL
#define DOMITO_CI26100_POLICY_MICROSOFT_ROOT_3 0x00000008UL
#define DOMITO_CI26100_POLICY_DMD_ROOT 0x00000020UL
#define DOMITO_CI26100_POLICY_DMD_TEST_ROOT 0x00000040UL
#define DOMITO_CI26100_POLICY_MICROSOFT_ROOT_5 0x00000080UL
#define DOMITO_CI26100_POLICY_FLIGHT_ROOT 0x00000400UL
#define DOMITO_CI26100_POLICY_MARKETPLACE_ROOT 0x00002000UL
#define DOMITO_CI26100_POLICY_SUPPLIED_CERT_OR_KEY 0x00004000UL
#define DOMITO_CI26100_POLICY_IDENTITY_ROOT_2020 0x00008000UL
#define DOMITO_CI26100_POLICY_PARTIAL_CHAIN 0x00000010UL
#define DOMITO_CI26100_POLICY_CHAIN_FAILURE 0x00020000UL
#define DOMITO_CI26100_POLICY_CRYPTO_FAILURE 0x00040000UL
#define DOMITO_CI26100_POLICY_EKU_FAILURE 0x00080000UL
#define DOMITO_CI26100_POLICY_PAGE_HASH_FAILURE 0x00100000UL
#define DOMITO_CI26100_POLICY_CERT_REVOKED 0x00200000UL
#define DOMITO_CI26100_POLICY_CERT_VALIDITY_FAILURE 0x00400000UL
#define DOMITO_CI26100_POLICY_PATH_LENGTH_FAILURE 0x08000000UL
#define DOMITO_CI26100_POLICY_GENERIC_FAILURE 0x10000000UL
#define DOMITO_CI26100_POLICY_CA_CONSTRAINT_FAILURE 0x20000000UL
/* Narrow branch observation: no usable timestamp during revoked-cert recovery;