Add CI validation helpers with explicit signature selection and owned results
This commit is contained in:
1 parent
28f284be8f
commit
1f4d62ae95
13 files changed
+596
-3
No files matched your search
@@ -197,8 +197,11 @@ statuses and signing time. Do not interpret status success alone as selection
|
||||
of the company certificate. First successful does not necessarily mean first
|
||||
listed: CI may reject the primary and continue.
|
||||
|
||||
`0x80` has additional policy and fallback effects. It has not been published as
|
||||
a supported Domito constant or a production default. The companion research
|
||||
`0x80` has additional policy and fallback effects. Domito exposes it only as
|
||||
`DOMITO_CI_VALIDATE_FLAG_FIRST_SUCCESS_EXPERIMENTAL` and through the opt-in
|
||||
`DomitoCiSignatureSelectionFirstSuccessfulExperimental` mode in
|
||||
`DomitoValidateFileObjectEx`. It is not a production default or a stable signer
|
||||
index. See the [validation helper contracts](ci-validation-helpers.md). The companion research
|
||||
`SIGNATURE-SELECTION.md` provides the full static evidence and an alternative
|
||||
primary-signature path using `CiCheckSignedFile`.
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
# 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.
|
||||
@@ -6,6 +6,13 @@ it should not be read as describing the corrected source unchanged.
|
||||
|
||||
## Implemented with host tests or compilation
|
||||
|
||||
- Additive CI result/selection helpers now package native file-object validation,
|
||||
opt-in x64 first-success selection and explicit embedded verification, with
|
||||
shared policy/digest cleanup. Existing APIs retain their behavior. See the
|
||||
[helper contracts](ci-validation-helpers.md). Host failure/forwarding tests and
|
||||
x64/ARM64 builds cover the wrappers; WPP probe v2 consumes them and awaits a
|
||||
returned kernel trace. The previous v1 trace establishes the raw native routes.
|
||||
|
||||
- **S01–S04:** subtraction-safe PE ranges, no fixed 4 MiB copy, bounded certificate
|
||||
intervals, deterministic failure outputs, and digest cleanup. Compatibility
|
||||
and explicit paths share the bounded hashing core.
|
||||
@@ -95,7 +102,7 @@ and compilation do not close the remaining work:
|
||||
|
||||
## Checks
|
||||
|
||||
Run the three host runners in `tests/README.md`. Kernel compilation also covers
|
||||
Run the four host runners in `tests/README.md`. Kernel compilation also covers
|
||||
the default modern x64/ARM64 structures, the pre-Windows-10 x64 compile variant,
|
||||
and 14 assertions in the 26100 opt-in header plus 12 historical-view assertions. Those are build checks,
|
||||
not a claim that historical or ARM64 CI runtime ABI has been verified.
|
||||
@@ -158,6 +158,10 @@ later conversion failure. It is not owned by either policy object.
|
||||
Evidence: `MincryptFreePolicyInfo`, `MincryptCopyPolicyInfo`,
|
||||
`I_MincryptAddChainInfo`, `CiVerifyHashInCatalog`, and `CiGetCertPublisherName`.
|
||||
|
||||
The additive [validation helpers](ci-validation-helpers.md) package safe result
|
||||
ownership, explicit file-object selection and embedded CI verification. They do
|
||||
not change raw CI declarations or existing legacy-helper behavior.
|
||||
|
||||
## Multiple signatures and selected results
|
||||
|
||||
`CiValidateFileObject` returns one selected signature result and its timestamp
|
||||
|
||||
Reference in new issue
Block a user