Expand %x and %D after bumped SQUID_X509_V_ERR_DOMAIN_MISMATCH (#2373)
Squid detects SQUID_X509_V_ERR_DOMAIN_MISMATCH errors during various
processing stages, including when receiving an HTTP request on a
successfully bumped TLS connection. If that request targets a domain not
covered by the server certificate, and sslproxy_cert_error prohibits a
mismatch (it does by default), then Squid terminates the transaction
with an ERR_SECURE_CONNECT_FAIL response. That generated error response
body lacked %x and %D error details:
- [No Error Detail]
+ Certificate does not match domainname: /L=.../O=.../CN=example.com
```
The first `[No Error]` expansion of %E remains unchanged because this
particular error does not set `errno`.
ConnStateData::serveDelayedError() changes fix the above problem but %x
expansion in error pages and %err_detail in access log get a misleading
`+broken_cert` detail. To address that flaw, we changed the default for
broken certificate in Security::ErrorDetail constructor API from peer
certificate to nil. When broken certificate is nil, ErrorDetail now uses
valid certificate to expand %ssl_cn and similar certificate-inspecting
error page %codes.
All Security::ErrorDetail creators were checked and adjusted if needed:
* ConnStateData::serveDelayedError(): No caller changes. Using the new
ErrorDetail creation API fixes this code by supplying nil broken
certificate (because the certificate is _valid_ in this context).
* ssl_verify_cb(): No caller changes. We already use peer certificate as
the default broken certificate because doing so is "reasonable" here.
* Security::PeerConnector::sslCrtvdCheckForErrors(): Adjusted to keep
the original "if there was no error_cert_ID, then use peerCert"
behavior while using new Security::ErrorDetail creation API.
Thus, the last two contexts are not affected by this error reporting API
change. The exceptional serveDelayedError() caller is affected, but
Squid did not report any certificate detail in that case until this
branch fixes, so this branch does not change one "reporting certificate"
to another; it only starts reporting (important) information when none
was available before.