From: Rainer Jung Date: Mon, 4 Apr 2016 11:33:31 +0000 (+0000) Subject: Support for OpenSSL 1.1.0: X-Git-Tag: 2.5.0-alpha~1787 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f31ec0318d66d8b8acfa0ca11d320c5bb36e2f43;p=apache Support for OpenSSL 1.1.0: - BIO was made opaque after OpenSSL 1.1.0pre4. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1737657 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 8304c8944b..a9dbb7ccd5 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -356,6 +356,9 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, modssl_init_app_data2_idx(); /* for modssl_get_app_data2() at request time */ init_dh_params(); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + init_bio_methods(); +#endif return OK; } @@ -1984,6 +1987,9 @@ apr_status_t ssl_init_ModuleKill(void *data) ssl_init_ctx_cleanup(sc->server); } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + free_bio_methods(); +#endif free_dh_params(); return APR_SUCCESS; diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 456e8d4a8d..a74ddf873a 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -149,7 +149,7 @@ static int bio_filter_out_pass(bio_filter_out_ctx_t *outctx) * success, -1 on failure. */ static int bio_filter_out_flush(BIO *bio) { - bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); apr_bucket *e; AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(outctx->bb)); @@ -162,10 +162,16 @@ static int bio_filter_out_flush(BIO *bio) static int bio_filter_create(BIO *bio) { - bio->shutdown = 1; - bio->init = 1; + BIO_set_shutdown(bio, 1); + BIO_set_init(bio, 1); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + /* No setter method for OpenSSL 1.1.0 available, + * but I can't find any functional use of the + * "num" field there either. + */ bio->num = -1; - bio->ptr = NULL; +#endif + BIO_set_data(bio, NULL); return 1; } @@ -185,7 +191,7 @@ static int bio_filter_destroy(BIO *bio) static int bio_filter_out_read(BIO *bio, char *out, int outl) { /* this is never called */ - bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c, "BUG: %s() should not be called", "bio_filter_out_read"); AP_DEBUG_ASSERT(0); @@ -194,7 +200,7 @@ static int bio_filter_out_read(BIO *bio, char *out, int outl) static int bio_filter_out_write(BIO *bio, const char *in, int inl) { - bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); apr_bucket *e; int need_flush; @@ -245,7 +251,7 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl) static long bio_filter_out_ctrl(BIO *bio, int cmd, long num, void *ptr) { long ret = 1; - bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); switch (cmd) { case BIO_CTRL_RESET: @@ -261,10 +267,10 @@ static long bio_filter_out_ctrl(BIO *bio, int cmd, long num, void *ptr) ret = 0; break; case BIO_CTRL_GET_CLOSE: - ret = (long)bio->shutdown; + ret = (long)BIO_get_shutdown(bio); break; case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; + BIO_set_shutdown(bio, (int)num); break; case BIO_CTRL_FLUSH: ret = bio_filter_out_flush(bio); @@ -289,7 +295,7 @@ static long bio_filter_out_ctrl(BIO *bio, int cmd, long num, void *ptr) static int bio_filter_out_gets(BIO *bio, char *buf, int size) { /* this is never called */ - bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c, "BUG: %s() should not be called", "bio_filter_out_gets"); AP_DEBUG_ASSERT(0); @@ -299,26 +305,13 @@ static int bio_filter_out_gets(BIO *bio, char *buf, int size) static int bio_filter_out_puts(BIO *bio, const char *str) { /* this is never called */ - bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c, "BUG: %s() should not be called", "bio_filter_out_puts"); AP_DEBUG_ASSERT(0); return -1; } -static BIO_METHOD bio_filter_out_method = { - BIO_TYPE_MEM, - "APR output filter", - bio_filter_out_write, - bio_filter_out_read, /* read is never called */ - bio_filter_out_puts, /* puts is never called */ - bio_filter_out_gets, /* gets is never called */ - bio_filter_out_ctrl, - bio_filter_create, - bio_filter_destroy, - NULL -}; - typedef struct { int length; char *value; @@ -468,7 +461,7 @@ static apr_status_t brigade_consume(apr_bucket_brigade *bb, static int bio_filter_in_read(BIO *bio, char *in, int inlen) { apr_size_t inl = inlen; - bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr); + bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); apr_read_type_e block = inctx->block; inctx->rc = APR_SUCCESS; @@ -550,7 +543,7 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen) static int bio_filter_in_write(BIO *bio, const char *in, int inl) { - bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr); + bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, "BUG: %s() should not be called", "bio_filter_in_write"); AP_DEBUG_ASSERT(0); @@ -559,7 +552,7 @@ static int bio_filter_in_write(BIO *bio, const char *in, int inl) static int bio_filter_in_puts(BIO *bio, const char *str) { - bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr); + bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, "BUG: %s() should not be called", "bio_filter_in_puts"); AP_DEBUG_ASSERT(0); @@ -568,7 +561,7 @@ static int bio_filter_in_puts(BIO *bio, const char *str) static int bio_filter_in_gets(BIO *bio, char *buf, int size) { - bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr); + bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, "BUG: %s() should not be called", "bio_filter_in_gets"); AP_DEBUG_ASSERT(0); @@ -577,13 +570,28 @@ static int bio_filter_in_gets(BIO *bio, char *buf, int size) static long bio_filter_in_ctrl(BIO *bio, int cmd, long num, void *ptr) { - bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr); + bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, "BUG: %s() should not be called", "bio_filter_in_ctrl"); AP_DEBUG_ASSERT(0); return -1; } +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +static BIO_METHOD bio_filter_out_method = { + BIO_TYPE_MEM, + "APR output filter", + bio_filter_out_write, + bio_filter_out_read, /* read is never called */ + bio_filter_out_puts, /* puts is never called */ + bio_filter_out_gets, /* gets is never called */ + bio_filter_out_ctrl, + bio_filter_create, + bio_filter_destroy, + NULL +}; + static BIO_METHOD bio_filter_in_method = { BIO_TYPE_MEM, "APR input filter", @@ -597,6 +605,38 @@ static BIO_METHOD bio_filter_in_method = { NULL }; +#else + +static BIO_METHOD *bio_filter_out_method = NULL; +static BIO_METHOD *bio_filter_in_method = NULL; + +void init_bio_methods(void) +{ + bio_filter_out_method = BIO_meth_new(BIO_TYPE_MEM, "APR output filter"); + BIO_meth_set_write(bio_filter_out_method, &bio_filter_out_write); + BIO_meth_set_read(bio_filter_out_method, &bio_filter_out_read); /* read is never called */ + BIO_meth_set_puts(bio_filter_out_method, &bio_filter_out_puts); /* puts is never called */ + BIO_meth_set_gets(bio_filter_out_method, &bio_filter_out_gets); /* gets is never called */ + BIO_meth_set_ctrl(bio_filter_out_method, &bio_filter_out_ctrl); + BIO_meth_set_create(bio_filter_out_method, &bio_filter_create); + BIO_meth_set_destroy(bio_filter_out_method, &bio_filter_destroy); + + bio_filter_in_method = BIO_meth_new(BIO_TYPE_MEM, "APR input filter"); + BIO_meth_set_write(bio_filter_in_method, &bio_filter_in_write); /* write is never called */ + BIO_meth_set_read(bio_filter_in_method, &bio_filter_in_read); + BIO_meth_set_puts(bio_filter_in_method, &bio_filter_in_puts); /* puts is never called */ + BIO_meth_set_gets(bio_filter_in_method, &bio_filter_in_gets); /* gets is never called */ + BIO_meth_set_ctrl(bio_filter_in_method, &bio_filter_in_ctrl); /* ctrl is never called */ + BIO_meth_set_create(bio_filter_in_method, &bio_filter_create); + BIO_meth_set_destroy(bio_filter_in_method, &bio_filter_destroy); +} + +void free_bio_methods(void) +{ + BIO_meth_free(bio_filter_out_method); + BIO_meth_free(bio_filter_in_method); +} +#endif static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, char *buf, @@ -826,7 +866,7 @@ static apr_status_t ssl_filter_write(ap_filter_t *f, return APR_EGENERAL; } - outctx = (bio_filter_out_ctx_t *)filter_ctx->pbioWrite->ptr; + outctx = (bio_filter_out_ctx_t *)BIO_get_data(filter_ctx->pbioWrite); res = SSL_write(filter_ctx->pssl, (unsigned char *)data, len); if (res < 0) { @@ -1301,9 +1341,9 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) if ((n = SSL_accept(filter_ctx->pssl)) <= 0) { bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *) - (filter_ctx->pbioRead->ptr); + BIO_get_data(filter_ctx->pbioRead); bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *) - (filter_ctx->pbioWrite->ptr); + BIO_get_data(filter_ctx->pbioWrite); apr_status_t rc = inctx->rc ? inctx->rc : outctx->rc ; ssl_err = SSL_get_error(filter_ctx->pssl, n); @@ -1725,8 +1765,8 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f, return ap_pass_brigade(f->next, bb); } - inctx = (bio_filter_in_ctx_t *)filter_ctx->pbioRead->ptr; - outctx = (bio_filter_out_ctx_t *)filter_ctx->pbioWrite->ptr; + inctx = (bio_filter_in_ctx_t *)BIO_get_data(filter_ctx->pbioRead); + outctx = (bio_filter_out_ctx_t *)BIO_get_data(filter_ctx->pbioWrite); /* When we are the writer, we must initialize the inctx * mode so that we block for any required ssl input, because @@ -2022,8 +2062,12 @@ static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c, filter_ctx->pInputFilter = ap_add_input_filter(ssl_io_filter, inctx, r, c); +#if OPENSSL_VERSION_NUMBER < 0x10100000L filter_ctx->pbioRead = BIO_new(&bio_filter_in_method); - filter_ctx->pbioRead->ptr = (void *)inctx; +#else + filter_ctx->pbioRead = BIO_new(bio_filter_in_method); +#endif + BIO_set_data(filter_ctx->pbioRead, (void *)inctx); inctx->ssl = ssl; inctx->bio_out = filter_ctx->pbioWrite; @@ -2053,8 +2097,12 @@ void ssl_io_filter_init(conn_rec *c, request_rec *r, SSL *ssl) filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter, filter_ctx, r, c); +#if OPENSSL_VERSION_NUMBER < 0x10100000L filter_ctx->pbioWrite = BIO_new(&bio_filter_out_method); - filter_ctx->pbioWrite->ptr = (void *)bio_filter_out_ctx_new(filter_ctx, c); +#else + filter_ctx->pbioWrite = BIO_new(bio_filter_out_method); +#endif + BIO_set_data(filter_ctx->pbioWrite, (void *)bio_filter_out_ctx_new(filter_ctx, c)); /* write is non blocking for the benefit of async mpm */ if (c->cs) { diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 958a713948..44fefb8cda 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -199,6 +199,17 @@ #endif /* !defined(OPENSSL_NO_TLSEXT) && defined(SSL_set_tlsext_host_name) */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define BIO_set_init(x,v) (x->init=v) +#define BIO_get_data(x) (x->ptr) +#define BIO_set_data(x,v) (x->ptr=v) +#define BIO_get_shutdown(x) (x->shutdown) +#define BIO_set_shutdown(x,v) (x->shutdown=v) +#else +void init_bio_methods(void); +void free_bio_methods(void); +#endif + /* mod_ssl headers */ #include "ssl_util_ssl.h"