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:
nefarius committed 2026-10-27 00:17:25 +01:00
1 parent 7985b23be5
commit 3fbfe31d15
38 files changed
+9201 -751

No files matched your search

+118
View File
@@ -0,0 +1,118 @@
# CI validation helpers
These additive APIs are declared in `Domito.h` for Windows 10 compile targets.
They reuse CI for cryptographic verification. They do not implement RSA/ECDSA,
certificate-chain building or timestamp-signature verification themselves.
Raw CI declarations and existing digest/legacy helpers are unchanged.
## Result lifetime
Zero-initialize `DOMITO_CI_VALIDATION_RESULT` before first use. Each validation
call frees its previous signer/timestamp policies before reuse and resets the
result. Do not pass uninitialized storage or copy an owning result as a second
owner. On every exit, including a failed call, release it with
`DomitoFreeCiValidationResult`. The destructor accepts NULL and empty results.
All three APIs require PASSIVE_LEVEL. Referenced input objects/buffers must stay
valid and file bytes must stay stable throughout validation and consumption.
On success, `Hash`/`HashSize`/`HashAlgId` describe a known SHA-1/256/384/512 file
digest with a consistent length. Unused digest bytes are zero. This is not a
certificate thumbprint. On failure, digest bytes/length/algorithm and signing
time are zero; policy objects may retain owned diagnostic allocations. Input
flags/level forwarded to the file-object export remain recorded if it was called.
Those fields are not CI's final internally normalized policy flags.
Check the returned NTSTATUS first. Policy verification status, policy bits,
certificate identity, timestamps and the application's intended trust policy
remain separate observations/checks. Returning STATUS_SUCCESS does not pin a
company signer, reproduce WinVerifyTrust policy or prove driver-load acceptance.
No helper traverses the private chain layout or matches a certificate for you.
## File-object path
`DomitoValidateFileObjectEx` takes a referenced FILE_OBJECT, caller-selected
validation flags, a byte-sized requested signing level and a selection mode.
It supplies fresh 64-byte hash capacity and initialized policy/time outputs on
every call. It does not read, duplicate or acquire ownership of the file object.
- `DomitoCiSignatureSelectionNative` forwards the caller's flags unchanged.
This is native policy, not a guarantee of preferred-level selection: the
caller's other flags may already change the search/exit path.
- `DomitoCiSignatureSelectionFirstSuccessfulExperimental` additionally sets
`DOMITO_CI_VALIDATE_FLAG_FIRST_SUCCESS_EXPERIMENTAL` (0x80). On examined x64
builds this changes a successful-candidate early-exit predicate. It also
affects other policy/fallback paths. This explicit mode returns
STATUS_NOT_SUPPORTED on non-x64 builds. No runtime behavior on ARM64 is implied.
Neither mode automatically adds `0x20`. Broadening accepted roots is a separate
caller decision. Neither mode selects an arbitrary signer index or guarantees
that signature zero succeeds. A rejected primary may still lead to another signer.
```c
DOMITO_CI_VALIDATION_RESULT result = {0};
NTSTATUS status = DomitoValidateFileObjectEx(
fileObject,
DOMITO_CI_VALIDATE_FLAG_BROADEN_ROOT_ACCEPTANCE,
0,
DomitoCiSignatureSelectionFirstSuccessfulExperimental,
&result
);
if (NT_SUCCESS(status))
{
// Apply your expected-certificate/trust policy to result.PolicyInfo.
// result.SigningTime belongs to that selected verification result.
}
DomitoFreeCiValidationResult(&result);
```
The native kernel experiment on the supplied dual-SHA256 BthPS3 fixture returned
Microsoft for flags 0x20 and Nefarius for flags 0xA0 on a Windows 11 22631 x64
TESTSIGNING-enabled machine. It does not establish all older builds, TESTSIGNING-off
behavior or every side effect of 0x80. See [the flag evidence](ci-validate-file-object.md).
Do not rename this mode "require our company" or "select primary signature".
## Embedded PE-buffer path
`DomitoValidatePortableExecutableEmbeddedSignature` accepts a stable PE buffer
and an explicit CALG_SHA1/CALG_SHA_256/CALG_SHA_384/CALG_SHA_512. It calls
`DomitoCalculatePortableExecutableDigestEx` and supplies the resulting digest
and original first WIN_CERTIFICATE to `CiCheckSignedFile`. The digest allocation
is always freed, and only copied digest bytes/owned CI policies remain in the
result. Unsupported algorithm/layout and CI errors propagate without trying a
different algorithm or a catalog. An absent certificate returns
STATUS_INVALID_IMAGE_HASH; the helper cannot turn an unsigned file into a
successful catalog verification.
```c
DOMITO_CI_VALIDATION_RESULT result = {0};
NTSTATUS status = DomitoValidatePortableExecutableEmbeddedSignature(stablePeBytes, peSize, CALG_SHA_256, &result);
if (NT_SUCCESS(status))
{
// Enforce the expected certificate and intended trust policy here.
}
DomitoFreeCiValidationResult(&result);
```
This uses the explicit digest helper's [supported PE layout subset](authenticode-digests.md):
bounded headers, contiguous nonoverlapping raw sections in file order and an EOF
certificate table. It is not an arbitrary PE/SIP parser. CI can select nested
signatures according to its algorithm rules, so the helper is deliberately named
**embedded**, not **force primary**. The matching SHA-256 request selected the
company primary in the tested BthPS3 layout; another layout may select another
signer or fail. General enumeration remains separate work.
## Support and validation
The functions are C-compatible and compile for x64/ARM64. The experimental
file-object mode is deliberately gated to x64; native forwarding/embedded code
compilation does not certify every architecture/build's CI runtime ABI. CI
imports are static and must exist on the target OS, as described in the
[availability matrix](ci-api-compatibility.md). Structure/chain interpretation
remains subject to the [mincrypt contracts](mincrypt-contracts.md).
The new host suite checks production code forwarding, hash invariants, failures,
partial allocations, cleanup, result reuse and the non-x64 conditional branch.
The existing digest suite independently compares Windows SIP and Crypt32 results.
Kernel compilation covers the full library, public C clients and layout checks.
CodeIntegrity-RE probe v2 now calls the new APIs; a further kernel run is needed
to validate these wrappers rather than merely their previously tested raw calls.