--- apache2-2.4.23/modules/ssl/mod_ssl.c +++ apache2-2.4.23/modules/ssl/mod_ssl.c @@ -312,7 +312,9 @@ static apr_status_t ssl_cleanup_pre_conf #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES ENGINE_cleanup(); #endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L ERR_remove_state(0); +#endif /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only * actually loaded the error strings once per process due to static @@ -342,7 +344,9 @@ static int ssl_hook_pre_config(apr_pool_ /* We must register the library in full, to ensure our configuration * code can successfully test the SSL environment. */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L CRYPTO_malloc_init(); +#endif ERR_load_crypto_strings(); SSL_load_error_strings(); SSL_library_init(); @@ -378,6 +382,8 @@ static int ssl_hook_pre_config(apr_pool_ APR_LOCK_DEFAULT, 0); #endif + ssl_engine_io_init(); + return OK; } --- apache2-2.4.23/modules/ssl/ssl_engine_init.c +++ apache2-2.4.23/modules/ssl/ssl_engine_init.c @@ -47,23 +47,37 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, #define KEYTYPES "RSA or DSA" #endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define DH_bits(dh) BN_num_bits(dh->p) +#endif + /* * Grab well-defined DH parameters from OpenSSL, see the get_rfc* * functions in for all available primes. */ static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *), const char *gen) { - DH *dh = DH_new(); + DH *dh; + BIGNUM *p, *g; + p = prime(NULL); + BN_dec2bn(&g, gen); + if (!p || !g) { + return NULL; + } + dh = DH_new(); if (!dh) { return NULL; } - dh->p = prime(NULL); - BN_dec2bn(&dh->g, gen); - if (!dh->p || !dh->g) { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (!DH_set0_pqg(dh, p, NULL, g)) { DH_free(dh); return NULL; } +#else + dh->p = p; + dh->g = g; +#endif return dh; } @@ -480,6 +494,7 @@ static apr_status_t ssl_init_ctx_protoco MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL; char *cp; int protocol = mctx->protocol; + int ssl_version = 0; SSLSrvConfigRec *sc = mySrvConfig(s); /* @@ -506,37 +521,38 @@ static apr_status_t ssl_init_ctx_protoco ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "Creating new SSL context (protocols: %s)", cp); + method = mctx->pkp ? + SSLv23_client_method() : /* proxy */ + SSLv23_server_method(); /* server */ + ctx = SSL_CTX_new(method); + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L #ifndef OPENSSL_NO_SSL3 - if (protocol == SSL_PROTOCOL_SSLV3) { - method = mctx->pkp ? - SSLv3_client_method() : /* proxy */ - SSLv3_server_method(); /* server */ - } + if (protocol == SSL_PROTOCOL_SSLV3) + ssl_version = SSL3_VERSION; else #endif - if (protocol == SSL_PROTOCOL_TLSV1) { - method = mctx->pkp ? - TLSv1_client_method() : /* proxy */ - TLSv1_server_method(); /* server */ - } -#ifdef HAVE_TLSV1_X - else if (protocol == SSL_PROTOCOL_TLSV1_1) { - method = mctx->pkp ? - TLSv1_1_client_method() : /* proxy */ - TLSv1_1_server_method(); /* server */ - } - else if (protocol == SSL_PROTOCOL_TLSV1_2) { - method = mctx->pkp ? - TLSv1_2_client_method() : /* proxy */ - TLSv1_2_server_method(); /* server */ - } + if (protocol == SSL_PROTOCOL_TLSV1) + ssl_version = TLS1_VERSION; + else if (protocol == SSL_PROTOCOL_TLSV1_1) + ssl_version = TLS1_1_VERSION; + else if (protocol == SSL_PROTOCOL_TLSV1_2) + ssl_version = TLS1_2_VERSION; + SSL_CTX_set_min_proto_version(ctx, ssl_version); + SSL_CTX_set_max_proto_version(ctx, ssl_version); +#else /* OPENSSL_VERSION_NUMBER */ +#ifndef OPENSSL_NO_SSL3 + if (protocol == SSL_PROTOCOL_SSLV3) + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2); + else #endif - else { /* For multiple protocols, we need a flexible method */ - method = mctx->pkp ? - SSLv23_client_method() : /* proxy */ - SSLv23_server_method(); /* server */ - } - ctx = SSL_CTX_new(method); + if (protocol == SSL_PROTOCOL_TLSV1) + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2); + else if (protocol == SSL_PROTOCOL_TLSV1_1) + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2); + else if (protocol == SSL_PROTOCOL_TLSV1_2) + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); +#endif /* OPENSSL_VERSION_NUMBER */ mctx->ssl_ctx = ctx; @@ -858,7 +874,7 @@ static int use_certificate_chain( unsigned long err; int n; - if ((bio = BIO_new(BIO_s_file_internal())) == NULL) + if ((bio = BIO_new(BIO_s_file())) == NULL) return -1; if (BIO_read_filename(bio, file) <= 0) { BIO_free(bio); @@ -1200,7 +1216,7 @@ static apr_status_t ssl_init_server_cert SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540) "Custom DH parameters (%d bits) for %s loaded from %s", - BN_num_bits(dhparams->p), vhost_id, certfile); + DH_bits(dhparams), vhost_id, certfile); DH_free(dhparams); } --- apache2-2.4.23/modules/ssl/ssl_engine_io.c +++ apache2-2.4.23/modules/ssl/ssl_engine_io.c @@ -36,6 +36,34 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, (conn_rec *c,SSL *ssl), (c,ssl),OK,DECLINED); +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define BIO_get_data(bio) (bio->ptr) +#define BIO_set_data(bio, data) bio->ptr = data +#define BIO_get_shutdown(bio) (bio->shutdown) +#define BIO_set_shutdown(bio, shut) bio->shutdown = shut +#define BIO_set_init(bio, i) bio->init = i + +static BIO_METHOD *BIO_meth_new(int type, const char *name) +{ + BIO_METHOD *bio = calloc(1, sizeof(BIO_METHOD)); + + if (bio != NULL) { + bio->type = type; + bio->name = name; + } + return bio; +} + +#define BIO_meth_set_write(bio, write_) bio->bwrite = write_ +#define BIO_meth_set_read(bio, read_) bio->bread = read_ +#define BIO_meth_set_puts(bio, puts_) bio->bputs = puts_ +#define BIO_meth_set_gets(bio, gets_) bio->bgets = gets_ +#define BIO_meth_set_ctrl(bio, ctrl_) bio->ctrl = ctrl_ +#define BIO_meth_set_create(bio, create_) bio->create = create_ +#define BIO_meth_set_destroy(bio, destroy_) bio->destroy = destroy_ + +#endif + /* _________________________________________________________________ ** ** I/O Hooks @@ -149,7 +177,7 @@ static int bio_filter_out_pass(bio_filte * 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 +190,9 @@ static int bio_filter_out_flush(BIO *bio static int bio_filter_create(BIO *bio) { - bio->shutdown = 1; - bio->init = 1; - bio->num = -1; - bio->ptr = NULL; + BIO_set_shutdown(bio, 1); + BIO_set_init(bio, 1); + BIO_set_data(bio, NULL); return 1; } @@ -190,7 +217,7 @@ static int bio_filter_out_read(BIO *bio, 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; @@ -241,7 +268,7 @@ static int bio_filter_out_write(BIO *bio 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: @@ -257,10 +284,10 @@ static long bio_filter_out_ctrl(BIO *bio 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); @@ -294,18 +321,22 @@ static int bio_filter_out_puts(BIO *bio, 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 -}; +static BIO_METHOD *bio_filter_out_method; + +static int create_bio_filter_out_method(void) +{ + bio_filter_out_method = BIO_meth_new(BIO_TYPE_MEM, "APR output filter"); + if (bio_filter_out_method == NULL) + return 0; + 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); + return 1; +} typedef struct { int length; @@ -456,7 +487,7 @@ static apr_status_t brigade_consume(apr_ 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; @@ -537,19 +568,18 @@ static int bio_filter_in_read(BIO *bio, } -static BIO_METHOD bio_filter_in_method = { - BIO_TYPE_MEM, - "APR input filter", - NULL, /* write is never called */ - bio_filter_in_read, - NULL, /* puts is never called */ - NULL, /* gets is never called */ - NULL, /* ctrl is never called */ - bio_filter_create, - bio_filter_destroy, - NULL -}; +static BIO_METHOD *bio_filter_in_method; +static int create_bio_filter_in_method(void) +{ + bio_filter_in_method = BIO_meth_new(BIO_TYPE_MEM, "APR input filter"); + if (bio_filter_in_method == NULL) + return 0; + BIO_meth_set_read(bio_filter_in_method, bio_filter_in_read); + BIO_meth_set_create(bio_filter_in_method, bio_filter_create); + BIO_meth_set_destroy(bio_filter_in_method, bio_filter_destroy); + return 1; +} static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, char *buf, @@ -779,7 +809,7 @@ static apr_status_t ssl_filter_write(ap_ 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) { @@ -1252,9 +1282,9 @@ static apr_status_t ssl_io_filter_handsh 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); @@ -1667,8 +1697,8 @@ static apr_status_t ssl_io_filter_output 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 @@ -1949,8 +1979,8 @@ static void ssl_io_input_add_filter(ssl_ filter_ctx->pInputFilter = ap_add_input_filter(ssl_io_filter, inctx, r, c); - filter_ctx->pbioRead = BIO_new(&bio_filter_in_method); - filter_ctx->pbioRead->ptr = (void *)inctx; + filter_ctx->pbioRead = BIO_new(bio_filter_in_method); + BIO_set_data(filter_ctx->pbioRead, inctx); inctx->ssl = ssl; inctx->bio_out = filter_ctx->pbioWrite; @@ -1980,8 +2010,8 @@ void ssl_io_filter_init(conn_rec *c, req filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter, filter_ctx, r, c); - filter_ctx->pbioWrite = BIO_new(&bio_filter_out_method); - filter_ctx->pbioWrite->ptr = (void *)bio_filter_out_ctx_new(filter_ctx, c); + filter_ctx->pbioWrite = BIO_new(bio_filter_out_method); + BIO_set_data(filter_ctx->pbioWrite, bio_filter_out_ctx_new(filter_ctx, c)); /* write is non blocking for the benefit of async mpm */ if (c->cs) { @@ -2130,3 +2160,13 @@ long ssl_io_data_cb(BIO *bio, int cmd, } return rc; } + +int ssl_engine_io_init(void) +{ + if (!create_bio_filter_out_method()) + return 0; + if (!create_bio_filter_in_method()) + return 0; + return 1; +} + --- apache2-2.4.23/modules/ssl/ssl_engine_kernel.c +++ apache2-2.4.23/modules/ssl/ssl_engine_kernel.c @@ -33,6 +33,10 @@ #include "util_md5.h" #include "scoreboard.h" +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define TLS_ST_OK SSL_ST_OK +#endif + static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); #ifdef HAVE_TLSEXT static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s); @@ -80,7 +84,7 @@ static apr_status_t upgrade_connection(r SSL_set_accept_state(ssl); SSL_do_handshake(ssl); - if (SSL_get_state(ssl) != SSL_ST_OK) { + if (SSL_get_state(ssl) != TLS_ST_OK) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02030) "TLS upgrade handshake failed"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server); @@ -432,7 +436,7 @@ int ssl_hook_Access(request_rec *r) X509 *cert; X509 *peercert; X509_STORE *cert_store = NULL; - X509_STORE_CTX cert_store_ctx; + X509_STORE_CTX *cert_store_ctx; STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL; const SSL_CIPHER *cipher = NULL; int depth, verify_old, verify, n, is_slave = 0; @@ -456,7 +460,7 @@ int ssl_hook_Access(request_rec *r) * forbidden in the latter case, let ap_die() handle * this recursive (same) error. */ - if (SSL_get_state(ssl) != SSL_ST_OK) { + if (SSL_get_state(ssl) != TLS_ST_OK) { return HTTP_FORBIDDEN; } ctx = SSL_get_SSL_CTX(ssl); @@ -622,7 +626,7 @@ int ssl_hook_Access(request_rec *r) !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list)); n++) { - SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n); + const SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n); if (sk_SSL_CIPHER_find(cipher_list_old, value) < 0) { renegotiate = TRUE; @@ -633,7 +637,7 @@ int ssl_hook_Access(request_rec *r) !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list_old)); n++) { - SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n); + const SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n); if (sk_SSL_CIPHER_find(cipher_list, value) < 0) { renegotiate = TRUE; @@ -914,25 +918,26 @@ int ssl_hook_Access(request_rec *r) cert = sk_X509_value(cert_stack, 0); } - X509_STORE_CTX_init(&cert_store_ctx, cert_store, cert, cert_stack); + cert_store_ctx = X509_STORE_CTX_new(); + X509_STORE_CTX_init(cert_store_ctx, cert_store, cert, cert_stack); depth = SSL_get_verify_depth(ssl); if (depth >= 0) { - X509_STORE_CTX_set_depth(&cert_store_ctx, depth); + X509_STORE_CTX_set_depth(cert_store_ctx, depth); } - X509_STORE_CTX_set_ex_data(&cert_store_ctx, + X509_STORE_CTX_set_ex_data(cert_store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), (char *)ssl); - if (!X509_verify_cert(&cert_store_ctx)) { + if (!X509_verify_cert(cert_store_ctx)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02224) "Re-negotiation verification step failed"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server); } - SSL_set_verify_result(ssl, cert_store_ctx.error); - X509_STORE_CTX_cleanup(&cert_store_ctx); + SSL_set_verify_result(ssl, X509_STORE_CTX_get_error(cert_store_ctx)); + X509_STORE_CTX_free(cert_store_ctx); if (cert_stack != SSL_get_peer_cert_chain(ssl)) { /* we created this ourselves, so free it */ @@ -983,7 +988,7 @@ int ssl_hook_Access(request_rec *r) SSL_renegotiate(ssl); SSL_do_handshake(ssl); - if (SSL_get_state(ssl) != SSL_ST_OK) { + if (SSL_get_state(ssl) != TLS_ST_OK) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02225) "Re-negotiation request failed"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server); @@ -995,20 +1000,14 @@ int ssl_hook_Access(request_rec *r) ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02226) "Awaiting re-negotiation handshake"); - /* XXX: Should replace setting state with SSL_renegotiate(ssl); - * However, this causes failures in perl-framework currently, - * perhaps pre-test if we have already negotiated? - */ -#ifdef OPENSSL_NO_SSL_INTERN - SSL_set_state(ssl, SSL_ST_ACCEPT); -#else - ssl->state = SSL_ST_ACCEPT; -#endif + /* XXX: Why is this done twice? */ + SSL_renegotiate(ssl); + /* XXX: Return value ignored, uses SSL_get_state instead? */ SSL_do_handshake(ssl); sslconn->reneg_state = RENEG_REJECT; - if (SSL_get_state(ssl) != SSL_ST_OK) { + if (SSL_get_state(ssl) != TLS_ST_OK) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261) "Re-negotiation handshake failed"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server); @@ -1513,7 +1512,7 @@ DH *ssl_callback_TmpDH(SSL *ssl, int exp SSL_set_current_cert(ssl, SSL_CERT_SET_SERVER); #endif pkey = SSL_get_privatekey(ssl); - type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE; + type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE; /* * OpenSSL will call us with either keylen == 512 or keylen == 1024 @@ -1725,11 +1724,20 @@ static void modssl_proxy_info_log(conn_r * so we need to increment here to prevent them from * being freed. */ + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#define modssl_set_cert_info(info, cert, pkey) \ + *cert = info->x509; \ + X509_up_ref(*cert); \ + *pkey = info->x_pkey->dec_pkey; \ + EVP_PKEY_up_ref(*pkey) +#else #define modssl_set_cert_info(info, cert, pkey) \ *cert = info->x509; \ CRYPTO_add(&(*cert)->references, +1, CRYPTO_LOCK_X509); \ *pkey = info->x_pkey->dec_pkey; \ CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_X509_PKEY) +#endif int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey) { @@ -1823,7 +1831,7 @@ int ssl_callback_proxy_cert(SSL *ssl, X5 static void ssl_session_log(server_rec *s, const char *request, - unsigned char *id, + const unsigned char *id, unsigned int idlen, const char *status, const char *result, @@ -1907,7 +1915,7 @@ int ssl_callback_NewSessionCacheEntry(SS * of our other Apache pre-forked server processes. */ SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *ssl, - unsigned char *id, + const unsigned char *id, int idlen, int *do_copy) { /* Get Apache context back through OpenSSL context */ @@ -2070,8 +2078,12 @@ void ssl_callback_Info(const SSL *ssl, i if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) { int state = SSL_get_state((SSL *)ssl); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (state == TLS_ST_SR_CLNT_HELLO) { +#else if (state == SSL3_ST_SR_CLNT_HELLO_A || state == SSL23_ST_SR_CLNT_HELLO_A) { +#endif scr->reneg_state = RENEG_ABORT; ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02042) "rejecting client initiated renegotiation"); @@ -2279,7 +2291,8 @@ int ssl_callback_SessionTicket(SSL *ssl, } memcpy(keyname, ticket_key->key_name, 16); - RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH); + /* XXX: Return value not checked. */ + RAND_bytes(iv, EVP_MAX_IV_LENGTH); EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, ticket_key->aes_key, iv); HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL); @@ -2416,18 +2429,20 @@ int ssl_callback_SRPServerParams(SSL *ss SRP_user_pwd *u; if (username == NULL - || (u = SRP_VBASE_get_by_user(mctx->srp_vbase, username)) == NULL) { + || (u = SRP_VBASE_get1_by_user(mctx->srp_vbase, username)) == NULL) { *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; return SSL3_AL_FATAL; } if (SSL_set_srp_server_param(ssl, u->N, u->g, u->s, u->v, u->info) < 0) { + SRP_user_pwd_free(u); *ad = SSL_AD_INTERNAL_ERROR; return SSL3_AL_FATAL; } /* reset all other options */ - SSL_set_verify(ssl, SSL_VERIFY_NONE, ssl_callback_SSLVerify); + SSL_set_verify(ssl, SSL_VERIFY_NONE, ssl_callback_SSLVerify); + SRP_user_pwd_free(u); return SSL_ERROR_NONE; } --- apache2-2.4.23/modules/ssl/ssl_engine_ocsp.c +++ apache2-2.4.23/modules/ssl/ssl_engine_ocsp.c @@ -109,7 +109,7 @@ static OCSP_REQUEST *create_request(X509 { OCSP_REQUEST *req = OCSP_REQUEST_new(); - *certid = OCSP_cert_to_id(NULL, cert, ctx->current_issuer); + *certid = OCSP_cert_to_id(NULL, cert, X509_STORE_CTX_get0_current_issuer(ctx)); if (!*certid || !OCSP_request_add0_id(req, *certid)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01921) "could not retrieve certificate id"); @@ -184,7 +184,7 @@ static int verify_ocsp_status(X509 *cert if (rc == V_OCSP_CERTSTATUS_GOOD) { /* TODO: allow flags configuration. */ - if (OCSP_basic_verify(basicResponse, NULL, ctx->ctx, 0) != 1) { + if (OCSP_basic_verify(basicResponse, NULL, X509_STORE_CTX_get0_store(ctx), 0) != 1) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01925) "failed to verify the OCSP response"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); @@ -262,7 +262,7 @@ int modssl_verify_ocsp(X509_STORE_CTX *c "No cert available to check with OCSP"); return 1; } - else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) { + else if (X509_check_issued(cert, cert) == X509_V_OK) { /* don't do OCSP checking for valid self-issued certs */ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "Skipping OCSP check for valid self-issued cert"); --- apache2-2.4.23/modules/ssl/ssl_engine_vars.c +++ apache2-2.4.23/modules/ssl/ssl_engine_vars.c @@ -33,6 +33,10 @@ #include "apr_time.h" +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define X509_get0_tbs_sigalg(x509) (xs->cert_info->signature) +#endif + /* _________________________________________________________________ ** ** Variable Lookup @@ -529,13 +533,16 @@ static char *ssl_var_lookup_ssl_cert(apr resdup = FALSE; } else if (strcEQ(var, "A_SIG")) { - nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->signature->algorithm)); + nid = OBJ_obj2nid(X509_get0_tbs_sigalg(xs)->algorithm); result = apr_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); resdup = FALSE; } else if (strcEQ(var, "A_KEY")) { - nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->key->algor->algorithm)); + X509_PUBKEY *pubkey = X509_get_X509_PUBKEY(xs); + X509_ALGOR *algor; + X509_PUBKEY_get0_param(NULL, NULL, NULL, &algor, pubkey); + nid = OBJ_obj2nid(algor->algorithm); result = apr_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); resdup = FALSE; @@ -597,13 +604,10 @@ static char *ssl_var_lookup_ssl_cert_dn( for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) { if (strEQn(var, ssl_var_lookup_ssl_cert_dn_rec[i].name, varlen) && strlen(ssl_var_lookup_ssl_cert_dn_rec[i].name) == varlen) { - for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *) - xsname->entries); - j++) { - xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *) - xsname->entries, j); + for (j = 0; j < X509_NAME_entry_count(xsname); j++) { + xsne = X509_NAME_get_entry(xsname, j); - n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne)); + n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(xsne)); if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid && idx-- == 0) { result = modssl_X509_NAME_ENTRY_to_string(p, xsne); @@ -903,7 +907,6 @@ static char *ssl_var_lookup_ssl_version( static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx, X509_NAME *xn, apr_pool_t *p) { - STACK_OF(X509_NAME_ENTRY) *ents = xn->entries; X509_NAME_ENTRY *xsne; apr_hash_t *count; int i, nid; @@ -913,14 +916,14 @@ static void extract_dn(apr_table_t *t, a count = apr_hash_make(p); /* For each RDN... */ - for (i = 0; i < sk_X509_NAME_ENTRY_num(ents); i++) { + for (i = 0; i < X509_NAME_entry_count(xn); i++) { const char *tag; - xsne = sk_X509_NAME_ENTRY_value(ents, i); + xsne = X509_NAME_get_entry(xn, i); /* Retrieve the nid, and check whether this is one of the nids * which are to be extracted. */ - nid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne)); + nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(xsne)); tag = apr_hash_get(nids, &nid, sizeof nid); if (tag) { @@ -1090,7 +1093,7 @@ apr_array_header_t *ssl_ext_list(apr_poo for (j = 0; j < count; j++) { X509_EXTENSION *ext = X509_get_ext(xs, j); - if (OBJ_cmp(ext->object, oid) == 0) { + if (OBJ_cmp(X509_EXTENSION_get_object(ext), oid) == 0) { BIO *bio = BIO_new(BIO_s_mem()); /* We want to obtain a string representation of the extensions --- apache2-2.4.23/modules/ssl/ssl_private.h +++ apache2-2.4.23/modules/ssl/ssl_private.h @@ -810,7 +810,7 @@ int ssl_callback_SSLVerify(int, int ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *); int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey); int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *); -SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); +SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, const unsigned char *, int, int *); void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); void ssl_callback_Info(const SSL *, int, int); #ifdef HAVE_TLSEXT @@ -833,7 +833,7 @@ void ssl_scache_status_register( void ssl_scache_kill(server_rec *); BOOL ssl_scache_store(server_rec *, UCHAR *, int, apr_time_t, SSL_SESSION *, apr_pool_t *); -SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int, apr_pool_t *); +SSL_SESSION *ssl_scache_retrieve(server_rec *, const UCHAR *, int, apr_pool_t *); void ssl_scache_remove(server_rec *, UCHAR *, int, apr_pool_t *); @@ -866,6 +866,7 @@ int ssl_callback_SRPServerParam void ssl_io_filter_init(conn_rec *, request_rec *r, SSL *); void ssl_io_filter_register(apr_pool_t *); long ssl_io_data_cb(BIO *, int, const char *, int, long, long); +int ssl_engine_io_init(void); /* ssl_io_buffer_fill fills the setaside buffering of the HTTP request * to allow an SSL renegotiation to take place. */ --- apache2-2.4.23/modules/ssl/ssl_scache.c +++ apache2-2.4.23/modules/ssl/ssl_scache.c @@ -144,7 +144,7 @@ BOOL ssl_scache_store(server_rec *s, UCH return rv == APR_SUCCESS ? TRUE : FALSE; } -SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen, +SSL_SESSION *ssl_scache_retrieve(server_rec *s, const UCHAR *id, int idlen, apr_pool_t *p) { SSLModConfigRec *mc = myModConfig(s); --- apache2-2.4.23/modules/ssl/ssl_util_ssl.c +++ apache2-2.4.23/modules/ssl/ssl_util_ssl.c @@ -488,7 +488,7 @@ EC_GROUP *ssl_ec_GetParamFromFile(const ** _________________________________________________________________ */ -char *modssl_SSL_SESSION_id2sz(unsigned char *id, int idlen, +char *modssl_SSL_SESSION_id2sz(const unsigned char *id, int idlen, char *str, int strsize) { if (idlen > SSL_MAX_SSL_SESSION_ID_LENGTH) --- apache2-2.4.23/modules/ssl/ssl_util_ssl.h +++ apache2-2.4.23/modules/ssl/ssl_util_ssl.h @@ -67,7 +67,7 @@ char *modssl_X509_NAME_ENTRY_to_st char *modssl_X509_NAME_to_string(apr_pool_t *, X509_NAME *, int); BOOL modssl_X509_getSAN(apr_pool_t *, X509 *, int, const char *, int, apr_array_header_t **); BOOL modssl_X509_match_name(apr_pool_t *, X509 *, const char *, BOOL, server_rec *); -char *modssl_SSL_SESSION_id2sz(unsigned char *, int, char *, int); +char *modssl_SSL_SESSION_id2sz(const unsigned char *, int, char *, int); #endif /* __SSL_UTIL_SSL_H__ */ /** @} */ --- apache2-2.4.23/modules/ssl/ssl_util_stapling.c +++ apache2-2.4.23/modules/ssl/ssl_util_stapling.c @@ -79,7 +79,7 @@ static X509 *stapling_get_issuer(modssl_ X509 *issuer = NULL; int i; X509_STORE *st = SSL_CTX_get_cert_store(mctx->ssl_ctx); - X509_STORE_CTX inctx; + X509_STORE_CTX *inctx; STACK_OF(X509) *extra_certs = NULL; #ifdef OPENSSL_NO_SSL_INTERN @@ -91,16 +91,21 @@ static X509 *stapling_get_issuer(modssl_ for (i = 0; i < sk_X509_num(extra_certs); i++) { issuer = sk_X509_value(extra_certs, i); if (X509_check_issued(issuer, x) == X509_V_OK) { +#if OPENSSL_VERSION_NUMBER < 0x10100000L CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509); +#else + X509_up_ref(issuer); +#endif return issuer; } } - if (!X509_STORE_CTX_init(&inctx, st, NULL, NULL)) + inctx = X509_STORE_CTX_new(); + if (!X509_STORE_CTX_init(inctx, st, NULL, NULL)) return 0; - if (X509_STORE_CTX_get1_issuer(&issuer, &inctx, x) <= 0) + if (X509_STORE_CTX_get1_issuer(&issuer, inctx, x) <= 0) issuer = NULL; - X509_STORE_CTX_cleanup(&inctx); + X509_STORE_CTX_free(inctx); return issuer; } @@ -398,7 +403,9 @@ static int stapling_check_response(serve if (bio) { int n; - if ((i2a_ASN1_INTEGER(bio, cinf->cid->serialNumber) != -1) && + ASN1_INTEGER *serial; + OCSP_id_get0_info(NULL, NULL, NULL, &serial, cinf->cid); + if ((i2a_ASN1_INTEGER(bio, serial) != -1) && ((n = BIO_read(bio, snum, sizeof snum - 1)) > 0)) snum[n] = '\0'; BIO_free(bio); --- apache2-2.4.23/support/ab.c +++ apache2-2.4.23/support/ab.c @@ -1991,12 +1991,6 @@ static void usage(const char *progname) fprintf(stderr, " -h Display usage information (this message)\n"); #ifdef USE_SSL -#ifndef OPENSSL_NO_SSL2 -#define SSL2_HELP_MSG "SSL2, " -#else -#define SSL2_HELP_MSG "" -#endif - #ifndef OPENSSL_NO_SSL3 #define SSL3_HELP_MSG "SSL3, " #else @@ -2011,7 +2005,7 @@ static void usage(const char *progname) fprintf(stderr, " -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)\n"); fprintf(stderr, " -f protocol Specify SSL/TLS protocol\n"); - fprintf(stderr, " (" SSL2_HELP_MSG SSL3_HELP_MSG "TLS1" TLS1_X_HELP_MSG " or ALL)\n"); + fprintf(stderr, " (" SSL3_HELP_MSG "TLS1" TLS1_X_HELP_MSG " or ALL)\n"); #endif exit(EINVAL); } @@ -2135,6 +2129,7 @@ int main(int argc, const char * const ar char c; #ifdef USE_SSL AB_SSL_METHOD_CONST SSL_METHOD *meth = SSLv23_client_method(); + int ssl_version = 0; #endif /* table defaults */ @@ -2351,23 +2346,17 @@ int main(int argc, const char * const ar break; case 'f': if (strncasecmp(opt_arg, "ALL", 3) == 0) { - meth = SSLv23_client_method(); -#ifndef OPENSSL_NO_SSL2 - } else if (strncasecmp(opt_arg, "SSL2", 4) == 0) { - meth = SSLv2_client_method(); -#endif + ssl_version = 0; #ifndef OPENSSL_NO_SSL3 } else if (strncasecmp(opt_arg, "SSL3", 4) == 0) { - meth = SSLv3_client_method(); + ssl_version = SSL3_VERSION; #endif -#ifdef HAVE_TLSV1_X } else if (strncasecmp(opt_arg, "TLS1.1", 6) == 0) { - meth = TLSv1_1_client_method(); + ssl_version = TLS1_1_VERSION; } else if (strncasecmp(opt_arg, "TLS1.2", 6) == 0) { - meth = TLSv1_2_client_method(); -#endif + ssl_version = TLS1_2_VERSION; } else if (strncasecmp(opt_arg, "TLS1", 4) == 0) { - meth = TLSv1_client_method(); + ssl_version = TLS1_VERSION; } break; #endif @@ -2413,8 +2402,10 @@ int main(int argc, const char * const ar #ifdef RSAREF R_malloc_init(); #else +#if OPENSSL_VERSION_NUMBER < 0x1010000L CRYPTO_malloc_init(); #endif +#endif SSL_load_error_strings(); SSL_library_init(); bio_out=BIO_new_fp(stdout,BIO_NOCLOSE); @@ -2425,6 +2416,27 @@ int main(int argc, const char * const ar ERR_print_errors(bio_err); exit(1); } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + SSL_CTX_set_min_proto_version(ssl_ctx, ssl_version); + SSL_CTX_set_max_proto_version(ssl_ctx, ssl_version); +#else + switch (ssl_version) { +#ifndef OPENSSL_NO_SSL3 + case SSL3_VERSION: + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2); + break; +#endif + case TLS1_VERSION: + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2); + break; + case TLS1_1_VERSION: + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2); + break; + case TLS1_2_VERSION: + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); + break; + } +#endif SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); #ifdef SSL_MODE_RELEASE_BUFFERS /* Keep memory usage as low as possible */