Changed TLS server to use OpenSSL SSL_accept() instead of SSL_read()

The server handshake processing was still using SSL_read() to get OpenSSL
to perform the handshake. While this works for most cases, it caused some
issues for re-authentication. This is now changed to use SSL_accept() which
is more approriate here since we know that the handshake is still going on
and there will not be any tunneled data available. This resolves some of
the re-authentication issues and makes it possible for the server to notice
if TLS processing fails (SSL_read() did not return an error in many of
these cases while SSL_accept() does).

Set session id context to a unique value in order to avoid fatal errors
when client tries session resumption (SSL_set_session_id_context() must be
called for that to work), but disable session resumption with the unique
value for the time being since not all server side code is ready for it yet
(e.g., EAP-TTLS needs special Phase 2 processing when using abbreviated
handshake).

Changed EAP-TLS server not to call TLS library when processing the final
ACK (empty data) from the client in order to avoid starting a new TLS
handshake with SSL_accept().
This commit is contained in:
Jouni Malinen 2008-05-29 20:36:18 +03:00
parent 8816045743
commit bf206cada3
2 changed files with 39 additions and 5 deletions

View file

@ -1282,6 +1282,8 @@ static int tls_connection_set_subject_match(struct tls_connection *conn,
int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
int verify_peer) int verify_peer)
{ {
static int counter = 0;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@ -1295,6 +1297,19 @@ int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
SSL_set_accept_state(conn->ssl); SSL_set_accept_state(conn->ssl);
/*
* Set session id context in order to avoid fatal errors when client
* tries to resume a session. However, set the context to a unique
* value in order to effectively disable session resumption for now
* since not all areas of the server code are ready for it (e.g.,
* EAP-TTLS needs special handling for Phase 2 after abbreviated TLS
* handshake).
*/
counter++;
SSL_set_session_id_context(conn->ssl,
(const unsigned char *) &counter,
sizeof(counter));
return 0; return 0;
} }
@ -2101,8 +2116,11 @@ u8 * tls_connection_server_handshake(void *ssl_ctx,
{ {
int res; int res;
u8 *out_data; u8 *out_data;
char buf[10];
/*
* Give TLS handshake data from the client (if available) to OpenSSL
* for processing.
*/
if (in_data && if (in_data &&
BIO_write(conn->ssl_in, in_data, in_len) < 0) { BIO_write(conn->ssl_in, in_data, in_len) < 0) {
tls_show_errors(MSG_INFO, __func__, tls_show_errors(MSG_INFO, __func__,
@ -2110,12 +2128,23 @@ u8 * tls_connection_server_handshake(void *ssl_ctx,
return NULL; return NULL;
} }
res = SSL_read(conn->ssl, buf, sizeof(buf)); /* Initiate TLS handshake or continue the existing handshake */
if (res >= 0) { res = SSL_accept(conn->ssl);
wpa_printf(MSG_DEBUG, "SSL: Unexpected data from SSL_read " if (res != 1) {
"(res=%d)", res); int err = SSL_get_error(conn->ssl, res);
if (err == SSL_ERROR_WANT_READ)
wpa_printf(MSG_DEBUG, "SSL: SSL_accept - want "
"more data");
else if (err == SSL_ERROR_WANT_WRITE)
wpa_printf(MSG_DEBUG, "SSL: SSL_accept - want to "
"write");
else {
tls_show_errors(MSG_INFO, __func__, "SSL_accept");
return NULL;
}
} }
/* Get the TLS handshake data to be sent to the client */
res = BIO_ctrl_pending(conn->ssl_out); res = BIO_ctrl_pending(conn->ssl_out);
wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
out_data = os_malloc(res == 0 ? 1 : res); out_data = os_malloc(res == 0 ? 1 : res);

View file

@ -159,6 +159,11 @@ static void eap_tls_process_msg(struct eap_sm *sm, void *priv,
const struct wpabuf *respData) const struct wpabuf *respData)
{ {
struct eap_tls_data *data = priv; struct eap_tls_data *data = priv;
if (data->state == SUCCESS && wpabuf_len(data->ssl.in_buf) == 0) {
wpa_printf(MSG_DEBUG, "EAP-TLS: Client acknowledged final TLS "
"handshake message");
return;
}
if (eap_server_tls_phase1(sm, &data->ssl) < 0) if (eap_server_tls_phase1(sm, &data->ssl) < 0)
eap_tls_state(data, FAILURE); eap_tls_state(data, FAILURE);
} }