Skip to content

Commit 4459c46

Browse files
author
Mohammad Azim Khan
committed
Fix handling MBEDTLS_ERR_SSL_WANT_READ with mbedtls functions
1 parent 20d415a commit 4459c46

File tree

1 file changed

+50
-63
lines changed

1 file changed

+50
-63
lines changed

tls-client/main.cpp

Lines changed: 50 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ const int HTTPS_SERVER_PORT = 443;
5555
const int RECV_BUFFER_SIZE = 600;
5656

5757
const char HTTPS_PATH[] = "/media/uploads/mbed_official/hello.txt";
58-
const size_t HTTPS_PATH_LEN = sizeof(HTTPS_PATH) - 1;
5958

6059
/* Test related data */
6160
const char *HTTPS_OK_STR = "200 OK";
@@ -110,12 +109,13 @@ class HelloHTTPS {
110109
_domain(domain), _port(port)
111110
{
112111

113-
_error = false;
114112
_gothello = false;
115113
_got200 = false;
116114
_bpos = 0;
117115
_request_sent = 0;
118116
_tcpsocket = new TCPSocket(net_iface);
117+
_tcpsocket->set_blocking(false);
118+
_buffer[RECV_BUFFER_SIZE - 1] = 0;
119119

120120
mbedtls_entropy_init(&_entropy);
121121
mbedtls_ctr_drbg_init(&_ctr_drbg);
@@ -132,6 +132,8 @@ class HelloHTTPS {
132132
mbedtls_x509_crt_free(&_cacert);
133133
mbedtls_ssl_free(&_ssl);
134134
mbedtls_ssl_config_free(&_ssl_conf);
135+
_tcpsocket->close();
136+
delete _tcpsocket;
135137
}
136138
/**
137139
* Start the test.
@@ -145,11 +147,8 @@ class HelloHTTPS {
145147
/* Initialize the flags */
146148
_got200 = false;
147149
_gothello = false;
148-
_error = false;
149150
_disconnected = false;
150151
_request_sent = false;
151-
/* Fill the request buffer */
152-
_bpos = snprintf(_buffer, sizeof(_buffer) - 1, "GET %s HTTP/1.1\nHost: %s\n\n", path, HTTPS_SERVER_NAME);
153152

154153
/*
155154
* Initialize TLS-related stuf.
@@ -159,14 +158,12 @@ class HelloHTTPS {
159158
(const unsigned char *) DRBG_PERS,
160159
sizeof (DRBG_PERS))) != 0) {
161160
print_mbedtls_error("mbedtls_crt_drbg_init", ret);
162-
_error = true;
163161
return;
164162
}
165163

166164
if ((ret = mbedtls_x509_crt_parse(&_cacert, (const unsigned char *) SSL_CA_PEM,
167165
sizeof (SSL_CA_PEM))) != 0) {
168166
print_mbedtls_error("mbedtls_x509_crt_parse", ret);
169-
_error = true;
170167
return;
171168
}
172169

@@ -175,7 +172,6 @@ class HelloHTTPS {
175172
MBEDTLS_SSL_TRANSPORT_STREAM,
176173
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
177174
print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
178-
_error = true;
179175
return;
180176
}
181177

@@ -195,7 +191,6 @@ class HelloHTTPS {
195191

196192
if ((ret = mbedtls_ssl_setup(&_ssl, &_ssl_conf)) != 0) {
197193
print_mbedtls_error("mbedtls_ssl_setup", ret);
198-
_error = true;
199194
return;
200195
}
201196

@@ -210,29 +205,39 @@ class HelloHTTPS {
210205
ret = _tcpsocket->connect(_domain, _port);
211206
if (ret != NSAPI_ERROR_OK) {
212207
mbedtls_printf("Failed to connect\r\n");
213-
onError(_tcpsocket, -1);
208+
printf("MBED: Socket Error: %d\r\n", ret);
209+
_tcpsocket->close();
214210
return;
215211
}
216212

217213
/* Start the handshake, the rest will be done in onReceive() */
218214
mbedtls_printf("Starting the TLS handshake...\r\n");
219-
ret = mbedtls_ssl_handshake(&_ssl);
215+
do {
216+
ret = mbedtls_ssl_handshake(&_ssl);
217+
} while (ret != 0 && (ret == MBEDTLS_ERR_SSL_WANT_READ ||
218+
ret == MBEDTLS_ERR_SSL_WANT_WRITE));
220219
if (ret < 0) {
221-
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
222-
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
223-
print_mbedtls_error("mbedtls_ssl_handshake", ret);
224-
onError(_tcpsocket, -1 );
225-
}
220+
print_mbedtls_error("mbedtls_ssl_handshake", ret);
221+
_tcpsocket->close();
226222
return;
227223
}
228224

229-
ret = mbedtls_ssl_write(&_ssl, (const unsigned char *) _buffer, _bpos);
225+
/* Fill the request buffer */
226+
_bpos = snprintf(_buffer, sizeof(_buffer) - 1,
227+
"GET %s HTTP/1.1\nHost: %s\n\n", path, HTTPS_SERVER_NAME);
228+
229+
int offset = 0;
230+
do {
231+
ret = mbedtls_ssl_write(&_ssl,
232+
(const unsigned char *) _buffer + offset,
233+
_bpos - offset);
234+
if (ret > 0)
235+
offset += ret;
236+
} while (offset < _bpos && (ret > 0 || ret == MBEDTLS_ERR_SSL_WANT_READ ||
237+
ret == MBEDTLS_ERR_SSL_WANT_WRITE));
230238
if (ret < 0) {
231-
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
232-
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
233-
print_mbedtls_error("mbedtls_ssl_write", ret);
234-
onError(_tcpsocket, -1 );
235-
}
239+
print_mbedtls_error("mbedtls_ssl_write", ret);
240+
_tcpsocket->close();
236241
return;
237242
}
238243

