diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index 348bba4c808289109de8fcf483075767d0d4703f..94863be57a9f7436a5d5e5c3813bdde1d89bcab6 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2016 Linaro Ltd. + * Copyright (c) 2019 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -60,6 +61,7 @@ struct ssl_args { mp_arg_val_t cert; mp_arg_val_t server_side; mp_arg_val_t server_hostname; + mp_arg_val_t do_handshake; }; STATIC const mp_obj_type_t ussl_socket_type; @@ -184,10 +186,12 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { assert(ret == 0); } - while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) { - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - printf("mbedtls_ssl_handshake error: -%x\n", -ret); - goto cleanup; + if (args->do_handshake.u_bool) { + while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + printf("mbedtls_ssl_handshake error: -%x\n", -ret); + goto cleanup; + } } } @@ -238,6 +242,11 @@ STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errc } if (ret == MBEDTLS_ERR_SSL_WANT_READ) { ret = MP_EWOULDBLOCK; + } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + // If handshake is not finished, read attempt may end up in protocol + // wanting to write next handshake message. The same may happen with + // renegotation. + ret = MP_EWOULDBLOCK; } *errcode = ret; return MP_STREAM_ERROR; @@ -252,6 +261,11 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in } if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { ret = MP_EWOULDBLOCK; + } else if (ret == MBEDTLS_ERR_SSL_WANT_READ) { + // If handshake is not finished, write attempt may end up in protocol + // wanting to read next handshake message. The same may happen with + // renegotation. + ret = MP_EWOULDBLOCK; } *errcode = ret; return MP_STREAM_ERROR; @@ -321,6 +335,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_ { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_do_handshake, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, }; // TODO: Check that sock implements stream protocol