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. Add CI validation helpers with explicit signature selection and owned results Document runtime-confirmed CI signer selection and crypto reuse Expand CI compatibility matrix to twenty verified samples Extend CI export matrix with Windows 11 x64 and ARM64 samples Document CI API availability and historical mincrypt layouts Add explicit Authenticode workflows and correct CI helper contracts Document CI validation flag 0x20 and add kernel probe Harden CI digest parsing and failure cleanup
This commit is contained in:
1 parent
7985b23be5
commit
3fbfe31d15
38 files changed
+9201
-751
No files matched your search
@@ -0,0 +1,200 @@
|
||||
#pragma once
|
||||
#include "Domito.h"
|
||||
|
||||
// Consumer helpers: see docs/consumer-helpers.md for ownership and trust limits.
|
||||
typedef struct _DOMITO_BYTE_VIEW
|
||||
{
|
||||
const UCHAR* Data;
|
||||
ULONG Size;
|
||||
} DOMITO_BYTE_VIEW;
|
||||
|
||||
typedef struct _DOMITO_CERTIFICATE_SPKI
|
||||
{
|
||||
DOMITO_BYTE_VIEW Encoded; // Complete SPKI SEQUENCE, including tag and length.
|
||||
DOMITO_BYTE_VIEW Content; // Legacy consumer convention: excludes that header.
|
||||
} DOMITO_CERTIFICATE_SPKI;
|
||||
|
||||
typedef enum _DOMITO_CERTIFICATE_HASH_KIND
|
||||
{
|
||||
DomitoCertificateHashDer = 0,
|
||||
DomitoCertificateHashSpkiDer = 1,
|
||||
DomitoCertificateHashSpkiContentLegacy = 2
|
||||
} DOMITO_CERTIFICATE_HASH_KIND;
|
||||
|
||||
// Bounded positional DER extraction, not X.509 validation. Views borrow CertData.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoGetCertificateSpki(
|
||||
_In_reads_bytes_(CertSize) const UCHAR* CertData,
|
||||
_In_ ULONG CertSize,
|
||||
_Out_ DOMITO_CERTIFICATE_SPKI* Spki
|
||||
);
|
||||
|
||||
// SHA-1/256/384/512. HashSize is capacity on entry, bytes on success, required
|
||||
// size on BUFFER_TOO_SMALL, zero on other failures. Hash may be NULL to size.
|
||||
// Input/output must not overlap. Hash contains zero bytes on operational failure.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoHashBuffer(
|
||||
_In_reads_bytes_opt_(Size) const UCHAR* Bytes,
|
||||
_In_ ULONG Size,
|
||||
_In_ ALG_ID Algorithm,
|
||||
_Out_writes_bytes_to_opt_(*HashSize, *HashSize) UCHAR* Hash,
|
||||
_Inout_ ULONG* HashSize
|
||||
);
|
||||
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoHashCertificate(
|
||||
_In_reads_bytes_(CertSize) const UCHAR* CertData,
|
||||
_In_ ULONG CertSize,
|
||||
_In_ DOMITO_CERTIFICATE_HASH_KIND Kind,
|
||||
_In_ ALG_ID Algorithm,
|
||||
_Out_writes_bytes_to_opt_(*HashSize, *HashSize) UCHAR* Hash,
|
||||
_Inout_ ULONG* HashSize
|
||||
);
|
||||
|
||||
// Strict length-delimited hex: no spaces, prefixes, separators or invalid digits.
|
||||
// Nonoverlapping buffers. Decode clears its output on malformed input.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoDecodeHex(
|
||||
_In_ const UNICODE_STRING* Hex,
|
||||
_Out_writes_bytes_(ByteCount) UCHAR* Bytes,
|
||||
_In_ ULONG ByteCount
|
||||
);
|
||||
|
||||
// Writes uppercase hex plus NUL; HexChars includes terminator capacity.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoEncodeHex(
|
||||
_In_reads_bytes_opt_(ByteCount) const UCHAR* Bytes,
|
||||
_In_ ULONG ByteCount,
|
||||
_Out_writes_(HexChars) WCHAR* Hex,
|
||||
_In_ ULONG HexChars
|
||||
);
|
||||
|
||||
// Resolve optional exports without creating a static import. Requires DomitoInit.
|
||||
// ModuleName is the full loaded-module path used by FindModuleBaseAddress.
|
||||
// Caller must keep that module mapped; this does not acquire a loader reference.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoFindModuleExportedFunctionAddress(
|
||||
_In_ PANSI_STRING ModuleName,
|
||||
_In_ PANSI_STRING FunctionName,
|
||||
_Outptr_result_maybenull_ PVOID* FunctionAddress
|
||||
);
|
||||
|
||||
// Results from either process-name API use one Domito allocation. The memory
|
||||
// callback pair must remain unchanged until all allocations are released.
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
void
|
||||
DomitoFreeProcessImageName(
|
||||
_In_opt_ PUNICODE_STRING ImageName
|
||||
);
|
||||
|
||||
// Caller holds a referenced PEPROCESS throughout the call. No PID re-lookup.
|
||||
// Returns a copy owned by Domito; use DomitoFreeProcessImageName once.
|
||||
// Name lookup does not establish the identity of a later reopened file.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoGetProcessImageNameEx(
|
||||
_In_ PEPROCESS Process,
|
||||
_Outptr_result_maybenull_ PUNICODE_STRING* ImageName
|
||||
);
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10)
|
||||
// These wrappers do not require DomitoInit. Handle must be a trusted kernel
|
||||
// handle with FILE_READ_DATA; it is borrowed, referenced for the call, not closed.
|
||||
// Same initialized-result/cleanup rules and explicit flags as FileObjectEx.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoValidateFileHandleEx(
|
||||
_In_ HANDLE FileHandle,
|
||||
_In_ UINT32 ValidationFlags,
|
||||
_In_ UINT8 RequestedSigningLevel,
|
||||
_In_ DOMITO_CI_SIGNATURE_SELECTION Selection,
|
||||
_Inout_ DOMITO_CI_VALIDATION_RESULT* Result
|
||||
);
|
||||
|
||||
// Absolute native path (e.g. \??\C:\...). Opens read-only, shares only reads,
|
||||
// closes its own handle. The path can be reparsed; this validates the opened
|
||||
// file, not process memory or a previous path identity. No fallback is implicit.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoValidateFilePathEx(
|
||||
_In_ const UNICODE_STRING* Path,
|
||||
_In_ UINT32 ValidationFlags,
|
||||
_In_ UINT8 RequestedSigningLevel,
|
||||
_In_ DOMITO_CI_SIGNATURE_SELECTION Selection,
|
||||
_Inout_ DOMITO_CI_VALIDATION_RESULT* Result
|
||||
);
|
||||
|
||||
typedef enum _DOMITO_CI_CHAIN_LAYOUT
|
||||
{
|
||||
// Explicit caller assertion: observed x64 +0x28 array/+0x30 count, 120-byte
|
||||
// elements and a minimum 56-byte header. NOT selected by allocation Size.
|
||||
DomitoCiChainLayoutObservedX64 = 1
|
||||
} DOMITO_CI_CHAIN_LAYOUT;
|
||||
|
||||
typedef struct _DOMITO_CI_CHAIN_VIEW
|
||||
{
|
||||
const MINCRYPT_CHAIN_ELEMENT* Elements;
|
||||
ULONG Count;
|
||||
ULONG RootId; // Opaque CI identifier, not proof the last element is a root.
|
||||
} DOMITO_CI_CHAIN_VIEW;
|
||||
|
||||
// Only accepts a readable, initialized CI-owned policy, never arbitrary pointers.
|
||||
// Checks every exposed name/certificate span against CI's owned allocation.
|
||||
// Leaf-first order is observed in sampled layouts. Last element is not promised
|
||||
// to be a self-signed/trusted root. No issuer/subject byte equality is imposed.
|
||||
// View borrows policy storage until CiFreePolicyInfo/result reuse. x64 only.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoGetCiChainView(
|
||||
_In_ const MINCRYPT_POLICY_INFO* Policy,
|
||||
_In_ DOMITO_CI_CHAIN_LAYOUT Layout,
|
||||
_Out_ DOMITO_CI_CHAIN_VIEW* View
|
||||
);
|
||||
|
||||
// Optional export, resolved at call time; requires DomitoInit. No static import
|
||||
// of CiGetCertPublisherName. Extracts a display name, not certificate trust.
|
||||
// Start with {0}; release even after failure using the dedicated free function.
|
||||
// Never pass an owning previous string: free it before making another call.
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoGetCertificatePublisherName(
|
||||
_In_ const MINCERT_BLOB* Certificate,
|
||||
_Out_ PUNICODE_STRING PublisherName
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
void
|
||||
DomitoFreeCertificatePublisherName(
|
||||
_Inout_ PUNICODE_STRING PublisherName
|
||||
);
|
||||
#endif
|
||||
@@ -0,0 +1,212 @@
|
||||
/* Opt-in observed-build declarations, not a universal Windows CI SDK.
|
||||
* Observed: ci.dll 10.0.26100.8328, x64, SHA-256 documented in docs/mincrypt-contracts.md.
|
||||
* Include after ntddk.h. Uses distinct names and function-pointer types so
|
||||
* including this file does not change the default layouts or add static imports.
|
||||
* Verify the actual CI build/architecture before use; Size alone cannot prove
|
||||
* layout identity. See docs/mincrypt-contracts.md for provenance and limits.
|
||||
* Field/parameter names are descriptive analyst names unless stated otherwise.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(_M_AMD64) && !defined(__x86_64__)
|
||||
#error This research layout is validated only for x64.
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 8)
|
||||
|
||||
typedef struct _DOMITO_CI26100_BLOB
|
||||
{
|
||||
ULONG Size;
|
||||
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. */
|
||||
} DOMITO_CI26100_NAME_BLOB;
|
||||
|
||||
typedef struct _DOMITO_CI26100_CHAIN_ELEMENT
|
||||
{
|
||||
ULONG HashAlgId;
|
||||
ULONG HashSize;
|
||||
UCHAR Hash[64];
|
||||
DOMITO_CI26100_NAME_BLOB Subject;
|
||||
DOMITO_CI26100_NAME_BLOB Issuer;
|
||||
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;
|
||||
ULONG NumberOfPublicKeys;
|
||||
DOMITO_CI26100_BLOB* EKUs;
|
||||
ULONG NumberOfEKUs;
|
||||
DOMITO_CI26100_CHAIN_ELEMENT* ChainElements;
|
||||
ULONG NumberOfChainElements;
|
||||
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
|
||||
{
|
||||
ULONG Size;
|
||||
NTSTATUS VerificationStatus; /* Does not replace the API return status. */
|
||||
ULONG PolicyBits;
|
||||
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(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(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(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 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
|
||||
);
|
||||
|
||||
typedef NTSTATUS(NTAPI* DOMITO_CI26100_CHECK_SIGNED_FILE)(
|
||||
PVOID Hash,
|
||||
ULONG HashSize,
|
||||
ULONG HashAlgId,
|
||||
PVOID WinCertificate, /* WIN_CERTIFICATE header, not bCertificate. */
|
||||
ULONG SizeOfSecurityDirectory,
|
||||
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
|
||||
* cross-architecture call-site evidence settles its formal type.
|
||||
* 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)(
|
||||
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
|
||||
);
|
||||
|
||||
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. */
|
||||
|
||||
/* 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
|
||||
// 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_CA_CONSTRAINT_FAILURE 0x20000000UL
|
||||
|
||||
/* Narrow branch observation: no usable timestamp during revoked-cert recovery;
|
||||
* not a universal flag for all signatures without a timestamp.
|
||||
*/
|
||||
#define DOMITO_CI26100_POLICY_REVOCATION_NO_TIMESTAMP 0x04000000UL
|
||||
@@ -0,0 +1,120 @@
|
||||
/* Opt-in x64 chain views for exact observed Windows 10 CI artifacts.
|
||||
* Include after ntddk.h. This does not alter Domito's default declarations.
|
||||
* Select a view only after establishing the matching runtime layout from
|
||||
* build/artifact evidence. ChainInfo->Size is TOTAL allocation size; it cannot
|
||||
* identify the header version, because variable payload follows the header.
|
||||
* See docs/mincrypt-contracts.md and NOTES.md for exact sampled versions/hashes.
|
||||
*/
|
||||
#pragma once
|
||||
#include "Domito.MinCrypt.h"
|
||||
|
||||
#if !defined(_M_AMD64) && !defined(__x86_64__)
|
||||
#error Historical CI views are validated only for the documented x64 artifacts.
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 8)
|
||||
|
||||
// Observed ci.dll 10.0.10240.16463. The variable payload begins at +0x38;
|
||||
// AuthenticodeAttributes does not exist at that offset in this header.
|
||||
typedef struct _DOMITO_CI10240_CHAIN_INFO
|
||||
{
|
||||
UINT32 Size;
|
||||
MINCERT_BLOB* PublicKeys;
|
||||
UINT32 NumberOfPublicKeys;
|
||||
MINCERT_BLOB* EKUs;
|
||||
UINT32 NumberOfEKUs;
|
||||
PVOID ChainElements; // Constructor copies 120-byte elements; borrowed storage.
|
||||
UINT32 NumberOfChainElements;
|
||||
UINT32 RootId; // Opaque identifier, not PolicyBits.
|
||||
} DOMITO_CI10240_CHAIN_INFO, *PDOMITO_CI10240_CHAIN_INFO;
|
||||
|
||||
// Observed ci.dll 10.0.10586.0. The variable payload begins at +0x48.
|
||||
typedef struct _DOMITO_CI10586_CHAIN_INFO
|
||||
{
|
||||
UINT32 Size;
|
||||
MINCERT_BLOB* PublicKeys;
|
||||
UINT32 NumberOfPublicKeys;
|
||||
MINCERT_BLOB* EKUs;
|
||||
UINT32 NumberOfEKUs;
|
||||
PVOID ChainElements;
|
||||
UINT32 NumberOfChainElements;
|
||||
UINT32 RootId;
|
||||
MINCRYPT_ATTR_BLOB AuthenticodeAttributes;
|
||||
} DOMITO_CI10586_CHAIN_INFO, *PDOMITO_CI10586_CHAIN_INFO;
|
||||
|
||||
// Observed 10.0.14393.2189, 15063.0, 16299.125 and 17134.1130 x64.
|
||||
// The variable payload begins at +0x68. Constructor evidence establishes the
|
||||
// 32-byte extension's space, not its semantic contents on every sampled build.
|
||||
typedef struct _DOMITO_CI14393_CHAIN_INFO
|
||||
{
|
||||
UINT32 Size;
|
||||
MINCERT_BLOB* PublicKeys;
|
||||
UINT32 NumberOfPublicKeys;
|
||||
MINCERT_BLOB* EKUs;
|
||||
UINT32 NumberOfEKUs;
|
||||
PVOID ChainElements;
|
||||
UINT32 NumberOfChainElements;
|
||||
UINT32 RootId;
|
||||
MINCRYPT_ATTR_BLOB AuthenticodeAttributes;
|
||||
UINT8 ReservedExtension[32];
|
||||
} DOMITO_CI14393_CHAIN_INFO, *PDOMITO_CI14393_CHAIN_INFO;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
C_ASSERT(sizeof(DOMITO_CI10240_CHAIN_INFO) == 56);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI10240_CHAIN_INFO,
|
||||
PublicKeys
|
||||
) == 8
|
||||
);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI10240_CHAIN_INFO,
|
||||
EKUs
|
||||
) == 24
|
||||
);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI10240_CHAIN_INFO,
|
||||
ChainElements
|
||||
) == 40
|
||||
);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI10240_CHAIN_INFO,
|
||||
RootId
|
||||
) == 52
|
||||
);
|
||||
C_ASSERT(sizeof(DOMITO_CI10586_CHAIN_INFO) == 72);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI10586_CHAIN_INFO,
|
||||
RootId
|
||||
) == 52
|
||||
);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI10586_CHAIN_INFO,
|
||||
AuthenticodeAttributes
|
||||
) == 56
|
||||
);
|
||||
C_ASSERT(sizeof(DOMITO_CI14393_CHAIN_INFO) == 104);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI14393_CHAIN_INFO,
|
||||
RootId
|
||||
) == 52
|
||||
);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI14393_CHAIN_INFO,
|
||||
AuthenticodeAttributes
|
||||
) == 56
|
||||
);
|
||||
C_ASSERT(
|
||||
FIELD_OFFSET(
|
||||
DOMITO_CI14393_CHAIN_INFO,
|
||||
ReservedExtension
|
||||
) == 72
|
||||
);
|
||||
+302
-249
@@ -22,16 +22,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Warnings which disabled for compiling
|
||||
// Warnings which disabled for compiling
|
||||
#if _MSC_VER >= 1200
|
||||
#pragma warning(push)
|
||||
// nonstandard extension used : nameless struct/union
|
||||
#pragma warning(disable:4201)
|
||||
#pragma warning(disable : 4201)
|
||||
// 'struct_name' : structure was padded due to __declspec(align())
|
||||
#pragma warning(disable:4324)
|
||||
#pragma warning(disable : 4324)
|
||||
// 'enumeration': a forward declaration of an unscoped enumeration must have an
|
||||
// underlying type (int assumed)
|
||||
#pragma warning(disable:4471)
|
||||
#pragma warning(disable : 4471)
|
||||
#endif
|
||||
|
||||
EXTERN_C_START
|
||||
@@ -47,144 +47,144 @@ EXTERN_C_START
|
||||
//
|
||||
|
||||
// ALG_ID crackers
|
||||
#define GET_ALG_CLASS(x) (x & (7 << 13))
|
||||
#define GET_ALG_TYPE(x) (x & (15 << 9))
|
||||
#define GET_ALG_SID(x) (x & (511))
|
||||
#define GET_ALG_CLASS(x) (x & (7 << 13))
|
||||
#define GET_ALG_TYPE(x) (x & (15 << 9))
|
||||
#define GET_ALG_SID(x) (x & (511))
|
||||
|
||||
// Algorithm classes
|
||||
// certenrolld_begin -- ALG_CLASS_*
|
||||
#define ALG_CLASS_ANY (0)
|
||||
#define ALG_CLASS_SIGNATURE (1 << 13)
|
||||
#define ALG_CLASS_MSG_ENCRYPT (2 << 13)
|
||||
#define ALG_CLASS_DATA_ENCRYPT (3 << 13)
|
||||
#define ALG_CLASS_HASH (4 << 13)
|
||||
#define ALG_CLASS_KEY_EXCHANGE (5 << 13)
|
||||
#define ALG_CLASS_ALL (7 << 13)
|
||||
#define ALG_CLASS_ANY (0)
|
||||
#define ALG_CLASS_SIGNATURE (1 << 13)
|
||||
#define ALG_CLASS_MSG_ENCRYPT (2 << 13)
|
||||
#define ALG_CLASS_DATA_ENCRYPT (3 << 13)
|
||||
#define ALG_CLASS_HASH (4 << 13)
|
||||
#define ALG_CLASS_KEY_EXCHANGE (5 << 13)
|
||||
#define ALG_CLASS_ALL (7 << 13)
|
||||
// certenrolld_end
|
||||
|
||||
// Algorithm types
|
||||
#define ALG_TYPE_ANY (0)
|
||||
#define ALG_TYPE_DSS (1 << 9)
|
||||
#define ALG_TYPE_RSA (2 << 9)
|
||||
#define ALG_TYPE_BLOCK (3 << 9)
|
||||
#define ALG_TYPE_STREAM (4 << 9)
|
||||
#define ALG_TYPE_DH (5 << 9)
|
||||
#define ALG_TYPE_SECURECHANNEL (6 << 9)
|
||||
#define ALG_TYPE_ANY (0)
|
||||
#define ALG_TYPE_DSS (1 << 9)
|
||||
#define ALG_TYPE_RSA (2 << 9)
|
||||
#define ALG_TYPE_BLOCK (3 << 9)
|
||||
#define ALG_TYPE_STREAM (4 << 9)
|
||||
#define ALG_TYPE_DH (5 << 9)
|
||||
#define ALG_TYPE_SECURECHANNEL (6 << 9)
|
||||
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
||||
#define ALG_TYPE_ECDH (7 << 9)
|
||||
#define ALG_TYPE_ECDH (7 << 9)
|
||||
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
|
||||
#define ALG_TYPE_THIRDPARTY (8 << 9)
|
||||
#define ALG_TYPE_THIRDPARTY (8 << 9)
|
||||
#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1)
|
||||
|
||||
// Generic sub-ids
|
||||
#define ALG_SID_ANY (0)
|
||||
#define ALG_SID_ANY (0)
|
||||
|
||||
// Generic ThirdParty sub-ids
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
|
||||
#define ALG_SID_THIRDPARTY_ANY (0)
|
||||
#define ALG_SID_THIRDPARTY_ANY (0)
|
||||
#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1)
|
||||
|
||||
// Some RSA sub-ids
|
||||
#define ALG_SID_RSA_ANY 0
|
||||
#define ALG_SID_RSA_PKCS 1
|
||||
#define ALG_SID_RSA_MSATWORK 2
|
||||
#define ALG_SID_RSA_ENTRUST 3
|
||||
#define ALG_SID_RSA_PGP 4
|
||||
#define ALG_SID_RSA_ANY 0
|
||||
#define ALG_SID_RSA_PKCS 1
|
||||
#define ALG_SID_RSA_MSATWORK 2
|
||||
#define ALG_SID_RSA_ENTRUST 3
|
||||
#define ALG_SID_RSA_PGP 4
|
||||
|
||||
// Some DSS sub-ids
|
||||
//
|
||||
#define ALG_SID_DSS_ANY 0
|
||||
#define ALG_SID_DSS_PKCS 1
|
||||
#define ALG_SID_DSS_DMS 2
|
||||
#define ALG_SID_DSS_ANY 0
|
||||
#define ALG_SID_DSS_PKCS 1
|
||||
#define ALG_SID_DSS_DMS 2
|
||||
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
||||
#define ALG_SID_ECDSA 3
|
||||
#define ALG_SID_ECDSA 3
|
||||
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
|
||||
|
||||
// Block cipher sub ids
|
||||
// DES sub_ids
|
||||
#define ALG_SID_DES 1
|
||||
#define ALG_SID_3DES 3
|
||||
#define ALG_SID_DESX 4
|
||||
#define ALG_SID_IDEA 5
|
||||
#define ALG_SID_CAST 6
|
||||
#define ALG_SID_SAFERSK64 7
|
||||
#define ALG_SID_SAFERSK128 8
|
||||
#define ALG_SID_3DES_112 9
|
||||
#define ALG_SID_CYLINK_MEK 12
|
||||
#define ALG_SID_RC5 13
|
||||
#define ALG_SID_DES 1
|
||||
#define ALG_SID_3DES 3
|
||||
#define ALG_SID_DESX 4
|
||||
#define ALG_SID_IDEA 5
|
||||
#define ALG_SID_CAST 6
|
||||
#define ALG_SID_SAFERSK64 7
|
||||
#define ALG_SID_SAFERSK128 8
|
||||
#define ALG_SID_3DES_112 9
|
||||
#define ALG_SID_CYLINK_MEK 12
|
||||
#define ALG_SID_RC5 13
|
||||
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#define ALG_SID_AES_128 14
|
||||
#define ALG_SID_AES_192 15
|
||||
#define ALG_SID_AES_256 16
|
||||
#define ALG_SID_AES 17
|
||||
#define ALG_SID_AES_128 14
|
||||
#define ALG_SID_AES_192 15
|
||||
#define ALG_SID_AES_256 16
|
||||
#define ALG_SID_AES 17
|
||||
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
|
||||
|
||||
// Fortezza sub-ids
|
||||
#define ALG_SID_SKIPJACK 10
|
||||
#define ALG_SID_TEK 11
|
||||
#define ALG_SID_SKIPJACK 10
|
||||
#define ALG_SID_TEK 11
|
||||
|
||||
// KP_MODE
|
||||
#define CRYPT_MODE_CBCI 6 // ANSI CBC Interleaved
|
||||
#define CRYPT_MODE_CFBP 7 // ANSI CFB Pipelined
|
||||
#define CRYPT_MODE_OFBP 8 // ANSI OFB Pipelined
|
||||
#define CRYPT_MODE_CBCOFM 9 // ANSI CBC + OF Masking
|
||||
#define CRYPT_MODE_CBCOFMI 10 // ANSI CBC + OFM Interleaved
|
||||
#define CRYPT_MODE_CBCI 6 // ANSI CBC Interleaved
|
||||
#define CRYPT_MODE_CFBP 7 // ANSI CFB Pipelined
|
||||
#define CRYPT_MODE_OFBP 8 // ANSI OFB Pipelined
|
||||
#define CRYPT_MODE_CBCOFM 9 // ANSI CBC + OF Masking
|
||||
#define CRYPT_MODE_CBCOFMI 10 // ANSI CBC + OFM Interleaved
|
||||
|
||||
// RC2 sub-ids
|
||||
#define ALG_SID_RC2 2
|
||||
#define ALG_SID_RC2 2
|
||||
|
||||
// Stream cipher sub-ids
|
||||
#define ALG_SID_RC4 1
|
||||
#define ALG_SID_SEAL 2
|
||||
#define ALG_SID_RC4 1
|
||||
#define ALG_SID_SEAL 2
|
||||
|
||||
// Diffie-Hellman sub-ids
|
||||
#define ALG_SID_DH_SANDF 1
|
||||
#define ALG_SID_DH_EPHEM 2
|
||||
#define ALG_SID_AGREED_KEY_ANY 3
|
||||
#define ALG_SID_KEA 4
|
||||
#define ALG_SID_DH_SANDF 1
|
||||
#define ALG_SID_DH_EPHEM 2
|
||||
#define ALG_SID_AGREED_KEY_ANY 3
|
||||
#define ALG_SID_KEA 4
|
||||
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
||||
#define ALG_SID_ECDH 5
|
||||
#define ALG_SID_ECDH_EPHEM 6
|
||||
#define ALG_SID_ECDH 5
|
||||
#define ALG_SID_ECDH_EPHEM 6
|
||||
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
|
||||
|
||||
// Hash sub ids
|
||||
#define ALG_SID_MD2 1
|
||||
#define ALG_SID_MD4 2
|
||||
#define ALG_SID_MD5 3
|
||||
#define ALG_SID_SHA 4
|
||||
#define ALG_SID_SHA1 4
|
||||
#define ALG_SID_MAC 5
|
||||
#define ALG_SID_RIPEMD 6
|
||||
#define ALG_SID_RIPEMD160 7
|
||||
#define ALG_SID_SSL3SHAMD5 8
|
||||
#define ALG_SID_HMAC 9
|
||||
#define ALG_SID_TLS1PRF 10
|
||||
#define ALG_SID_MD2 1
|
||||
#define ALG_SID_MD4 2
|
||||
#define ALG_SID_MD5 3
|
||||
#define ALG_SID_SHA 4
|
||||
#define ALG_SID_SHA1 4
|
||||
#define ALG_SID_MAC 5
|
||||
#define ALG_SID_RIPEMD 6
|
||||
#define ALG_SID_RIPEMD160 7
|
||||
#define ALG_SID_SSL3SHAMD5 8
|
||||
#define ALG_SID_HMAC 9
|
||||
#define ALG_SID_TLS1PRF 10
|
||||
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#define ALG_SID_HASH_REPLACE_OWF 11
|
||||
#define ALG_SID_HASH_REPLACE_OWF 11
|
||||
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#if (NTDDI_VERSION > NTDDI_WINXPSP2)
|
||||
#define ALG_SID_SHA_256 12
|
||||
#define ALG_SID_SHA_384 13
|
||||
#define ALG_SID_SHA_512 14
|
||||
#define ALG_SID_SHA_256 12
|
||||
#define ALG_SID_SHA_384 13
|
||||
#define ALG_SID_SHA_512 14
|
||||
#endif //(NTDDI_VERSION > NTDDI_WINXPSP2)
|
||||
|
||||
// secure channel sub ids
|
||||
#define ALG_SID_SSL3_MASTER 1
|
||||
#define ALG_SID_SCHANNEL_MASTER_HASH 2
|
||||
#define ALG_SID_SCHANNEL_MAC_KEY 3
|
||||
#define ALG_SID_PCT1_MASTER 4
|
||||
#define ALG_SID_SSL2_MASTER 5
|
||||
#define ALG_SID_TLS1_MASTER 6
|
||||
#define ALG_SID_SCHANNEL_ENC_KEY 7
|
||||
#define ALG_SID_SSL3_MASTER 1
|
||||
#define ALG_SID_SCHANNEL_MASTER_HASH 2
|
||||
#define ALG_SID_SCHANNEL_MAC_KEY 3
|
||||
#define ALG_SID_PCT1_MASTER 4
|
||||
#define ALG_SID_SSL2_MASTER 5
|
||||
#define ALG_SID_TLS1_MASTER 6
|
||||
#define ALG_SID_SCHANNEL_ENC_KEY 7
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
||||
// misc ECC sub ids
|
||||
#define ALG_SID_ECMQV 1
|
||||
#define ALG_SID_ECMQV 1
|
||||
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
|
||||
|
||||
// Our silly example sub-id
|
||||
#define ALG_SID_EXAMPLE 80
|
||||
#define ALG_SID_EXAMPLE 80
|
||||
|
||||
// certenrolls_begin -- PROV_ENUMALGS_EX
|
||||
#ifndef ALGIDDEF
|
||||
@@ -194,132 +194,139 @@ typedef unsigned int ALG_ID;
|
||||
// certenrolls_end
|
||||
|
||||
// algorithm identifier definitions
|
||||
#define CALG_MD2 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2)
|
||||
#define CALG_MD4 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4)
|
||||
#define CALG_MD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5)
|
||||
#define CALG_SHA (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA)
|
||||
#define CALG_SHA1 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1)
|
||||
#define CALG_MAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC) // Deprecated. Don't use.
|
||||
#define CALG_RSA_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
|
||||
#define CALG_DSS_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY)
|
||||
#define CALG_MD2 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2)
|
||||
#define CALG_MD4 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4)
|
||||
#define CALG_MD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5)
|
||||
#define CALG_SHA (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA)
|
||||
#define CALG_SHA1 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1)
|
||||
#define CALG_MAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC) // Deprecated. Don't use.
|
||||
#define CALG_RSA_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
|
||||
#define CALG_DSS_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY)
|
||||
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#define CALG_NO_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | ALG_SID_ANY)
|
||||
#define CALG_NO_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | ALG_SID_ANY)
|
||||
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#define CALG_RSA_KEYX (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_RSA|ALG_SID_RSA_ANY)
|
||||
#define CALG_DES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_DES)
|
||||
#define CALG_3DES_112 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_3DES_112)
|
||||
#define CALG_3DES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_3DES)
|
||||
#define CALG_DESX (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_DESX)
|
||||
#define CALG_RC2 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_RC2)
|
||||
#define CALG_RC4 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_STREAM|ALG_SID_RC4)
|
||||
#define CALG_SEAL (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_STREAM|ALG_SID_SEAL)
|
||||
#define CALG_DH_SF (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_DH_SANDF)
|
||||
#define CALG_DH_EPHEM (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_DH_EPHEM)
|
||||
#define CALG_AGREEDKEY_ANY (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_AGREED_KEY_ANY)
|
||||
#define CALG_KEA_KEYX (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_KEA)
|
||||
#define CALG_HUGHES_MD5 (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_ANY|ALG_SID_MD5)
|
||||
#define CALG_SKIPJACK (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_SKIPJACK)
|
||||
#define CALG_TEK (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_TEK)
|
||||
#define CALG_CYLINK_MEK (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_CYLINK_MEK) // Deprecated. Do not use
|
||||
#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
|
||||
#define CALG_SSL3_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SSL3_MASTER)
|
||||
#define CALG_SCHANNEL_MASTER_HASH (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SCHANNEL_MASTER_HASH)
|
||||
#define CALG_SCHANNEL_MAC_KEY (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SCHANNEL_MAC_KEY)
|
||||
#define CALG_SCHANNEL_ENC_KEY (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SCHANNEL_ENC_KEY)
|
||||
#define CALG_PCT1_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_PCT1_MASTER)
|
||||
#define CALG_SSL2_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SSL2_MASTER)
|
||||
#define CALG_TLS1_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_TLS1_MASTER)
|
||||
#define CALG_RC5 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_RC5)
|
||||
#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
|
||||
#define CALG_TLS1PRF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF)
|
||||
#define CALG_RSA_KEYX (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
|
||||
#define CALG_DES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES)
|
||||
#define CALG_3DES_112 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES_112)
|
||||
#define CALG_3DES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES)
|
||||
#define CALG_DESX (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DESX)
|
||||
#define CALG_RC2 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2)
|
||||
#define CALG_RC4 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4)
|
||||
#define CALG_SEAL (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL)
|
||||
#define CALG_DH_SF (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_SANDF)
|
||||
#define CALG_DH_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EPHEM)
|
||||
#define CALG_AGREEDKEY_ANY (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_AGREED_KEY_ANY)
|
||||
#define CALG_KEA_KEYX (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_KEA)
|
||||
#define CALG_HUGHES_MD5 (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_MD5)
|
||||
#define CALG_SKIPJACK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_SKIPJACK)
|
||||
#define CALG_TEK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_TEK)
|
||||
#define CALG_CYLINK_MEK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_CYLINK_MEK) // Deprecated. Do not use
|
||||
#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
|
||||
#define CALG_SSL3_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL3_MASTER)
|
||||
#define CALG_SCHANNEL_MASTER_HASH (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MASTER_HASH)
|
||||
#define CALG_SCHANNEL_MAC_KEY (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MAC_KEY)
|
||||
#define CALG_SCHANNEL_ENC_KEY (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_ENC_KEY)
|
||||
#define CALG_PCT1_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_PCT1_MASTER)
|
||||
#define CALG_SSL2_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL2_MASTER)
|
||||
#define CALG_TLS1_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_TLS1_MASTER)
|
||||
#define CALG_RC5 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC5)
|
||||
#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
|
||||
#define CALG_TLS1PRF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF)
|
||||
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#define CALG_HASH_REPLACE_OWF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HASH_REPLACE_OWF)
|
||||
#define CALG_AES_128 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_128)
|
||||
#define CALG_AES_192 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_192)
|
||||
#define CALG_AES_256 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_256)
|
||||
#define CALG_AES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES)
|
||||
#define CALG_HASH_REPLACE_OWF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HASH_REPLACE_OWF)
|
||||
#define CALG_AES_128 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_128)
|
||||
#define CALG_AES_192 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_192)
|
||||
#define CALG_AES_256 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256)
|
||||
#define CALG_AES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES)
|
||||
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#if (NTDDI_VERSION > NTDDI_WINXPSP2)
|
||||
#define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
|
||||
#define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384)
|
||||
#define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512)
|
||||
#define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
|
||||
#define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384)
|
||||
#define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512)
|
||||
#endif //(NTDDI_VERSION > NTDDI_WINXPSP2)
|
||||
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
||||
#define CALG_ECDH (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_ECDH)
|
||||
#define CALG_ECDH_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ECDH | ALG_SID_ECDH_EPHEM)
|
||||
#define CALG_ECMQV (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV)
|
||||
#define CALG_ECDSA (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)
|
||||
#define CALG_NULLCIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_ANY | 0)
|
||||
#define CALG_ECDH (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_ECDH)
|
||||
#define CALG_ECDH_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ECDH | ALG_SID_ECDH_EPHEM)
|
||||
#define CALG_ECMQV (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV)
|
||||
#define CALG_ECDSA (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)
|
||||
#define CALG_NULLCIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_ANY | 0)
|
||||
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
|
||||
#define CALG_THIRDPARTY_KEY_EXCHANGE (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#define CALG_THIRDPARTY_SIGNATURE (ALG_CLASS_SIGNATURE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#define CALG_THIRDPARTY_CIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#define CALG_THIRDPARTY_HASH (ALG_CLASS_HASH | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#define CALG_THIRDPARTY_KEY_EXCHANGE (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#define CALG_THIRDPARTY_SIGNATURE (ALG_CLASS_SIGNATURE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#define CALG_THIRDPARTY_CIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#define CALG_THIRDPARTY_HASH (ALG_CLASS_HASH | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
|
||||
#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1)
|
||||
|
||||
#include <pshpack8.h>
|
||||
|
||||
typedef struct _MINCRYPTOAPI_BLOB
|
||||
{
|
||||
UINT32 Size;
|
||||
_Field_size_bytes_(Size) UINT8* Data;
|
||||
_Field_size_bytes_(Size) UINT8* Data;
|
||||
|
||||
} MINCRYPT_INTEGER_BLOB, * PMINCRYPT_INTEGER_BLOB,
|
||||
MINCRYPT_UINT_BLOB, * PMINCRYPT_UINT_BLOB,
|
||||
MINCRYPT_OBJID_BLOB, * PMINCRYPT_OBJID_BLOB,
|
||||
MINCERT_NAME_BLOB, * PMINCERT_NAME_BLOB,
|
||||
MINCERT_RDN_VALUE_BLOB, * PMINCERT_RDN_VALUE_BLOB,
|
||||
MINCERT_BLOB, * PMINCERT_BLOB,
|
||||
MINCRL_BLOB, * PMINCRL_BLOB,
|
||||
MINCRYPT_DATA_BLOB, * PMINCRYPT_DATA_BLOB,
|
||||
MINCRYPT_HASH_BLOB, * PMINCRYPT_HASH_BLOB,
|
||||
MINCRYPT_DIGEST_BLOB, * PMINCRYPT_DIGEST_BLOB,
|
||||
MINCRYPT_DER_BLOB, * PMINCRYPT_DER_BLOB,
|
||||
MINCRYPT_ATTR_BLOB, * PMINCRYPT_ATTR_BLOB;
|
||||
} MINCRYPT_INTEGER_BLOB, *PMINCRYPT_INTEGER_BLOB, MINCRYPT_UINT_BLOB, *PMINCRYPT_UINT_BLOB, MINCRYPT_OBJID_BLOB,
|
||||
*PMINCRYPT_OBJID_BLOB, MINCERT_NAME_BLOB, *PMINCERT_NAME_BLOB, MINCERT_RDN_VALUE_BLOB, *PMINCERT_RDN_VALUE_BLOB,
|
||||
MINCERT_BLOB, *PMINCERT_BLOB, MINCRL_BLOB, *PMINCRL_BLOB, MINCRYPT_DATA_BLOB, *PMINCRYPT_DATA_BLOB,
|
||||
MINCRYPT_HASH_BLOB, *PMINCRYPT_HASH_BLOB, MINCRYPT_DIGEST_BLOB, *PMINCRYPT_DIGEST_BLOB, MINCRYPT_DER_BLOB,
|
||||
*PMINCRYPT_DER_BLOB, MINCRYPT_ATTR_BLOB, *PMINCRYPT_ATTR_BLOB;
|
||||
|
||||
// Encoded, length-delimited name bytes; not necessarily ANSI or NUL-terminated.
|
||||
// The observed 26100 x64 string tag occupies padding; see the opt-in version header.
|
||||
typedef struct _MINCRYPT_NAME_BLOB
|
||||
{
|
||||
_Field_size_bytes_(Size) PCHAR Data;
|
||||
_Field_size_bytes_(Size) PCHAR Data;
|
||||
USHORT Size;
|
||||
|
||||
}MINCRYPT_NAME_BLOB, * PMINCRYPT_NAME_BLOB;
|
||||
} MINCRYPT_NAME_BLOB, *PMINCRYPT_NAME_BLOB;
|
||||
|
||||
#define MINCRYPT_MAX_HASH_LENGTH (64)
|
||||
#define MINCRYPT_SHA1_LENGTH (160/8)
|
||||
#define MINCRYPT_SHA256_LENGTH (256/8)
|
||||
#define MINCRYPT_MAX_HASH_LENGTH (64)
|
||||
#define MINCRYPT_SHA1_LENGTH (160 / 8)
|
||||
#define MINCRYPT_SHA256_LENGTH (256 / 8)
|
||||
#define MINCRYPT_SHA384_LENGTH (384 / 8)
|
||||
#define MINCRYPT_SHA512_LENGTH (512 / 8)
|
||||
|
||||
typedef struct _MINCRYPT_CHAIN_ELEMENT
|
||||
{
|
||||
ALG_ID HashAlgId; // CALG_SHA1, CALG_SHA_256
|
||||
UINT32 HashSize; // SHA1(160bit/8), SHA256(256bit/8)
|
||||
UINT8 Hash[MINCRYPT_MAX_HASH_LENGTH];
|
||||
ALG_ID HashAlgId; // CALG_SHA1, CALG_SHA_256
|
||||
UINT32 HashSize; // SHA1(160bit/8), SHA256(256bit/8)
|
||||
UINT8 Hash[MINCRYPT_MAX_HASH_LENGTH];
|
||||
|
||||
MINCRYPT_NAME_BLOB Subject;
|
||||
MINCRYPT_NAME_BLOB Issuer;
|
||||
|
||||
MINCERT_BLOB Certificate;
|
||||
MINCERT_BLOB Certificate;
|
||||
|
||||
}MINCRYPT_CHAIN_ELEMENT, * PMINCRYPT_CHAIN_ELEMENT;
|
||||
} MINCRYPT_CHAIN_ELEMENT, *PMINCRYPT_CHAIN_ELEMENT;
|
||||
|
||||
// CI owns one chain allocation; nested pointers borrow that allocation.
|
||||
// Do not free child blobs separately or use memcpy to create a second owner.
|
||||
typedef struct _MINCRYPT_CHAIN_INFO
|
||||
{
|
||||
UINT32 Size;
|
||||
UINT32 Size; // Observed 26100 x64: total allocation bytes, including trailing data.
|
||||
|
||||
MINCERT_BLOB* PublicKeys;
|
||||
UINT32 NumberOfPublicKeys;
|
||||
MINCERT_BLOB* PublicKeys;
|
||||
UINT32 NumberOfPublicKeys;
|
||||
|
||||
MINCERT_BLOB* EKUs;
|
||||
UINT32 NumberOfEKUs;
|
||||
MINCERT_BLOB* EKUs;
|
||||
UINT32 NumberOfEKUs;
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10)
|
||||
|
||||
PMINCRYPT_CHAIN_ELEMENT ChainElements;
|
||||
UINT32 NumberOfChainElement;
|
||||
UINT32 NumberOfChainElement;
|
||||
|
||||
// ASN.1 blob of authenticated attributes - spcSpOpusInfo, contentType, etc.
|
||||
// REQUIRES a confirmed runtime layout (10586 and later sampled profiles).
|
||||
// Sampled 10240 has only 56 header bytes: +0x38 begins variable payload.
|
||||
// NTDDI_VERSION and allocation Size cannot establish field availability.
|
||||
// See Domito.MinCrypt.Historical.h for distinct observed x64 prefix views.
|
||||
MINCRYPT_ATTR_BLOB AuthenticodeAttributes;
|
||||
|
||||
// UINT8 Hash[32];
|
||||
// RootId occupies padding at +0x34 in all six historical x64 samples and
|
||||
// 26100. The historical views name it without extending this default layout.
|
||||
// 26100's 32-byte platform-manifest binary ID at +0x48 is named only in its
|
||||
// explicit version header. Earlier 104-byte views reserve that extension.
|
||||
// Do not infer field availability solely from NTDDI_VERSION or Size.
|
||||
|
||||
#endif // NTDDI_VERSION >= NTDDI_WIN10
|
||||
|
||||
@@ -333,60 +340,66 @@ typedef struct _MINCRYPT_CHAIN_INFO
|
||||
|
||||
// ChainElements[NumberOfChainElement]
|
||||
|
||||
}MINCRYPT_CHAIN_INFO, * PMINCRYPT_CHAIN_INFO;
|
||||
} MINCRYPT_CHAIN_INFO, *PMINCRYPT_CHAIN_INFO;
|
||||
|
||||
typedef struct _MINCRYPT_POLICY_INFO
|
||||
{
|
||||
UINT32 Size;
|
||||
UINT32 VerificationStatus;
|
||||
UINT32 PolicyBits;
|
||||
UINT32 Size;
|
||||
NTSTATUS VerificationStatus; // Check API return status separately.
|
||||
UINT32 PolicyBits;
|
||||
|
||||
MINCRYPT_CHAIN_INFO* ChainInfo;
|
||||
|
||||
LARGE_INTEGER RevocationTime; // When was the certificate revoked (if applicable)
|
||||
LARGE_INTEGER RevocationTime; // When was the certificate revoked (if applicable)
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10)
|
||||
|
||||
LARGE_INTEGER NotBefore; // The certificate is not valid before this time
|
||||
LARGE_INTEGER NotAfter; // The certificate is not valid after this time
|
||||
LARGE_INTEGER NotBefore; // Observed: signer certificate validity start.
|
||||
LARGE_INTEGER NotAfter; // Observed: signer certificate validity end.
|
||||
|
||||
#endif // NTDDI_VERSION >= NTDDI_WIN10
|
||||
|
||||
}MINCRYPT_POLICY_INFO, PMINCRYPT_POLICY_INFO;
|
||||
} MINCRYPT_POLICY_INFO, *PMINCRYPT_POLICY_INFO;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resets a PolicyInfo struct - frees the dynamically allocated buffer in PolicyInfo (ChainInfo) if not null.
|
||||
* Zeros the entire PolicyInfo struct.
|
||||
* Release a known initialized policy's owned ChainInfo allocation and reset it.
|
||||
* Zero-initialize policy objects before first use. Release both signer and TSA
|
||||
* policies after use, including failures, and before reusing output storage.
|
||||
* Borrowed child pointers become invalid when the owner is released. Never clear
|
||||
* Size while a chain is still owned. Size does not negotiate the runtime layout.
|
||||
*
|
||||
* @param PolicyInfo - the struct to reset.
|
||||
* @param PolicyInfo - initialized policy, not arbitrary uninitialized storage.
|
||||
*
|
||||
* @return the struct which was reset.
|
||||
* Ignore the return value. The legacy PVOID declaration is retained for source
|
||||
* compatibility; observed 26100 x64 code provides no defined pointer return.
|
||||
*/
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
MINCRYPTAPI
|
||||
PVOID
|
||||
NTAPI
|
||||
PVOID NTAPI
|
||||
CiFreePolicyInfo(
|
||||
_Inout_ MINCRYPT_POLICY_INFO* PolicyInfo
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Win7SP1-Win8.1 only (KB3033929 installed). Use CiValidateFileObject on Win10!
|
||||
* Digest-based workflow, also implemented on observed Windows 11 build 26100.
|
||||
* Prefer the file-object workflow when its policy fits. Older-build ABI and
|
||||
* KB3033929 requirements need a separately verified compatibility matrix.
|
||||
*
|
||||
* Given a file digest and signature of a file, verify the signature and provide information regarding
|
||||
* the certificates that was used for signing (the entire certificate chain)
|
||||
*
|
||||
* @param Hash - buffer containing the digest
|
||||
* @param Hash[in] - caller-computed file digest; CI does not recompute the file bytes
|
||||
*
|
||||
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
|
||||
*
|
||||
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
|
||||
*
|
||||
* @param SecurityDirectory - pointer to the start of the security directory
|
||||
* @param SecurityDirectory - WIN_CERTIFICATE header, not the PKCS#7 payload.
|
||||
* Observed 26100 x64 checks 4-byte pointer alignment, revision 0x200,
|
||||
* type 2, supplied size >=12 and 8 < dwLength <= supplied size.
|
||||
* This wrapper selects the first entry; it does not enumerate the table.
|
||||
*
|
||||
* @param SizeOfSecurityDirectory - size the security directory
|
||||
*
|
||||
@@ -396,94 +409,109 @@ CiFreePolicyInfo(
|
||||
*
|
||||
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain
|
||||
*
|
||||
* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified.
|
||||
* @return Overall verification NTSTATUS. A successful policy VerificationStatus
|
||||
* does not replace this return value: the final file-digest comparison
|
||||
* can still fail. Both policy outputs may carry diagnostics on failure.
|
||||
* See docs/mincrypt-contracts.md for ownership and policy limits.
|
||||
* Various error values otherwise, for example:
|
||||
* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature
|
||||
* STATUS_INVALID_IMAGE_HASH - digest/signature or selected CI policy rejected
|
||||
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
|
||||
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
|
||||
*/
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
MINCRYPTAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NTSTATUS NTAPI
|
||||
CiCheckSignedFile(
|
||||
_In_ PVOID Hash,
|
||||
_In_ UINT32 HashSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_In_ PVOID SecurityDirectory,
|
||||
_In_ UINT32 SizeOfSecurityDirectory,
|
||||
_In_reads_bytes_(HashSize) PVOID Hash,
|
||||
_In_ UINT32 HashSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_In_reads_bytes_(SizeOfSecurityDirectory) PVOID SecurityDirectory,
|
||||
_In_ UINT32 SizeOfSecurityDirectory,
|
||||
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
|
||||
);
|
||||
|
||||
// Existing Domito compatibility filter, not a universal trusted-root policy.
|
||||
// Includes test/DMD categories and a diagnostic bit; select policy deliberately.
|
||||
#define DOMITO_CI_LEGACY_CATALOG_POLICY_BITS 0x0002007FUL
|
||||
|
||||
/**
|
||||
* Win7SP1-Win8.1 only (KB3033929 installed). Use CiValidateFileObject on Win10!
|
||||
* Digest-based workflow, also implemented on observed Windows 11 build 26100.
|
||||
* Prefer the file-object workflow when its policy fits. Older-build ABI and
|
||||
* KB3033929 requirements need a separately verified compatibility matrix.
|
||||
*
|
||||
* Checks if the SHA-1 message digest is contained within a verified system catalog
|
||||
* Finds a caller-computed file digest in an accepted installed catalog.
|
||||
* Observed 26100 x64 file-hash lookup supports SHA-1 and SHA-256.
|
||||
*
|
||||
* @note must be attached to the PsInitialSystemProcess first!
|
||||
*
|
||||
* @param Hash - buffer containing the digest
|
||||
* @param Hash[in] - caller-computed file digest; CI does not recompute the file bytes
|
||||
*
|
||||
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
|
||||
*
|
||||
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
|
||||
*
|
||||
* @param IsReloadCatalogs - is reload catalogs cache.
|
||||
* @param ReloadCatalogs - request catalog-store reload; process/silo and cache state matter.
|
||||
*
|
||||
* @param Always0 - this is for IsReloadCatalogs, Always0 != 0 ? 16 : 24;
|
||||
* @param RequireTrustedCatalog - nonzero requires the observed catalog TRUSTED
|
||||
* extension marker. This does not itself establish Microsoft signer trust.
|
||||
*
|
||||
* @param Always2007F - unknown, always 0x2007F, maybe a mask.
|
||||
* @param AcceptedCatalogPolicyBits - candidate catalog policy-bit filter.
|
||||
* Observed 26100 x64 requires ANY overlap with catalog PolicyBits, not
|
||||
* every requested bit. This is not a flags-to-enable input.
|
||||
*
|
||||
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain.
|
||||
*
|
||||
* @param CatalogName[out option] - catalog file name.
|
||||
* @param CatalogName[out option] - initialize empty; observed 26100 x64 returns
|
||||
* a separate duplicated string allocation. Release a returned Buffer
|
||||
* with RtlFreeUnicodeString, separately from both policy outputs.
|
||||
*
|
||||
* @param SigningTime[out] - when the file was signed (FILETIME format)
|
||||
*
|
||||
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain.
|
||||
*
|
||||
* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified.
|
||||
* @return Overall verification NTSTATUS. A successful policy VerificationStatus
|
||||
* does not replace this return value. Catalog selection and the
|
||||
* selected policy still apply. Outputs may carry diagnostics on failure.
|
||||
* See docs/mincrypt-contracts.md for ownership and policy limits.
|
||||
* Various error values otherwise, for example:
|
||||
* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature
|
||||
* STATUS_INVALID_IMAGE_HASH - digest/signature or selected CI policy rejected
|
||||
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
|
||||
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
|
||||
*/
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
MINCRYPTAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NTSTATUS NTAPI
|
||||
CiVerifyHashInCatalog(
|
||||
_In_ PVOID Hash,
|
||||
_In_ UINT32 HashSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_In_ BOOLEAN IsReloadCatalogs,
|
||||
_In_ UINT32 Always0,
|
||||
_In_ UINT32 Always2007F,
|
||||
_In_reads_bytes_(HashSize) PVOID Hash,
|
||||
_In_ UINT32 HashSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_In_ BOOLEAN ReloadCatalogs,
|
||||
_In_ UINT32 RequireTrustedCatalog,
|
||||
_In_ UINT32 AcceptedCatalogPolicyBits,
|
||||
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
||||
_Out_opt_ UNICODE_STRING* CatalogName,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Out_opt_ UNICODE_STRING* CatalogName,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
|
||||
);
|
||||
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10)
|
||||
|
||||
typedef
|
||||
_IRQL_requires_same_
|
||||
_Function_class_(MINCRYPT_ALLOCATE_ROUTINE)
|
||||
__drv_allocatesMem(Mem)
|
||||
typedef _IRQL_requires_same_ _Function_class_(MINCRYPT_ALLOCATE_ROUTINE)
|
||||
__drv_allocatesMem(
|
||||
Mem
|
||||
)
|
||||
PVOID
|
||||
NTAPI
|
||||
MINCRYPT_ALLOCATE_ROUTINE(
|
||||
_In_ SIZE_T ByteSize
|
||||
);
|
||||
MINCRYPT_ALLOCATE_ROUTINE(_In_ SIZE_T ByteSize);
|
||||
typedef MINCRYPT_ALLOCATE_ROUTINE* PMINCRYPT_ALLOCATE_ROUTINE;
|
||||
|
||||
/**
|
||||
* Parse the publisher name from the certificate
|
||||
* Parse the publisher name from the certificate.
|
||||
* Export absent from sampled Windows 10 x64 builds 10240–17134; observed present
|
||||
* on 19041.1865, 22000.318 and 26100 x64; absent on sampled 19041.1 x64.
|
||||
* The NTDDI guard does not establish runtime availability. See NOTES.md.
|
||||
*
|
||||
* @param Certificate - &PolicyInfo.ChainInfo->ChainElements[x].Certificate
|
||||
*
|
||||
@@ -491,7 +519,10 @@ typedef MINCRYPT_ALLOCATE_ROUTINE* PMINCRYPT_ALLOCATE_ROUTINE;
|
||||
*
|
||||
* @param PublisherName[out] - publisher name.
|
||||
*
|
||||
* @return buffer length.
|
||||
* @return NTSTATUS. The string byte count is returned in PublisherName->Length.
|
||||
* Free PublisherName->Buffer with the allocator paired with AllocateRoutine,
|
||||
* including on failure if a buffer was allocated. This routine extracts a name;
|
||||
* it does not verify the certificate or its signer.
|
||||
*/
|
||||
MINCRYPTAPI
|
||||
NTSTATUS
|
||||
@@ -502,23 +533,40 @@ CiGetCertPublisherName(
|
||||
_Out_ PUNICODE_STRING PublisherName
|
||||
);
|
||||
|
||||
|
||||
// Export observed already in 15063.0 x64 (1703); absent from sampled
|
||||
// 10240/10586/14393 files. This writes CI-global state, not per-file policy.
|
||||
MINCRYPTAPI
|
||||
VOID
|
||||
NTAPI
|
||||
VOID NTAPI
|
||||
CiSetTrustedOriginClaimId(
|
||||
_In_ UINT32 ClaimId
|
||||
);
|
||||
|
||||
// Domito descriptive name, not an official Microsoft flag name.
|
||||
// Observed on CI 10.0.26100.8328 x64: broadens the accepted-root mask in
|
||||
// CipGetAcceptedRootKeys. Sampled 1709/1803 instead select 0x224FF; earlier helper
|
||||
// generations differ. This is not a WinVerifyTrust-equivalent trust policy.
|
||||
// See docs/ci-validate-file-object.md for evidence and version limitations.
|
||||
#define DOMITO_CI_VALIDATE_FLAG_BROADEN_ROOT_ACCEPTANCE 0x00000020UL
|
||||
|
||||
// Descriptive experimental bit, not an official or isolated selector flag.
|
||||
// Participates in first-success guards in examined 22621/26100 x64 CI bodies;
|
||||
// also changes default-path policy and fallback. One 22631 TESTSIGNING-enabled
|
||||
// BthPS3 run confirms 0x20|0x80 returns its primary company signer. It is not an
|
||||
// arbitrary signer index, guaranteed primary selection, or a production default.
|
||||
#define DOMITO_CI_VALIDATE_FLAG_FIRST_SUCCESS_EXPERIMENTAL 0x00000080UL
|
||||
|
||||
/**
|
||||
* Given a file object, verify the signature and provide information regarding
|
||||
* the certificates that was used for signing (the entire certificate chain)
|
||||
*
|
||||
* @param FileObject - FileObject of the PE in question
|
||||
*
|
||||
* @param Unkonwn1 - unknown, 0 is a valid value. (Unkonwn1 and Unkonwn2 together calculate the minimum support algorithm)
|
||||
* @param ValidationFlags - validation policy flags; 0 is a valid value.
|
||||
* See DOMITO_CI_VALIDATE_FLAG_BROADEN_ROOT_ACCEPTANCE and the accompanying documentation.
|
||||
*
|
||||
* @param Unkonwn2 - unknown, 0 is a valid value. (^ the words above refer to 'CipGetHashAlgorithmForLegacyScenario')
|
||||
* @param RequestedSigningLevel - requested signing level; 0 is used by the probe.
|
||||
* CI 26100 x64 consumes the low byte. UINT32 is retained for ABI compatibility
|
||||
* until other supported architectures/builds are verified; use values in 0..255.
|
||||
*
|
||||
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain.
|
||||
*
|
||||
@@ -526,32 +574,37 @@ CiSetTrustedOriginClaimId(
|
||||
*
|
||||
* @param SigningTime[out] - when the file was signed (FILETIME format)
|
||||
*
|
||||
* @param Hash - buffer containing the digest
|
||||
* @param Hash[out] - file digest, not a certificate thumbprint. Supply at least
|
||||
* MINCRYPT_MAX_HASH_LENGTH bytes (required by the observed 26100 x64 helper).
|
||||
*
|
||||
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
|
||||
* @param HashSize[in,out] - buffer capacity on entry; actual digest size on success.
|
||||
* Initialize to sizeof(Hash) for every call, including retries.
|
||||
*
|
||||
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
|
||||
*
|
||||
* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified.
|
||||
* Initialize both policy outputs to empty objects and free both with CiFreePolicyInfo
|
||||
* before reuse. Do not interpret failed-call outputs as a verification result.
|
||||
*
|
||||
* @return STATUS_SUCCESS when verification succeeds under the selected CI policy.
|
||||
* This does not by itself establish the application's signer trust policy.
|
||||
* Various error values otherwise, for example:
|
||||
* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature
|
||||
* STATUS_INVALID_IMAGE_HASH - digest/signature or selected CI policy rejected
|
||||
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
|
||||
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
|
||||
*/
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
MINCRYPTAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NTSTATUS NTAPI
|
||||
CiValidateFileObject(
|
||||
_In_ FILE_OBJECT* FileObject,
|
||||
_In_opt_ UINT32 Unkonwn1,
|
||||
_In_opt_ UINT32 Unkonwn2,
|
||||
_In_ FILE_OBJECT* FileObject,
|
||||
_In_ UINT32 ValidationFlags,
|
||||
_In_ UINT32 RequestedSigningLevel,
|
||||
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
||||
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Out_ UINT8* Hash,
|
||||
_Inout_ UINT32* HashSize,
|
||||
_Out_ ALG_ID* HashAlgId
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Out_writes_bytes_(*HashSize) UINT8* Hash,
|
||||
_Inout_ UINT32* HashSize,
|
||||
_Out_ ALG_ID* HashAlgId
|
||||
);
|
||||
|
||||
#endif // NTDDI_VERSION >= NTDDI_WIN10
|
||||
|
||||
+233
-55
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <Domito.MinCrypt.h>
|
||||
|
||||
|
||||
/* ___
|
||||
* / __|___ _ __ _ __ ___ _ _
|
||||
* | (__/ _ \ ' \| ' \/ _ \ ' \
|
||||
@@ -12,7 +11,7 @@
|
||||
|
||||
//
|
||||
// Library initialization tasks. Call once in your DriverEntry
|
||||
//
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
@@ -25,7 +24,6 @@ EXTERN_C
|
||||
void
|
||||
DomitoShutdown();
|
||||
|
||||
|
||||
/* __ __ __ __ _
|
||||
* | \/ |___ _ __ ___ _ _ _ _ | \/ |__ _ _ _ __ _ __ _ ___ _ __ ___ _ _| |_
|
||||
* | |\/| / -_) ' \/ _ \ '_| || | | |\/| / _` | ' \/ _` / _` / -_) ' \/ -_) ' \ _|
|
||||
@@ -35,34 +33,26 @@ DomitoShutdown();
|
||||
|
||||
//
|
||||
// Allocator function the library uses.
|
||||
//
|
||||
typedef
|
||||
_IRQL_requires_same_
|
||||
_Function_class_(EVT_DOMITO_ALLOCATE_ROUTINE)
|
||||
__drv_allocatesMem(mem)
|
||||
//
|
||||
typedef _IRQL_requires_same_ _Function_class_(EVT_DOMITO_ALLOCATE_ROUTINE)
|
||||
__drv_allocatesMem(
|
||||
mem
|
||||
)
|
||||
PVOID
|
||||
NTAPI
|
||||
EVT_DOMITO_ALLOCATE_ROUTINE(
|
||||
_In_ SIZE_T ByteSize
|
||||
);
|
||||
EVT_DOMITO_ALLOCATE_ROUTINE(_In_ SIZE_T ByteSize);
|
||||
typedef EVT_DOMITO_ALLOCATE_ROUTINE* PFN_DOMITO_ALLOCATE_ROUTINE;
|
||||
|
||||
//
|
||||
// Freeing function the library uses.
|
||||
//
|
||||
typedef
|
||||
_IRQL_requires_same_
|
||||
_Function_class_(EVT_DOMITO_FREE_ROUTINE)
|
||||
void
|
||||
NTAPI
|
||||
EVT_DOMITO_FREE_ROUTINE(
|
||||
_In_ __drv_freesMem(mem) PVOID Memory
|
||||
);
|
||||
//
|
||||
typedef _IRQL_requires_same_ _Function_class_(EVT_DOMITO_FREE_ROUTINE) void NTAPI
|
||||
EVT_DOMITO_FREE_ROUTINE(_In_ __drv_freesMem(mem) PVOID Memory);
|
||||
typedef EVT_DOMITO_FREE_ROUTINE* PFN_DOMITO_FREE_ROUTINE;
|
||||
|
||||
//
|
||||
// Get the original set of Domito memory functions.
|
||||
//
|
||||
//
|
||||
EXTERN_C
|
||||
void
|
||||
DomitoGetOriginalMemoryFunctions(
|
||||
@@ -72,7 +62,7 @@ DomitoGetOriginalMemoryFunctions(
|
||||
|
||||
//
|
||||
// Get the current set of Domito memory functions.
|
||||
//
|
||||
//
|
||||
EXTERN_C
|
||||
void
|
||||
DomitoGetMemoryFunctions(
|
||||
@@ -81,7 +71,9 @@ DomitoGetMemoryFunctions(
|
||||
);
|
||||
|
||||
//
|
||||
// Replace Domito's memory allocation functions with a custom set
|
||||
// Replace Domito's memory allocation functions with a compatible pair during
|
||||
// quiescent initialization. No in-flight calls or outstanding callback-backed
|
||||
// allocations may span a pair change. Replacement is not synchronized.
|
||||
EXTERN_C
|
||||
void
|
||||
DomitoSetMemoryFunctions(
|
||||
@@ -89,7 +81,6 @@ DomitoSetMemoryFunctions(
|
||||
_In_opt_ PFN_DOMITO_FREE_ROUTINE Free
|
||||
);
|
||||
|
||||
|
||||
/* ___ _ _
|
||||
* / __|_ _ _ _ _ __| |_ ___ __ _ _ _ __ _ _ __| |_ _ _
|
||||
* | (__| '_| || | '_ \ _/ _ \/ _` | '_/ _` | '_ \ ' \ || |
|
||||
@@ -97,9 +88,9 @@ DomitoSetMemoryFunctions(
|
||||
* |__/|_| |___/ |_| |__/
|
||||
*/
|
||||
|
||||
//
|
||||
// This structure encapsulates a signature used in verifying executable files.
|
||||
//
|
||||
//
|
||||
// This structure encapsulates a signature used in verifying executable files.
|
||||
//
|
||||
#if !defined(WIN_CERTIFICATE)
|
||||
typedef struct _WIN_CERTIFICATE
|
||||
{
|
||||
@@ -112,16 +103,16 @@ typedef struct _WIN_CERTIFICATE
|
||||
|
||||
//
|
||||
// UM definitions of WinCrypt.h
|
||||
//
|
||||
//
|
||||
|
||||
#if !defined(WIN_CERT_TYPE_X509)
|
||||
#define WIN_CERT_TYPE_X509 (0x0001) // The bCertificate member contains an X.509 certificate.
|
||||
#define WIN_CERT_TYPE_X509 (0x0001) // The bCertificate member contains an X.509 certificate.
|
||||
#endif
|
||||
#if !defined(WIN_CERT_TYPE_PKCS_SIGNED_DATA)
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA (0x0002) // The bCertificate member contains a PKCS SignedData structure.
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA (0x0002) // The bCertificate member contains a PKCS SignedData structure.
|
||||
#endif
|
||||
#if !defined(WIN_CERT_TYPE_PKCS1_SIGN)
|
||||
#define WIN_CERT_TYPE_PKCS1_SIGN (0x0009) // The bCertificate member contains PKCS1_MODULE_SIGN fields.
|
||||
#define WIN_CERT_TYPE_PKCS1_SIGN (0x0009) // The bCertificate member contains PKCS1_MODULE_SIGN fields.
|
||||
#endif
|
||||
|
||||
#if !defined(CALG_SHA1)
|
||||
@@ -141,6 +132,7 @@ typedef struct _WIN_CERTIFICATE
|
||||
// Converts a WinCrypt CALG_ID to a BCRYPT_ALGORITHM identifier.
|
||||
//
|
||||
PCWSTR
|
||||
|
||||
FORCEINLINE
|
||||
DOMITO_CALG_TO_BCRYPT_ALGORITHM(
|
||||
_In_ UINT32 Calg
|
||||
@@ -161,7 +153,6 @@ DOMITO_CALG_TO_BCRYPT_ALGORITHM(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ___ _ ___ _ _ _
|
||||
* / __|___ __| |___ |_ _|_ _| |_ ___ __ _ _ _(_) |_ _ _
|
||||
* | (__/ _ \/ _` / -_) | || ' \ _/ -_) _` | '_| | _| || |
|
||||
@@ -170,26 +161,74 @@ DOMITO_CALG_TO_BCRYPT_ALGORITHM(
|
||||
*/
|
||||
|
||||
//
|
||||
// Extracts the CALG_ID from a signed PE that was used to
|
||||
// calculate the message digest when it was signed
|
||||
// Heuristically detects the CALG_ID in the first WIN_CERTIFICATE using byte patterns.
|
||||
// Returns CALG_SHA1 when absent, malformed, or unrecognized; this is not ASN.1
|
||||
// validation or signature verification. The directory array must contain the
|
||||
// IMAGE_DIRECTORY_ENTRY_SECURITY entry.
|
||||
//
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
EXTERN_C
|
||||
UINT32
|
||||
__declspec(deprecated(
|
||||
"Use DomitoGetPortableExecutableDigestKindEx; heuristic detection silently falls back to SHA-1. Check the returned NTSTATUS."
|
||||
)) UINT32
|
||||
DomitoGetPortableExecutableDigestKind(
|
||||
_In_ PUCHAR pPeBytes,
|
||||
_In_ ULONG PeSize,
|
||||
_In_ PIMAGE_DATA_DIRECTORY pImgDataDirectory
|
||||
);
|
||||
|
||||
//
|
||||
// Extracts Authenticode signing information and calculates the file digest of a PE file.
|
||||
//
|
||||
// Reads the first PKCS#7 entry's SpcIndirectDataContent DigestInfo algorithm
|
||||
// using bounded DER navigation. Does not validate the signature or select among
|
||||
// multiple/nested signatures. Absent table => STATUS_NOT_FOUND; unsupported OID
|
||||
// or certificate type => STATUS_NOT_SUPPORTED; malformed DER => format error.
|
||||
// Unlike the compatibility helper above, it never silently falls back to SHA-1.
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoGetPortableExecutableDigestKindEx(
|
||||
_In_reads_bytes_(PeSize) const UCHAR* PeBytes,
|
||||
_In_ ULONG PeSize,
|
||||
_In_reads_(IMAGE_DIRECTORY_ENTRY_SECURITY + 1) const IMAGE_DATA_DIRECTORY* Directories,
|
||||
_Out_ PUINT32 DigestCalg
|
||||
);
|
||||
|
||||
// Algorithm-explicit Authenticode digest for the supported layout subset:
|
||||
// bounded PE32/PE32+ headers, contiguous nonoverlapping raw sections in file
|
||||
// offset order, optional overlay before a complete EOF certificate table.
|
||||
// SHA-1/256/384/512 supported. Gaps/overlaps/nonterminal certificates are rejected.
|
||||
// No signature trust decision is made. Outputs are cleared on failure; the
|
||||
// certificate borrows stable input memory, and only the digest must be freed.
|
||||
// See docs/authenticode-digests.md for policy and Windows SIP comparisons.
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoCalculatePortableExecutableDigestEx(
|
||||
_In_reads_bytes_(PeSize) const UCHAR* PeBytes,
|
||||
_In_ ULONG PeSize,
|
||||
_In_ UINT32 HashAlgId,
|
||||
_Out_ PULONG DigestSize,
|
||||
_Outptr_result_bytebuffer_(*DigestSize) PVOID* Digest,
|
||||
_Outptr_result_maybenull_ LPWIN_CERTIFICATE* Certificate,
|
||||
_Out_ PULONG SecuritySize
|
||||
);
|
||||
|
||||
//
|
||||
// Calculates a PE digest using the existing linear hashing convention.
|
||||
// Validates accessed header/certificate ranges and clears outputs on failure
|
||||
// when all output pointers are valid. The input buffer must remain stable.
|
||||
// The returned certificate pointer borrows the input buffer; free only the digest
|
||||
// with DomitoFreePortableExecutableDigest. Algorithm detection is heuristic;
|
||||
// general section-ordered Authenticode hashing is not implemented here.
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
__declspec(deprecated(
|
||||
"Use DomitoCalculatePortableExecutableDigestEx with an explicit algorithm; review its supported PE layout and failure statuses."
|
||||
)) NTSTATUS
|
||||
DomitoCalculatePortableExecutableDigest(
|
||||
_In_ PUCHAR pPeBytes,
|
||||
_In_ ULONG PeSize,
|
||||
@@ -202,7 +241,7 @@ DomitoCalculatePortableExecutableDigest(
|
||||
|
||||
//
|
||||
// Frees the memory allocated by DomitoCalculatePortableExecutableDigest.
|
||||
//
|
||||
//
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
EXTERN_C
|
||||
void
|
||||
@@ -210,14 +249,121 @@ DomitoFreePortableExecutableDigest(
|
||||
_In_ PVOID pDigestOut
|
||||
);
|
||||
|
||||
//
|
||||
// Verifies if the Authenticode signature of a give PE file matches the provided (e.g. SHA1) file digest.
|
||||
//
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10)
|
||||
// Native forwards caller flags unchanged. The experimental x64 mode additionally
|
||||
// sets 0x80; it stops after the first accepted candidate in examined CI builds,
|
||||
// and also changes other policy/fallback paths. Neither mode selects a publisher
|
||||
// or enumerates signatures. No root-acceptance flag is added automatically.
|
||||
typedef enum _DOMITO_CI_SIGNATURE_SELECTION
|
||||
{
|
||||
DomitoCiSignatureSelectionNative = 0,
|
||||
DomitoCiSignatureSelectionFirstSuccessfulExperimental = 1
|
||||
} DOMITO_CI_SIGNATURE_SELECTION;
|
||||
|
||||
// Zero-initialize before first use. Both policies own their CI chain allocations,
|
||||
// including possible diagnostic allocations on failure. Do not copy as an owner.
|
||||
// Hash is a file digest, not a certificate thumbprint. Hash/algorithm/signing time
|
||||
// are cleared on failure; policies may retain diagnostics. Check return NTSTATUS.
|
||||
typedef struct _DOMITO_CI_VALIDATION_RESULT
|
||||
{
|
||||
MINCRYPT_POLICY_INFO PolicyInfo;
|
||||
MINCRYPT_POLICY_INFO TimeStampPolicyInfo;
|
||||
LARGE_INTEGER SigningTime;
|
||||
UINT8 Hash[MINCRYPT_MAX_HASH_LENGTH];
|
||||
UINT32 HashSize;
|
||||
ALG_ID HashAlgId;
|
||||
UINT32 FileObjectValidationFlags; // Flags passed to CI export; zero for embedded helper.
|
||||
UINT8 RequestedSigningLevel; // File-object helper only.
|
||||
} DOMITO_CI_VALIDATION_RESULT, *PDOMITO_CI_VALIDATION_RESULT;
|
||||
|
||||
// Safe for NULL or an empty/initialized result; resets all fields after cleanup.
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
void
|
||||
DomitoFreeCiValidationResult(
|
||||
_Inout_opt_ DOMITO_CI_VALIDATION_RESULT* Result
|
||||
);
|
||||
|
||||
// Referenced FILE_OBJECT at PASSIVE_LEVEL; keep file bytes stable. Previous result
|
||||
// policies are released before reuse, including invalid-argument failures.
|
||||
// Supplies a fresh 64-byte hash buffer on every call. FirstSuccessfulExperimental
|
||||
// is opt-in and x64-only; other architectures return STATUS_NOT_SUPPORTED for it.
|
||||
// Only one selected signer plus its timestamp policy is returned. The caller
|
||||
// must enforce its expected certificate and intended trust policy separately.
|
||||
_Success_(return >= 0)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoValidateFileObjectEx(
|
||||
_In_ PFILE_OBJECT FileObject,
|
||||
_In_ UINT32 ValidationFlags,
|
||||
_In_ UINT8 RequestedSigningLevel,
|
||||
_In_ DOMITO_CI_SIGNATURE_SELECTION Selection,
|
||||
_Inout_ DOMITO_CI_VALIDATION_RESULT* Result
|
||||
);
|
||||
|
||||
// Hash and verify the first WIN_CERTIFICATE in a stable PE buffer. Uses the
|
||||
// explicit digest helper's supported contiguous-section/EOF-certificate subset.
|
||||
// SHA-1/256/384/512 are explicit; no algorithm retry or catalog fallback occurs.
|
||||
// CI may select a nested signature under its algorithm rules: this is not a
|
||||
// universal force-primary API. Matching SHA-256 selects the company primary in
|
||||
// the tested dual-signed BthPS3 fixture. Caller still checks the returned signer.
|
||||
_Success_(return >= 0)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoValidatePortableExecutableEmbeddedSignature(
|
||||
_In_reads_bytes_(PeSize) const UCHAR* PeBytes,
|
||||
_In_ ULONG PeSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_Inout_ DOMITO_CI_VALIDATION_RESULT* Result
|
||||
);
|
||||
#endif // NTDDI_VERSION >= NTDDI_WIN10
|
||||
|
||||
#define DOMITO_CI_SOURCE_EMBEDDED 1UL
|
||||
#define DOMITO_CI_SOURCE_CATALOG 2UL
|
||||
|
||||
// Policy-explicit legacy helper. SHA-1/256 only; hash size must match algorithm.
|
||||
// Policy objects must be zero-initialized or own valid CI results; both are freed
|
||||
// before each attempt. Caller owns both final policy outputs, including failure.
|
||||
// Embedded validation is tried first; only INVALID_IMAGE_HASH permits catalog
|
||||
// fallback/reload. AcceptedCatalogPolicyBits uses ANY-overlap catalog filtering;
|
||||
// RequireTrustedCatalog gates the observed marker, not publisher identity.
|
||||
// Source is 0 on failure, EMBEDDED/CATALOG on success. Stable file bytes and a
|
||||
// handle valid in the caller's current process context are required during I/O.
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoValidateFileLegacyModeEx(
|
||||
_In_ HANDLE FileHandle,
|
||||
_In_reads_bytes_(HashSize) PVOID Hash,
|
||||
_In_ UINT32 HashSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_In_ const IMAGE_DATA_DIRECTORY* SecurityDirectory,
|
||||
_Inout_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Inout_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo,
|
||||
_In_ UINT32 AcceptedCatalogPolicyBits,
|
||||
_In_ BOOLEAN RequireTrustedCatalog,
|
||||
_Out_ PULONG ValidationSource
|
||||
);
|
||||
|
||||
//
|
||||
// Compatibility wrapper around DomitoValidateFileLegacyModeEx, with catalog
|
||||
// mask DOMITO_CI_LEGACY_CATALOG_POLICY_BITS and RequireTrustedCatalog = FALSE.
|
||||
// The same initialization, ownership, hash, handle, and stable-file rules apply.
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
__declspec(deprecated(
|
||||
"Use DomitoValidateFileLegacyModeEx with explicit catalog policy and validation-source output; do not change trust policy implicitly."
|
||||
)) NTSTATUS
|
||||
DomitoValidateFileLegacyMode(
|
||||
_In_ HANDLE FileHandle,
|
||||
_In_ PVOID Hash,
|
||||
@@ -229,7 +375,6 @@ DomitoValidateFileLegacyMode(
|
||||
_Inout_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
|
||||
);
|
||||
|
||||
|
||||
/* __ __ _
|
||||
* | \/ (_)___ __
|
||||
* | |\/| | (_-</ _|_
|
||||
@@ -237,9 +382,9 @@ DomitoValidateFileLegacyMode(
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// Finds the base address of a driver module.
|
||||
//
|
||||
//
|
||||
// Finds the base address of a driver module. Clears the optional output first.
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
@@ -251,8 +396,11 @@ DomitoFindModuleBaseAddress(
|
||||
);
|
||||
|
||||
//
|
||||
// Finds the address of an exported function by name.
|
||||
//
|
||||
// Finds an export by name (case-insensitive) in a valid loader-mapped module.
|
||||
// ModuleBase must remain mapped; arbitrary file buffers are not supported.
|
||||
// Export table spans are checked against SizeOfImage. Forwarded exports return
|
||||
// STATUS_NOT_SUPPORTED; the optional output is cleared before lookup.
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
@@ -266,7 +414,7 @@ DomitoFindExportedFunctionAddress(
|
||||
|
||||
//
|
||||
// Scans a provided buffer for a memory pattern.
|
||||
//
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
@@ -282,8 +430,29 @@ DomitoMemorySearchPattern(
|
||||
);
|
||||
|
||||
//
|
||||
// Reads from the beginning of a file until the end or the buffer size is reached.
|
||||
//
|
||||
// Reads exactly BufferSize bytes at a nonnegative absolute file offset.
|
||||
// Same completion, buffer, handle, APC, and short-read contract as DomitoReadFile.
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoReadFileAt(
|
||||
_In_ HANDLE FileHandle,
|
||||
_Out_writes_bytes_(BufferSize) PVOID Buffer,
|
||||
_In_ ULONG BufferSize,
|
||||
_In_ const LARGE_INTEGER* ByteOffset
|
||||
);
|
||||
|
||||
//
|
||||
// Reads exactly BufferSize bytes from file offset zero. Short reads return
|
||||
// STATUS_END_OF_FILE; Buffer may then contain a partial read. Zero length succeeds.
|
||||
// Waits for pending I/O on a private event before returning. Requires PASSIVE_LEVEL
|
||||
// with special kernel APCs enabled, a readable handle valid in the current process
|
||||
// (or a kernel handle), and a buffer that remains valid for the entire call.
|
||||
// For synchronous handles, the explicit read also updates the file position.
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
@@ -296,14 +465,23 @@ DomitoReadFile(
|
||||
);
|
||||
|
||||
//
|
||||
// Gets the name of the main image of the process identified by PID.
|
||||
//
|
||||
// Gets the main image name after resolving the ULONG PID once to a process handle.
|
||||
// Requires DomitoInit. Output is NULL on failure; successful result is one Domito
|
||||
// allocation containing UNICODE_STRING and its buffer. Use DomitoFreeProcessImageName.
|
||||
// Do not change memory callbacks with outstanding allocations. PID reuse can race
|
||||
// the initial open; a later path reopen is not proof of original image identity.
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
__declspec(deprecated(
|
||||
"Use DomitoGetProcessImageNameEx with a caller-referenced PEPROCESS to avoid a fresh PID lookup; free the result with DomitoFreeProcessImageName."
|
||||
)) NTSTATUS
|
||||
DomitoGetProcessImageName(
|
||||
_In_ ULONG ProcessId,
|
||||
_Inout_ PUNICODE_STRING* ProcessImageName
|
||||
_Outptr_result_maybenull_ PUNICODE_STRING* ProcessImageName
|
||||
);
|
||||
|
||||
// Additive consumer helpers, included here for existing Domito.h clients.
|
||||
#include "Domito.Consumer.h"
|
||||
Reference in new issue
Block a user