11#include " HTTPSConnection.hpp"
2+ #include " mbedtls/net_sockets.h"
23
34namespace httpsserver {
45
56
67HTTPSConnection::HTTPSConnection (ResourceResolver * resResolver):
78 HTTPConnection (resResolver) {
8- _ssl = NULL ;
9+ _sslCreated = false ;
10+ _socket = 0 ;
911}
1012
1113HTTPSConnection::~HTTPSConnection () {
@@ -17,38 +19,58 @@ bool HTTPSConnection::isSecure() {
1719 return true ;
1820}
1921
22+ bool HTTPSConnection::setup (mbedtls_ssl_config *sslConfig) {
23+ mbedtls_ssl_init (&_ssl);
24+ int res = mbedtls_ssl_setup (&_ssl, sslConfig);
25+ if (res == 0 ) {
26+ return true ;
27+ } else {
28+ mbedtls_ssl_free (&_ssl);
29+ return false ;
30+ }
31+ }
32+
33+ bool HTTPSConnection::handshake () {
34+ int res;
35+ while (true ) {
36+ res = mbedtls_ssl_handshake (&_ssl);
37+ if (res == 0 ) {
38+ return true ;
39+ }
40+ if (res != MBEDTLS_ERR_SSL_WANT_READ && res != MBEDTLS_ERR_SSL_WANT_WRITE) {
41+ return false ;
42+ }
43+ }
44+ }
45+
2046/* *
2147 * Initializes the connection from a server socket.
2248 *
2349 * The call WILL BLOCK if accept(serverSocketID) blocks. So use select() to check for that in advance.
2450 */
25- int HTTPSConnection::initialize (int serverSocketID, SSL_CTX * sslCtx , HTTPHeaders *defaultHeaders) {
51+ int HTTPSConnection::initialize (int serverSocketID, mbedtls_ssl_config *sslConfig , HTTPHeaders *defaultHeaders) {
2652 if (_connectionState == STATE_UNDEFINED) {
2753 // Let the base class connect the plain tcp socket
2854 int resSocket = HTTPConnection::initialize (serverSocketID, defaultHeaders);
2955
3056 // Build up SSL Connection context if the socket has been created successfully
3157 if (resSocket >= 0 ) {
3258
33- _ssl = SSL_new (sslCtx);
59+ _socket = resSocket;
60+ _sslCreated = setup (sslConfig);
3461
35- if (_ssl ) {
62+ if (_sslCreated ) {
3663 // Bind SSL to the socket
37- int success = SSL_set_fd (_ssl, resSocket);
38- if (success) {
39-
40- // Perform the handshake
41- success = SSL_accept (_ssl);
42- if (success) {
43- return resSocket;
44- } else {
45- HTTPS_LOGE (" SSL_accept failed. Aborting handshake. FID=%d" , resSocket);
46- }
64+ mbedtls_ssl_set_bio (&_ssl, &_socket, mbedtls_net_send, mbedtls_net_recv, NULL );
65+
66+ // Perform the handshake
67+ if (handshake ()) {
68+ return resSocket;
4769 } else {
48- HTTPS_LOGE (" SSL_set_fd failed. Aborting handshake. FID=%d" , resSocket);
70+ HTTPS_LOGE (" SSL handshake failed. Aborting handshake. FID=%d" , resSocket);
4971 }
5072 } else {
51- HTTPS_LOGE (" SSL_new failed. Aborting handshake. FID=%d" , resSocket);
73+ HTTPS_LOGE (" SSL setup failed. Aborting handshake. FID=%d" , resSocket);
5274 }
5375
5476 } else {
@@ -66,6 +88,18 @@ int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeader
6688 return -1 ;
6789}
6890
91+ int HTTPSConnection::shutdown () {
92+ int res;
93+ while (true ) {
94+ res = mbedtls_ssl_close_notify (&_ssl);
95+ if (res == 0 ) {
96+ return 1 ;
97+ }
98+ if (res != MBEDTLS_ERR_SSL_WANT_WRITE) {
99+ return 0 ;
100+ }
101+ }
102+ }
69103
70104void HTTPSConnection::closeConnection () {
71105
@@ -83,41 +117,53 @@ void HTTPSConnection::closeConnection() {
83117 }
84118
85119 // Try to tear down SSL while we are in the _shutdownTS timeout period or if an error occurred
86- if (_ssl ) {
87- if (_connectionState == STATE_ERROR || SSL_shutdown (_ssl ) == 0 ) {
88- // SSL_shutdown will return 1 as soon as the client answered with close notify
120+ if (_sslCreated ) {
121+ if (_connectionState == STATE_ERROR || shutdown ( ) == 0 ) {
122+ // SSL shutdown will return 1 as soon as the client answered with close notify
89123 // This means we are safe to close the socket
90- SSL_free ( _ssl);
91- _ssl = NULL ;
124+ mbedtls_ssl_free (& _ssl);
125+ _sslCreated = false ;
92126 } else if (_shutdownTS + HTTPS_SHUTDOWN_TIMEOUT < millis ()) {
93- // The timeout has been hit, we force SSL shutdown now by freeing the context
94- SSL_free ( _ssl);
95- _ssl = NULL ;
96- HTTPS_LOGW (" SSL_shutdown did not receive close notification from the client" );
127+ // The timeout has been hit, we force SSL shutdown now by resetting the session
128+ mbedtls_ssl_free (& _ssl);
129+ _sslCreated = false ;
130+ HTTPS_LOGW (" SSL shutdown did not receive close notification from the client" );
97131 _connectionState = STATE_ERROR;
98132 }
99133 }
100134
101135 // If SSL has been brought down, close the socket
102- if (!_ssl ) {
136+ if (!_sslCreated ) {
103137 HTTPConnection::closeConnection ();
104138 }
105139}
106140
107141size_t HTTPSConnection::writeBuffer (byte* buffer, size_t length) {
108- return SSL_write (_ssl, buffer, length);
142+ while (true ) {
143+ int res = mbedtls_ssl_write (&_ssl, buffer, length);
144+ if (res == MBEDTLS_ERR_SSL_WANT_READ || res == MBEDTLS_ERR_SSL_WANT_WRITE) {
145+ continue ;
146+ }
147+ return res;
148+ }
109149}
110150
111151size_t HTTPSConnection::readBytesToBuffer (byte* buffer, size_t length) {
112- return SSL_read (_ssl, buffer, length);
152+ while (true ) {
153+ int res = mbedtls_ssl_read (&_ssl, buffer, length);
154+ if (res == MBEDTLS_ERR_SSL_WANT_READ || res == MBEDTLS_ERR_SSL_WANT_WRITE) {
155+ continue ;
156+ }
157+ return res;
158+ }
113159}
114160
115161size_t HTTPSConnection::pendingByteCount () {
116- return SSL_pending ( _ssl);
162+ return mbedtls_ssl_get_bytes_avail (& _ssl);
117163}
118164
119165bool HTTPSConnection::canReadData () {
120- return HTTPConnection::canReadData () || (SSL_pending ( _ssl) > 0 );
166+ return HTTPConnection::canReadData () || (mbedtls_ssl_get_bytes_avail (& _ssl) > 0 );
121167}
122168
123169} /* namespace httpsserver */
0 commit comments