Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TLSSocketWrapper.cpp Source File

TLSSocketWrapper.cpp

00001 /*
00002  * Copyright (c) 2018 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "TLSSocketWrapper.h"
00019 #include "platform/Callback.h"
00020 #include "drivers/Timer.h"
00021 #include "events/mbed_events.h"
00022 
00023 #define TRACE_GROUP "TLSW"
00024 #include "mbed-trace/mbed_trace.h"
00025 #include "mbedtls/debug.h"
00026 #include "mbedtls/platform.h"
00027 #include "mbed_error.h"
00028 #include "Kernel.h"
00029 
00030 // This class requires Mbed TLS SSL/TLS client code
00031 #if defined(MBEDTLS_SSL_CLI_C)
00032 
00033 TLSSocketWrapper::TLSSocketWrapper(Socket *transport, const char *hostname, control_transport control) :
00034     _transport(transport),
00035     _timeout(-1),
00036 #ifdef MBEDTLS_X509_CRT_PARSE_C
00037     _cacert(NULL),
00038     _clicert(NULL),
00039 #endif
00040     _ssl_conf(NULL),
00041     _connect_transport(control == TRANSPORT_CONNECT || control == TRANSPORT_CONNECT_AND_CLOSE),
00042     _close_transport(control == TRANSPORT_CLOSE || control == TRANSPORT_CONNECT_AND_CLOSE),
00043     _tls_initialized(false),
00044     _handshake_completed(false),
00045     _cacert_allocated(false),
00046     _clicert_allocated(false),
00047     _ssl_conf_allocated(false)
00048 {
00049 #if defined(MBEDTLS_PLATFORM_C)
00050     int ret = mbedtls_platform_setup(NULL);
00051     if (ret != 0) {
00052         print_mbedtls_error("mbedtls_platform_setup()", ret);
00053     }
00054 #endif /* MBEDTLS_PLATFORM_C */
00055     mbedtls_entropy_init(&_entropy);
00056     mbedtls_ctr_drbg_init(&_ctr_drbg);
00057     mbedtls_ssl_init(&_ssl);
00058 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00059     mbedtls_pk_init(&_pkctx);
00060 #endif
00061 
00062     if (hostname) {
00063         set_hostname(hostname);
00064     }
00065 }
00066 
00067 TLSSocketWrapper::~TLSSocketWrapper()
00068 {
00069     if (_transport) {
00070         close();
00071     }
00072     mbedtls_entropy_free(&_entropy);
00073     mbedtls_ctr_drbg_free(&_ctr_drbg);
00074     mbedtls_ssl_free(&_ssl);
00075 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00076     mbedtls_pk_free(&_pkctx);
00077     set_own_cert(NULL);
00078     set_ca_chain(NULL);
00079 #endif
00080     set_ssl_config(NULL);
00081 #if defined(MBEDTLS_PLATFORM_C)
00082     mbedtls_platform_teardown(NULL);
00083 #endif /* MBEDTLS_PLATFORM_C */
00084 }
00085 
00086 void TLSSocketWrapper::set_hostname(const char *hostname)
00087 {
00088 #ifdef MBEDTLS_X509_CRT_PARSE_C
00089     mbedtls_ssl_set_hostname(&_ssl, hostname);
00090 #endif
00091 }
00092 
00093 nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const void *root_ca, size_t len)
00094 {
00095 #if !defined(MBEDTLS_X509_CRT_PARSE_C)
00096     return NSAPI_ERROR_UNSUPPORTED ;
00097 #else
00098     mbedtls_x509_crt *crt;
00099 
00100     crt = new (std::nothrow) mbedtls_x509_crt;
00101     if (!crt) {
00102         return NSAPI_ERROR_NO_MEMORY ;
00103     }
00104 
00105     mbedtls_x509_crt_init(crt);
00106 
00107     /* Parse CA certification */
00108     int ret;
00109     if ((ret = mbedtls_x509_crt_parse(crt, static_cast<const unsigned char *>(root_ca),
00110                                       len)) != 0) {
00111         print_mbedtls_error("mbedtls_x509_crt_parse", ret);
00112         mbedtls_x509_crt_free(crt);
00113         delete crt;
00114         return NSAPI_ERROR_PARAMETER ;
00115     }
00116     set_ca_chain(crt);
00117     _cacert_allocated = true;
00118     return NSAPI_ERROR_OK ;
00119 #endif
00120 }
00121 
00122 nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const char *root_ca_pem)
00123 {
00124     return set_root_ca_cert(root_ca_pem, strlen(root_ca_pem) + 1);
00125 }
00126 
00127 nsapi_error_t TLSSocketWrapper::set_client_cert_key(const char *client_cert_pem, const char *client_private_key_pem)
00128 {
00129     return set_client_cert_key(client_cert_pem, strlen(client_cert_pem) + 1, client_private_key_pem, strlen(client_private_key_pem) + 1);
00130 }
00131 
00132 nsapi_error_t TLSSocketWrapper::set_client_cert_key(const void *client_cert, size_t client_cert_len,
00133                                                     const void *client_private_key_pem, size_t client_private_key_len)
00134 {
00135 #if !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PK_C)
00136     return NSAPI_ERROR_UNSUPPORTED ;
00137 #else
00138 
00139     int ret;
00140     mbedtls_x509_crt *crt = new mbedtls_x509_crt;
00141     mbedtls_x509_crt_init(crt);
00142     if ((ret = mbedtls_x509_crt_parse(crt, static_cast<const unsigned char *>(client_cert),
00143                                       client_cert_len)) != 0) {
00144         print_mbedtls_error("mbedtls_x509_crt_parse", ret);
00145         mbedtls_x509_crt_free(crt);
00146         delete crt;
00147         return NSAPI_ERROR_PARAMETER ;
00148     }
00149     mbedtls_pk_init(&_pkctx);
00150     if ((ret = mbedtls_pk_parse_key(&_pkctx, static_cast<const unsigned char *>(client_private_key_pem),
00151                                     client_private_key_len, NULL, 0)) != 0) {
00152         print_mbedtls_error("mbedtls_pk_parse_key", ret);
00153         mbedtls_x509_crt_free(crt);
00154         delete crt;
00155         return NSAPI_ERROR_PARAMETER ;
00156     }
00157     set_own_cert(crt);
00158     _clicert_allocated = true;
00159 
00160     return NSAPI_ERROR_OK ;
00161 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00162 }
00163 
00164 
00165 nsapi_error_t TLSSocketWrapper::start_handshake(bool first_call)
00166 {
00167     const char DRBG_PERS[] = "mbed TLS client";
00168     int ret;
00169 
00170     if (!_transport) {
00171         return NSAPI_ERROR_NO_SOCKET ;
00172     }
00173 
00174     if (_tls_initialized) {
00175         return continue_handshake();
00176     }
00177 
00178 #ifdef MBEDTLS_X509_CRT_PARSE_C
00179     tr_info("Starting TLS handshake with %s", _ssl.hostname);
00180 #else
00181     tr_info("Starting TLS handshake");
00182 #endif
00183     /*
00184      * Initialize TLS-related stuf.
00185      */
00186     if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy,
00187                                      (const unsigned char *) DRBG_PERS,
00188                                      sizeof(DRBG_PERS))) != 0) {
00189         print_mbedtls_error("mbedtls_crt_drbg_init", ret);
00190         return NSAPI_ERROR_AUTH_FAILURE ;
00191     }
00192 
00193     mbedtls_ssl_conf_rng(get_ssl_config(), mbedtls_ctr_drbg_random, &_ctr_drbg);
00194 
00195 
00196 #if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
00197     mbedtls_ssl_conf_verify(get_ssl_config(), my_verify, NULL);
00198     mbedtls_ssl_conf_dbg(get_ssl_config(), my_debug, NULL);
00199     mbedtls_debug_set_threshold(MBED_CONF_TLS_SOCKET_DEBUG_LEVEL);
00200 #endif
00201 
00202     tr_debug("mbedtls_ssl_setup()");
00203     if ((ret = mbedtls_ssl_setup(&_ssl, get_ssl_config())) != 0) {
00204         print_mbedtls_error("mbedtls_ssl_setup", ret);
00205         return NSAPI_ERROR_AUTH_FAILURE ;
00206     }
00207 
00208     _transport->set_blocking(false);
00209     _transport->sigio(mbed::callback(this, &TLSSocketWrapper::event));
00210     mbedtls_ssl_set_bio(&_ssl, this, ssl_send, ssl_recv, NULL);
00211 
00212     _tls_initialized = true;
00213 
00214     ret = continue_handshake();
00215     if (first_call) {
00216         if (ret == NSAPI_ERROR_ALREADY ) {
00217             ret = NSAPI_ERROR_IN_PROGRESS ; // If first call should return IN_PROGRESS
00218         }
00219         if (ret == NSAPI_ERROR_IS_CONNECTED ) {
00220             ret = NSAPI_ERROR_OK ;   // If we happened to complete the request on the first call, return OK.
00221         }
00222     }
00223     return ret;
00224 }
00225 
00226 nsapi_error_t TLSSocketWrapper::continue_handshake()
00227 {
00228     int ret;
00229 
00230     if (_handshake_completed) {
00231         return NSAPI_ERROR_IS_CONNECTED ;
00232     }
00233 
00234     if (!_tls_initialized) {
00235         return NSAPI_ERROR_NO_CONNECTION ;
00236     }
00237 
00238     while (true) {
00239         ret = mbedtls_ssl_handshake(&_ssl);
00240         if (_timeout && (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)) {
00241             uint32_t flag;
00242             flag = _event_flag.wait_any(1, _timeout);
00243             if (flag & osFlagsError) {
00244                 break;
00245             }
00246         } else {
00247             break;
00248         }
00249     }
00250 
00251     if (ret < 0) {
00252         print_mbedtls_error("mbedtls_ssl_handshake", ret);
00253         if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
00254             return NSAPI_ERROR_ALREADY ;
00255         } else {
00256             return NSAPI_ERROR_AUTH_FAILURE ;
00257         }
00258     }
00259 
00260 #ifdef MBEDTLS_X509_CRT_PARSE_C
00261     /* It also means the handshake is done, time to print info */
00262     tr_info("TLS connection to %s established", _ssl.hostname);
00263 #else
00264     tr_info("TLS connection established");
00265 #endif
00266 
00267 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(FEA_TRACE_SUPPORT)
00268     /* Prints the server certificate and verify it. */
00269     const size_t buf_size = 1024;
00270     char *buf = new char[buf_size];
00271     mbedtls_x509_crt_info(buf, buf_size, "\r    ",
00272                           mbedtls_ssl_get_peer_cert(&_ssl));
00273     tr_debug("Server certificate:\r\n%s\r\n", buf);
00274 
00275     uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl);
00276     if (flags != 0) {
00277         /* Verification failed. */
00278         mbedtls_x509_crt_verify_info(buf, buf_size, "\r  ! ", flags);
00279         tr_error("Certificate verification failed:\r\n%s", buf);
00280     } else {
00281         /* Verification succeeded. */
00282         tr_info("Certificate verification passed");
00283     }
00284     delete[] buf;
00285 #endif
00286 
00287     _handshake_completed = true;
00288     return NSAPI_ERROR_IS_CONNECTED ;
00289 }
00290 
00291 
00292 nsapi_error_t TLSSocketWrapper::send(const void *data, nsapi_size_t size)
00293 {
00294     int ret;
00295 
00296     if (!_transport) {
00297         return NSAPI_ERROR_NO_SOCKET ;
00298     }
00299 
00300     tr_debug("send %d", size);
00301     while (true) {
00302         if (!_handshake_completed) {
00303             ret = continue_handshake();
00304             if (ret != NSAPI_ERROR_IS_CONNECTED ) {
00305                 if (ret == NSAPI_ERROR_ALREADY ) {
00306                     ret = NSAPI_ERROR_WOULD_BLOCK ;
00307                 }
00308                 return ret;
00309             }
00310         }
00311 
00312         ret = mbedtls_ssl_write(&_ssl, (const unsigned char *) data, size);
00313 
00314         if (_timeout == 0) {
00315             break;
00316         } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) {
00317             uint32_t flag;
00318             flag = _event_flag.wait_any(1, _timeout);
00319             if (flag & osFlagsError) {
00320                 // Timeout break
00321                 break;
00322             }
00323         } else {
00324             break;
00325         }
00326     }
00327 
00328     if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
00329             ret == MBEDTLS_ERR_SSL_WANT_READ) {
00330         // translate to socket error
00331         return NSAPI_ERROR_WOULD_BLOCK ;
00332     }
00333 
00334     if (ret < 0) {
00335         print_mbedtls_error("mbedtls_ssl_write", ret);
00336         return NSAPI_ERROR_DEVICE_ERROR ;
00337     }
00338     return ret; // Assume "non negative errorcode" to be propagated from Socket layer
00339 }
00340 
00341 nsapi_size_or_error_t TLSSocketWrapper::sendto(const SocketAddress &, const void *data, nsapi_size_t size)
00342 {
00343     // Ignore the SocketAddress
00344     return send(data, size);
00345 }
00346 
00347 nsapi_size_or_error_t TLSSocketWrapper::recv(void *data, nsapi_size_t size)
00348 {
00349     int ret;
00350 
00351     if (!_transport) {
00352         return NSAPI_ERROR_NO_SOCKET ;
00353     }
00354 
00355     while (true) {
00356         if (!_handshake_completed) {
00357             ret = continue_handshake();
00358             if (ret != NSAPI_ERROR_IS_CONNECTED ) {
00359                 if (ret == NSAPI_ERROR_ALREADY ) {
00360                     ret = NSAPI_ERROR_WOULD_BLOCK ;
00361                 }
00362                 return ret;
00363             }
00364         }
00365 
00366         ret = mbedtls_ssl_read(&_ssl, (unsigned char *) data, size);
00367 
00368         if (_timeout == 0) {
00369             break;
00370         } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) {
00371             uint32_t flag;
00372             flag = _event_flag.wait_any(1, _timeout);
00373             if (flag & osFlagsError) {
00374                 // Timeout break
00375                 break;
00376             }
00377         } else {
00378             break;
00379         }
00380     }
00381     if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
00382             ret == MBEDTLS_ERR_SSL_WANT_READ) {
00383         // translate to socket error
00384         return NSAPI_ERROR_WOULD_BLOCK ;
00385     } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
00386         /* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is not considered as error.
00387          * Just ignore here. Once connection is closed, mbedtls_ssl_read()
00388          * will return 0.
00389          */
00390         return 0;
00391     } else if (ret < 0) {
00392         print_mbedtls_error("mbedtls_ssl_read", ret);
00393         // There is no mapping of TLS error codes to Socket API so return most generic error to application
00394         return NSAPI_ERROR_DEVICE_ERROR ;
00395     }
00396     return ret;
00397 }
00398 
00399 nsapi_size_or_error_t TLSSocketWrapper::recvfrom(SocketAddress *address, void *data, nsapi_size_t size)
00400 {
00401     if (address) {
00402         getpeername(address);
00403     }
00404     return recv(data, size);
00405 }
00406 
00407 void TLSSocketWrapper::print_mbedtls_error(MBED_UNUSED const char *name, MBED_UNUSED int err)
00408 {
00409 // Avoid pulling in mbedtls_strerror when trace is not enabled
00410 #if defined FEA_TRACE_SUPPORT && defined MBEDTLS_ERROR_C
00411     char *buf = new char[128];
00412     mbedtls_strerror(err, buf, 128);
00413     tr_err("%s() failed: -0x%04x (%d): %s", name, -err, err, buf);
00414     delete[] buf;
00415 #else
00416     tr_err("%s() failed: -0x%04x (%d)", name, -err, err);
00417 #endif
00418 }
00419 
00420 
00421 #if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
00422 
00423 void TLSSocketWrapper::my_debug(void *ctx, int level, const char *file, int line,
00424                                 const char *str)
00425 {
00426     const char *p, *basename;
00427     (void) ctx;
00428 
00429     /* Extract basename from file */
00430     for (p = basename = file; *p != '\0'; p++) {
00431         if (*p == '/' || *p == '\\') {
00432             basename = p + 1;
00433         }
00434     }
00435 
00436     tr_debug("%s:%04d: |%d| %s", basename, line, level, str);
00437 }
00438 
00439 
00440 int TLSSocketWrapper::my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
00441 {
00442     const uint32_t buf_size = 1024;
00443     char *buf = new char[buf_size];
00444     (void) data;
00445 
00446     tr_debug("\nVerifying certificate at depth %d:\n", depth);
00447     mbedtls_x509_crt_info(buf, buf_size - 1, "  ", crt);
00448     tr_debug("%s", buf);
00449 
00450     if (*flags == 0) {
00451         tr_info("No verification issue for this certificate\n");
00452     } else {
00453         mbedtls_x509_crt_verify_info(buf, buf_size, "  ! ", *flags);
00454         tr_info("%s\n", buf);
00455     }
00456 
00457     delete[] buf;
00458 
00459     return 0;
00460 }
00461 
00462 #endif /* MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 */
00463 
00464 
00465 int TLSSocketWrapper::ssl_recv(void *ctx, unsigned char *buf, size_t len)
00466 {
00467     int recv;
00468 
00469     TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
00470 
00471     if (!my->_transport) {
00472         return NSAPI_ERROR_NO_SOCKET ;
00473     }
00474 
00475     recv = my->_transport->recv(buf, len);
00476 
00477     if (NSAPI_ERROR_WOULD_BLOCK  == recv) {
00478         return MBEDTLS_ERR_SSL_WANT_READ;
00479     } else if (recv < 0) {
00480         tr_error("Socket recv error %d", recv);
00481     }
00482     // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
00483     return recv;
00484 }
00485 
00486 int TLSSocketWrapper::ssl_send(void *ctx, const unsigned char *buf, size_t len)
00487 {
00488     int size = -1;
00489     TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
00490 
00491     if (!my->_transport) {
00492         return NSAPI_ERROR_NO_SOCKET ;
00493     }
00494 
00495     size = my->_transport->send(buf, len);
00496 
00497     if (NSAPI_ERROR_WOULD_BLOCK  == size) {
00498         return MBEDTLS_ERR_SSL_WANT_WRITE;
00499     } else if (size < 0) {
00500         tr_error("Socket send error %d", size);
00501     }
00502     // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
00503     return size;
00504 }
00505 
00506 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00507 
00508 mbedtls_x509_crt *TLSSocketWrapper::get_own_cert()
00509 {
00510     return _clicert;
00511 }
00512 
00513 int TLSSocketWrapper::set_own_cert(mbedtls_x509_crt *crt)
00514 {
00515     int ret = 0;
00516     if (_clicert && _clicert_allocated) {
00517         mbedtls_x509_crt_free(_clicert);
00518         delete _clicert;
00519         _clicert_allocated = false;
00520     }
00521     _clicert = crt;
00522     if (crt) {
00523         if ((ret = mbedtls_ssl_conf_own_cert(get_ssl_config(), _clicert, &_pkctx)) != 0) {
00524             print_mbedtls_error("mbedtls_ssl_conf_own_cert", ret);
00525         }
00526     }
00527     return ret;
00528 }
00529 
00530 mbedtls_x509_crt *TLSSocketWrapper::get_ca_chain()
00531 {
00532     return _cacert;
00533 }
00534 
00535 void TLSSocketWrapper::set_ca_chain(mbedtls_x509_crt *crt)
00536 {
00537     if (_cacert && _cacert_allocated) {
00538         mbedtls_x509_crt_free(_cacert);
00539         delete _cacert;
00540         _cacert_allocated = false;
00541     }
00542     _cacert = crt;
00543     tr_debug("mbedtls_ssl_conf_ca_chain()");
00544     mbedtls_ssl_conf_ca_chain(get_ssl_config(), _cacert, NULL);
00545 }
00546 
00547 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00548 
00549 mbedtls_ssl_config *TLSSocketWrapper::get_ssl_config()
00550 {
00551     if (!_ssl_conf) {
00552         int ret;
00553         _ssl_conf = new mbedtls_ssl_config;
00554         mbedtls_ssl_config_init(_ssl_conf);
00555         _ssl_conf_allocated = true;
00556 
00557         if ((ret = mbedtls_ssl_config_defaults(_ssl_conf,
00558                                                MBEDTLS_SSL_IS_CLIENT,
00559                                                MBEDTLS_SSL_TRANSPORT_STREAM,
00560                                                MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
00561             print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
00562             set_ssl_config(NULL);
00563             MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_OUT_OF_MEMORY), "mbedtls_ssl_config_defaults() failed");
00564             return NULL;
00565         }
00566         /* It is possible to disable authentication by passing
00567          * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
00568          */
00569         mbedtls_ssl_conf_authmode(get_ssl_config(), MBEDTLS_SSL_VERIFY_REQUIRED);
00570     }
00571     return _ssl_conf;
00572 }
00573 
00574 void TLSSocketWrapper::set_ssl_config(mbedtls_ssl_config *conf)
00575 {
00576     if (_ssl_conf && _ssl_conf_allocated) {
00577         mbedtls_ssl_config_free(_ssl_conf);
00578         delete _ssl_conf;
00579         _ssl_conf_allocated = false;
00580     }
00581     _ssl_conf = conf;
00582 }
00583 
00584 mbedtls_ssl_context *TLSSocketWrapper::get_ssl_context()
00585 {
00586     return &_ssl;
00587 }
00588 
00589 nsapi_error_t TLSSocketWrapper::close()
00590 {
00591     if (!_transport) {
00592         return NSAPI_ERROR_NO_SOCKET ;
00593     }
00594 
00595     tr_info("Closing TLS");
00596 
00597     int ret = 0;
00598     if (_handshake_completed) {
00599         _transport->set_blocking(true);
00600         ret = mbedtls_ssl_close_notify(&_ssl);
00601         if (ret) {
00602             print_mbedtls_error("mbedtls_ssl_close_notify", ret);
00603         }
00604         _handshake_completed = false;
00605     }
00606 
00607     if (_close_transport) {
00608         int ret2 = _transport->close();
00609         if (!ret) {
00610             ret = ret2;
00611         }
00612     }
00613 
00614     _transport = NULL;
00615 
00616     return ret;
00617 }
00618 
00619 nsapi_error_t TLSSocketWrapper::connect(const SocketAddress &address)
00620 {
00621     nsapi_error_t ret = NSAPI_ERROR_OK ;
00622     if (!_transport) {
00623         return NSAPI_ERROR_NO_SOCKET ;
00624     }
00625 
00626     if (!is_handshake_started() && _connect_transport) {
00627         ret = _transport->connect(address);
00628         if (ret && ret != NSAPI_ERROR_IS_CONNECTED ) {
00629             return ret;
00630         }
00631     }
00632     return start_handshake(ret == NSAPI_ERROR_OK );
00633 }
00634 
00635 nsapi_error_t TLSSocketWrapper::bind(const SocketAddress &address)
00636 {
00637     if (!_transport) {
00638         return NSAPI_ERROR_NO_SOCKET ;
00639     }
00640     return _transport->bind(address);
00641 }
00642 
00643 void TLSSocketWrapper::set_blocking(bool blocking)
00644 {
00645     set_timeout(blocking ? -1 : 0);
00646 }
00647 
00648 void TLSSocketWrapper::set_timeout(int timeout)
00649 {
00650     _timeout = timeout;
00651     if (!is_handshake_started() && timeout != -1 && _connect_transport) {
00652         // If we have not yet connected the transport, we need to modify its blocking mode as well.
00653         // After connection is initiated, it is already set to non blocking mode
00654         _transport->set_timeout(timeout);
00655     }
00656 }
00657 
00658 void TLSSocketWrapper::sigio(mbed::Callback<void()> func)
00659 {
00660     if (!_transport) {
00661         return;
00662     }
00663     _sigio = func;
00664     _transport->sigio(mbed::callback(this, &TLSSocketWrapper::event));
00665 }
00666 
00667 nsapi_error_t TLSSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
00668 {
00669     if (!_transport) {
00670         return NSAPI_ERROR_NO_SOCKET ;
00671     }
00672     return _transport->setsockopt(level, optname, optval, optlen);
00673 }
00674 
00675 nsapi_error_t TLSSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen)
00676 {
00677     if (!_transport) {
00678         return NSAPI_ERROR_NO_SOCKET ;
00679     }
00680     return _transport->getsockopt(level, optname, optval, optlen);
00681 }
00682 
00683 Socket *TLSSocketWrapper::accept(nsapi_error_t *err)
00684 {
00685     if (err) {
00686         *err = NSAPI_ERROR_UNSUPPORTED ;
00687     }
00688     return NULL;
00689 }
00690 
00691 nsapi_error_t TLSSocketWrapper::listen(int)
00692 {
00693     return NSAPI_ERROR_UNSUPPORTED ;
00694 }
00695 
00696 void TLSSocketWrapper::event()
00697 {
00698     _event_flag.set(1);
00699     if (_sigio) {
00700         _sigio();
00701     }
00702 }
00703 
00704 bool TLSSocketWrapper::is_handshake_started() const
00705 {
00706     return _tls_initialized;
00707 }
00708 
00709 
00710 nsapi_error_t TLSSocketWrapper::getpeername(SocketAddress *address)
00711 {
00712     if (!_handshake_completed) {
00713         return NSAPI_ERROR_NO_CONNECTION ;
00714     }
00715     return _transport->getpeername(address);
00716 }
00717 
00718 #endif /* MBEDTLS_SSL_CLI_C */