Add explicit Authenticode workflows and correct CI helper contracts
This commit is contained in:
1 parent
1026c48324
commit
7aa23f50be
18 files changed
+1952
-185
No files matched your search
+68
-33
@@ -277,6 +277,8 @@ 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;
|
||||
@@ -287,6 +289,8 @@ typedef struct _MINCRYPT_NAME_BLOB
|
||||
#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
|
||||
{
|
||||
@@ -301,9 +305,11 @@ typedef struct _MINCRYPT_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;
|
||||
@@ -319,7 +325,9 @@ typedef struct _MINCRYPT_CHAIN_INFO
|
||||
// ASN.1 blob of authenticated attributes - spcSpOpusInfo, contentType, etc.
|
||||
MINCRYPT_ATTR_BLOB AuthenticodeAttributes;
|
||||
|
||||
// UINT8 Hash[32];
|
||||
// Observed 26100 x64 adds RootId at +0x34 and a 32-byte platform-manifest
|
||||
// binary ID at +0x48. These are exposed only by Domito.MinCrypt.26100.h.
|
||||
// Do not infer their availability solely from NTDDI_VERSION or Size.
|
||||
|
||||
#endif // NTDDI_VERSION >= NTDDI_WIN10
|
||||
|
||||
@@ -338,7 +346,7 @@ typedef struct _MINCRYPT_CHAIN_INFO
|
||||
typedef struct _MINCRYPT_POLICY_INFO
|
||||
{
|
||||
UINT32 Size;
|
||||
UINT32 VerificationStatus;
|
||||
NTSTATUS VerificationStatus; // Check API return status separately.
|
||||
UINT32 PolicyBits;
|
||||
|
||||
MINCRYPT_CHAIN_INFO* ChainInfo;
|
||||
@@ -347,8 +355,8 @@ typedef struct _MINCRYPT_POLICY_INFO
|
||||
|
||||
#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
|
||||
|
||||
@@ -358,12 +366,16 @@ typedef struct _MINCRYPT_POLICY_INFO
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -375,18 +387,23 @@ CiFreePolicyInfo(
|
||||
|
||||
|
||||
/**
|
||||
* 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,9 +413,12 @@ 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
|
||||
*/
|
||||
@@ -407,10 +427,10 @@ MINCRYPTAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CiCheckSignedFile(
|
||||
_In_ PVOID Hash,
|
||||
_In_reads_bytes_(HashSize) PVOID Hash,
|
||||
_In_ UINT32 HashSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_In_ PVOID SecurityDirectory,
|
||||
_In_reads_bytes_(SizeOfSecurityDirectory) PVOID SecurityDirectory,
|
||||
_In_ UINT32 SizeOfSecurityDirectory,
|
||||
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
@@ -418,36 +438,51 @@ CiCheckSignedFile(
|
||||
);
|
||||
|
||||
|
||||
// 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
|
||||
*/
|
||||
@@ -456,12 +491,12 @@ MINCRYPTAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CiVerifyHashInCatalog(
|
||||
_In_ PVOID Hash,
|
||||
_In_reads_bytes_(HashSize) PVOID Hash,
|
||||
_In_ UINT32 HashSize,
|
||||
_In_ ALG_ID HashAlgId,
|
||||
_In_ BOOLEAN IsReloadCatalogs,
|
||||
_In_ UINT32 Always0,
|
||||
_In_ UINT32 Always2007F,
|
||||
_In_ BOOLEAN ReloadCatalogs,
|
||||
_In_ UINT32 RequireTrustedCatalog,
|
||||
_In_ UINT32 AcceptedCatalogPolicyBits,
|
||||
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
||||
_Out_opt_ UNICODE_STRING* CatalogName,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
@@ -552,7 +587,7 @@ CiSetTrustedOriginClaimId(
|
||||
* @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
|
||||
*/
|
||||
@@ -562,12 +597,12 @@ NTSTATUS
|
||||
NTAPI
|
||||
CiValidateFileObject(
|
||||
_In_ FILE_OBJECT* FileObject,
|
||||
_In_opt_ UINT32 ValidationFlags,
|
||||
_In_opt_ UINT32 RequestedSigningLevel,
|
||||
_In_ UINT32 ValidationFlags,
|
||||
_In_ UINT32 RequestedSigningLevel,
|
||||
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
||||
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo,
|
||||
_Out_ LARGE_INTEGER* SigningTime,
|
||||
_Out_ UINT8* Hash,
|
||||
_Out_writes_bytes_(*HashSize) UINT8* Hash,
|
||||
_Inout_ UINT32* HashSize,
|
||||
_Out_ ALG_ID* HashAlgId
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user