1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

*) mod_ssl/mod_md:

Adding 2 new hooks for init/get of OCSP stapling status information when
     other modules want to provide those. Falls back to own implementation with
     same behaviour as before.
 


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1862384 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stefan Eissing
2019-07-01 14:22:04 +00:00
parent f9fb4c48b1
commit 360986b191
4 changed files with 114 additions and 27 deletions

View File

@@ -4,6 +4,9 @@ Changes with Apache 2.5.1
*) mod_ssl/mod_md: reversing dependency by letting mod_ssl offer hooks for
adding certificates and keys to a virtual host. An additional hook allows
answering special TLS connections as used in ACME challenges.
Adding 2 new hooks for init/get of OCSP stapling status information when
other modules want to provide those. Falls back to own implementation with
same behaviour as before.
[Stefan Eissing]
*) mod_md: bringing over v2.0.6 from github.

View File

@@ -121,11 +121,42 @@ APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_fallback_cert_files,
/** On TLS connections that do not relate to a configured virtual host,
* allow other modules to provide a X509 certificate and EVP_PKEY to
* be used on the connection. This first hook which does not
* return DECLINDED will determine the outcome. */
* return DECLINED will determine the outcome. */
APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, answer_challenge,
(conn_rec *c, const char *server_name,
void **pX509, void **pEVP_PKEY))
/** During post_config phase, ask around if someone wants to provide
* OCSP stapling status information for the given cert (with the also
* provided issuer certificate). The first hook which does not
* return DECLINED promises to take responsibility (and respond
* in later calls via hook ssl_get_stapling_status).
* If no hook takes over, mod_ssl's own stapling implementation will
* be applied (if configured).
*/
APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, init_stapling_status,
(server_rec *s, apr_pool_t *p,
void *x509cert, void *x509issuer))
/** Anyone answering positive to ssl_init_stapling_status for a
* certificate, needs to register here and supply the actual OCSP stapling
* status data (OCSP_RESP) for a new connection.
* The data is returned in DER encoded bytes via pder and pderlen. The
* returned pointer may be NULL, which indicates that data is (currently)
* unavailable.
* If DER data is returned, it MUST come from a response with
* status OCSP_RESPONSE_STATUS_SUCCESSFUL and V_OCSP_CERTSTATUS_GOOD
* or V_OCSP_CERTSTATUS_REVOKED, not V_OCSP_CERTSTATUS_UNKNOWN. This means
* errors in OCSP retrieval are to be handled/logged by the hook and
* are not done by mod_ssl.
* Any DER bytes returned MUST be allocated via malloc() and ownership
* passes to mod_ssl. Meaning, the hook must return a malloced copy of
* the data it has. mod_ssl (or OpenSSL) will free it.
*/
APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, get_stapling_status,
(unsigned char **pder, int *pderlen,
conn_rec *c, server_rec *s, void *x509cert))
#endif /* SSL_CERT_HOOKS */
#endif /* __MOD_SSL_H__ */

View File

@@ -59,7 +59,6 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, answer_challenge,
DECLINED, DECLINED)
/* _________________________________________________________________
**
** Module Initialization
@@ -1423,8 +1422,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
* loaded via SSLOpenSSLConfCmd Certificate), so for 1.0.2 and
* later, we defer to the code in ssl_init_server_ctx.
*/
if ((mctx->stapling_enabled == TRUE) &&
!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
if (!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567)
"Unable to configure certificate %s for stapling",
key_id);
@@ -1833,8 +1831,8 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
pks->service_unavailable = 1;
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085)
"Init: %s will respond with '503 Service Unavailable' for now. This "
"has no SSL certificate configured and no other module contributed any.",
"Init: %s will respond with '503 Service Unavailable' for now. There "
"are no SSL certificates configured and no other module contributed any.",
ssl_util_vhostid(p, s));
}
@@ -1887,7 +1885,7 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
* (late) point makes sure that we catch both certificates loaded
* via SSLCertificateFile and SSLOpenSSLConfCmd Certificate.
*/
if (sc->server->stapling_enabled == TRUE) {
do {
X509 *cert;
int i = 0;
int ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx,
@@ -1904,7 +1902,7 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
SSL_CERT_SET_NEXT);
i++;
}
}
} while(0);
#endif
#ifdef HAVE_TLS_SESSION_TICKETS

View File

