fix(tls): verify rollback restoration - #42
Draft
bymoye wants to merge 2 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
Stacked on #41 and limited to the rollback proof boundary for issue #31. It does not add a NazoAuth API, generate NazoAuth protocol keys, or modify the NazoAuth repository.
Related: #31
Cross-repository dependency: nazozero/NazoAuth#130
Stack: #41 -> #40 -> #39 -> #37 -> #34
Root cause
Rollback trusted the recorded previous leaf digest and the provider reload process exit code. It did not securely reopen the previous generation before activation, so damaged or replaced certificate/private-key files could be switched back without proving chain, SAN, serverAuth usage, expiry, key match, permissions or receipt digests.
For a failed first installation, rollback removed the activation link and accepted a successful reload without public evidence that the candidate was no longer served. It could therefore finalize with no receipt while a consumer retained the candidate in memory.
The pending transaction also carried an embedded provider configuration without a separate stable digest binding that snapshot to its commands and authority fields.
Changes
The first-install behavior is intentionally fail-closed: an unavailable endpoint is not treated as proof that the candidate disappeared.
Validation
Local Windows, exact head
f2d500ac9eb6888a3f1a46abae8c26c3b5a15d3d:cargo fmt --all -- --checkcargo check --locked --workspace --all-targetscargo clippy --locked --workspace --all-targets -- -D warningscargo test --locked --workspace: 369 passedcargo build --locked --release --workspace: 0 errors; one aggregated informational MSVC import-library linker messageThe first remote run exposed that serializing
PathBufdirectly produced different provider snapshot digests on Windows and Unix. Commitf2d500areplaced it with typed path-component encoding and retained a fixed digest vector plus a Unix non-collision test.Remote GitHub checks for the exact head: 13/13 passed:
Verification boundary
No real certificate rollback, provider reload, public hostname, remote deployment, power-loss injection, stopped-ctl runtime, or NazoAuth Direct TLS integration was exercised locally. The Unix symlink rollback path is covered by Linux CI, but not by a real service switch. ACME authority restrictions remain a separate follow-up PR.