mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /*
kenjiArai 0:5b88d5760320 2 * Copyright (c) 2018 ARM Limited
kenjiArai 0:5b88d5760320 3 * SPDX-License-Identifier: Apache-2.0
kenjiArai 0:5b88d5760320 4 *
kenjiArai 0:5b88d5760320 5 * Licensed under the Apache License, Version 2.0 (the "License");
kenjiArai 0:5b88d5760320 6 * you may not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 7 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 8 *
kenjiArai 0:5b88d5760320 9 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 10 *
kenjiArai 0:5b88d5760320 11 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 12 * distributed under the License is distributed on an "AS IS" BASIS,
kenjiArai 0:5b88d5760320 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 14 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 15 * limitations under the License.
kenjiArai 0:5b88d5760320 16 */
kenjiArai 0:5b88d5760320 17
kenjiArai 0:5b88d5760320 18 #include "TLSSocketWrapper.h"
kenjiArai 0:5b88d5760320 19 #include "platform/Callback.h"
kenjiArai 0:5b88d5760320 20 #include "drivers/Timer.h"
kenjiArai 0:5b88d5760320 21 #include "events/mbed_events.h"
kenjiArai 0:5b88d5760320 22
kenjiArai 0:5b88d5760320 23 #define TRACE_GROUP "TLSW"
kenjiArai 0:5b88d5760320 24 #include "mbed-trace/mbed_trace.h"
kenjiArai 0:5b88d5760320 25 #include "mbedtls/debug.h"
kenjiArai 0:5b88d5760320 26 #include "mbedtls/platform.h"
kenjiArai 0:5b88d5760320 27 #include "mbed_error.h"
kenjiArai 0:5b88d5760320 28 #include "Kernel.h"
kenjiArai 0:5b88d5760320 29
kenjiArai 0:5b88d5760320 30 // This class requires Mbed TLS SSL/TLS client code
kenjiArai 0:5b88d5760320 31 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 32
kenjiArai 0:5b88d5760320 33 TLSSocketWrapper::TLSSocketWrapper(Socket *transport, const char *hostname, control_transport control) :
kenjiArai 0:5b88d5760320 34 _transport(transport),
kenjiArai 0:5b88d5760320 35 _timeout(-1),
kenjiArai 0:5b88d5760320 36 #ifdef MBEDTLS_X509_CRT_PARSE_C
kenjiArai 0:5b88d5760320 37 _cacert(NULL),
kenjiArai 0:5b88d5760320 38 _clicert(NULL),
kenjiArai 0:5b88d5760320 39 #endif
kenjiArai 0:5b88d5760320 40 _ssl_conf(NULL),
kenjiArai 0:5b88d5760320 41 _connect_transport(control == TRANSPORT_CONNECT || control == TRANSPORT_CONNECT_AND_CLOSE),
kenjiArai 0:5b88d5760320 42 _close_transport(control == TRANSPORT_CLOSE || control == TRANSPORT_CONNECT_AND_CLOSE),
kenjiArai 0:5b88d5760320 43 _tls_initialized(false),
kenjiArai 0:5b88d5760320 44 _handshake_completed(false),
kenjiArai 0:5b88d5760320 45 _cacert_allocated(false),
kenjiArai 0:5b88d5760320 46 _clicert_allocated(false),
kenjiArai 0:5b88d5760320 47 _ssl_conf_allocated(false)
kenjiArai 0:5b88d5760320 48 {
kenjiArai 0:5b88d5760320 49 #if defined(MBEDTLS_PLATFORM_C)
kenjiArai 0:5b88d5760320 50 int ret = mbedtls_platform_setup(NULL);
kenjiArai 0:5b88d5760320 51 if (ret != 0) {
kenjiArai 0:5b88d5760320 52 print_mbedtls_error("mbedtls_platform_setup()", ret);
kenjiArai 0:5b88d5760320 53 }
kenjiArai 0:5b88d5760320 54 #endif /* MBEDTLS_PLATFORM_C */
kenjiArai 0:5b88d5760320 55 mbedtls_entropy_init(&_entropy);
kenjiArai 0:5b88d5760320 56 mbedtls_ctr_drbg_init(&_ctr_drbg);
kenjiArai 0:5b88d5760320 57 mbedtls_ssl_init(&_ssl);
kenjiArai 0:5b88d5760320 58 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 59 mbedtls_pk_init(&_pkctx);
kenjiArai 0:5b88d5760320 60 #endif
kenjiArai 0:5b88d5760320 61
kenjiArai 0:5b88d5760320 62 if (hostname) {
kenjiArai 0:5b88d5760320 63 set_hostname(hostname);
kenjiArai 0:5b88d5760320 64 }
kenjiArai 0:5b88d5760320 65 }
kenjiArai 0:5b88d5760320 66
kenjiArai 0:5b88d5760320 67 TLSSocketWrapper::~TLSSocketWrapper()
kenjiArai 0:5b88d5760320 68 {
kenjiArai 0:5b88d5760320 69 if (_transport) {
kenjiArai 0:5b88d5760320 70 close();
kenjiArai 0:5b88d5760320 71 }
kenjiArai 0:5b88d5760320 72 mbedtls_entropy_free(&_entropy);
kenjiArai 0:5b88d5760320 73 mbedtls_ctr_drbg_free(&_ctr_drbg);
kenjiArai 0:5b88d5760320 74 mbedtls_ssl_free(&_ssl);
kenjiArai 0:5b88d5760320 75 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 76 mbedtls_pk_free(&_pkctx);
kenjiArai 0:5b88d5760320 77 set_own_cert(NULL);
kenjiArai 0:5b88d5760320 78 set_ca_chain(NULL);
kenjiArai 0:5b88d5760320 79 #endif
kenjiArai 0:5b88d5760320 80 set_ssl_config(NULL);
kenjiArai 0:5b88d5760320 81 #if defined(MBEDTLS_PLATFORM_C)
kenjiArai 0:5b88d5760320 82 mbedtls_platform_teardown(NULL);
kenjiArai 0:5b88d5760320 83 #endif /* MBEDTLS_PLATFORM_C */
kenjiArai 0:5b88d5760320 84 }
kenjiArai 0:5b88d5760320 85
kenjiArai 0:5b88d5760320 86 void TLSSocketWrapper::set_hostname(const char *hostname)
kenjiArai 0:5b88d5760320 87 {
kenjiArai 0:5b88d5760320 88 #ifdef MBEDTLS_X509_CRT_PARSE_C
kenjiArai 0:5b88d5760320 89 mbedtls_ssl_set_hostname(&_ssl, hostname);
kenjiArai 0:5b88d5760320 90 #endif
kenjiArai 0:5b88d5760320 91 }
kenjiArai 0:5b88d5760320 92
kenjiArai 0:5b88d5760320 93 nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const void *root_ca, size_t len)
kenjiArai 0:5b88d5760320 94 {
kenjiArai 0:5b88d5760320 95 #if !defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 96 return NSAPI_ERROR_UNSUPPORTED;
kenjiArai 0:5b88d5760320 97 #else
kenjiArai 0:5b88d5760320 98 mbedtls_x509_crt *crt;
kenjiArai 0:5b88d5760320 99
kenjiArai 0:5b88d5760320 100 crt = new (std::nothrow) mbedtls_x509_crt;
kenjiArai 0:5b88d5760320 101 if (!crt) {
kenjiArai 0:5b88d5760320 102 return NSAPI_ERROR_NO_MEMORY;
kenjiArai 0:5b88d5760320 103 }
kenjiArai 0:5b88d5760320 104
kenjiArai 0:5b88d5760320 105 mbedtls_x509_crt_init(crt);
kenjiArai 0:5b88d5760320 106
kenjiArai 0:5b88d5760320 107 /* Parse CA certification */
kenjiArai 0:5b88d5760320 108 int ret;
kenjiArai 0:5b88d5760320 109 if ((ret = mbedtls_x509_crt_parse(crt, static_cast<const unsigned char *>(root_ca),
kenjiArai 0:5b88d5760320 110 len)) != 0) {
kenjiArai 0:5b88d5760320 111 print_mbedtls_error("mbedtls_x509_crt_parse", ret);
kenjiArai 0:5b88d5760320 112 mbedtls_x509_crt_free(crt);
kenjiArai 0:5b88d5760320 113 delete crt;
kenjiArai 0:5b88d5760320 114 return NSAPI_ERROR_PARAMETER;
kenjiArai 0:5b88d5760320 115 }
kenjiArai 0:5b88d5760320 116 set_ca_chain(crt);
kenjiArai 0:5b88d5760320 117 _cacert_allocated = true;
kenjiArai 0:5b88d5760320 118 return NSAPI_ERROR_OK;
kenjiArai 0:5b88d5760320 119 #endif
kenjiArai 0:5b88d5760320 120 }
kenjiArai 0:5b88d5760320 121
kenjiArai 0:5b88d5760320 122 nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const char *root_ca_pem)
kenjiArai 0:5b88d5760320 123 {
kenjiArai 0:5b88d5760320 124 return set_root_ca_cert(root_ca_pem, strlen(root_ca_pem) + 1);
kenjiArai 0:5b88d5760320 125 }
kenjiArai 0:5b88d5760320 126
kenjiArai 0:5b88d5760320 127 nsapi_error_t TLSSocketWrapper::set_client_cert_key(const char *client_cert_pem, const char *client_private_key_pem)
kenjiArai 0:5b88d5760320 128 {
kenjiArai 0:5b88d5760320 129 return set_client_cert_key(client_cert_pem, strlen(client_cert_pem) + 1, client_private_key_pem, strlen(client_private_key_pem) + 1);
kenjiArai 0:5b88d5760320 130 }
kenjiArai 0:5b88d5760320 131
kenjiArai 0:5b88d5760320 132 nsapi_error_t TLSSocketWrapper::set_client_cert_key(const void *client_cert, size_t client_cert_len,
kenjiArai 0:5b88d5760320 133 const void *client_private_key_pem, size_t client_private_key_len)
kenjiArai 0:5b88d5760320 134 {
kenjiArai 0:5b88d5760320 135 #if !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PK_C)
kenjiArai 0:5b88d5760320 136 return NSAPI_ERROR_UNSUPPORTED;
kenjiArai 0:5b88d5760320 137 #else
kenjiArai 0:5b88d5760320 138
kenjiArai 0:5b88d5760320 139 int ret;
kenjiArai 0:5b88d5760320 140 mbedtls_x509_crt *crt = new mbedtls_x509_crt;
kenjiArai 0:5b88d5760320 141 mbedtls_x509_crt_init(crt);
kenjiArai 0:5b88d5760320 142 if ((ret = mbedtls_x509_crt_parse(crt, static_cast<const unsigned char *>(client_cert),
kenjiArai 0:5b88d5760320 143 client_cert_len)) != 0) {
kenjiArai 0:5b88d5760320 144 print_mbedtls_error("mbedtls_x509_crt_parse", ret);
kenjiArai 0:5b88d5760320 145 mbedtls_x509_crt_free(crt);
kenjiArai 0:5b88d5760320 146 delete crt;
kenjiArai 0:5b88d5760320 147 return NSAPI_ERROR_PARAMETER;
kenjiArai 0:5b88d5760320 148 }
kenjiArai 0:5b88d5760320 149 mbedtls_pk_init(&_pkctx);
kenjiArai 0:5b88d5760320 150 if ((ret = mbedtls_pk_parse_key(&_pkctx, static_cast<const unsigned char *>(client_private_key_pem),
kenjiArai 0:5b88d5760320 151 client_private_key_len, NULL, 0)) != 0) {
kenjiArai 0:5b88d5760320 152 print_mbedtls_error("mbedtls_pk_parse_key", ret);
kenjiArai 0:5b88d5760320 153 mbedtls_x509_crt_free(crt);
kenjiArai 0:5b88d5760320 154 delete crt;
kenjiArai 0:5b88d5760320 155 return NSAPI_ERROR_PARAMETER;
kenjiArai 0:5b88d5760320 156 }
kenjiArai 0:5b88d5760320 157 set_own_cert(crt);
kenjiArai 0:5b88d5760320 158 _clicert_allocated = true;
kenjiArai 0:5b88d5760320 159
kenjiArai 0:5b88d5760320 160 return NSAPI_ERROR_OK;
kenjiArai 0:5b88d5760320 161 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 162 }
kenjiArai 0:5b88d5760320 163
kenjiArai 0:5b88d5760320 164
kenjiArai 0:5b88d5760320 165 nsapi_error_t TLSSocketWrapper::start_handshake(bool first_call)
kenjiArai 0:5b88d5760320 166 {
kenjiArai 0:5b88d5760320 167 const char DRBG_PERS[] = "mbed TLS client";
kenjiArai 0:5b88d5760320 168 int ret;
kenjiArai 0:5b88d5760320 169
kenjiArai 0:5b88d5760320 170 if (!_transport) {
kenjiArai 0:5b88d5760320 171 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 172 }
kenjiArai 0:5b88d5760320 173
kenjiArai 0:5b88d5760320 174 if (_tls_initialized) {
kenjiArai 0:5b88d5760320 175 return continue_handshake();
kenjiArai 0:5b88d5760320 176 }
kenjiArai 0:5b88d5760320 177
kenjiArai 0:5b88d5760320 178 #ifdef MBEDTLS_X509_CRT_PARSE_C
kenjiArai 0:5b88d5760320 179 tr_info("Starting TLS handshake with %s", _ssl.hostname);
kenjiArai 0:5b88d5760320 180 #else
kenjiArai 0:5b88d5760320 181 tr_info("Starting TLS handshake");
kenjiArai 0:5b88d5760320 182 #endif
kenjiArai 0:5b88d5760320 183 /*
kenjiArai 0:5b88d5760320 184 * Initialize TLS-related stuf.
kenjiArai 0:5b88d5760320 185 */
kenjiArai 0:5b88d5760320 186 if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy,
kenjiArai 0:5b88d5760320 187 (const unsigned char *) DRBG_PERS,
kenjiArai 0:5b88d5760320 188 sizeof(DRBG_PERS))) != 0) {
kenjiArai 0:5b88d5760320 189 print_mbedtls_error("mbedtls_crt_drbg_init", ret);
kenjiArai 0:5b88d5760320 190 return NSAPI_ERROR_AUTH_FAILURE;
kenjiArai 0:5b88d5760320 191 }
kenjiArai 0:5b88d5760320 192
kenjiArai 0:5b88d5760320 193 mbedtls_ssl_conf_rng(get_ssl_config(), mbedtls_ctr_drbg_random, &_ctr_drbg);
kenjiArai 0:5b88d5760320 194
kenjiArai 0:5b88d5760320 195
kenjiArai 0:5b88d5760320 196 #if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
kenjiArai 0:5b88d5760320 197 mbedtls_ssl_conf_verify(get_ssl_config(), my_verify, NULL);
kenjiArai 0:5b88d5760320 198 mbedtls_ssl_conf_dbg(get_ssl_config(), my_debug, NULL);
kenjiArai 0:5b88d5760320 199 mbedtls_debug_set_threshold(MBED_CONF_TLS_SOCKET_DEBUG_LEVEL);
kenjiArai 0:5b88d5760320 200 #endif
kenjiArai 0:5b88d5760320 201
kenjiArai 0:5b88d5760320 202 tr_debug("mbedtls_ssl_setup()");
kenjiArai 0:5b88d5760320 203 if ((ret = mbedtls_ssl_setup(&_ssl, get_ssl_config())) != 0) {
kenjiArai 0:5b88d5760320 204 print_mbedtls_error("mbedtls_ssl_setup", ret);
kenjiArai 0:5b88d5760320 205 return NSAPI_ERROR_AUTH_FAILURE;
kenjiArai 0:5b88d5760320 206 }
kenjiArai 0:5b88d5760320 207
kenjiArai 0:5b88d5760320 208 _transport->set_blocking(false);
kenjiArai 0:5b88d5760320 209 _transport->sigio(mbed::callback(this, &TLSSocketWrapper::event));
kenjiArai 0:5b88d5760320 210 mbedtls_ssl_set_bio(&_ssl, this, ssl_send, ssl_recv, NULL);
kenjiArai 0:5b88d5760320 211
kenjiArai 0:5b88d5760320 212 _tls_initialized = true;
kenjiArai 0:5b88d5760320 213
kenjiArai 0:5b88d5760320 214 ret = continue_handshake();
kenjiArai 0:5b88d5760320 215 if (first_call) {
kenjiArai 0:5b88d5760320 216 if (ret == NSAPI_ERROR_ALREADY) {
kenjiArai 0:5b88d5760320 217 ret = NSAPI_ERROR_IN_PROGRESS; // If first call should return IN_PROGRESS
kenjiArai 0:5b88d5760320 218 }
kenjiArai 0:5b88d5760320 219 if (ret == NSAPI_ERROR_IS_CONNECTED) {
kenjiArai 0:5b88d5760320 220 ret = NSAPI_ERROR_OK; // If we happened to complete the request on the first call, return OK.
kenjiArai 0:5b88d5760320 221 }
kenjiArai 0:5b88d5760320 222 }
kenjiArai 0:5b88d5760320 223 return ret;
kenjiArai 0:5b88d5760320 224 }
kenjiArai 0:5b88d5760320 225
kenjiArai 0:5b88d5760320 226 nsapi_error_t TLSSocketWrapper::continue_handshake()
kenjiArai 0:5b88d5760320 227 {
kenjiArai 0:5b88d5760320 228 int ret;
kenjiArai 0:5b88d5760320 229
kenjiArai 0:5b88d5760320 230 if (_handshake_completed) {
kenjiArai 0:5b88d5760320 231 return NSAPI_ERROR_IS_CONNECTED;
kenjiArai 0:5b88d5760320 232 }
kenjiArai 0:5b88d5760320 233
kenjiArai 0:5b88d5760320 234 if (!_tls_initialized) {
kenjiArai 0:5b88d5760320 235 return NSAPI_ERROR_NO_CONNECTION;
kenjiArai 0:5b88d5760320 236 }
kenjiArai 0:5b88d5760320 237
kenjiArai 0:5b88d5760320 238 while (true) {
kenjiArai 0:5b88d5760320 239 ret = mbedtls_ssl_handshake(&_ssl);
kenjiArai 0:5b88d5760320 240 if (_timeout && (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)) {
kenjiArai 0:5b88d5760320 241 uint32_t flag;
kenjiArai 0:5b88d5760320 242 flag = _event_flag.wait_any(1, _timeout);
kenjiArai 0:5b88d5760320 243 if (flag & osFlagsError) {
kenjiArai 0:5b88d5760320 244 break;
kenjiArai 0:5b88d5760320 245 }
kenjiArai 0:5b88d5760320 246 } else {
kenjiArai 0:5b88d5760320 247 break;
kenjiArai 0:5b88d5760320 248 }
kenjiArai 0:5b88d5760320 249 }
kenjiArai 0:5b88d5760320 250
kenjiArai 0:5b88d5760320 251 if (ret < 0) {
kenjiArai 0:5b88d5760320 252 print_mbedtls_error("mbedtls_ssl_handshake", ret);
kenjiArai 0:5b88d5760320 253 if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
kenjiArai 0:5b88d5760320 254 return NSAPI_ERROR_ALREADY;
kenjiArai 0:5b88d5760320 255 } else {
kenjiArai 0:5b88d5760320 256 return NSAPI_ERROR_AUTH_FAILURE;
kenjiArai 0:5b88d5760320 257 }
kenjiArai 0:5b88d5760320 258 }
kenjiArai 0:5b88d5760320 259
kenjiArai 0:5b88d5760320 260 #ifdef MBEDTLS_X509_CRT_PARSE_C
kenjiArai 0:5b88d5760320 261 /* It also means the handshake is done, time to print info */
kenjiArai 0:5b88d5760320 262 tr_info("TLS connection to %s established", _ssl.hostname);
kenjiArai 0:5b88d5760320 263 #else
kenjiArai 0:5b88d5760320 264 tr_info("TLS connection established");
kenjiArai 0:5b88d5760320 265 #endif
kenjiArai 0:5b88d5760320 266
kenjiArai 0:5b88d5760320 267 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(FEA_TRACE_SUPPORT)
kenjiArai 0:5b88d5760320 268 /* Prints the server certificate and verify it. */
kenjiArai 0:5b88d5760320 269 const size_t buf_size = 1024;
kenjiArai 0:5b88d5760320 270 char *buf = new char[buf_size];
kenjiArai 0:5b88d5760320 271 mbedtls_x509_crt_info(buf, buf_size, "\r ",
kenjiArai 0:5b88d5760320 272 mbedtls_ssl_get_peer_cert(&_ssl));
kenjiArai 0:5b88d5760320 273 tr_debug("Server certificate:\r\n%s\r\n", buf);
kenjiArai 0:5b88d5760320 274
kenjiArai 0:5b88d5760320 275 uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl);
kenjiArai 0:5b88d5760320 276 if (flags != 0) {
kenjiArai 0:5b88d5760320 277 /* Verification failed. */
kenjiArai 0:5b88d5760320 278 mbedtls_x509_crt_verify_info(buf, buf_size, "\r ! ", flags);
kenjiArai 0:5b88d5760320 279 tr_error("Certificate verification failed:\r\n%s", buf);
kenjiArai 0:5b88d5760320 280 } else {
kenjiArai 0:5b88d5760320 281 /* Verification succeeded. */
kenjiArai 0:5b88d5760320 282 tr_info("Certificate verification passed");
kenjiArai 0:5b88d5760320 283 }
kenjiArai 0:5b88d5760320 284 delete[] buf;
kenjiArai 0:5b88d5760320 285 #endif
kenjiArai 0:5b88d5760320 286
kenjiArai 0:5b88d5760320 287 _handshake_completed = true;
kenjiArai 0:5b88d5760320 288 return NSAPI_ERROR_IS_CONNECTED;
kenjiArai 0:5b88d5760320 289 }
kenjiArai 0:5b88d5760320 290
kenjiArai 0:5b88d5760320 291
kenjiArai 0:5b88d5760320 292 nsapi_error_t TLSSocketWrapper::send(const void *data, nsapi_size_t size)
kenjiArai 0:5b88d5760320 293 {
kenjiArai 0:5b88d5760320 294 int ret;
kenjiArai 0:5b88d5760320 295
kenjiArai 0:5b88d5760320 296 if (!_transport) {
kenjiArai 0:5b88d5760320 297 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 298 }
kenjiArai 0:5b88d5760320 299
kenjiArai 0:5b88d5760320 300 tr_debug("send %d", size);
kenjiArai 0:5b88d5760320 301 while (true) {
kenjiArai 0:5b88d5760320 302 if (!_handshake_completed) {
kenjiArai 0:5b88d5760320 303 ret = continue_handshake();
kenjiArai 0:5b88d5760320 304 if (ret != NSAPI_ERROR_IS_CONNECTED) {
kenjiArai 0:5b88d5760320 305 if (ret == NSAPI_ERROR_ALREADY) {
kenjiArai 0:5b88d5760320 306 ret = NSAPI_ERROR_WOULD_BLOCK;
kenjiArai 0:5b88d5760320 307 }
kenjiArai 0:5b88d5760320 308 return ret;
kenjiArai 0:5b88d5760320 309 }
kenjiArai 0:5b88d5760320 310 }
kenjiArai 0:5b88d5760320 311
kenjiArai 0:5b88d5760320 312 ret = mbedtls_ssl_write(&_ssl, (const unsigned char *) data, size);
kenjiArai 0:5b88d5760320 313
kenjiArai 0:5b88d5760320 314 if (_timeout == 0) {
kenjiArai 0:5b88d5760320 315 break;
kenjiArai 0:5b88d5760320 316 } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) {
kenjiArai 0:5b88d5760320 317 uint32_t flag;
kenjiArai 0:5b88d5760320 318 flag = _event_flag.wait_any(1, _timeout);
kenjiArai 0:5b88d5760320 319 if (flag & osFlagsError) {
kenjiArai 0:5b88d5760320 320 // Timeout break
kenjiArai 0:5b88d5760320 321 break;
kenjiArai 0:5b88d5760320 322 }
kenjiArai 0:5b88d5760320 323 } else {
kenjiArai 0:5b88d5760320 324 break;
kenjiArai 0:5b88d5760320 325 }
kenjiArai 0:5b88d5760320 326 }
kenjiArai 0:5b88d5760320 327
kenjiArai 0:5b88d5760320 328 if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
kenjiArai 0:5b88d5760320 329 ret == MBEDTLS_ERR_SSL_WANT_READ) {
kenjiArai 0:5b88d5760320 330 // translate to socket error
kenjiArai 0:5b88d5760320 331 return NSAPI_ERROR_WOULD_BLOCK;
kenjiArai 0:5b88d5760320 332 }
kenjiArai 0:5b88d5760320 333
kenjiArai 0:5b88d5760320 334 if (ret < 0) {
kenjiArai 0:5b88d5760320 335 print_mbedtls_error("mbedtls_ssl_write", ret);
kenjiArai 0:5b88d5760320 336 return NSAPI_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 337 }
kenjiArai 0:5b88d5760320 338 return ret; // Assume "non negative errorcode" to be propagated from Socket layer
kenjiArai 0:5b88d5760320 339 }
kenjiArai 0:5b88d5760320 340
kenjiArai 0:5b88d5760320 341 nsapi_size_or_error_t TLSSocketWrapper::sendto(const SocketAddress &, const void *data, nsapi_size_t size)
kenjiArai 0:5b88d5760320 342 {
kenjiArai 0:5b88d5760320 343 // Ignore the SocketAddress
kenjiArai 0:5b88d5760320 344 return send(data, size);
kenjiArai 0:5b88d5760320 345 }
kenjiArai 0:5b88d5760320 346
kenjiArai 0:5b88d5760320 347 nsapi_size_or_error_t TLSSocketWrapper::recv(void *data, nsapi_size_t size)
kenjiArai 0:5b88d5760320 348 {
kenjiArai 0:5b88d5760320 349 int ret;
kenjiArai 0:5b88d5760320 350
kenjiArai 0:5b88d5760320 351 if (!_transport) {
kenjiArai 0:5b88d5760320 352 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 353 }
kenjiArai 0:5b88d5760320 354
kenjiArai 0:5b88d5760320 355 while (true) {
kenjiArai 0:5b88d5760320 356 if (!_handshake_completed) {
kenjiArai 0:5b88d5760320 357 ret = continue_handshake();
kenjiArai 0:5b88d5760320 358 if (ret != NSAPI_ERROR_IS_CONNECTED) {
kenjiArai 0:5b88d5760320 359 if (ret == NSAPI_ERROR_ALREADY) {
kenjiArai 0:5b88d5760320 360 ret = NSAPI_ERROR_WOULD_BLOCK;
kenjiArai 0:5b88d5760320 361 }
kenjiArai 0:5b88d5760320 362 return ret;
kenjiArai 0:5b88d5760320 363 }
kenjiArai 0:5b88d5760320 364 }
kenjiArai 0:5b88d5760320 365
kenjiArai 0:5b88d5760320 366 ret = mbedtls_ssl_read(&_ssl, (unsigned char *) data, size);
kenjiArai 0:5b88d5760320 367
kenjiArai 0:5b88d5760320 368 if (_timeout == 0) {
kenjiArai 0:5b88d5760320 369 break;
kenjiArai 0:5b88d5760320 370 } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) {
kenjiArai 0:5b88d5760320 371 uint32_t flag;
kenjiArai 0:5b88d5760320 372 flag = _event_flag.wait_any(1, _timeout);
kenjiArai 0:5b88d5760320 373 if (flag & osFlagsError) {
kenjiArai 0:5b88d5760320 374 // Timeout break
kenjiArai 0:5b88d5760320 375 break;
kenjiArai 0:5b88d5760320 376 }
kenjiArai 0:5b88d5760320 377 } else {
kenjiArai 0:5b88d5760320 378 break;
kenjiArai 0:5b88d5760320 379 }
kenjiArai 0:5b88d5760320 380 }
kenjiArai 0:5b88d5760320 381 if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
kenjiArai 0:5b88d5760320 382 ret == MBEDTLS_ERR_SSL_WANT_READ) {
kenjiArai 0:5b88d5760320 383 // translate to socket error
kenjiArai 0:5b88d5760320 384 return NSAPI_ERROR_WOULD_BLOCK;
kenjiArai 0:5b88d5760320 385 } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
kenjiArai 0:5b88d5760320 386 /* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is not considered as error.
kenjiArai 0:5b88d5760320 387 * Just ignore here. Once connection is closed, mbedtls_ssl_read()
kenjiArai 0:5b88d5760320 388 * will return 0.
kenjiArai 0:5b88d5760320 389 */
kenjiArai 0:5b88d5760320 390 return 0;
kenjiArai 0:5b88d5760320 391 } else if (ret < 0) {
kenjiArai 0:5b88d5760320 392 print_mbedtls_error("mbedtls_ssl_read", ret);
kenjiArai 0:5b88d5760320 393 // There is no mapping of TLS error codes to Socket API so return most generic error to application
kenjiArai 0:5b88d5760320 394 return NSAPI_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 395 }
kenjiArai 0:5b88d5760320 396 return ret;
kenjiArai 0:5b88d5760320 397 }
kenjiArai 0:5b88d5760320 398
kenjiArai 0:5b88d5760320 399 nsapi_size_or_error_t TLSSocketWrapper::recvfrom(SocketAddress *address, void *data, nsapi_size_t size)
kenjiArai 0:5b88d5760320 400 {
kenjiArai 1:9db0e321a9f4 401 if (address) {
kenjiArai 1:9db0e321a9f4 402 getpeername(address);
kenjiArai 1:9db0e321a9f4 403 }
kenjiArai 0:5b88d5760320 404 return recv(data, size);
kenjiArai 0:5b88d5760320 405 }
kenjiArai 0:5b88d5760320 406
kenjiArai 0:5b88d5760320 407 void TLSSocketWrapper::print_mbedtls_error(MBED_UNUSED const char *name, MBED_UNUSED int err)
kenjiArai 0:5b88d5760320 408 {
kenjiArai 0:5b88d5760320 409 // Avoid pulling in mbedtls_strerror when trace is not enabled
kenjiArai 0:5b88d5760320 410 #if defined FEA_TRACE_SUPPORT && defined MBEDTLS_ERROR_C
kenjiArai 0:5b88d5760320 411 char *buf = new char[128];
kenjiArai 0:5b88d5760320 412 mbedtls_strerror(err, buf, 128);
kenjiArai 0:5b88d5760320 413 tr_err("%s() failed: -0x%04x (%d): %s", name, -err, err, buf);
kenjiArai 0:5b88d5760320 414 delete[] buf;
kenjiArai 0:5b88d5760320 415 #else
kenjiArai 0:5b88d5760320 416 tr_err("%s() failed: -0x%04x (%d)", name, -err, err);
kenjiArai 0:5b88d5760320 417 #endif
kenjiArai 0:5b88d5760320 418 }
kenjiArai 0:5b88d5760320 419
kenjiArai 0:5b88d5760320 420
kenjiArai 0:5b88d5760320 421 #if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
kenjiArai 0:5b88d5760320 422
kenjiArai 0:5b88d5760320 423 void TLSSocketWrapper::my_debug(void *ctx, int level, const char *file, int line,
kenjiArai 0:5b88d5760320 424 const char *str)
kenjiArai 0:5b88d5760320 425 {
kenjiArai 0:5b88d5760320 426 const char *p, *basename;
kenjiArai 0:5b88d5760320 427 (void) ctx;
kenjiArai 0:5b88d5760320 428
kenjiArai 0:5b88d5760320 429 /* Extract basename from file */
kenjiArai 0:5b88d5760320 430 for (p = basename = file; *p != '\0'; p++) {
kenjiArai 0:5b88d5760320 431 if (*p == '/' || *p == '\\') {
kenjiArai 0:5b88d5760320 432 basename = p + 1;
kenjiArai 0:5b88d5760320 433 }
kenjiArai 0:5b88d5760320 434 }
kenjiArai 0:5b88d5760320 435
kenjiArai 0:5b88d5760320 436 tr_debug("%s:%04d: |%d| %s", basename, line, level, str);
kenjiArai 0:5b88d5760320 437 }
kenjiArai 0:5b88d5760320 438
kenjiArai 0:5b88d5760320 439
kenjiArai 0:5b88d5760320 440 int TLSSocketWrapper::my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
kenjiArai 0:5b88d5760320 441 {
kenjiArai 0:5b88d5760320 442 const uint32_t buf_size = 1024;
kenjiArai 0:5b88d5760320 443 char *buf = new char[buf_size];
kenjiArai 0:5b88d5760320 444 (void) data;
kenjiArai 0:5b88d5760320 445
kenjiArai 0:5b88d5760320 446 tr_debug("\nVerifying certificate at depth %d:\n", depth);
kenjiArai 0:5b88d5760320 447 mbedtls_x509_crt_info(buf, buf_size - 1, " ", crt);
kenjiArai 0:5b88d5760320 448 tr_debug("%s", buf);
kenjiArai 0:5b88d5760320 449
kenjiArai 0:5b88d5760320 450 if (*flags == 0) {
kenjiArai 0:5b88d5760320 451 tr_info("No verification issue for this certificate\n");
kenjiArai 0:5b88d5760320 452 } else {
kenjiArai 0:5b88d5760320 453 mbedtls_x509_crt_verify_info(buf, buf_size, " ! ", *flags);
kenjiArai 0:5b88d5760320 454 tr_info("%s\n", buf);
kenjiArai 0:5b88d5760320 455 }
kenjiArai 0:5b88d5760320 456
kenjiArai 0:5b88d5760320 457 delete[] buf;
kenjiArai 0:5b88d5760320 458
kenjiArai 0:5b88d5760320 459 return 0;
kenjiArai 0:5b88d5760320 460 }
kenjiArai 0:5b88d5760320 461
kenjiArai 0:5b88d5760320 462 #endif /* MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 */
kenjiArai 0:5b88d5760320 463
kenjiArai 0:5b88d5760320 464
kenjiArai 0:5b88d5760320 465 int TLSSocketWrapper::ssl_recv(void *ctx, unsigned char *buf, size_t len)
kenjiArai 0:5b88d5760320 466 {
kenjiArai 0:5b88d5760320 467 int recv;
kenjiArai 0:5b88d5760320 468
kenjiArai 0:5b88d5760320 469 TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
kenjiArai 0:5b88d5760320 470
kenjiArai 0:5b88d5760320 471 if (!my->_transport) {
kenjiArai 0:5b88d5760320 472 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 473 }
kenjiArai 0:5b88d5760320 474
kenjiArai 0:5b88d5760320 475 recv = my->_transport->recv(buf, len);
kenjiArai 0:5b88d5760320 476
kenjiArai 0:5b88d5760320 477 if (NSAPI_ERROR_WOULD_BLOCK == recv) {
kenjiArai 0:5b88d5760320 478 return MBEDTLS_ERR_SSL_WANT_READ;
kenjiArai 0:5b88d5760320 479 } else if (recv < 0) {
kenjiArai 0:5b88d5760320 480 tr_error("Socket recv error %d", recv);
kenjiArai 0:5b88d5760320 481 }
kenjiArai 0:5b88d5760320 482 // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
kenjiArai 0:5b88d5760320 483 return recv;
kenjiArai 0:5b88d5760320 484 }
kenjiArai 0:5b88d5760320 485
kenjiArai 0:5b88d5760320 486 int TLSSocketWrapper::ssl_send(void *ctx, const unsigned char *buf, size_t len)
kenjiArai 0:5b88d5760320 487 {
kenjiArai 0:5b88d5760320 488 int size = -1;
kenjiArai 0:5b88d5760320 489 TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
kenjiArai 0:5b88d5760320 490
kenjiArai 0:5b88d5760320 491 if (!my->_transport) {
kenjiArai 0:5b88d5760320 492 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 493 }
kenjiArai 0:5b88d5760320 494
kenjiArai 0:5b88d5760320 495 size = my->_transport->send(buf, len);
kenjiArai 0:5b88d5760320 496
kenjiArai 0:5b88d5760320 497 if (NSAPI_ERROR_WOULD_BLOCK == size) {
kenjiArai 0:5b88d5760320 498 return MBEDTLS_ERR_SSL_WANT_WRITE;
kenjiArai 0:5b88d5760320 499 } else if (size < 0) {
kenjiArai 0:5b88d5760320 500 tr_error("Socket send error %d", size);
kenjiArai 0:5b88d5760320 501 }
kenjiArai 0:5b88d5760320 502 // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
kenjiArai 0:5b88d5760320 503 return size;
kenjiArai 0:5b88d5760320 504 }
kenjiArai 0:5b88d5760320 505
kenjiArai 0:5b88d5760320 506 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 507
kenjiArai 0:5b88d5760320 508 mbedtls_x509_crt *TLSSocketWrapper::get_own_cert()
kenjiArai 0:5b88d5760320 509 {
kenjiArai 0:5b88d5760320 510 return _clicert;
kenjiArai 0:5b88d5760320 511 }
kenjiArai 0:5b88d5760320 512
kenjiArai 0:5b88d5760320 513 int TLSSocketWrapper::set_own_cert(mbedtls_x509_crt *crt)
kenjiArai 0:5b88d5760320 514 {
kenjiArai 0:5b88d5760320 515 int ret = 0;
kenjiArai 0:5b88d5760320 516 if (_clicert && _clicert_allocated) {
kenjiArai 0:5b88d5760320 517 mbedtls_x509_crt_free(_clicert);
kenjiArai 0:5b88d5760320 518 delete _clicert;
kenjiArai 0:5b88d5760320 519 _clicert_allocated = false;
kenjiArai 0:5b88d5760320 520 }
kenjiArai 0:5b88d5760320 521 _clicert = crt;
kenjiArai 0:5b88d5760320 522 if (crt) {
kenjiArai 0:5b88d5760320 523 if ((ret = mbedtls_ssl_conf_own_cert(get_ssl_config(), _clicert, &_pkctx)) != 0) {
kenjiArai 0:5b88d5760320 524 print_mbedtls_error("mbedtls_ssl_conf_own_cert", ret);
kenjiArai 0:5b88d5760320 525 }
kenjiArai 0:5b88d5760320 526 }
kenjiArai 0:5b88d5760320 527 return ret;
kenjiArai 0:5b88d5760320 528 }
kenjiArai 0:5b88d5760320 529
kenjiArai 0:5b88d5760320 530 mbedtls_x509_crt *TLSSocketWrapper::get_ca_chain()
kenjiArai 0:5b88d5760320 531 {
kenjiArai 0:5b88d5760320 532 return _cacert;
kenjiArai 0:5b88d5760320 533 }
kenjiArai 0:5b88d5760320 534
kenjiArai 0:5b88d5760320 535 void TLSSocketWrapper::set_ca_chain(mbedtls_x509_crt *crt)
kenjiArai 0:5b88d5760320 536 {
kenjiArai 0:5b88d5760320 537 if (_cacert && _cacert_allocated) {
kenjiArai 0:5b88d5760320 538 mbedtls_x509_crt_free(_cacert);
kenjiArai 0:5b88d5760320 539 delete _cacert;
kenjiArai 0:5b88d5760320 540 _cacert_allocated = false;
kenjiArai 0:5b88d5760320 541 }
kenjiArai 0:5b88d5760320 542 _cacert = crt;
kenjiArai 0:5b88d5760320 543 tr_debug("mbedtls_ssl_conf_ca_chain()");
kenjiArai 0:5b88d5760320 544 mbedtls_ssl_conf_ca_chain(get_ssl_config(), _cacert, NULL);
kenjiArai 0:5b88d5760320 545 }
kenjiArai 0:5b88d5760320 546
kenjiArai 0:5b88d5760320 547 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 548
kenjiArai 0:5b88d5760320 549 mbedtls_ssl_config *TLSSocketWrapper::get_ssl_config()
kenjiArai 0:5b88d5760320 550 {
kenjiArai 0:5b88d5760320 551 if (!_ssl_conf) {
kenjiArai 0:5b88d5760320 552 int ret;
kenjiArai 0:5b88d5760320 553 _ssl_conf = new mbedtls_ssl_config;
kenjiArai 0:5b88d5760320 554 mbedtls_ssl_config_init(_ssl_conf);
kenjiArai 0:5b88d5760320 555 _ssl_conf_allocated = true;
kenjiArai 0:5b88d5760320 556
kenjiArai 0:5b88d5760320 557 if ((ret = mbedtls_ssl_config_defaults(_ssl_conf,
kenjiArai 0:5b88d5760320 558 MBEDTLS_SSL_IS_CLIENT,
kenjiArai 0:5b88d5760320 559 MBEDTLS_SSL_TRANSPORT_STREAM,
kenjiArai 0:5b88d5760320 560 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
kenjiArai 0:5b88d5760320 561 print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
kenjiArai 0:5b88d5760320 562 set_ssl_config(NULL);
kenjiArai 0:5b88d5760320 563 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_OUT_OF_MEMORY), "mbedtls_ssl_config_defaults() failed");
kenjiArai 0:5b88d5760320 564 return NULL;
kenjiArai 0:5b88d5760320 565 }
kenjiArai 0:5b88d5760320 566 /* It is possible to disable authentication by passing
kenjiArai 0:5b88d5760320 567 * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
kenjiArai 0:5b88d5760320 568 */
kenjiArai 0:5b88d5760320 569 mbedtls_ssl_conf_authmode(get_ssl_config(), MBEDTLS_SSL_VERIFY_REQUIRED);
kenjiArai 0:5b88d5760320 570 }
kenjiArai 0:5b88d5760320 571 return _ssl_conf;
kenjiArai 0:5b88d5760320 572 }
kenjiArai 0:5b88d5760320 573
kenjiArai 0:5b88d5760320 574 void TLSSocketWrapper::set_ssl_config(mbedtls_ssl_config *conf)
kenjiArai 0:5b88d5760320 575 {
kenjiArai 0:5b88d5760320 576 if (_ssl_conf && _ssl_conf_allocated) {
kenjiArai 0:5b88d5760320 577 mbedtls_ssl_config_free(_ssl_conf);
kenjiArai 0:5b88d5760320 578 delete _ssl_conf;
kenjiArai 0:5b88d5760320 579 _ssl_conf_allocated = false;
kenjiArai 0:5b88d5760320 580 }
kenjiArai 0:5b88d5760320 581 _ssl_conf = conf;
kenjiArai 0:5b88d5760320 582 }
kenjiArai 0:5b88d5760320 583
kenjiArai 0:5b88d5760320 584 mbedtls_ssl_context *TLSSocketWrapper::get_ssl_context()
kenjiArai 0:5b88d5760320 585 {
kenjiArai 0:5b88d5760320 586 return &_ssl;
kenjiArai 0:5b88d5760320 587 }
kenjiArai 0:5b88d5760320 588
kenjiArai 0:5b88d5760320 589 nsapi_error_t TLSSocketWrapper::close()
kenjiArai 0:5b88d5760320 590 {
kenjiArai 0:5b88d5760320 591 if (!_transport) {
kenjiArai 0:5b88d5760320 592 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 593 }
kenjiArai 0:5b88d5760320 594
kenjiArai 0:5b88d5760320 595 tr_info("Closing TLS");
kenjiArai 0:5b88d5760320 596
kenjiArai 0:5b88d5760320 597 int ret = 0;
kenjiArai 0:5b88d5760320 598 if (_handshake_completed) {
kenjiArai 0:5b88d5760320 599 _transport->set_blocking(true);
kenjiArai 0:5b88d5760320 600 ret = mbedtls_ssl_close_notify(&_ssl);
kenjiArai 0:5b88d5760320 601 if (ret) {
kenjiArai 0:5b88d5760320 602 print_mbedtls_error("mbedtls_ssl_close_notify", ret);
kenjiArai 0:5b88d5760320 603 }
kenjiArai 0:5b88d5760320 604 _handshake_completed = false;
kenjiArai 0:5b88d5760320 605 }
kenjiArai 0:5b88d5760320 606
kenjiArai 0:5b88d5760320 607 if (_close_transport) {
kenjiArai 0:5b88d5760320 608 int ret2 = _transport->close();
kenjiArai 0:5b88d5760320 609 if (!ret) {
kenjiArai 0:5b88d5760320 610 ret = ret2;
kenjiArai 0:5b88d5760320 611 }
kenjiArai 0:5b88d5760320 612 }
kenjiArai 0:5b88d5760320 613
kenjiArai 0:5b88d5760320 614 _transport = NULL;
kenjiArai 0:5b88d5760320 615
kenjiArai 0:5b88d5760320 616 return ret;
kenjiArai 0:5b88d5760320 617 }
kenjiArai 0:5b88d5760320 618
kenjiArai 0:5b88d5760320 619 nsapi_error_t TLSSocketWrapper::connect(const SocketAddress &address)
kenjiArai 0:5b88d5760320 620 {
kenjiArai 0:5b88d5760320 621 nsapi_error_t ret = NSAPI_ERROR_OK;
kenjiArai 0:5b88d5760320 622 if (!_transport) {
kenjiArai 0:5b88d5760320 623 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 624 }
kenjiArai 0:5b88d5760320 625
kenjiArai 0:5b88d5760320 626 if (!is_handshake_started() && _connect_transport) {
kenjiArai 0:5b88d5760320 627 ret = _transport->connect(address);
kenjiArai 0:5b88d5760320 628 if (ret && ret != NSAPI_ERROR_IS_CONNECTED) {
kenjiArai 0:5b88d5760320 629 return ret;
kenjiArai 0:5b88d5760320 630 }
kenjiArai 0:5b88d5760320 631 }
kenjiArai 0:5b88d5760320 632 return start_handshake(ret == NSAPI_ERROR_OK);
kenjiArai 0:5b88d5760320 633 }
kenjiArai 0:5b88d5760320 634
kenjiArai 0:5b88d5760320 635 nsapi_error_t TLSSocketWrapper::bind(const SocketAddress &address)
kenjiArai 0:5b88d5760320 636 {
kenjiArai 0:5b88d5760320 637 if (!_transport) {
kenjiArai 0:5b88d5760320 638 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 639 }
kenjiArai 0:5b88d5760320 640 return _transport->bind(address);
kenjiArai 0:5b88d5760320 641 }
kenjiArai 0:5b88d5760320 642
kenjiArai 0:5b88d5760320 643 void TLSSocketWrapper::set_blocking(bool blocking)
kenjiArai 0:5b88d5760320 644 {
kenjiArai 0:5b88d5760320 645 set_timeout(blocking ? -1 : 0);
kenjiArai 0:5b88d5760320 646 }
kenjiArai 0:5b88d5760320 647
kenjiArai 0:5b88d5760320 648 void TLSSocketWrapper::set_timeout(int timeout)
kenjiArai 0:5b88d5760320 649 {
kenjiArai 0:5b88d5760320 650 _timeout = timeout;
kenjiArai 0:5b88d5760320 651 if (!is_handshake_started() && timeout != -1 && _connect_transport) {
kenjiArai 0:5b88d5760320 652 // If we have not yet connected the transport, we need to modify its blocking mode as well.
kenjiArai 0:5b88d5760320 653 // After connection is initiated, it is already set to non blocking mode
kenjiArai 0:5b88d5760320 654 _transport->set_timeout(timeout);
kenjiArai 0:5b88d5760320 655 }
kenjiArai 0:5b88d5760320 656 }
kenjiArai 0:5b88d5760320 657
kenjiArai 0:5b88d5760320 658 void TLSSocketWrapper::sigio(mbed::Callback<void()> func)
kenjiArai 0:5b88d5760320 659 {
kenjiArai 0:5b88d5760320 660 if (!_transport) {
kenjiArai 0:5b88d5760320 661 return;
kenjiArai 0:5b88d5760320 662 }
kenjiArai 0:5b88d5760320 663 _sigio = func;
kenjiArai 0:5b88d5760320 664 _transport->sigio(mbed::callback(this, &TLSSocketWrapper::event));
kenjiArai 0:5b88d5760320 665 }
kenjiArai 0:5b88d5760320 666
kenjiArai 0:5b88d5760320 667 nsapi_error_t TLSSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
kenjiArai 0:5b88d5760320 668 {
kenjiArai 0:5b88d5760320 669 if (!_transport) {
kenjiArai 0:5b88d5760320 670 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 671 }
kenjiArai 0:5b88d5760320 672 return _transport->setsockopt(level, optname, optval, optlen);
kenjiArai 0:5b88d5760320 673 }
kenjiArai 0:5b88d5760320 674
kenjiArai 0:5b88d5760320 675 nsapi_error_t TLSSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen)
kenjiArai 0:5b88d5760320 676 {
kenjiArai 0:5b88d5760320 677 if (!_transport) {
kenjiArai 0:5b88d5760320 678 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 679 }
kenjiArai 0:5b88d5760320 680 return _transport->getsockopt(level, optname, optval, optlen);
kenjiArai 0:5b88d5760320 681 }
kenjiArai 0:5b88d5760320 682
kenjiArai 0:5b88d5760320 683 Socket *TLSSocketWrapper::accept(nsapi_error_t *err)
kenjiArai 0:5b88d5760320 684 {
kenjiArai 0:5b88d5760320 685 if (err) {
kenjiArai 0:5b88d5760320 686 *err = NSAPI_ERROR_UNSUPPORTED;
kenjiArai 0:5b88d5760320 687 }
kenjiArai 0:5b88d5760320 688 return NULL;
kenjiArai 0:5b88d5760320 689 }
kenjiArai 0:5b88d5760320 690
kenjiArai 0:5b88d5760320 691 nsapi_error_t TLSSocketWrapper::listen(int)
kenjiArai 0:5b88d5760320 692 {
kenjiArai 0:5b88d5760320 693 return NSAPI_ERROR_UNSUPPORTED;
kenjiArai 0:5b88d5760320 694 }
kenjiArai 0:5b88d5760320 695
kenjiArai 0:5b88d5760320 696 void TLSSocketWrapper::event()
kenjiArai 0:5b88d5760320 697 {
kenjiArai 0:5b88d5760320 698 _event_flag.set(1);
kenjiArai 0:5b88d5760320 699 if (_sigio) {
kenjiArai 0:5b88d5760320 700 _sigio();
kenjiArai 0:5b88d5760320 701 }
kenjiArai 0:5b88d5760320 702 }
kenjiArai 0:5b88d5760320 703
kenjiArai 0:5b88d5760320 704 bool TLSSocketWrapper::is_handshake_started() const
kenjiArai 0:5b88d5760320 705 {
kenjiArai 0:5b88d5760320 706 return _tls_initialized;
kenjiArai 0:5b88d5760320 707 }
kenjiArai 0:5b88d5760320 708
kenjiArai 0:5b88d5760320 709
kenjiArai 0:5b88d5760320 710 nsapi_error_t TLSSocketWrapper::getpeername(SocketAddress *address)
kenjiArai 0:5b88d5760320 711 {
kenjiArai 0:5b88d5760320 712 if (!_handshake_completed) {
kenjiArai 0:5b88d5760320 713 return NSAPI_ERROR_NO_CONNECTION;
kenjiArai 0:5b88d5760320 714 }
kenjiArai 0:5b88d5760320 715 return _transport->getpeername(address);
kenjiArai 0:5b88d5760320 716 }
kenjiArai 0:5b88d5760320 717
kenjiArai 0:5b88d5760320 718 #endif /* MBEDTLS_SSL_CLI_C */