From e125888ded9af43cb4e6b949aa540af23ac41c01 Mon Sep 17 00:00:00 2001 From: jcmichelou Date: Sat, 21 Oct 2017 19:16:23 +0200 Subject: [PATCH] openssl: Handshake can also complete in SSL_accept and SSL_connect. --- include/coap/coap_dtls.h | 4 ++-- src/coap_notls.c | 4 ++-- src/coap_openssl.c | 41 +++++++++++++++++++++++----------------- src/coap_session.c | 14 ++++++++++++-- src/coap_tinydtls.c | 4 ++-- src/net.c | 19 +++++++++++++++---- 6 files changed, 57 insertions(+), 29 deletions(-) diff --git a/include/coap/coap_dtls.h b/include/coap/coap_dtls.h index 597f20c5..da4b7e46 100644 --- a/include/coap/coap_dtls.h +++ b/include/coap/coap_dtls.h @@ -161,7 +161,7 @@ unsigned int coap_dtls_get_overhead(coap_session_t *session); * @param session The CoAP session * @return Opaque handle to underlying TLS library object containing security parameters for the session. */ -void *coap_tls_new_client_session(coap_session_t *session); +void *coap_tls_new_client_session(coap_session_t *session, int *connected); /** * Create a new server-side session. @@ -169,7 +169,7 @@ void *coap_tls_new_client_session(coap_session_t *session); * @param session The CoAP session * @return Opaque handle to underlying TLS library object containing security parameters for the session. */ -void *coap_tls_new_server_session(coap_session_t *session); +void *coap_tls_new_server_session(coap_session_t *session, int *connected); /** * Send data to a TLS peer, with implicit flush. diff --git a/src/coap_notls.c b/src/coap_notls.c index 0e634762..d8102d0d 100644 --- a/src/coap_notls.c +++ b/src/coap_notls.c @@ -110,11 +110,11 @@ unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED) { return 0; } -void *coap_tls_new_client_session(coap_session_t *session UNUSED) { +void *coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED) { return NULL; } -void *coap_tls_new_server_session(coap_session_t *session UNUSED) { +void *coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED) { return NULL; } diff --git a/src/coap_openssl.c b/src/coap_openssl.c index 328d4c57..2e855034 100644 --- a/src/coap_openssl.c +++ b/src/coap_openssl.c @@ -781,12 +781,13 @@ unsigned int coap_dtls_get_overhead(coap_session_t *session) { return overhead; } -void *coap_tls_new_client_session(coap_session_t *session) { +void *coap_tls_new_client_session(coap_session_t *session, int *connected) { BIO *bio = NULL; SSL *ssl = NULL; int r; coap_tls_context_t *tls = &((coap_openssl_context_t *)session->context->dtls_context)->tls; + *connected = 0; ssl = SSL_new(tls->ctx); if (!ssl) goto error; @@ -811,6 +812,8 @@ void *coap_tls_new_client_session(coap_session_t *session) { if (r == 0) goto error; + *connected = SSL_is_init_finished(ssl); + return ssl; error: @@ -819,12 +822,13 @@ error: return NULL; } -void * coap_tls_new_server_session(coap_session_t *session) { +void *coap_tls_new_server_session(coap_session_t *session, int *connected) { BIO *bio = NULL; SSL *ssl = NULL; coap_tls_context_t *tls = &((coap_openssl_context_t *)session->context->dtls_context)->tls; int r; + *connected = 0; ssl = SSL_new(tls->ctx); if (!ssl) goto error; @@ -858,6 +862,8 @@ void * coap_tls_new_server_session(coap_session_t *session) { if (r == 0) goto error; + *connected = SSL_is_init_finished(ssl); + return ssl; error: @@ -876,16 +882,16 @@ ssize_t coap_tls_write(coap_session_t *session, if (ssl == NULL) return -1; - in_init = SSL_in_init( ssl ); + in_init = !SSL_is_init_finished(ssl); dtls_event = -1; r = SSL_write(ssl, data, (int)data_len); if (r <= 0) { int err = SSL_get_error(ssl, r); if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { - if ( in_init && SSL_is_init_finished( ssl ) ) { - coap_handle_event( session->context, COAP_EVENT_DTLS_CONNECTED, session ); - coap_session_send_csm( session ); + if (in_init && SSL_is_init_finished(ssl)) { + coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); + coap_session_send_csm(session); } if (err == SSL_ERROR_WANT_READ) session->sock.flags |= COAP_SOCKET_WANT_READ; @@ -900,6 +906,9 @@ ssize_t coap_tls_write(coap_session_t *session, dtls_event = COAP_EVENT_DTLS_ERROR; r = -1; } + } else if (in_init && SSL_is_init_finished(ssl)) { + coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); + coap_session_send_csm(session); } if (dtls_event >= 0) { @@ -908,9 +917,6 @@ ssize_t coap_tls_write(coap_session_t *session, coap_session_disconnected(session, COAP_NACK_TLS_FAILED); r = -1; } - } else if ( in_init && SSL_is_init_finished( ssl ) ) { - coap_handle_event( session->context, COAP_EVENT_DTLS_CONNECTED, session ); - coap_session_send_csm( session ); } return r; @@ -926,7 +932,7 @@ ssize_t coap_tls_read(coap_session_t *session, if (ssl == NULL) return -1; - in_init = SSL_in_init(ssl); + in_init = !SSL_is_init_finished(ssl); dtls_event = -1; r = SSL_read(ssl, data, (int)data_len); if (r <= 0) { @@ -948,18 +954,19 @@ ssize_t coap_tls_read(coap_session_t *session, dtls_event = COAP_EVENT_DTLS_ERROR; r = -1; } - if (dtls_event >= 0) { - coap_handle_event(session->context, dtls_event, session); - if (dtls_event == COAP_EVENT_DTLS_ERROR || dtls_event == COAP_EVENT_DTLS_CLOSED) { - coap_session_disconnected(session, COAP_NACK_TLS_FAILED); - r = -1; - } - } } else if (in_init && SSL_is_init_finished(ssl)) { coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); coap_session_send_csm(session); } + if (dtls_event >= 0) { + coap_handle_event(session->context, dtls_event, session); + if (dtls_event == COAP_EVENT_DTLS_ERROR || dtls_event == COAP_EVENT_DTLS_CLOSED) { + coap_session_disconnected(session, COAP_NACK_TLS_FAILED); + r = -1; + } + } + return r; } diff --git a/src/coap_session.c b/src/coap_session.c index e833d4c1..4b96cf41 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -479,9 +479,14 @@ coap_session_connect(coap_session_t *session) { if (session->sock.flags & COAP_SOCKET_WANT_CONNECT) { session->state = COAP_SESSION_STATE_CONNECTING; } else if (session->proto == COAP_PROTO_TLS) { - session->tls = coap_tls_new_client_session(session); + int connected = 0; + session->tls = coap_tls_new_client_session(session, &connected); if (session->tls) { session->state = COAP_SESSION_STATE_HANDSHAKE; + if (connected) { + coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); + coap_session_send_csm(session); + } } else { coap_session_free(session); return NULL; @@ -499,9 +504,14 @@ coap_session_accept(coap_session_t *session) { if (session->proto == COAP_PROTO_TCP) { coap_session_send_csm(session); } else if (session->proto == COAP_PROTO_TLS) { - session->tls = coap_tls_new_server_session(session); + int connected = 0; + session->tls = coap_tls_new_server_session(session, &connected); if (session->tls) { session->state = COAP_SESSION_STATE_HANDSHAKE; + if (connected) { + coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); + coap_session_send_csm(session); + } } else { coap_session_free(session); session = NULL; diff --git a/src/coap_tinydtls.c b/src/coap_tinydtls.c index 039d9266..3090c8ba 100644 --- a/src/coap_tinydtls.c +++ b/src/coap_tinydtls.c @@ -444,11 +444,11 @@ int coap_tls_is_supported(void) { return 0; } -void *coap_tls_new_client_session(coap_session_t *session UNUSED) { +void *coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED) { return NULL; } -void *coap_tls_new_server_session(coap_session_t *session UNUSED) { +void *coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED) { return NULL; } diff --git a/src/net.c b/src/net.c index b2d2dd63..2085adc4 100644 --- a/src/net.c +++ b/src/net.c @@ -704,9 +704,14 @@ coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { return coap_session_delay_pdu(session, pdu, node); } if (session->proto == COAP_PROTO_TLS) { - session->tls = coap_tls_new_client_session(session); + int connected = 0; + session->tls = coap_tls_new_client_session(session, &connected); if (session->tls) { session->state = COAP_SESSION_STATE_HANDSHAKE; + if (connected) { + coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); + coap_session_send_csm(session); + } return coap_session_delay_pdu(session, pdu, node); } } else { @@ -1004,11 +1009,17 @@ coap_connect_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t n if (session->proto == COAP_PROTO_TCP) { coap_session_send_csm(session); } else if (session->proto == COAP_PROTO_TLS) { - session->tls = coap_tls_new_client_session(session); - if (session->tls) + int connected = 0; + session->tls = coap_tls_new_client_session(session, &connected); + if (session->tls) { session->state = COAP_SESSION_STATE_HANDSHAKE; - else + if (connected) { + coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); + coap_session_send_csm(session); + } + } else { coap_session_reset(session); + } } } else { coap_session_reset(session);