In TLS, what changes for revocation checking when the server fetches the signed OCSP answer itself and delivers it with its certificate?
answer
- the server does the asking
- the courier cannot edit the letter
- one query per refresh, not per client
- the responder stops seeing clients
- silence is still accepted
basics
~20 sThe fetch moves off the client's path: the server queries the responder on a schedule and passes the responder-signed answer to the client. That removes a round trip, removes the privacy leak of the client naming the site to a third party, and survives a responder outage. It does not make an absent answer fatal.
solid answer
~40 sWithout stapling, every client that checks makes its own query to the issuer's responder while the connection waits - a round trip, a dependency on a third party, and a query that tells that third party which client is visiting which site. With stapling, the server periodically fetches the signed answer for its own certificate and delivers it alongside the certificate. Nothing about trust changes: the answer is still signed by the responder, so the server cannot forge or edit it, and it is still time-boxed by `thisUpdate` and `nextUpdate`. What does not change is the failure mode - a server that staples nothing simply presents no answer, and a client that soft-fails accepts the connection exactly as it would have on a failed query of its own.
code
pseudocode · 16 lines// server side, on a timer well before nextUpdate
function refresh_stapled_answer(my_certid):
answer = query_responder(my_certid)
if answer.responseStatus is not successful: return // keep last good
if verify_signature(answer) is false: return
if answer.certID != my_certid: return // wrong certificate
cache.store(answer, until = answer.nextUpdate)
// client side, on receiving the delivered answer
function evaluate(answer, presented_certid, now):
if answer is absent: return SOFT_FAIL_PATH
if verify_signature(answer) is false: return SOFT_FAIL_PATH
if answer.certID != presented_certid: return SOFT_FAIL_PATH
if now > answer.nextUpdate: return SOFT_FAIL_PATH
if answer.certStatus is revoked: return REJECT
return ACCEPTgo deeper
Know that the server can fetch the revocation status answer for its own certificate and hand it to clients, so the client does not have to ask a third party.
Explain who signs the answer, why the server cannot tamper with it, and which costs move: a round trip, a third-party dependency, and a privacy disclosure.
Treat stapling as a job you operate: refresh ahead of expiry, keep the last good answer through an outage, re-fetch on renewal, and know that a broken pipeline fails silently.
Decide how much of the estate's availability you are willing to make dependent on a status pipeline, given that the stronger the enforcement you add on top, the more a refresh failure becomes an outage.
## Who fetches, and why that is the whole change The status answer is the same artefact either way: a signed statement from the issuer's responder about one certificate, time-boxed by `thisUpdate` and `nextUpdate`. Stapling changes only **who fetches it**. - **Client-fetched.** The client, mid-handshake, opens a separate connection to the responder named in the certificate's `authorityInfoAccess` `id-ad-ocsp` pointer and asks about the certificate it has just been shown. - **Server-delivered (stapled).** The server asks the responder about **its own** certificate on a schedule of its choosing, caches the signed answer, and hands it to every client along with the certificate. Because the answer is signed by the responder and names the certificate by `CertID`, the server is only a courier. It cannot forge a `good`, cannot edit out a `revoked`, and cannot extend the freshness window. This is why it is safe to accept a status answer from the very party whose certificate it describes. ## What genuinely improves | concern | client-fetched | server-delivered | |---|---|---| | latency | an extra fetch while the handshake waits | none; the answer arrives with the certificate | | responder availability | a responder outage stalls or fails every client's check | the server serves its cached answer until it expires | | privacy | the responder learns which client asked about which site, and when | the responder sees only the server, on its refresh schedule | | load | one query per client connection | one query per server refresh interval | The privacy point is the one candidates most often miss. A client-side status query is a third party being told, in real time, which site a particular address is connecting to - a disclosure the connection's encryption otherwise prevents. ## What does not change 1. **The freshness window.** A stapled answer is still bounded by `thisUpdate` and `nextUpdate`. A server that stops refreshing eventually serves a stale answer, and a client checking the window should reject it. 2. **Who signs.** The responder, not the server. A stapled answer that does not verify, or that names a different `CertID`, is worth nothing. 3. **The default on silence.** This is the big one. A server that delivers no answer at all - never configured, refresh pipeline broken, or an attacker in the path simply omitting it - presents a client with the same situation as a failed query. Clients overwhelmingly proceed. **Stapling makes a successful check cheaper; on its own it does not make a missing check fatal.** 4. **Scope.** The answer normally covers the end-entity certificate only, so a revoked intermediate above it is not addressed by a plain stapled answer. ## Covering more than the leaf RFC 6961 defines `status_request_v2`, whose `CertificateStatusRequestItemV2` carries a `CertificateStatusType` of `ocsp(1)` for the end-entity certificate or `ocsp_multi(2)` for a status per certificate in the chain. It exists precisely because the original single-status delivery says nothing about intermediates. Deployment of it was thin, and TLS 1.3 instead allows a status to accompany each certificate in the chain - but which handshake slot carries the bytes is a TLS-layer matter; what matters here is the scope of the answer being delivered. ## Operating it Stapling turns a client-side check into a **server-side job**, with the failure modes of a job: - the refresh must run well before `nextUpdate`, not at it, so one failed refresh is survivable; - the last known-good answer should be retained and served while the responder is unreachable, rather than replaced with nothing; - a response that fails signature verification or names the wrong `CertID` must be discarded rather than cached; - the answer must be re-fetched when the certificate is renewed, since the old answer names the old serial and is simply about a different certificate. A deployment that gets this wrong usually fails quietly, because a missing stapled answer is invisible to soft-failing clients - right up until the certificate carries an extension that demands one, at which point the quiet failure becomes an outage.
- Does a stapled answer say anything about the intermediate certificates in the chain?Not in the ordinary single-status case: the answer names one `CertID`, normally the end-entity certificate's. RFC 6961 defined `status_request_v2` with `CertificateStatusType` `ocsp_multi(2)` to request a status per certificate in the chain, and TLS 1.3 allows a status to travel with each certificate. Without one of those, a revoked intermediate is simply not covered by what was delivered.
- What should a client do with a stapled answer whose nextUpdate has passed?Treat it as no answer rather than as a `good`. The window from `thisUpdate` to `nextUpdate` is what makes the statement time-bounded, and a response past it describes a state the responder has already promised to have superseded. In practice clients vary in strictness, which is why a server should refresh well ahead of expiry rather than at it.
- Why is it safe to take the status answer from the server whose certificate it describes?Because the answer is signed by the issuer's responder and binds itself to a specific `CertID` and time window. The server is a courier: it cannot produce a `good` it was not given, cannot suppress a `revoked` while still supplying a verifiable answer, and cannot move the freshness window. The client verifies the signature and the CertID exactly as it would for an answer it fetched itself.
saying these in an interview costs you the question
- Says the server signs the stapled status answer itself
- Thinks stapling makes a missing status answer fatal by itself
- Believes a stapled answer never goes stale because the server refreshes it
- Assumes one stapled answer covers every certificate in the chain
- Says the client still queries the responder to confirm the stapled answer
- Treats stapling as a performance feature with no privacy consequence