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:
3
CHANGES
3
CHANGES
@@ -4,6 +4,9 @@ Changes with Apache 2.5.1
|
|||||||
*) mod_ssl/mod_md: reversing dependency by letting mod_ssl offer hooks for
|
*) 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
|
adding certificates and keys to a virtual host. An additional hook allows
|
||||||
answering special TLS connections as used in ACME challenges.
|
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]
|
[Stefan Eissing]
|
||||||
|
|
||||||
*) mod_md: bringing over v2.0.6 from github.
|
*) mod_md: bringing over v2.0.6 from github.
|
||||||
|
@@ -121,10 +121,41 @@ APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_fallback_cert_files,
|
|||||||
/** On TLS connections that do not relate to a configured virtual host,
|
/** On TLS connections that do not relate to a configured virtual host,
|
||||||
* allow other modules to provide a X509 certificate and EVP_PKEY to
|
* allow other modules to provide a X509 certificate and EVP_PKEY to
|
||||||
* be used on the connection. This first hook which does not
|
* 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,
|
APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, answer_challenge,
|
||||||
(conn_rec *c, const char *server_name,
|
(conn_rec *c, const char *server_name,
|
||||||
void **pX509, void **pEVP_PKEY))
|
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 /* SSL_CERT_HOOKS */
|
||||||
|
|
||||||
|
@@ -59,7 +59,6 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, answer_challenge,
|
|||||||
DECLINED, DECLINED)
|
DECLINED, DECLINED)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* _________________________________________________________________
|
/* _________________________________________________________________
|
||||||
**
|
**
|
||||||
** Module Initialization
|
** 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
|
* loaded via SSLOpenSSLConfCmd Certificate), so for 1.0.2 and
|
||||||
* later, we defer to the code in ssl_init_server_ctx.
|
* later, we defer to the code in ssl_init_server_ctx.
|
||||||
*/
|
*/
|
||||||
if ((mctx->stapling_enabled == TRUE) &&
|
if (!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
|
||||||
!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567)
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567)
|
||||||
"Unable to configure certificate %s for stapling",
|
"Unable to configure certificate %s for stapling",
|
||||||
key_id);
|
key_id);
|
||||||
@@ -1833,8 +1831,8 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
|
|||||||
|
|
||||||
pks->service_unavailable = 1;
|
pks->service_unavailable = 1;
|
||||||
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085)
|
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085)
|
||||||
"Init: %s will respond with '503 Service Unavailable' for now. This "
|
"Init: %s will respond with '503 Service Unavailable' for now. There "
|
||||||
"has no SSL certificate configured and no other module contributed any.",
|
"are no SSL certificates configured and no other module contributed any.",
|
||||||
ssl_util_vhostid(p, s));
|
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
|
* (late) point makes sure that we catch both certificates loaded
|
||||||
* via SSLCertificateFile and SSLOpenSSLConfCmd Certificate.
|
* via SSLCertificateFile and SSLOpenSSLConfCmd Certificate.
|
||||||
*/
|
*/
|
||||||
if (sc->server->stapling_enabled == TRUE) {
|
do {
|
||||||
X509 *cert;
|
X509 *cert;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx,
|
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);
|
SSL_CERT_SET_NEXT);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
} while(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TLS_SESSION_TICKETS
|
#ifdef HAVE_TLS_SESSION_TICKETS
|
||||||
|
@@ -31,12 +31,28 @@
|
|||||||
#include "ssl_private.h"
|
#include "ssl_private.h"
|
||||||
#include "ap_mpm.h"
|
#include "ap_mpm.h"
|
||||||
#include "apr_thread_mutex.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
|
#ifdef HAVE_OCSP_STAPLING
|
||||||
|
|
||||||
static int stapling_cache_mutex_on(server_rec *s);
|
static int stapling_cache_mutex_on(server_rec *s);
|
||||||
static int stapling_cache_mutex_off(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
|
* Maxiumum OCSP stapling response size. This should be the response for a
|
||||||
* single certificate and will typically include the responder certificate chain
|
* 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;
|
OCSP_CERTID *cid = NULL;
|
||||||
STACK_OF(OPENSSL_STRING) *aia = 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;
|
return 0;
|
||||||
|
|
||||||
cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
|
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;
|
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);
|
cid = OCSP_cert_to_id(NULL, x, issuer);
|
||||||
X509_free(issuer);
|
X509_free(issuer);
|
||||||
if (!cid) {
|
if (!cid) {
|
||||||
@@ -182,18 +222,16 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
|
|||||||
mctx->sc->vhost_id);
|
mctx->sc->vhost_id);
|
||||||
|
|
||||||
apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf);
|
apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf);
|
||||||
|
|
||||||
return 1;
|
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)
|
SSL *ssl)
|
||||||
{
|
{
|
||||||
certinfo *cinf;
|
certinfo *cinf;
|
||||||
X509 *x;
|
|
||||||
UCHAR idx[SHA_DIGEST_LENGTH];
|
UCHAR idx[SHA_DIGEST_LENGTH];
|
||||||
x = SSL_get_certificate(ssl);
|
if (X509_digest(x, EVP_sha1(), idx, NULL) != 1)
|
||||||
if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
|
cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
|
||||||
if (cinf && cinf->cid)
|
if (cinf && cinf->cid)
|
||||||
@@ -751,18 +789,34 @@ static int stapling_cb(SSL *ssl, void *arg)
|
|||||||
OCSP_RESPONSE *rsp = NULL;
|
OCSP_RESPONSE *rsp = NULL;
|
||||||
int rv;
|
int rv;
|
||||||
BOOL ok = TRUE;
|
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) {
|
if (sc->server->stapling_enabled != TRUE) {
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01950)
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01950)
|
||||||
"stapling_cb: OCSP Stapling disabled");
|
"stapling_cb: OCSP Stapling disabled");
|
||||||
return SSL_TLSEXT_ERR_NOACK;
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
|
if ((cinf = stapling_get_certinfo(s, x, mctx, ssl)) == NULL) {
|
||||||
"stapling_cb: OCSP Stapling callback called");
|
|
||||||
|
|
||||||
cinf = stapling_get_certinfo(s, mctx, ssl);
|
|
||||||
if (cinf == NULL) {
|
|
||||||
return SSL_TLSEXT_ERR_NOACK;
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -865,9 +919,10 @@ apr_status_t modssl_init_stapling(server_rec *s, apr_pool_t *p,
|
|||||||
if (mctx->stapling_responder_timeout == UNSET) {
|
if (mctx->stapling_responder_timeout == UNSET) {
|
||||||
mctx->stapling_responder_timeout = 10 * APR_USEC_PER_SEC;
|
mctx->stapling_responder_timeout = 10 * APR_USEC_PER_SEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX_set_tlsext_status_cb(ctx, stapling_cb);
|
SSL_CTX_set_tlsext_status_cb(ctx, stapling_cb);
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01960) "OCSP stapling initialized");
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01960) "OCSP stapling initialized");
|
||||||
|
|
||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user