feat(verify): let the reachability probe and live smoke speak TLS (BACKLOG #1178) - #914
Open
wshallwshall wants to merge 2 commits into
Open
feat(verify): let the reachability probe and live smoke speak TLS (BACKLOG #1178)#914wshallwshall wants to merge 2 commits into
wshallwshall wants to merge 2 commits into
Conversation
…CKLOG #1178) probe_tcp_reachable and smoke_live both opened a bare socket regardless of the hop they tested. Re-measured at c57903c by execution: a tls=true MLLP destination's test_connection() returned OK having sent no ClientHello, while the same destination's send() in the same run sent one -- the zero-byte reading was a finding, not a blind probe. smoke_live wrote a whole MLLP frame onto a plaintext socket. Both now take an optional ssl_context and cross the hop the caller uses. None keeps the plaintext path byte-identical, which is right for raw TCP and X12. A handshake failure is named as one, not as a failed connect. Neither retries the other protocol: that fall-back is what ASVS 12.3.1 forbids. The smoke is reachable as verify --smoke live --smoke-tls; its context uses the shared hardening seam and has no verify-off switch. Both new TLS call sites are registered in the crypto inventory. Corrects the item's drifted anchor: base.py:588, not :557. Item stays OPEN; the mllp.py call site is still owed.
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.
BACKLOG #1178 -- the reachability probe and the live smoke can now cross the hop they test
This PR does NOT close #1178 and does not claim to. The item carries
Verdict: researchandClosing-act: scorecard-rescore, which no builder performs. Its banner is untouched. Two namedresidual limbs are built; the rest of the item stands.
Scope is the item's own "Proposed work" list, the two entries that live in one file pair:
pass the destination's SSL context into
probe_tcp_reachable, and grade the second bareconnection in
verify/smoke.py.Re-measurement first, by execution, with a positive control in the same run
Measured at
c57903c2cbefore any edit. Both named defects held, and one of the item's twoanchors had drifted.
inspect.signature(probe_tcp_reachable)(host, port, timeout, label). Nosslortlsparameter of any kind.transports/base.py:557:588, the bare connect at:593. Corrected in the row.verify/smoke.py:126tls=trueMLLP destination builds a context?ssl.SSLContext.test_connection()send(), same listener, same run16 03 01 ...). So the instrument could see a handshake, and the zero-byte reading is a finding rather than a blind probe.smoke_live\x0bMSH|^~\&|...onto a bare socket. A synthetic body, but a body, and worse than the probe on this cell's terms.The item pre-rejects "it sends zero bytes so nothing is disclosed" as the vacuity argument. I did
not make it, and the smoke limb turns out not to qualify for it at all.
What changed
probe_tcp_reachabletakes optionalssl_contextandserver_hostname(defaulting tohost)and hands them to
asyncio.open_connection. It stays a no-data probe: under TLS the handshake isall that crosses. A handshake failure is now named as one rather than reported as a failed
connect, because a trust-anchor problem read as an unreachable partner sends the operator to the
firewall.
Nonekeeps today's plaintext probe byte-identical, which is the honest posture for rawTCP and X12: they have no
tlsparameter to migrate to and their cleartext hop is gatedseparately at construction.
smoke_livetakes the same optional context and completes the handshake before any applicationbyte. Reachable as
messagefoundry verify --smoke live --smoke-tls [--smoke-tls-ca <file>].live_smoke_ssl_contextbuilds that client context through the shared hardening seam(
harden_kex_groups/harden_cipher_suites/harden_verify_flags) rather than inheriting theinterpreter's defaults, and carries no verify-off switch. A smoke that accepts any certificate
proves the port answers, not that it is the engine.
forbids. The plaintext smoke's "0 bytes received" now names a TLS inbound as a possible cause,
which is a diagnosis and deliberately not a retry.
scripts/security/crypto_inventory_check.py. The gatewas made to fail on purpose first (it reported both files undocumented), then satisfied: 77 sites
before, 79 after.
What is deliberately NOT here
The MLLP destination's call site,
transports/mllp.py:1215, still passes no context. It is aone-line change and needs no design work, but a peer builder held
mllp.pyin this wave and mybrief forbids editing a sibling's file. Until it lands, a deploying site's connection test for a
tls=trueMLLP destination would still open a plaintext socket to the partner. This is theremaining half of the item's probe residual and should be dispatched.
tcp.pyandx12.pyneedno such change: they have no TLS to pass.
Everything else in the item is untouched: the gradient amendment, the attested early return at both
sites, the attestation re-scoping, the remaining data-layer hop sites, the upstream-termination
allow, and the Vault and IDE limbs.
Checks
Run from this worktree with
.venv\Scripts\python.exethroughout. Interpreter and pins printedtogether, since three interpreters on this machine disagree:
Ran, all green:
ruff check .andruff format --check .mypy messagefoundry(strict): no issues in 268 source filesscripts/security/crypto_inventory_check.py: OK, no driftscripts/docs/backlog_status_check.py: OK, 670 items, each declaring one statuspytest tests/test_verify.py tests/test_connection_api.py(80 passed)pytest tests/test_tls_policy.py tests/test_tls_cipher_assertion_sites.py tests/test_cli.py(240 passed)pytest tests/test_mllp_tls.py tests/test_transports.py tests/test_tcp_transport.py tests/test_hop_refusal_rawtcp.py tests/test_mllp_persistent.py(220 passed, 1 skipped)hook found in my BACKLOG text, from the quoted-heredoc unescaping bug. Fixed, then green.
Skipped: the full suite. Under fleet contention (ten builders on this account) it may not finish
inside one turn. I ran the files covering the change plus the TLS and CLI neighbours instead.
CI legs somebody must read after I exit: the full
testmatrix including py3.11,bandit,pip-audit, and thecrypto-inventory (ASVS 11.1.3 discovery gate)leg insecurity.yml, whichthis PR moves. Also anything that only runs on a hosted runner, such as
windows-service-smoke.New tests
tests/test_connection_api.py::test_probe_sends_a_client_hello_only_when_given_a_contextis thedirect regression, built the same paired way as the re-measurement: one recorder, both arms, so
the plaintext arm proves the recorder can see bytes at all.
tests/test_verify.py::test_live_smoke_over_tls_puts_no_plaintext_frame_on_the_wireis the sameshape for the smoke, and asserts no
MSHescapes the handshake.diagnostic wording, the context having no verify-off escape, and a forward-secrecy assertion test
that monkeypatches
_is_forward_secretso the shared assertion can actually fire.Housekeeping
system-reminderin this session declared it, which is the whole test.reviewedlabel, no enqueue, no auto-merge.