mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MINOR: ssl: Add helper function that checks the validity of an OCSP response
This helper function will check that an OCSP response is valid, meaning that the proper "Content-Type: application/ocsp-response" header is present and the data itself is a proper OCSP_RESPONSE that can be checked thanks to the issuer certificate.
This commit is contained in:
parent
e09d2ae598
commit
c0b4058e7e
@ -90,6 +90,8 @@ int ssl_sock_update_ocsp_response(struct buffer *ocsp_response, char **err);
|
||||
int ssl_ocsp_get_uri_from_cert(X509 *cert, struct buffer *out, char **err);
|
||||
int ssl_ocsp_create_request_details(const OCSP_CERTID *certid, struct buffer *req_url,
|
||||
struct buffer *req_body, char **err);
|
||||
int ssl_ocsp_check_response(STACK_OF(X509) *chain, X509 *issuer,
|
||||
struct buffer *respbuf, char **err);
|
||||
#endif
|
||||
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
||||
int ssl_sock_update_tlskey_ref(struct tls_keys_ref *ref,
|
||||
|
@ -1248,6 +1248,72 @@ int ssl_ocsp_create_request_details(const OCSP_CERTID *certid, struct buffer *re
|
||||
return errcode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an OCSP_RESPONSE contained in <respbuf> and check its validity in
|
||||
* regard to the contents of <ckch> or the <issuer> certificate.
|
||||
* Certificate_ocsp structure does not keep a reference to the corresponding
|
||||
* ckch_store so outside of a CLI context (see "send ssl ocsp-response"
|
||||
* command), we only have an easy access to the issuer's certificate whose
|
||||
* reference is held in the structure.
|
||||
* Return 0 in case of success, 1 otherwise.
|
||||
*/
|
||||
int ssl_ocsp_check_response(STACK_OF(X509) *chain, X509 *issuer,
|
||||
struct buffer *respbuf, char **err)
|
||||
{
|
||||
int ret = 1;
|
||||
int n;
|
||||
OCSP_RESPONSE *response = NULL;
|
||||
OCSP_BASICRESP *basic = NULL;
|
||||
X509_STORE *store = NULL;
|
||||
const unsigned char *start = (const unsigned char*)b_orig(respbuf);
|
||||
|
||||
if (!chain && !issuer) {
|
||||
memprintf(err, "check_ocsp_response needs a certificate validation chain or an issuer certificate");
|
||||
goto end;
|
||||
}
|
||||
|
||||
response = d2i_OCSP_RESPONSE(NULL, &start, b_data(respbuf));
|
||||
if (!response) {
|
||||
memprintf(err, "d2i_OCSP_RESPONSE() failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
n = OCSP_response_status(response);
|
||||
|
||||
if (n != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
|
||||
memprintf(err, "OCSP response not successful (%d: %s)",
|
||||
n, OCSP_response_status_str(n));
|
||||
goto end;
|
||||
}
|
||||
|
||||
basic = OCSP_response_get1_basic(response);
|
||||
if (basic == NULL) {
|
||||
memprintf(err, "OCSP_response_get1_basic() failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Add ocsp issuer certificate to a store in order verify the ocsp
|
||||
* response. */
|
||||
store = X509_STORE_new();
|
||||
if (!store) {
|
||||
memprintf(err, "X509_STORE_new() failed");
|
||||
goto end;
|
||||
}
|
||||
X509_STORE_add_cert(store, issuer);
|
||||
|
||||
if (OCSP_basic_verify(basic, chain, store, 0) != 1) {
|
||||
memprintf(err, "OCSP_basic_verify() failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
X509_STORE_free(store);
|
||||
OCSP_RESPONSE_free(response);
|
||||
OCSP_BASICRESP_free(basic);
|
||||
return ret;
|
||||
}
|
||||
#endif /* defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP */
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user