-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update ssl_engine_ocsp.c #501
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -117,8 +117,150 @@ static OCSP_REQUEST *create_request(X509_STORE_CTX *ctx, X509 *cert, | |
return NULL; | ||
} | ||
|
||
if (sc->server->ocsp_use_request_nonce != FALSE) { | ||
OCSP_request_add1_nonce(req, 0, -1); | ||
static OCSP_REQUEST *create_request(X509_STORE_CTX *ctx, X509 *cert, | ||
OCSP_CERTID **certid, | ||
server_rec *s, apr_pool_t *p, | ||
SSLSrvConfigRec *sc) | ||
{ | ||
OCSP_REQUEST *req = OCSP_REQUEST_new(); | ||
|
||
*certid = OCSP_cert_to_id(NULL, cert, X509_STORE_CTX_get0_current_issuer(ctx)); | ||
if (!*certid || !OCSP_request_add0_id(req, *certid)) { | ||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01921) | ||
"could not retrieve certificate id"); | ||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); | ||
return NULL; | ||
} | ||
|
||
OCSP_request_add1_nonce(req, 0, -1); | ||
|
||
return req; | ||
} | ||
|
||
static int verify_ocsp_status(X509 *cert, X509_STORE_CTX *ctx, conn_rec *c, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function looks duplicated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The create_request function is not duplicated. Returns req which is used later in verify_ocsp_status. The separation of the two functions is aimed at maintaining a clear division of responsibilities: create_request is responsible for generating the OCSP request, while verify_ocsp_status is responsible for verifying its status. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am referring to verify_ocsp_status(). The commit seems to add a second copy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked the code again and found no errors. Tell me if you don't understand something and I'll try to explain better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As @covener says it looks like you have inserted a second copy of
|
||
SSLSrvConfigRec *sc, server_rec *s, | ||
apr_pool_t *pool) | ||
{ | ||
int rc = V_OCSP_CERTSTATUS_GOOD; | ||
OCSP_RESPONSE *response = NULL; | ||
OCSP_BASICRESP *basicResponse = NULL; | ||
OCSP_REQUEST *request = NULL; | ||
OCSP_CERTID *certID = NULL; | ||
apr_uri_t *ruri; | ||
|
||
ruri = determine_responder_uri(sc, cert, c, pool); | ||
if (!ruri) { | ||
if (sc->server->ocsp_mask & SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK) { | ||
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, | ||
"Skipping OCSP check for certificate cos no OCSP URL" | ||
" found and no_ocsp_for_cert_ok is set"); | ||
return V_OCSP_CERTSTATUS_GOOD; | ||
} else { | ||
return V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
} | ||
|
||
request = create_request(ctx, cert, &certID, s, pool, sc); | ||
if (request) { | ||
apr_interval_time_t to = sc->server->ocsp_responder_timeout == UNSET ? | ||
apr_time_from_sec(DEFAULT_OCSP_TIMEOUT) : | ||
sc->server->ocsp_responder_timeout; | ||
response = modssl_dispatch_ocsp_request(ruri, to, request, c, pool); | ||
} | ||
|
||
if (!request || !response) { | ||
rc = V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
|
||
if (rc == V_OCSP_CERTSTATUS_GOOD) { | ||
int r = OCSP_response_status(response); | ||
|
||
if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) { | ||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01922) | ||
"OCSP response not successful: %d", r); | ||
rc = V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
} | ||
|
||
if (rc == V_OCSP_CERTSTATUS_GOOD) { | ||
basicResponse = OCSP_response_get1_basic(response); | ||
if (!basicResponse) { | ||
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01923) | ||
"could not retrieve OCSP basic response"); | ||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); | ||
rc = V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
} | ||
|
||
if (rc == V_OCSP_CERTSTATUS_GOOD && | ||
OCSP_check_nonce(request, basicResponse) != 1) { | ||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01924) | ||
"Bad OCSP responder answer (bad nonce)"); | ||
rc = V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
|
||
if (rc == V_OCSP_CERTSTATUS_GOOD) { | ||
if (sc->server->ocsp_noverify != TRUE) { | ||
if (OCSP_basic_verify(basicResponse, sc->server->ocsp_certs, X509_STORE_CTX_get0_store(ctx), | ||
sc->server->ocsp_verify_flags) != 1) { | ||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01925) | ||
"failed to verify the OCSP response"); | ||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); | ||
rc = V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
} | ||
} | ||
|
||
if (rc == V_OCSP_CERTSTATUS_GOOD) { | ||
int reason = -1, status; | ||
ASN1_GENERALIZEDTIME *thisup = NULL, *nextup = NULL; | ||
|
||
rc = OCSP_resp_find_status(basicResponse, certID, &status, | ||
&reason, NULL, &thisup, &nextup); | ||
if (rc != 1) { | ||
ssl_log_cxerror(SSLLOG_MARK, APLOG_ERR, 0, c, cert, APLOGNO(02272) | ||
"failed to retrieve OCSP response status"); | ||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); | ||
rc = V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
else { | ||
rc = status; | ||
} | ||
|
||
if (rc != V_OCSP_CERTSTATUS_UNKNOWN) { | ||
long resptime_skew = sc->server->ocsp_resptime_skew == UNSET ? | ||
DEFAULT_OCSP_MAX_SKEW : sc->server->ocsp_resptime_skew; | ||
int vrc = OCSP_check_validity(thisup, nextup, resptime_skew, | ||
sc->server->ocsp_resp_maxage); | ||
if (vrc != 1) { | ||
ssl_log_cxerror(SSLLOG_MARK, APLOG_ERR, 0, c, cert, APLOGNO(02273) | ||
"OCSP response outside validity period"); | ||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); | ||
rc = V_OCSP_CERTSTATUS_UNKNOWN; | ||
} | ||
} | ||
|
||
{ | ||
int level = | ||
(status == V_OCSP_CERTSTATUS_GOOD) ? APLOG_INFO : APLOG_ERR; | ||
const char *result = | ||
status == V_OCSP_CERTSTATUS_GOOD ? "good" : | ||
(status == V_OCSP_CERTSTATUS_REVOKED ? "revoked" : "unknown"); | ||
|
||
ssl_log_cxerror(SSLLOG_MARK, level, 0, c, cert, APLOGNO(03239) | ||
"OCSP validation completed, " | ||
"certificate status: %s (%d, %d)", | ||
result, status, reason); | ||
} | ||
} | ||
|
||
if (request) OCSP_REQUEST_free(request); | ||
if (response) OCSP_RESPONSE_free(response); | ||
if (basicResponse) OCSP_BASICRESP_free(basicResponse); | ||
|
||
return rc; | ||
} | ||
|
||
} | ||
|
||
return req; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why ignore the opt-out config of SSLOCSPUseRequestNonce?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decision to enforce the inclusion of the nonce in OCSP requests, regardless of the SSLOCSPUseRequestNonce configuration, was made to enhance security. Nonce inclusion helps mitigate replay attacks, where a malicious actor might reuse a previously valid OCSP response to falsely indicate the validity of a revoked certificate.
By ensuring the nonce is always added, the integrity and freshness of the OCSP responses can be guaranteed. While this approach overrides the opt-out feature, it prioritizes preventing potential vulnerabilities.