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
|
||||
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.
|
||||
|
@@ -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__ */
|
||||
|
@@ -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
|
||||
|
@@ -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");
|
||||
|
||||
|
Reference in New Issue
Block a user