1
1
#include " HTTPSConnection.hpp"
2
+ #include " mbedtls/net_sockets.h"
2
3
3
4
namespace httpsserver {
4
5
5
6
6
7
HTTPSConnection::HTTPSConnection (ResourceResolver * resResolver):
7
8
HTTPConnection (resResolver) {
8
- _ssl = NULL ;
9
+ _sslCreated = false ;
10
+ _socket = 0 ;
9
11
}
10
12
11
13
HTTPSConnection::~HTTPSConnection () {
@@ -17,38 +19,58 @@ bool HTTPSConnection::isSecure() {
17
19
return true ;
18
20
}
19
21
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
+
20
46
/* *
21
47
* Initializes the connection from a server socket.
22
48
*
23
49
* The call WILL BLOCK if accept(serverSocketID) blocks. So use select() to check for that in advance.
24
50
*/
25
- int HTTPSConnection::initialize (int serverSocketID, SSL_CTX * sslCtx , HTTPHeaders *defaultHeaders) {
51
+ int HTTPSConnection::initialize (int serverSocketID, mbedtls_ssl_config *sslConfig , HTTPHeaders *defaultHeaders) {
26
52
if (_connectionState == STATE_UNDEFINED) {
27
53
// Let the base class connect the plain tcp socket
28
54
int resSocket = HTTPConnection::initialize (serverSocketID, defaultHeaders);
29
55
30
56
// Build up SSL Connection context if the socket has been created successfully
31
57
if (resSocket >= 0 ) {
32
58
33
- _ssl = SSL_new (sslCtx);
59
+ _socket = resSocket;
60
+ _sslCreated = setup (sslConfig);
34
61
35
- if (_ssl ) {
62
+ if (_sslCreated ) {
36
63
// 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;
47
69
} else {
48
- HTTPS_LOGE (" SSL_set_fd failed. Aborting handshake. FID=%d" , resSocket);
70
+ HTTPS_LOGE (" SSL handshake failed. Aborting handshake. FID=%d" , resSocket);
49
71
}
50
72
} else {
51
- HTTPS_LOGE (" SSL_new failed. Aborting handshake. FID=%d" , resSocket);
73
+ HTTPS_LOGE (" SSL setup failed. Aborting handshake. FID=%d" , resSocket);
52
74
}
53
75
54
76
} else {
@@ -66,6 +88,18 @@ int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeader
66
88
return -1 ;
67
89
}
68
90
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
+ }
69
103
70
104
void HTTPSConnection::closeConnection () {
71
105
@@ -83,41 +117,53 @@ void HTTPSConnection::closeConnection() {
83
117
}
84
118
85
119
// 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
89
123
// This means we are safe to close the socket
90
- SSL_free ( _ssl);
91
- _ssl = NULL ;
124
+ mbedtls_ssl_free (& _ssl);
125
+ _sslCreated = false ;
92
126
} 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" );
97
131
_connectionState = STATE_ERROR;
98
132
}
99
133
}
100
134
101
135
// If SSL has been brought down, close the socket
102
- if (!_ssl ) {
136
+ if (!_sslCreated ) {
103
137
HTTPConnection::closeConnection ();
104
138
}
105
139
}
106
140
107
141
size_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
+ }
109
149
}
110
150
111
151
size_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
+ }
113
159
}
114
160
115
161
size_t HTTPSConnection::pendingByteCount () {
116
- return SSL_pending ( _ssl);
162
+ return mbedtls_ssl_get_bytes_avail (& _ssl);
117
163
}
118
164
119
165
bool HTTPSConnection::canReadData () {
120
- return HTTPConnection::canReadData () || (SSL_pending ( _ssl) > 0 );
166
+ return HTTPConnection::canReadData () || (mbedtls_ssl_get_bytes_avail (& _ssl) > 0 );
121
167
}
122
168
123
169
} /* namespace httpsserver */
0 commit comments