From: Alan T. DeKok Date: Sun, 11 Oct 2015 17:21:42 +0000 (-0400) Subject: Wrappers and portability fixes for newer OpenSSL. X-Git-Tag: release_3_0_11~269 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f3441b6da05c20e8c177ff4248b1384133f206d;p=thirdparty%2Ffreeradius-server.git Wrappers and portability fixes for newer OpenSSL. Which no longer exposes the internal fields of SSL* --- diff --git a/src/include/tls-h b/src/include/tls-h index a41c6f5abfc..0169b2f9163 100644 --- a/src/include/tls-h +++ b/src/include/tls-h @@ -106,6 +106,12 @@ typedef struct _tls_info_t { int version; } tls_info_t; +#if OPENSSL_VERSION_NUMBER < 0x10001000L +#define ssl_session ssl->session +#else +#define ssl_session session +#endif + /** Contains EAP-REQUEST specific data (ie FR_TLS_DATA(fragment), EAPTLS-ALERT, EAPTLS-REQUEST ...) * * The tls_session_t Structure gets stored as opaque in eap_handler_t @@ -113,6 +119,9 @@ typedef struct _tls_info_t { typedef struct _tls_session_t { SSL_CTX *ctx; SSL *ssl; +#if OPENSSL_VERSION_NUMBER >= 0x10001000L + SSL_SESSION *session; +#endif tls_info_t info; BIO *into_ssl; @@ -298,6 +307,7 @@ SSL_CTX *tls_init_ctx(fr_tls_server_conf_t *conf, int client); int tls_handshake_recv(REQUEST *, tls_session_t *ssn); int tls_handshake_send(REQUEST *, tls_session_t *ssn); void tls_session_information(tls_session_t *ssn); +void tls_session_id(SSL_SESSION *ssn, char *buffer, size_t bufsize); /* * Low-level TLS stuff diff --git a/src/main/tls.c b/src/main/tls.c index 0f6a99a94cb..8d40b204bdc 100644 --- a/src/main/tls.c +++ b/src/main/tls.c @@ -240,6 +240,32 @@ static unsigned int psk_client_callback(SSL *ssl, UNUSED char const *hint, #endif +#define MAX_SESSION_SIZE (256) + + +void tls_session_id(SSL_SESSION *ssn, char *buffer, size_t bufsize) +{ +#if OPENSSL_VERSION_NUMBER < 0x10001000L + size_t size; + + size = ssn->session_id_length; + if (size > bufsize) size = bufsize; + + fr_bin2hex(buffer, ssn->session_id, size); +#else + unsigned int size; + uint8_t const *p; + + p = SSL_SESSION_get_id(ssn, &size); + if (size > bufsize) size = bufsize; + + fr_bin2hex(buffer, p, size); + +#endif +} + + + static int _tls_session_free(tls_session_t *ssn) { /* @@ -547,6 +573,19 @@ int tls_handshake_recv(REQUEST *request, tls_session_t *ssn) if (SSL_in_accept_init(ssn->ssl)) RDEBUG2("In SSL Accept mode"); if (SSL_in_connect_init(ssn->ssl)) RDEBUG2("In SSL Connect mode"); +#if OPENSSL_VERSION_NUMBER >= 0x10001000L + /* + * Cache the SSL_SESSION pointer. + */ + if (SSL_is_init_finished(ssn->ssl)) { + ssn->ssl_session = SSL_get_session(ssn->ssl); + if (!ssn->ssl_session) { + RDEBUG("Failed getting SSL session"); + return 0; + } + } +#endif + err = BIO_ctrl_pending(ssn->from_ssl); if (err > 0) { err = BIO_read(ssn->from_ssl, ssn->dirty_out.data, @@ -1114,18 +1153,12 @@ static int load_dh_params(SSL_CTX *ctx, char *file) /* * Print debugging messages, and free data. */ -#define MAX_SESSION_SIZE (256) - static void cbtls_remove_session(SSL_CTX *ctx, SSL_SESSION *sess) { - size_t size; char buffer[2 * MAX_SESSION_SIZE + 1]; fr_tls_server_conf_t *conf; - size = sess->session_id_length; - if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE; - - fr_bin2hex(buffer, sess->session_id, size); + tls_session_id(sess, buffer, MAX_SESSION_SIZE); conf = (fr_tls_server_conf_t *)SSL_CTX_get_app_data(ctx); if (!conf) { @@ -1158,7 +1191,6 @@ static void cbtls_remove_session(SSL_CTX *ctx, SSL_SESSION *sess) static int cbtls_new_session(SSL *ssl, SSL_SESSION *sess) { - size_t size; char buffer[2 * MAX_SESSION_SIZE + 1]; fr_tls_server_conf_t *conf; unsigned char *sess_blob = NULL; @@ -1171,10 +1203,7 @@ static int cbtls_new_session(SSL *ssl, SSL_SESSION *sess) return 0; } - size = sess->session_id_length; - if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE; - - fr_bin2hex(buffer, sess->session_id, size); + tls_session_id(sess, buffer, MAX_SESSION_SIZE); { int fd, rv, todo, blob_len; @@ -2894,7 +2923,7 @@ int tls_success(tls_session_t *ssn, REQUEST *request) (((vp = fr_pair_find_by_num(request->config, PW_ALLOW_SESSION_RESUMPTION, 0, TAG_ANY)) != NULL) && (vp->vp_integer == 0))) { SSL_CTX_remove_session(ssn->ctx, - ssn->ssl->session); + ssn->ssl_session); ssn->allow_session_resumption = false; /* @@ -2911,14 +2940,10 @@ int tls_success(tls_session_t *ssn, REQUEST *request) * user data in the cache. */ } else if (!SSL_session_reused(ssn->ssl)) { - size_t size; VALUE_PAIR **certs; char buffer[2 * MAX_SESSION_SIZE + 1]; - size = ssn->ssl->session->session_id_length; - if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE; - - fr_bin2hex(buffer, ssn->ssl->session->session_id, size); + tls_session_id(ssn->ssl_session, buffer, MAX_SESSION_SIZE); vp = fr_pair_list_copy_by_num(talloc_ctx, request->reply->vps, PW_USER_NAME, 0, TAG_ANY); if (vp) fr_pair_add(&vps, vp); @@ -2954,7 +2979,7 @@ int tls_success(tls_session_t *ssn, REQUEST *request) } if (vps) { - SSL_SESSION_set_ex_data(ssn->ssl->session, fr_tls_ex_index_vps, vps); + SSL_SESSION_set_ex_data(ssn->ssl_session, fr_tls_ex_index_vps, vps); rdebug_pair_list(L_DBG_LVL_2, request, vps, " caching "); if (conf->session_cache_path) { @@ -3004,20 +3029,16 @@ int tls_success(tls_session_t *ssn, REQUEST *request) } } else { RDEBUG2("No information to cache: session caching will be disabled for session %s", buffer); - SSL_CTX_remove_session(ssn->ctx, ssn->ssl->session); + SSL_CTX_remove_session(ssn->ctx, ssn->ssl_session); } /* * Else the session WAS allowed. Copy the cached reply. */ } else { - size_t size; char buffer[2 * MAX_SESSION_SIZE + 1]; - size = ssn->ssl->session->session_id_length; - if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE; - - fr_bin2hex(buffer, ssn->ssl->session->session_id, size); + tls_session_id(ssn->ssl_session, buffer, MAX_SESSION_SIZE); /* * The "restore VPs from OpenSSL cache" code is @@ -3051,7 +3072,7 @@ void tls_fail(tls_session_t *ssn) /* * Force the session to NOT be cached. */ - SSL_CTX_remove_session(ssn->ctx, ssn->ssl->session); + SSL_CTX_remove_session(ssn->ctx, ssn->ssl_session); } fr_tls_status_t tls_application_data(tls_session_t *ssn, REQUEST *request) diff --git a/src/modules/rlm_eap/libeap/eap_tls.c b/src/modules/rlm_eap/libeap/eap_tls.c index 2846e1d8460..fadc72c8108 100644 --- a/src/modules/rlm_eap/libeap/eap_tls.c +++ b/src/modules/rlm_eap/libeap/eap_tls.c @@ -901,19 +901,16 @@ fr_tls_status_t eaptls_process(eap_handler_t *handler) status = eaptls_operation(status, handler); if (status == FR_TLS_SUCCESS) { #define MAX_SESSION_SIZE (256) - size_t size; VALUE_PAIR *vps; char buffer[2 * MAX_SESSION_SIZE + 1]; + /* * Restore the cached VPs before processing the * application data. */ - size = tls_session->ssl->session->session_id_length; - if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE; - - fr_bin2hex(buffer, tls_session->ssl->session->session_id, size); + tls_session_id(tls_session->ssl_session, buffer, MAX_SESSION_SIZE); - vps = SSL_SESSION_get_ex_data(tls_session->ssl->session, fr_tls_ex_index_vps); + vps = SSL_SESSION_get_ex_data(tls_session->ssl_session, fr_tls_ex_index_vps); if (!vps) { RWDEBUG("No information in cached session %s", buffer); } else {