mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 17 23:23:45 2019 +0000
Revision:
0:5b88d5760320
Child:
1:9db0e321a9f4
mbed-os5 only for TYBLE16

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 0:5b88d5760320 401 return recv(data, size);
kenjiArai 0:5b88d5760320 402 }
kenjiArai 0:5b88d5760320 403
kenjiArai 0:5b88d5760320 404 void TLSSocketWrapper::print_mbedtls_error(MBED_UNUSED const char *name, MBED_UNUSED int err)
kenjiArai 0:5b88d5760320 405 {
kenjiArai 0:5b88d5760320 406 // Avoid pulling in mbedtls_strerror when trace is not enabled
kenjiArai 0:5b88d5760320 407 #if defined FEA_TRACE_SUPPORT && defined MBEDTLS_ERROR_C
kenjiArai 0:5b88d5760320 408 char *buf = new char[128];
kenjiArai 0:5b88d5760320 409 mbedtls_strerror(err, buf, 128);
kenjiArai 0:5b88d5760320 410 tr_err("%s() failed: -0x%04x (%d): %s", name, -err, err, buf);
kenjiArai 0:5b88d5760320 411 delete[] buf;
kenjiArai 0:5b88d5760320 412 #else
kenjiArai 0:5b88d5760320 413 tr_err("%s() failed: -0x%04x (%d)", name, -err, err);
kenjiArai 0:5b88d5760320 414 #endif
kenjiArai 0:5b88d5760320 415 }
kenjiArai 0:5b88d5760320 416
kenjiArai 0:5b88d5760320 417
kenjiArai 0:5b88d5760320 418 #if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
kenjiArai 0:5b88d5760320 419
kenjiArai 0:5b88d5760320 420 void TLSSocketWrapper::my_debug(void *ctx, int level, const char *file, int line,
kenjiArai 0:5b88d5760320 421 const char *str)
kenjiArai 0:5b88d5760320 422 {
kenjiArai 0:5b88d5760320 423 const char *p, *basename;
kenjiArai 0:5b88d5760320 424 (void) ctx;
kenjiArai 0:5b88d5760320 425
kenjiArai 0:5b88d5760320 426 /* Extract basename from file */
kenjiArai 0:5b88d5760320 427 for (p = basename = file; *p != '\0'; p++) {
kenjiArai 0:5b88d5760320 428 if (*p == '/' || *p == '\\') {
kenjiArai 0:5b88d5760320 429 basename = p + 1;
kenjiArai 0:5b88d5760320 430 }
kenjiArai 0:5b88d5760320 431 }
kenjiArai 0:5b88d5760320 432
kenjiArai 0:5b88d5760320 433 tr_debug("%s:%04d: |%d| %s", basename, line, level, str);
kenjiArai 0:5b88d5760320 434 }
kenjiArai 0:5b88d5760320 435
kenjiArai 0:5b88d5760320 436
kenjiArai 0:5b88d5760320 437 int TLSSocketWrapper::my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
kenjiArai 0:5b88d5760320 438 {
kenjiArai 0:5b88d5760320 439 const uint32_t buf_size = 1024;
kenjiArai 0:5b88d5760320 440 char *buf = new char[buf_size];
kenjiArai 0:5b88d5760320 441 (void) data;
kenjiArai 0:5b88d5760320 442
kenjiArai 0:5b88d5760320 443 tr_debug("\nVerifying certificate at depth %d:\n", depth);
kenjiArai 0:5b88d5760320 444 mbedtls_x509_crt_info(buf, buf_size - 1, " ", crt);
kenjiArai 0:5b88d5760320 445 tr_debug("%s", buf);
kenjiArai 0:5b88d5760320 446
kenjiArai 0:5b88d5760320 447 if (*flags == 0) {
kenjiArai 0:5b88d5760320 448 tr_info("No verification issue for this certificate\n");
kenjiArai 0:5b88d5760320 449 } else {
kenjiArai 0:5b88d5760320 450 mbedtls_x509_crt_verify_info(buf, buf_size, " ! ", *flags);
kenjiArai 0:5b88d5760320 451 tr_info("%s\n", buf);
kenjiArai 0:5b88d5760320 452 }
kenjiArai 0:5b88d5760320 453
kenjiArai 0:5b88d5760320 454 delete[] buf;
kenjiArai 0:5b88d5760320 455
kenjiArai 0:5b88d5760320 456 return 0;
kenjiArai 0:5b88d5760320 457 }
kenjiArai 0:5b88d5760320 458
kenjiArai 0:5b88d5760320 459 #endif /* MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 */
kenjiArai 0:5b88d5760320 460
kenjiArai 0:5b88d5760320 461
kenjiArai 0:5b88d5760320 462 int TLSSocketWrapper::ssl_recv(void *ctx, unsigned char *buf, size_t len)
kenjiArai 0:5b88d5760320 463 {
kenjiArai 0:5b88d5760320 464 int recv;
kenjiArai 0:5b88d5760320 465
kenjiArai 0:5b88d5760320 466 TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
kenjiArai 0:5b88d5760320 467
kenjiArai 0:5b88d5760320 468 if (!my->_transport) {
kenjiArai 0:5b88d5760320 469 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 470 }
kenjiArai 0:5b88d5760320 471
kenjiArai 0:5b88d5760320 472 recv = my->_transport->recv(buf, len);
kenjiArai 0:5b88d5760320 473
kenjiArai 0:5b88d5760320 474 if (NSAPI_ERROR_WOULD_BLOCK == recv) {
kenjiArai 0:5b88d5760320 475 return MBEDTLS_ERR_SSL_WANT_READ;
kenjiArai 0:5b88d5760320 476 } else if (recv < 0) {
kenjiArai 0:5b88d5760320 477 tr_error("Socket recv error %d", recv);
kenjiArai 0:5b88d5760320 478 }
kenjiArai 0:5b88d5760320 479 // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
kenjiArai 0:5b88d5760320 480 return recv;
kenjiArai 0:5b88d5760320 481 }
kenjiArai 0:5b88d5760320 482
kenjiArai 0:5b88d5760320 483 int TLSSocketWrapper::ssl_send(void *ctx, const unsigned char *buf, size_t len)
kenjiArai 0:5b88d5760320 484 {
kenjiArai 0:5b88d5760320 485 int size = -1;
kenjiArai 0:5b88d5760320 486 TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
kenjiArai 0:5b88d5760320 487
kenjiArai 0:5b88d5760320 488 if (!my->_transport) {
kenjiArai 0:5b88d5760320 489 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 490 }
kenjiArai 0:5b88d5760320 491
kenjiArai 0:5b88d5760320 492 size = my->_transport->send(buf, len);
kenjiArai 0:5b88d5760320 493
kenjiArai 0:5b88d5760320 494 if (NSAPI_ERROR_WOULD_BLOCK == size) {
kenjiArai 0:5b88d5760320 495 return MBEDTLS_ERR_SSL_WANT_WRITE;
kenjiArai 0:5b88d5760320 496 } else if (size < 0) {
kenjiArai 0:5b88d5760320 497 tr_error("Socket send error %d", size);
kenjiArai 0:5b88d5760320 498 }
kenjiArai 0:5b88d5760320 499 // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
kenjiArai 0:5b88d5760320 500 return size;
kenjiArai 0:5b88d5760320 501 }
kenjiArai 0:5b88d5760320 502
kenjiArai 0:5b88d5760320 503 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 504
kenjiArai 0:5b88d5760320 505 mbedtls_x509_crt *TLSSocketWrapper::get_own_cert()
kenjiArai 0:5b88d5760320 506 {
kenjiArai 0:5b88d5760320 507 return _clicert;
kenjiArai 0:5b88d5760320 508 }
kenjiArai 0:5b88d5760320 509
kenjiArai 0:5b88d5760320 510 int TLSSocketWrapper::set_own_cert(mbedtls_x509_crt *crt)
kenjiArai 0:5b88d5760320 511 {
kenjiArai 0:5b88d5760320 512 int ret = 0;
kenjiArai 0:5b88d5760320 513 if (_clicert && _clicert_allocated) {
kenjiArai 0:5b88d5760320 514 mbedtls_x509_crt_free(_clicert);
kenjiArai 0:5b88d5760320 515 delete _clicert;
kenjiArai 0:5b88d5760320 516 _clicert_allocated = false;
kenjiArai 0:5b88d5760320 517 }
kenjiArai 0:5b88d5760320 518 _clicert = crt;
kenjiArai 0:5b88d5760320 519 if (crt) {
kenjiArai 0:5b88d5760320 520 if ((ret = mbedtls_ssl_conf_own_cert(get_ssl_config(), _clicert, &_pkctx)) != 0) {
kenjiArai 0:5b88d5760320 521 print_mbedtls_error("mbedtls_ssl_conf_own_cert", ret);
kenjiArai 0:5b88d5760320 522 }
kenjiArai 0:5b88d5760320 523 }
kenjiArai 0:5b88d5760320 524 return ret;
kenjiArai 0:5b88d5760320 525 }
kenjiArai 0:5b88d5760320 526
kenjiArai 0:5b88d5760320 527 mbedtls_x509_crt *TLSSocketWrapper::get_ca_chain()
kenjiArai 0:5b88d5760320 528 {
kenjiArai 0:5b88d5760320 529 return _cacert;
kenjiArai 0:5b88d5760320 530 }
kenjiArai 0:5b88d5760320 531
kenjiArai 0:5b88d5760320 532 void TLSSocketWrapper::set_ca_chain(mbedtls_x509_crt *crt)
kenjiArai 0:5b88d5760320 533 {
kenjiArai 0:5b88d5760320 534 if (_cacert && _cacert_allocated) {
kenjiArai 0:5b88d5760320 535 mbedtls_x509_crt_free(_cacert);
kenjiArai 0:5b88d5760320 536 delete _cacert;
kenjiArai 0:5b88d5760320 537 _cacert_allocated = false;
kenjiArai 0:5b88d5760320 538 }
kenjiArai 0:5b88d5760320 539 _cacert = crt;
kenjiArai 0:5b88d5760320 540 tr_debug("mbedtls_ssl_conf_ca_chain()");
kenjiArai 0:5b88d5760320 541 mbedtls_ssl_conf_ca_chain(get_ssl_config(), _cacert, NULL);
kenjiArai 0:5b88d5760320 542 }
kenjiArai 0:5b88d5760320 543
kenjiArai 0:5b88d5760320 544 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 545
kenjiArai 0:5b88d5760320 546 mbedtls_ssl_config *TLSSocketWrapper::get_ssl_config()
kenjiArai 0:5b88d5760320 547 {
kenjiArai 0:5b88d5760320 548 if (!_ssl_conf) {
kenjiArai 0:5b88d5760320 549 int ret;
kenjiArai 0:5b88d5760320 550 _ssl_conf = new mbedtls_ssl_config;
kenjiArai 0:5b88d5760320 551 mbedtls_ssl_config_init(_ssl_conf);
kenjiArai 0:5b88d5760320 552 _ssl_conf_allocated = true;
kenjiArai 0:5b88d5760320 553
kenjiArai 0:5b88d5760320 554 if ((ret = mbedtls_ssl_config_defaults(_ssl_conf,
kenjiArai 0:5b88d5760320 555 MBEDTLS_SSL_IS_CLIENT,
kenjiArai 0:5b88d5760320 556 MBEDTLS_SSL_TRANSPORT_STREAM,
kenjiArai 0:5b88d5760320 557 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
kenjiArai 0:5b88d5760320 558 print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
kenjiArai 0:5b88d5760320 559 set_ssl_config(NULL);
kenjiArai 0:5b88d5760320 560 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_OUT_OF_MEMORY), "mbedtls_ssl_config_defaults() failed");
kenjiArai 0:5b88d5760320 561 return NULL;
kenjiArai 0:5b88d5760320 562 }
kenjiArai 0:5b88d5760320 563 /* It is possible to disable authentication by passing
kenjiArai 0:5b88d5760320 564 * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
kenjiArai 0:5b88d5760320 565 */
kenjiArai 0:5b88d5760320 566 mbedtls_ssl_conf_authmode(get_ssl_config(), MBEDTLS_SSL_VERIFY_REQUIRED);
kenjiArai 0:5b88d5760320 567 }
kenjiArai 0:5b88d5760320 568 return _ssl_conf;
kenjiArai 0:5b88d5760320 569 }
kenjiArai 0:5b88d5760320 570
kenjiArai 0:5b88d5760320 571 void TLSSocketWrapper::set_ssl_config(mbedtls_ssl_config *conf)
kenjiArai 0:5b88d5760320 572 {
kenjiArai 0:5b88d5760320 573 if (_ssl_conf && _ssl_conf_allocated) {
kenjiArai 0:5b88d5760320 574 mbedtls_ssl_config_free(_ssl_conf);
kenjiArai 0:5b88d5760320 575 delete _ssl_conf;
kenjiArai 0:5b88d5760320 576 _ssl_conf_allocated = false;
kenjiArai 0:5b88d5760320 577 }
kenjiArai 0:5b88d5760320 578 _ssl_conf = conf;
kenjiArai 0:5b88d5760320 579 }
kenjiArai 0:5b88d5760320 580
kenjiArai 0:5b88d5760320 581 mbedtls_ssl_context *TLSSocketWrapper::get_ssl_context()
kenjiArai 0:5b88d5760320 582 {
kenjiArai 0:5b88d5760320 583 return &_ssl;
kenjiArai 0:5b88d5760320 584 }
kenjiArai 0:5b88d5760320 585
kenjiArai 0:5b88d5760320 586 nsapi_error_t TLSSocketWrapper::close()
kenjiArai 0:5b88d5760320 587 {
kenjiArai 0:5b88d5760320 588 if (!_transport) {
kenjiArai 0:5b88d5760320 589 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 590 }
kenjiArai 0:5b88d5760320 591
kenjiArai 0:5b88d5760320 592 tr_info("Closing TLS");
kenjiArai 0:5b88d5760320 593
kenjiArai 0:5b88d5760320 594 int ret = 0;
kenjiArai 0:5b88d5760320 595 if (_handshake_completed) {
kenjiArai 0:5b88d5760320 596 _transport->set_blocking(true);
kenjiArai 0:5b88d5760320 597 ret = mbedtls_ssl_close_notify(&_ssl);
kenjiArai 0:5b88d5760320 598 if (ret) {
kenjiArai 0:5b88d5760320 599 print_mbedtls_error("mbedtls_ssl_close_notify", ret);
kenjiArai 0:5b88d5760320 600 }
kenjiArai 0:5b88d5760320 601 _handshake_completed = false;
kenjiArai 0:5b88d5760320 602 }
kenjiArai 0:5b88d5760320 603
kenjiArai 0:5b88d5760320 604 if (_close_transport) {
kenjiArai 0:5b88d5760320 605 int ret2 = _transport->close();
kenjiArai 0:5b88d5760320 606 if (!ret) {
kenjiArai 0:5b88d5760320 607 ret = ret2;
kenjiArai 0:5b88d5760320 608 }
kenjiArai 0:5b88d5760320 609 }
kenjiArai 0:5b88d5760320 610
kenjiArai 0:5b88d5760320 611 _transport = NULL;
kenjiArai 0:5b88d5760320 612
kenjiArai 0:5b88d5760320 613 return ret;
kenjiArai 0:5b88d5760320 614 }
kenjiArai 0:5b88d5760320 615
kenjiArai 0:5b88d5760320 616 nsapi_error_t TLSSocketWrapper::connect(const SocketAddress &address)
kenjiArai 0:5b88d5760320 617 {
kenjiArai 0:5b88d5760320 618 nsapi_error_t ret = NSAPI_ERROR_OK;
kenjiArai 0:5b88d5760320 619 if (!_transport) {
kenjiArai 0:5b88d5760320 620 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 621 }
kenjiArai 0:5b88d5760320 622
kenjiArai 0:5b88d5760320 623 if (!is_handshake_started() && _connect_transport) {
kenjiArai 0:5b88d5760320 624 ret = _transport->connect(address);
kenjiArai 0:5b88d5760320 625 if (ret && ret != NSAPI_ERROR_IS_CONNECTED) {
kenjiArai 0:5b88d5760320 626 return ret;
kenjiArai 0:5b88d5760320 627 }
kenjiArai 0:5b88d5760320 628 }
kenjiArai 0:5b88d5760320 629 return start_handshake(ret == NSAPI_ERROR_OK);
kenjiArai 0:5b88d5760320 630 }
kenjiArai 0:5b88d5760320 631
kenjiArai 0:5b88d5760320 632 nsapi_error_t TLSSocketWrapper::bind(const SocketAddress &address)
kenjiArai 0:5b88d5760320 633 {
kenjiArai 0:5b88d5760320 634 if (!_transport) {
kenjiArai 0:5b88d5760320 635 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 636 }
kenjiArai 0:5b88d5760320 637 return _transport->bind(address);
kenjiArai 0:5b88d5760320 638 }
kenjiArai 0:5b88d5760320 639
kenjiArai 0:5b88d5760320 640 void TLSSocketWrapper::set_blocking(bool blocking)
kenjiArai 0:5b88d5760320 641 {
kenjiArai 0:5b88d5760320 642 set_timeout(blocking ? -1 : 0);
kenjiArai 0:5b88d5760320 643 }
kenjiArai 0:5b88d5760320 644
kenjiArai 0:5b88d5760320 645 void TLSSocketWrapper::set_timeout(int timeout)
kenjiArai 0:5b88d5760320 646 {
kenjiArai 0:5b88d5760320 647 _timeout = timeout;
kenjiArai 0:5b88d5760320 648 if (!is_handshake_started() && timeout != -1 && _connect_transport) {
kenjiArai 0:5b88d5760320 649 // If we have not yet connected the transport, we need to modify its blocking mode as well.
kenjiArai 0:5b88d5760320 650 // After connection is initiated, it is already set to non blocking mode
kenjiArai 0:5b88d5760320 651 _transport->set_timeout(timeout);
kenjiArai 0:5b88d5760320 652 }
kenjiArai 0:5b88d5760320 653 }
kenjiArai 0:5b88d5760320 654
kenjiArai 0:5b88d5760320 655 void TLSSocketWrapper::sigio(mbed::Callback<void()> func)
kenjiArai 0:5b88d5760320 656 {
kenjiArai 0:5b88d5760320 657 if (!_transport) {
kenjiArai 0:5b88d5760320 658 return;
kenjiArai 0:5b88d5760320 659 }
kenjiArai 0:5b88d5760320 660 _sigio = func;
kenjiArai 0:5b88d5760320 661 _transport->sigio(mbed::callback(this, &TLSSocketWrapper::event));
kenjiArai 0:5b88d5760320 662 }
kenjiArai 0:5b88d5760320 663
kenjiArai 0:5b88d5760320 664 nsapi_error_t TLSSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
kenjiArai 0:5b88d5760320 665 {
kenjiArai 0:5b88d5760320 666 if (!_transport) {
kenjiArai 0:5b88d5760320 667 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 668 }
kenjiArai 0:5b88d5760320 669 return _transport->setsockopt(level, optname, optval, optlen);
kenjiArai 0:5b88d5760320 670 }
kenjiArai 0:5b88d5760320 671
kenjiArai 0:5b88d5760320 672 nsapi_error_t TLSSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen)
kenjiArai 0:5b88d5760320 673 {
kenjiArai 0:5b88d5760320 674 if (!_transport) {
kenjiArai 0:5b88d5760320 675 return NSAPI_ERROR_NO_SOCKET;
kenjiArai 0:5b88d5760320 676 }
kenjiArai 0:5b88d5760320 677 return _transport->getsockopt(level, optname, optval, optlen);
kenjiArai 0:5b88d5760320 678 }
kenjiArai 0:5b88d5760320 679
kenjiArai 0:5b88d5760320 680 Socket *TLSSocketWrapper::accept(nsapi_error_t *err)
kenjiArai 0:5b88d5760320 681 {
kenjiArai 0:5b88d5760320 682 if (err) {
kenjiArai 0:5b88d5760320 683 *err = NSAPI_ERROR_UNSUPPORTED;
kenjiArai 0:5b88d5760320 684 }
kenjiArai 0:5b88d5760320 685 return NULL;
kenjiArai 0:5b88d5760320 686 }
kenjiArai 0:5b88d5760320 687
kenjiArai 0:5b88d5760320 688 nsapi_error_t TLSSocketWrapper::listen(int)
kenjiArai 0:5b88d5760320 689 {
kenjiArai 0:5b88d5760320 690 return NSAPI_ERROR_UNSUPPORTED;
kenjiArai 0:5b88d5760320 691 }
kenjiArai 0:5b88d5760320 692
kenjiArai 0:5b88d5760320 693 void TLSSocketWrapper::event()
kenjiArai 0:5b88d5760320 694 {
kenjiArai 0:5b88d5760320 695 _event_flag.set(1);
kenjiArai 0:5b88d5760320 696 if (_sigio) {
kenjiArai 0:5b88d5760320 697 _sigio();
kenjiArai 0:5b88d5760320 698 }
kenjiArai 0:5b88d5760320 699 }
kenjiArai 0:5b88d5760320 700
kenjiArai 0:5b88d5760320 701 bool TLSSocketWrapper::is_handshake_started() const
kenjiArai 0:5b88d5760320 702 {
kenjiArai 0:5b88d5760320 703 return _tls_initialized;
kenjiArai 0:5b88d5760320 704 }
kenjiArai 0:5b88d5760320 705
kenjiArai 0:5b88d5760320 706
kenjiArai 0:5b88d5760320 707 nsapi_error_t TLSSocketWrapper::getpeername(SocketAddress *address)
kenjiArai 0:5b88d5760320 708 {
kenjiArai 0:5b88d5760320 709 if (!_handshake_completed) {
kenjiArai 0:5b88d5760320 710 return NSAPI_ERROR_NO_CONNECTION;
kenjiArai 0:5b88d5760320 711 }
kenjiArai 0:5b88d5760320 712 return _transport->getpeername(address);
kenjiArai 0:5b88d5760320 713 }
kenjiArai 0:5b88d5760320 714
kenjiArai 0:5b88d5760320 715 #endif /* MBEDTLS_SSL_CLI_C */