maskit opened a new issue, #13730:
URL: https://github.com/apache/trafficserver/issues/13730

   When a `TS_SSL_CERT_HOOK` plugin pauses the handshake and later reenables 
it, the TLS library calls `ssl_cert_callback()` again 
(`src/iocore/net/SSLUtils.cc`). By then the cert hooks have already finished, 
but the callback does not recognize that state.
   
   ## Sequence
   
   1. The cert hook pauses, and `ssl_cert_callback()` returns -1.
   2. The plugin reenables. `SSLNetVConnection::reenable()` calls 
`resume_tls_event()` (`CERT_INVOKE` → `CERT`), then `invoke_tls_event()`, which 
finds no further cert hook and moves the state to `HANDSHAKE_HOOKS_CLIENT_CERT`.
   3. The library calls the callback again. OpenSSL re-invokes `cert_cb` from 
`tls_post_process_client_hello()` after a negative return. BoringSSL re-runs 
the select certificate callback once #13729 returns a retry for the pause.
   4. In `HANDSHAKE_HOOKS_CLIENT_CERT`, `calledHooks(TS_EVENT_SSL_CERT)` 
returns false, so `selectCertificate()` runs a second time.
   5. `callHooks(TS_EVENT_SSL_CERT)` in `HANDSHAKE_HOOKS_CLIENT_CERT` starts 
the `TS_SSL_VERIFY_CLIENT_HOOK` list and invokes it with `TS_EVENT_SSL_CERT`.
   
   ## Effect
   
   - Verify-client hooks are called early and with `TS_EVENT_SSL_CERT` instead 
of `TS_EVENT_SSL_VERIFY_CLIENT`.
   - The second `selectCertificate()` may replace an `SSL_CTX` that the cert 
hook plugin set while it held the pause. Not yet confirmed; it depends on 
whether the name or IP lookup finds a match.
   
   With no verify-client hooks registered, `callHooks()` returns success and 
the handshake completes, which may be why this has gone unnoticed.
   
   ## Possible fix
   
   In `ssl_cert_callback()`, when the hook state shows the cert hooks have 
completed (`HANDSHAKE_HOOKS_CLIENT_CERT` / 
`HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE`), skip `selectCertificate()` and 
`callHooks(TS_EVENT_SSL_CERT)` and continue as success. The CA cert and session 
ticket steps at the end of the callback still need to run on that call, since 
the paused call skipped them.
   
   ## Testing
   
   A test that pauses the cert hook with a verify-client hook registered, and 
checks that the verify-client hook only receives `TS_EVENT_SSL_VERIFY_CLIENT`, 
should cover both backends.
   
   Found while reviewing #13729. The sequence above is from reading the code; 
it has not been reproduced yet.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to