shell-tls-intermediate-chain-bundle-order
The full lab is built and verified. Here's the summary.
PKI built using only openssl: an offline root CA (CA:TRUE, pathlen:1) → an intermediate CA (CA:TRUE, pathlen:0) → a localhost leaf with serverAuth, DNS:localhost, IP:<ip-address>.
openssl verify treats -CAfile as trust anchor, not a chain member. With the leaf alone: error 20: unable to get local issuer certificate. Passing the intermediate via -untrusted makes it OK. The CLI has no way to say "attach this as an intermediate"; only the server places it on the wire.pathlen:0 on the intermediate means it may certify zero subordinate CAs. OpenSign CLI will blithely sign a rogue sub-CA under it, but a real verifier must reject it.~/tls-chain/demo)| PEM server sent | Client (trust=only root) | s_client outcome |
|---|---|---|
leaf + intermediate |
code 0 (ok) — correct |
|
leaf alone |
code 21: unable to verify the first certificate |
|
leaf + root, no intermediate |
code 21: unable to verify the first certificate |
|
leaf + rogue CA + intermediate |
code 25: path length constraint exceeded |
Key artifacts
- SOLUTION.md — self-contained write-up (title, root-cause analysis, exact openssl commands, verification).
- demo/{root,intermediate,leaf,rogue}.crt / .key — complete three-level PKI plus the rogue sub-CA used to prove pathlen enforcement.
- bundle-leaf-intermediate.pem — the correct presentation order (leaf, intermediate).
- server.py — HTTPS server with a trust store containing only the root.
The hard parts are all demonstrated with concrete error codes: verify's -untrusted requirement (error 20 without it), the on-wire ordering, and pathlen:0 rejecting a wrongly-signed second CA (error 25).
# Evidence - Problem class: shell-tls-intermediate-chain-bundle-order - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-21T22:26:37.607Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Using only the openssl CLI, build a three-level PKI: an offline root CA, an intermediate CA (CA:TRUE, pathlen:0), and a localhost leaf certificate signed by the intermediate. Stand up an HTTPS server whose client trust store contains ONLY the root, and determine the exact PEM bundle (which certificates, in what order) the server must present for verification to succeed; then reproduce the two failure modes \u2014 serving the leaf alone, and serving leaf+root without the intermediate \u2014 capturing the exact s_client verify error each produces. The hard parts: openssl verify requires the intermediate via -untrusted while the server must ship it in the chain after the leaf, and path validation must reject a second intermediate wrongly signed under the pathlen:0 constraint.", "environment": "bash", "language": "shell", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "shell-tls-intermediate-chain-bundle-order", "provider": "openrouter", "solved_at": "2026-08-21T22:26:37.608Z", "version": "5.2"}The full lab is built and verified. Here's the summary.
PKI built using only openssl: an offline root CA (CA:TRUE, pathlen:1) → an intermediate CA (CA:TRUE, pathlen:0) → a localhost leaf with serverAuth, DNS:localhost, IP:<ip-address>.
openssl verify treats -CAfile as trust anchor, not a chain member. With the leaf alone: error 20: unable to get local issuer certificate. Passing the intermediate via -untrusted makes it OK. The CLI has no way to say "attach this as an intermediate"; only the server places it on the wire.pathlen:0 on the intermediate means it may certify zero subordinate CAs. OpenSign CLI will blithely sign a rogue sub-CA under it, but a real verifier must reject it.~/tls-chain/demo)| PEM server sent | Client (trust=only root) | s_client outcome |
|---|---|---|
leaf + intermediate |
code 0 (ok) — correct |
|
leaf alone |
code 21: unable to verify the first certificate |
|
leaf + root, no intermediate |
code 21: unable to verify the first certificate |
|
leaf + rogue CA + intermediate |
code 25: path length constraint exceeded |
Key artifacts
- SOLUTION.md — self-contained write-up (title, root-cause analysis, exact openssl commands, verification).
- demo/{root,intermediate,leaf,rogue}.crt / .key — complete three-level PKI plus the rogue sub-CA used to prove pathlen enforcement.
- bundle-leaf-intermediate.pem — the correct presentation order (leaf, intermediate).
- server.py — HTTPS server with a trust store containing only the root.
The hard parts are all demonstrated with concrete error codes: verify's -untrusted requirement (error 20 without it), the on-wire ordering, and pathlen:0 rejecting a wrongly-signed second CA (error 25).
# Evidence - Problem class: shell-tls-intermediate-chain-bundle-order - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-21T22:26:37.607Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Using only the openssl CLI, build a three-level PKI: an offline root CA, an intermediate CA (CA:TRUE, pathlen:0), and a localhost leaf certificate signed by the intermediate. Stand up an HTTPS server whose client trust store contains ONLY the root, and determine the exact PEM bundle (which certificates, in what order) the server must present for verification to succeed; then reproduce the two failure modes \u2014 serving the leaf alone, and serving leaf+root without the intermediate \u2014 capturing the exact s_client verify error each produces. The hard parts: openssl verify requires the intermediate via -untrusted while the server must ship it in the chain after the leaf, and path validation must reject a second intermediate wrongly signed under the pathlen:0 constraint.", "environment": "bash", "language": "shell", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "shell-tls-intermediate-chain-bundle-order", "provider": "openrouter", "solved_at": "2026-08-21T22:26:37.608Z", "version": "5.2"}