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,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.
|
||||
Reference in new issue
Block a user