@@ -256,56 +261,43 @@ class HelloHTTPS {
256261

257262

258263
/* Read data out of the socket */
259-
ret = mbedtls_ssl_read(&_ssl, (unsigned char *) _buffer, sizeof(_buffer));
264+
offset = 0;
265+
do {
266+
ret = mbedtls_ssl_read(&_ssl, (unsigned char *) _buffer + offset,
267+
sizeof(_buffer) - offset - 1);
268+
if (ret > 0)
269+
offset += ret;
270+
271+
/* Check each of the flags */
272+
_buffer[offset] = 0;
273+
_got200 = _got200 || strstr(_buffer, HTTPS_OK_STR) != NULL;
274+
_gothello = _gothello || strstr(_buffer, HTTPS_HELLO_STR) != NULL;
275+
} while ( (!_got200 || !_gothello) &&
276+
(ret > 0 || ret == MBEDTLS_ERR_SSL_WANT_READ ||
277+
ret == MBEDTLS_ERR_SSL_WANT_WRITE));
260278
if (ret < 0) {
261-
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
262-
print_mbedtls_error("mbedtls_ssl_read", ret);
263-
onError(_tcpsocket, -1 );
264-
}
279+
print_mbedtls_error("mbedtls_ssl_read", ret);
265280
delete[] buf;
281+
_tcpsocket->close();
266282
return;
267283
}
268-
_bpos = static_cast<size_t>(ret);
284+
_bpos = static_cast<size_t>(offset);
269285

270286
_buffer[_bpos] = 0;
271287

272-
/* Check each of the flags */
273-
_got200 = _got200 || strstr(_buffer, HTTPS_OK_STR) != NULL;
274-
_gothello = _gothello || strstr(_buffer, HTTPS_HELLO_STR) != NULL;
288+
/* Close socket before status */
289+
_tcpsocket->close();
275290

276291
/* Print status messages */
277292
mbedtls_printf("HTTPS: Received %d chars from server\r\n", _bpos);
278293
mbedtls_printf("HTTPS: Received 200 OK status ... %s\r\n", _got200 ? "[OK]" : "[FAIL]");
279294
mbedtls_printf("HTTPS: Received '%s' status ... %s\r\n", HTTPS_HELLO_STR, _gothello ? "[OK]" : "[FAIL]");
280295
mbedtls_printf("HTTPS: Received message:\r\n\r\n");
281296
mbedtls_printf("%s", _buffer);
282-
_error = !(_got200 && _gothello);
283297

284-
_tcpsocket->close();
285298
delete[] buf;
286299
}
287-
/**
288-
* Check if the test has completed.
289-
* @return Returns true if done, false otherwise.
290-
*/
291-
bool done() {
292-
return _error || (_got200 && _gothello);
293-
}
294-
/**
295-
* Check if there was an error
296-
* @return Returns true if there was an error, false otherwise.
297-
*/
298-
bool error() {
299-
return _error;
300-
}
301-
/**
302-
* Closes the TCP socket
303-
*/
304-
void close() {
305-
_tcpsocket->close();
306-
while (!_disconnected)
307-
__WFI();
308-
}
300+
309301
protected:
310302
/**
311303
* Helper for pretty-printing mbed TLS error codes
@@ -375,6 +367,7 @@ class HelloHTTPS {
375367
if(NSAPI_ERROR_WOULD_BLOCK == recv){
376368
return MBEDTLS_ERR_SSL_WANT_READ;
377369
}else if(recv < 0){
370+
mbedtls_printf("Socket recv error %d\r\n", recv);
378371
return -1;
379372
}else{
380373
return recv;
@@ -390,20 +383,15 @@ class HelloHTTPS {
390383
size = socket->send(buf, len);
391384

392385
if(NSAPI_ERROR_WOULD_BLOCK == size){
393-
return len;
386+
return MBEDTLS_ERR_SSL_WANT_WRITE;
394387
}else if(size < 0){
388+
mbedtls_printf("Socket send error %d\r\n", size);
395389
return -1;
396390
}else{
397391
return size;
398392
}
399393
}
400394

401-
void onError(TCPSocket *s, int error) {
402-
printf("MBED: Socket Error: %d\r\n", error);
403-
s->close();
404-
_error = true;
405-
}
406-
407395
protected:
408396
TCPSocket* _tcpsocket;
409397

@@ -413,7 +401,6 @@ class HelloHTTPS {
413401
size_t _bpos; /**< The current offset in the response buffer */
414402
volatile bool _got200; /**< Status flag for HTTPS 200 */
415403
volatile bool _gothello; /**< Status flag for finding the test string */
416-
volatile bool _error; /**< Status flag for an error */
417404
volatile bool _disconnected;
418405
volatile bool _request_sent;
419406

0 commit comments

Comments
 (0)