@@ -31,12 +31,28 @@
#include "ssl_private.h"
#include "ap_mpm.h"
#include "apr_thread_mutex.h"
#include "mod_ssl.h"
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_stapling_status,
(server_rec *s, apr_pool_t *p,
void *x509cert, void *x509issuer),
(s, p, x509cert, x509issuer),
DECLINED, DECLINED)
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, get_stapling_status,
(unsigned char **pder, int *pderlen,
conn_rec *c, server_rec *s, void *x509cert),
(pder, pderlen, c, s, x509cert),
DECLINED, DECLINED)
#ifdef HAVE_OCSP_STAPLING
static int stapling_cache_mutex_on(server_rec *s);
static int stapling_cache_mutex_off(server_rec *s);
static int stapling_cb(SSL *ssl, void *arg);
/**
* Maxiumum OCSP stapling response size. This should be the response for a
* single certificate and will typically include the responder certificate chain
@@ -119,7 +135,38 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
OCSP_CERTID *cid = NULL;
STACK_OF(OPENSSL_STRING) *aia = NULL;
if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1))
if (x == NULL)
return 0;
if (!(issuer = stapling_get_issuer(mctx, x))) {
/* In Apache pre 2.4.40, we use to come here only when mod_ssl stapling
* was enabled. With the new hooks, we give other modules the chance
* to provide stapling status. However, we do not want to log ssl errors
* where we did not do so in the past. */
if (mctx->stapling_enabled == TRUE) {
ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217)
"ssl_stapling_init_cert: can't retrieve issuer "
"certificate!");
return 0;
}
return 1;
}
if (ssl_run_init_stapling_status(s, p, x, issuer) == APR_SUCCESS) {
/* Someone's taken over or mod_ssl's own implementation is not enabled */
if (mctx->stapling_enabled != TRUE) {
SSL_CTX_set_tlsext_status_cb(mctx->ssl_ctx, stapling_cb);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() "OCSP stapling added via hook");
}
return 1;
}
if (mctx->stapling_enabled != TRUE) {
/* mod_ssl's own implementation is not enabled */
return 1;
}
if (X509_digest(x, EVP_sha1(), idx, NULL) != 1)
return 0;
cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
@@ -139,13 +186,6 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
return 1;
}
if (!(issuer = stapling_get_issuer(mctx, x))) {
ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217)
"ssl_stapling_init_cert: can't retrieve issuer "
"certificate!");
return 0;
}
cid = OCSP_cert_to_id(NULL, x, issuer);
X509_free(issuer);
if (!cid) {
@@ -186,14 +226,12 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
return 1;
}
static certinfo *stapling_get_certinfo(server_rec *s, modssl_ctx_t *mctx,
static certinfo *stapling_get_certinfo(server_rec *s, X509 *x, modssl_ctx_t *mctx,
SSL *ssl)
{
certinfo *cinf;
X509 *x;
UCHAR idx[SHA_DIGEST_LENGTH];
x = SSL_get_certificate(ssl);
if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1))
if (X509_digest(x, EVP_sha1(), idx, NULL) != 1)
return NULL;
cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
if (cinf && cinf->cid)
@@ -751,6 +789,26 @@ static int stapling_cb(SSL *ssl, void *arg)
OCSP_RESPONSE *rsp = NULL;
int rv;
BOOL ok = TRUE;
X509 *x;
unsigned char *rspder = NULL;
int rspderlen;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
"stapling_cb: OCSP Stapling callback called");
x = SSL_get_certificate(ssl);
if (x == NULL) {
return SSL_TLSEXT_ERR_NOACK;
}
if (ssl_run_get_stapling_status(&rspder, &rspderlen, conn, s, x) == APR_SUCCESS) {
/* a hook handles stapling for this certicate and determines the response */
if (rspder == NULL || rspderlen <= 0) {
return SSL_TLSEXT_ERR_NOACK;
}
SSL_set_tlsext_status_ocsp_resp(ssl, rspder, rspderlen);
return SSL_TLSEXT_ERR_OK;
}
if (sc->server->stapling_enabled != TRUE) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01950)
@@ -758,11 +816,7 @@ static int stapling_cb(SSL *ssl, void *arg)
return SSL_TLSEXT_ERR_NOACK;
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
"stapling_cb: OCSP Stapling callback called");
cinf = stapling_get_certinfo(s, mctx, ssl);
if (cinf == NULL) {
if ((cinf = stapling_get_certinfo(s, x, mctx, ssl)) == NULL) {
return SSL_TLSEXT_ERR_NOACK;
}
@@ -865,6 +919,7 @@ apr_status_t modssl_init_stapling(server_rec *s, apr_pool_t *p,
if (mctx->stapling_responder_timeout == UNSET) {
mctx->stapling_responder_timeout = 10 * APR_USEC_PER_SEC;
}
SSL_CTX_set_tlsext_status_cb(ctx, stapling_cb);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01960) "OCSP stapling initialized");