Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
XinZhangMS 0:f7f1f0d76dd6 1 // Copyright (c) Microsoft. All rights reserved.
XinZhangMS 0:f7f1f0d76dd6 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
XinZhangMS 0:f7f1f0d76dd6 3 #include "azure_c_shared_utility/tlsio_mbedtls.h"
XinZhangMS 0:f7f1f0d76dd6 4
XinZhangMS 0:f7f1f0d76dd6 5 // DEPRECATED: the USE_MBED_TLS #define is deprecated.
XinZhangMS 0:f7f1f0d76dd6 6 #ifdef USE_MBED_TLS
XinZhangMS 0:f7f1f0d76dd6 7
XinZhangMS 0:f7f1f0d76dd6 8 #include <stdlib.h>
XinZhangMS 0:f7f1f0d76dd6 9
XinZhangMS 0:f7f1f0d76dd6 10 #ifdef TIZENRT
XinZhangMS 0:f7f1f0d76dd6 11 #include "tls/config.h"
XinZhangMS 0:f7f1f0d76dd6 12 #include "tls/debug.h"
XinZhangMS 0:f7f1f0d76dd6 13 #include "tls/ssl.h"
XinZhangMS 0:f7f1f0d76dd6 14 #include "tls/entropy.h"
XinZhangMS 0:f7f1f0d76dd6 15 #include "tls/ctr_drbg.h"
XinZhangMS 0:f7f1f0d76dd6 16 #include "tls/error.h"
XinZhangMS 0:f7f1f0d76dd6 17 #include "tls/certs.h"
XinZhangMS 0:f7f1f0d76dd6 18 #include "tls/entropy_poll.h"
XinZhangMS 0:f7f1f0d76dd6 19 #else
XinZhangMS 0:f7f1f0d76dd6 20 #include "mbedtls/config.h"
XinZhangMS 0:f7f1f0d76dd6 21 #include "mbedtls/debug.h"
XinZhangMS 0:f7f1f0d76dd6 22 #include "mbedtls/ssl.h"
XinZhangMS 0:f7f1f0d76dd6 23 #include "mbedtls/entropy.h"
XinZhangMS 0:f7f1f0d76dd6 24 #include "mbedtls/ctr_drbg.h"
XinZhangMS 0:f7f1f0d76dd6 25 #include "mbedtls/error.h"
XinZhangMS 0:f7f1f0d76dd6 26 #include "mbedtls/certs.h"
XinZhangMS 0:f7f1f0d76dd6 27 #include "mbedtls/entropy_poll.h"
XinZhangMS 0:f7f1f0d76dd6 28 #endif
XinZhangMS 0:f7f1f0d76dd6 29
XinZhangMS 0:f7f1f0d76dd6 30 #include <stdio.h>
XinZhangMS 0:f7f1f0d76dd6 31 #include <stdbool.h>
XinZhangMS 0:f7f1f0d76dd6 32 #include <string.h>
XinZhangMS 0:f7f1f0d76dd6 33 #include "azure_c_shared_utility/optimize_size.h"
XinZhangMS 0:f7f1f0d76dd6 34 #include "azure_c_shared_utility/tlsio.h"
XinZhangMS 0:f7f1f0d76dd6 35 #include "azure_c_shared_utility/tlsio_mbedtls.h"
XinZhangMS 0:f7f1f0d76dd6 36 #include "azure_c_shared_utility/socketio.h"
XinZhangMS 0:f7f1f0d76dd6 37 #include "azure_c_shared_utility/crt_abstractions.h"
XinZhangMS 0:f7f1f0d76dd6 38 #include "azure_c_shared_utility/shared_util_options.h"
XinZhangMS 0:f7f1f0d76dd6 39
XinZhangMS 0:f7f1f0d76dd6 40 #define OPTION_UNDERLYING_IO_OPTIONS "underlying_io_options"
XinZhangMS 0:f7f1f0d76dd6 41
XinZhangMS 0:f7f1f0d76dd6 42 // DEPRECATED: debug functions do not belong in the tree.
XinZhangMS 0:f7f1f0d76dd6 43 #define MBED_TLS_DEBUG_ENABLE
XinZhangMS 0:f7f1f0d76dd6 44
XinZhangMS 0:f7f1f0d76dd6 45 typedef enum TLSIO_STATE_ENUM_TAG
XinZhangMS 0:f7f1f0d76dd6 46 {
XinZhangMS 0:f7f1f0d76dd6 47 TLSIO_STATE_NOT_OPEN,
XinZhangMS 0:f7f1f0d76dd6 48 TLSIO_STATE_OPENING_UNDERLYING_IO,
XinZhangMS 0:f7f1f0d76dd6 49 TLSIO_STATE_IN_HANDSHAKE,
XinZhangMS 0:f7f1f0d76dd6 50 TLSIO_STATE_OPEN,
XinZhangMS 0:f7f1f0d76dd6 51 TLSIO_STATE_CLOSING,
XinZhangMS 0:f7f1f0d76dd6 52 TLSIO_STATE_ERROR
XinZhangMS 0:f7f1f0d76dd6 53 } TLSIO_STATE_ENUM;
XinZhangMS 0:f7f1f0d76dd6 54
XinZhangMS 0:f7f1f0d76dd6 55 typedef struct TLS_IO_INSTANCE_TAG
XinZhangMS 0:f7f1f0d76dd6 56 {
XinZhangMS 0:f7f1f0d76dd6 57 XIO_HANDLE socket_io;
XinZhangMS 0:f7f1f0d76dd6 58 ON_BYTES_RECEIVED on_bytes_received;
XinZhangMS 0:f7f1f0d76dd6 59 ON_IO_OPEN_COMPLETE on_io_open_complete;
XinZhangMS 0:f7f1f0d76dd6 60 ON_IO_CLOSE_COMPLETE on_io_close_complete;
XinZhangMS 0:f7f1f0d76dd6 61 ON_IO_ERROR on_io_error;
XinZhangMS 0:f7f1f0d76dd6 62 void* on_bytes_received_context;
XinZhangMS 0:f7f1f0d76dd6 63 void* on_io_open_complete_context;
XinZhangMS 0:f7f1f0d76dd6 64 void* on_io_close_complete_context;
XinZhangMS 0:f7f1f0d76dd6 65 void* on_io_error_context;
XinZhangMS 0:f7f1f0d76dd6 66 TLSIO_STATE_ENUM tlsio_state;
XinZhangMS 0:f7f1f0d76dd6 67 unsigned char* socket_io_read_bytes;
XinZhangMS 0:f7f1f0d76dd6 68 size_t socket_io_read_byte_count;
XinZhangMS 0:f7f1f0d76dd6 69 ON_SEND_COMPLETE on_send_complete;
XinZhangMS 0:f7f1f0d76dd6 70 void* on_send_complete_callback_context;
XinZhangMS 0:f7f1f0d76dd6 71 mbedtls_entropy_context entropy;
XinZhangMS 0:f7f1f0d76dd6 72 mbedtls_ctr_drbg_context ctr_drbg;
XinZhangMS 0:f7f1f0d76dd6 73 mbedtls_ssl_context ssl;
XinZhangMS 0:f7f1f0d76dd6 74 mbedtls_ssl_config config;
XinZhangMS 0:f7f1f0d76dd6 75 mbedtls_x509_crt trusted_certificates_parsed;
XinZhangMS 0:f7f1f0d76dd6 76 mbedtls_ssl_session ssn;
XinZhangMS 0:f7f1f0d76dd6 77 char* trusted_certificates;
XinZhangMS 0:f7f1f0d76dd6 78 } TLS_IO_INSTANCE;
XinZhangMS 0:f7f1f0d76dd6 79
XinZhangMS 0:f7f1f0d76dd6 80 static const IO_INTERFACE_DESCRIPTION tlsio_mbedtls_interface_description =
XinZhangMS 0:f7f1f0d76dd6 81 {
XinZhangMS 0:f7f1f0d76dd6 82 tlsio_mbedtls_retrieveoptions,
XinZhangMS 0:f7f1f0d76dd6 83 tlsio_mbedtls_create,
XinZhangMS 0:f7f1f0d76dd6 84 tlsio_mbedtls_destroy,
XinZhangMS 0:f7f1f0d76dd6 85 tlsio_mbedtls_open,
XinZhangMS 0:f7f1f0d76dd6 86 tlsio_mbedtls_close,
XinZhangMS 0:f7f1f0d76dd6 87 tlsio_mbedtls_send,
XinZhangMS 0:f7f1f0d76dd6 88 tlsio_mbedtls_dowork,
XinZhangMS 0:f7f1f0d76dd6 89 tlsio_mbedtls_setoption
XinZhangMS 0:f7f1f0d76dd6 90 };
XinZhangMS 0:f7f1f0d76dd6 91
XinZhangMS 0:f7f1f0d76dd6 92 // DEPRECATED: debug functions do not belong in the tree.
XinZhangMS 0:f7f1f0d76dd6 93 #if defined (MBED_TLS_DEBUG_ENABLE)
XinZhangMS 0:f7f1f0d76dd6 94 void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str)
XinZhangMS 0:f7f1f0d76dd6 95 {
XinZhangMS 0:f7f1f0d76dd6 96 ((void)level);
XinZhangMS 0:f7f1f0d76dd6 97 printf("%s (%d): %s\r\n", file, line, str);
XinZhangMS 0:f7f1f0d76dd6 98 }
XinZhangMS 0:f7f1f0d76dd6 99 #endif
XinZhangMS 0:f7f1f0d76dd6 100
XinZhangMS 0:f7f1f0d76dd6 101 static void indicate_error(TLS_IO_INSTANCE* tls_io_instance)
XinZhangMS 0:f7f1f0d76dd6 102 {
XinZhangMS 0:f7f1f0d76dd6 103 if (tls_io_instance->on_io_error != NULL)
XinZhangMS 0:f7f1f0d76dd6 104 {
XinZhangMS 0:f7f1f0d76dd6 105 tls_io_instance->on_io_error(tls_io_instance->on_io_error_context);
XinZhangMS 0:f7f1f0d76dd6 106 }
XinZhangMS 0:f7f1f0d76dd6 107 }
XinZhangMS 0:f7f1f0d76dd6 108
XinZhangMS 0:f7f1f0d76dd6 109 static void indicate_open_complete(TLS_IO_INSTANCE* tls_io_instance, IO_OPEN_RESULT open_result)
XinZhangMS 0:f7f1f0d76dd6 110 {
XinZhangMS 0:f7f1f0d76dd6 111 if (tls_io_instance->on_io_open_complete != NULL)
XinZhangMS 0:f7f1f0d76dd6 112 {
XinZhangMS 0:f7f1f0d76dd6 113 tls_io_instance->on_io_open_complete(tls_io_instance->on_io_open_complete_context, open_result);
XinZhangMS 0:f7f1f0d76dd6 114 }
XinZhangMS 0:f7f1f0d76dd6 115 }
XinZhangMS 0:f7f1f0d76dd6 116
XinZhangMS 0:f7f1f0d76dd6 117 static int decode_ssl_received_bytes(TLS_IO_INSTANCE* tls_io_instance)
XinZhangMS 0:f7f1f0d76dd6 118 {
XinZhangMS 0:f7f1f0d76dd6 119 int result = 0;
XinZhangMS 0:f7f1f0d76dd6 120 unsigned char buffer[64];
XinZhangMS 0:f7f1f0d76dd6 121 int rcv_bytes = 1;
XinZhangMS 0:f7f1f0d76dd6 122
XinZhangMS 0:f7f1f0d76dd6 123 while (rcv_bytes > 0)
XinZhangMS 0:f7f1f0d76dd6 124 {
XinZhangMS 0:f7f1f0d76dd6 125 rcv_bytes = mbedtls_ssl_read(&tls_io_instance->ssl, buffer, sizeof(buffer));
XinZhangMS 0:f7f1f0d76dd6 126 if (rcv_bytes > 0)
XinZhangMS 0:f7f1f0d76dd6 127 {
XinZhangMS 0:f7f1f0d76dd6 128 if (tls_io_instance->on_bytes_received != NULL)
XinZhangMS 0:f7f1f0d76dd6 129 {
XinZhangMS 0:f7f1f0d76dd6 130 tls_io_instance->on_bytes_received(tls_io_instance->on_bytes_received_context, buffer, rcv_bytes);
XinZhangMS 0:f7f1f0d76dd6 131 }
XinZhangMS 0:f7f1f0d76dd6 132 }
XinZhangMS 0:f7f1f0d76dd6 133 }
XinZhangMS 0:f7f1f0d76dd6 134
XinZhangMS 0:f7f1f0d76dd6 135 return result;
XinZhangMS 0:f7f1f0d76dd6 136 }
XinZhangMS 0:f7f1f0d76dd6 137
XinZhangMS 0:f7f1f0d76dd6 138 static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result)
XinZhangMS 0:f7f1f0d76dd6 139 {
XinZhangMS 0:f7f1f0d76dd6 140 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
XinZhangMS 0:f7f1f0d76dd6 141 int result = 0;
XinZhangMS 0:f7f1f0d76dd6 142
XinZhangMS 0:f7f1f0d76dd6 143 if (open_result != IO_OPEN_OK)
XinZhangMS 0:f7f1f0d76dd6 144 {
XinZhangMS 0:f7f1f0d76dd6 145 xio_close(tls_io_instance->socket_io, NULL, NULL);
XinZhangMS 0:f7f1f0d76dd6 146 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
XinZhangMS 0:f7f1f0d76dd6 147 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
XinZhangMS 0:f7f1f0d76dd6 148 }
XinZhangMS 0:f7f1f0d76dd6 149 else
XinZhangMS 0:f7f1f0d76dd6 150 {
XinZhangMS 0:f7f1f0d76dd6 151 tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE;
XinZhangMS 0:f7f1f0d76dd6 152
XinZhangMS 0:f7f1f0d76dd6 153 do {
XinZhangMS 0:f7f1f0d76dd6 154 result = mbedtls_ssl_handshake(&tls_io_instance->ssl);
XinZhangMS 0:f7f1f0d76dd6 155 } while (result == MBEDTLS_ERR_SSL_WANT_READ || result == MBEDTLS_ERR_SSL_WANT_WRITE);
XinZhangMS 0:f7f1f0d76dd6 156
XinZhangMS 0:f7f1f0d76dd6 157 if (result == 0)
XinZhangMS 0:f7f1f0d76dd6 158 {
XinZhangMS 0:f7f1f0d76dd6 159 tls_io_instance->tlsio_state = TLSIO_STATE_OPEN;
XinZhangMS 0:f7f1f0d76dd6 160 indicate_open_complete(tls_io_instance, IO_OPEN_OK);
XinZhangMS 0:f7f1f0d76dd6 161 }
XinZhangMS 0:f7f1f0d76dd6 162 else
XinZhangMS 0:f7f1f0d76dd6 163 {
XinZhangMS 0:f7f1f0d76dd6 164 xio_close(tls_io_instance->socket_io, NULL, NULL);
XinZhangMS 0:f7f1f0d76dd6 165 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
XinZhangMS 0:f7f1f0d76dd6 166 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
XinZhangMS 0:f7f1f0d76dd6 167 }
XinZhangMS 0:f7f1f0d76dd6 168 }
XinZhangMS 0:f7f1f0d76dd6 169 }
XinZhangMS 0:f7f1f0d76dd6 170
XinZhangMS 0:f7f1f0d76dd6 171 static void on_underlying_io_bytes_received(void* context, const unsigned char* buffer, size_t size)
XinZhangMS 0:f7f1f0d76dd6 172 {
XinZhangMS 0:f7f1f0d76dd6 173 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
XinZhangMS 0:f7f1f0d76dd6 174
XinZhangMS 0:f7f1f0d76dd6 175 unsigned char* new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count + size);
XinZhangMS 0:f7f1f0d76dd6 176
XinZhangMS 0:f7f1f0d76dd6 177 if (new_socket_io_read_bytes == NULL)
XinZhangMS 0:f7f1f0d76dd6 178 {
XinZhangMS 0:f7f1f0d76dd6 179 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
XinZhangMS 0:f7f1f0d76dd6 180 indicate_error(tls_io_instance);
XinZhangMS 0:f7f1f0d76dd6 181 }
XinZhangMS 0:f7f1f0d76dd6 182 else
XinZhangMS 0:f7f1f0d76dd6 183 {
XinZhangMS 0:f7f1f0d76dd6 184 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes;
XinZhangMS 0:f7f1f0d76dd6 185 (void)memcpy(tls_io_instance->socket_io_read_bytes + tls_io_instance->socket_io_read_byte_count, buffer, size);
XinZhangMS 0:f7f1f0d76dd6 186 tls_io_instance->socket_io_read_byte_count += size;
XinZhangMS 0:f7f1f0d76dd6 187 }
XinZhangMS 0:f7f1f0d76dd6 188 }
XinZhangMS 0:f7f1f0d76dd6 189
XinZhangMS 0:f7f1f0d76dd6 190 static void on_underlying_io_error(void* context)
XinZhangMS 0:f7f1f0d76dd6 191 {
XinZhangMS 0:f7f1f0d76dd6 192 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
XinZhangMS 0:f7f1f0d76dd6 193
XinZhangMS 0:f7f1f0d76dd6 194 switch (tls_io_instance->tlsio_state)
XinZhangMS 0:f7f1f0d76dd6 195 {
XinZhangMS 0:f7f1f0d76dd6 196 default:
XinZhangMS 0:f7f1f0d76dd6 197 case TLSIO_STATE_NOT_OPEN:
XinZhangMS 0:f7f1f0d76dd6 198 case TLSIO_STATE_ERROR:
XinZhangMS 0:f7f1f0d76dd6 199 break;
XinZhangMS 0:f7f1f0d76dd6 200
XinZhangMS 0:f7f1f0d76dd6 201 case TLSIO_STATE_OPENING_UNDERLYING_IO:
XinZhangMS 0:f7f1f0d76dd6 202 case TLSIO_STATE_IN_HANDSHAKE:
XinZhangMS 0:f7f1f0d76dd6 203 // Existing socket impls are all synchronous close, and this
XinZhangMS 0:f7f1f0d76dd6 204 // adapter does not yet support async close.
XinZhangMS 0:f7f1f0d76dd6 205 xio_close(tls_io_instance->socket_io, NULL, NULL);
XinZhangMS 0:f7f1f0d76dd6 206 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
XinZhangMS 0:f7f1f0d76dd6 207 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
XinZhangMS 0:f7f1f0d76dd6 208 break;
XinZhangMS 0:f7f1f0d76dd6 209
XinZhangMS 0:f7f1f0d76dd6 210 case TLSIO_STATE_OPEN:
XinZhangMS 0:f7f1f0d76dd6 211 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
XinZhangMS 0:f7f1f0d76dd6 212 indicate_error(tls_io_instance);
XinZhangMS 0:f7f1f0d76dd6 213 break;
XinZhangMS 0:f7f1f0d76dd6 214 }
XinZhangMS 0:f7f1f0d76dd6 215 }
XinZhangMS 0:f7f1f0d76dd6 216
XinZhangMS 0:f7f1f0d76dd6 217 static void on_underlying_io_close_complete_during_close(void* context)
XinZhangMS 0:f7f1f0d76dd6 218 {
XinZhangMS 0:f7f1f0d76dd6 219 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
XinZhangMS 0:f7f1f0d76dd6 220
XinZhangMS 0:f7f1f0d76dd6 221 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
XinZhangMS 0:f7f1f0d76dd6 222
XinZhangMS 0:f7f1f0d76dd6 223 if (tls_io_instance->on_io_close_complete != NULL)
XinZhangMS 0:f7f1f0d76dd6 224 {
XinZhangMS 0:f7f1f0d76dd6 225 tls_io_instance->on_io_close_complete(tls_io_instance->on_io_close_complete_context);
XinZhangMS 0:f7f1f0d76dd6 226 }
XinZhangMS 0:f7f1f0d76dd6 227 }
XinZhangMS 0:f7f1f0d76dd6 228
XinZhangMS 0:f7f1f0d76dd6 229 static int on_io_recv(void *context, unsigned char *buf, size_t sz)
XinZhangMS 0:f7f1f0d76dd6 230 {
XinZhangMS 0:f7f1f0d76dd6 231 int result;
XinZhangMS 0:f7f1f0d76dd6 232 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
XinZhangMS 0:f7f1f0d76dd6 233 unsigned char* new_socket_io_read_bytes;
XinZhangMS 0:f7f1f0d76dd6 234
XinZhangMS 0:f7f1f0d76dd6 235 while (tls_io_instance->socket_io_read_byte_count == 0)
XinZhangMS 0:f7f1f0d76dd6 236 {
XinZhangMS 0:f7f1f0d76dd6 237 xio_dowork(tls_io_instance->socket_io);
XinZhangMS 0:f7f1f0d76dd6 238 if (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN)
XinZhangMS 0:f7f1f0d76dd6 239 {
XinZhangMS 0:f7f1f0d76dd6 240 break;
XinZhangMS 0:f7f1f0d76dd6 241 }
XinZhangMS 0:f7f1f0d76dd6 242 }
XinZhangMS 0:f7f1f0d76dd6 243
XinZhangMS 0:f7f1f0d76dd6 244 result = tls_io_instance->socket_io_read_byte_count;
XinZhangMS 0:f7f1f0d76dd6 245 if (result > sz)
XinZhangMS 0:f7f1f0d76dd6 246 {
XinZhangMS 0:f7f1f0d76dd6 247 result = sz;
XinZhangMS 0:f7f1f0d76dd6 248 }
XinZhangMS 0:f7f1f0d76dd6 249
XinZhangMS 0:f7f1f0d76dd6 250 if (result > 0)
XinZhangMS 0:f7f1f0d76dd6 251 {
XinZhangMS 0:f7f1f0d76dd6 252 (void)memcpy((void *)buf, tls_io_instance->socket_io_read_bytes, result);
XinZhangMS 0:f7f1f0d76dd6 253 (void)memmove(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_bytes + result, tls_io_instance->socket_io_read_byte_count - result);
XinZhangMS 0:f7f1f0d76dd6 254 tls_io_instance->socket_io_read_byte_count -= result;
XinZhangMS 0:f7f1f0d76dd6 255 if (tls_io_instance->socket_io_read_byte_count > 0)
XinZhangMS 0:f7f1f0d76dd6 256 {
XinZhangMS 0:f7f1f0d76dd6 257 new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count);
XinZhangMS 0:f7f1f0d76dd6 258 if (new_socket_io_read_bytes != NULL)
XinZhangMS 0:f7f1f0d76dd6 259 {
XinZhangMS 0:f7f1f0d76dd6 260 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes;
XinZhangMS 0:f7f1f0d76dd6 261 }
XinZhangMS 0:f7f1f0d76dd6 262 }
XinZhangMS 0:f7f1f0d76dd6 263 else
XinZhangMS 0:f7f1f0d76dd6 264 {
XinZhangMS 0:f7f1f0d76dd6 265 free(tls_io_instance->socket_io_read_bytes);
XinZhangMS 0:f7f1f0d76dd6 266 tls_io_instance->socket_io_read_bytes = NULL;
XinZhangMS 0:f7f1f0d76dd6 267 }
XinZhangMS 0:f7f1f0d76dd6 268 }
XinZhangMS 0:f7f1f0d76dd6 269
XinZhangMS 0:f7f1f0d76dd6 270
XinZhangMS 0:f7f1f0d76dd6 271 if ((result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN))
XinZhangMS 0:f7f1f0d76dd6 272 {
XinZhangMS 0:f7f1f0d76dd6 273 result = MBEDTLS_ERR_SSL_WANT_READ;
XinZhangMS 0:f7f1f0d76dd6 274 }
XinZhangMS 0:f7f1f0d76dd6 275
XinZhangMS 0:f7f1f0d76dd6 276 return result;
XinZhangMS 0:f7f1f0d76dd6 277 }
XinZhangMS 0:f7f1f0d76dd6 278
XinZhangMS 0:f7f1f0d76dd6 279 static int on_io_send(void *context, const unsigned char *buf, size_t sz)
XinZhangMS 0:f7f1f0d76dd6 280 {
XinZhangMS 0:f7f1f0d76dd6 281 int result;
XinZhangMS 0:f7f1f0d76dd6 282 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
XinZhangMS 0:f7f1f0d76dd6 283
XinZhangMS 0:f7f1f0d76dd6 284 if (xio_send(tls_io_instance->socket_io, buf, sz, tls_io_instance->on_send_complete, tls_io_instance->on_send_complete_callback_context) != 0)
XinZhangMS 0:f7f1f0d76dd6 285 {
XinZhangMS 0:f7f1f0d76dd6 286 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
XinZhangMS 0:f7f1f0d76dd6 287 indicate_error(tls_io_instance);
XinZhangMS 0:f7f1f0d76dd6 288 result = 0;
XinZhangMS 0:f7f1f0d76dd6 289 }
XinZhangMS 0:f7f1f0d76dd6 290 else
XinZhangMS 0:f7f1f0d76dd6 291 {
XinZhangMS 0:f7f1f0d76dd6 292 result = sz;
XinZhangMS 0:f7f1f0d76dd6 293 }
XinZhangMS 0:f7f1f0d76dd6 294
XinZhangMS 0:f7f1f0d76dd6 295 return result;
XinZhangMS 0:f7f1f0d76dd6 296 }
XinZhangMS 0:f7f1f0d76dd6 297
XinZhangMS 0:f7f1f0d76dd6 298 static int tlsio_entropy_poll(void *v, unsigned char *output, size_t len, size_t *olen)
XinZhangMS 0:f7f1f0d76dd6 299 {
XinZhangMS 0:f7f1f0d76dd6 300 srand(time(NULL));
XinZhangMS 0:f7f1f0d76dd6 301 char *c = (char*)malloc(len);
XinZhangMS 0:f7f1f0d76dd6 302 memset(c, 0, len);
XinZhangMS 0:f7f1f0d76dd6 303 for (uint16_t i = 0; i < len; i++) {
XinZhangMS 0:f7f1f0d76dd6 304 c[i] = rand() % 256;
XinZhangMS 0:f7f1f0d76dd6 305 }
XinZhangMS 0:f7f1f0d76dd6 306 memmove(output, c, len);
XinZhangMS 0:f7f1f0d76dd6 307 *olen = len;
XinZhangMS 0:f7f1f0d76dd6 308
XinZhangMS 0:f7f1f0d76dd6 309 free(c);
XinZhangMS 0:f7f1f0d76dd6 310 return(0);
XinZhangMS 0:f7f1f0d76dd6 311 }
XinZhangMS 0:f7f1f0d76dd6 312
XinZhangMS 0:f7f1f0d76dd6 313 static void mbedtls_init(void *instance, const char *host) {
XinZhangMS 0:f7f1f0d76dd6 314 TLS_IO_INSTANCE *result = (TLS_IO_INSTANCE *)instance;
XinZhangMS 0:f7f1f0d76dd6 315 char *pers = "azure_iot_client";
XinZhangMS 0:f7f1f0d76dd6 316
XinZhangMS 0:f7f1f0d76dd6 317 // mbedTLS initialize...
XinZhangMS 0:f7f1f0d76dd6 318 mbedtls_entropy_init(&result->entropy);
XinZhangMS 0:f7f1f0d76dd6 319 mbedtls_ctr_drbg_init(&result->ctr_drbg);
XinZhangMS 0:f7f1f0d76dd6 320 mbedtls_ssl_init(&result->ssl);
XinZhangMS 0:f7f1f0d76dd6 321 mbedtls_ssl_session_init(&result->ssn);
XinZhangMS 0:f7f1f0d76dd6 322 mbedtls_ssl_config_init(&result->config);
XinZhangMS 0:f7f1f0d76dd6 323 mbedtls_x509_crt_init(&result->trusted_certificates_parsed);
XinZhangMS 0:f7f1f0d76dd6 324 mbedtls_entropy_add_source(&result->entropy, tlsio_entropy_poll, NULL, 128, 0);
XinZhangMS 0:f7f1f0d76dd6 325 mbedtls_ctr_drbg_seed(&result->ctr_drbg, mbedtls_entropy_func, &result->entropy, (const unsigned char *)pers, strlen(pers));
XinZhangMS 0:f7f1f0d76dd6 326 mbedtls_ssl_config_defaults(&result->config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
XinZhangMS 0:f7f1f0d76dd6 327 mbedtls_ssl_conf_rng(&result->config, mbedtls_ctr_drbg_random, &result->ctr_drbg);
XinZhangMS 0:f7f1f0d76dd6 328 mbedtls_ssl_conf_authmode(&result->config, MBEDTLS_SSL_VERIFY_REQUIRED);
XinZhangMS 0:f7f1f0d76dd6 329 mbedtls_ssl_conf_min_version(&result->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); // v1.2
XinZhangMS 0:f7f1f0d76dd6 330 mbedtls_ssl_set_bio(&result->ssl, instance, on_io_send, on_io_recv, NULL);
XinZhangMS 0:f7f1f0d76dd6 331 mbedtls_ssl_set_hostname(&result->ssl, host);
XinZhangMS 0:f7f1f0d76dd6 332 mbedtls_ssl_set_session(&result->ssl, &result->ssn);
XinZhangMS 0:f7f1f0d76dd6 333
XinZhangMS 0:f7f1f0d76dd6 334 // DEPRECATED: debug functions do not belong in the tree.
XinZhangMS 0:f7f1f0d76dd6 335 #if defined (MBED_TLS_DEBUG_ENABLE)
XinZhangMS 0:f7f1f0d76dd6 336 mbedtls_ssl_conf_dbg(&result->config, mbedtls_debug, stdout);
XinZhangMS 0:f7f1f0d76dd6 337 mbedtls_debug_set_threshold(1);
XinZhangMS 0:f7f1f0d76dd6 338 #endif
XinZhangMS 0:f7f1f0d76dd6 339
XinZhangMS 0:f7f1f0d76dd6 340 mbedtls_ssl_setup(&result->ssl, &result->config);
XinZhangMS 0:f7f1f0d76dd6 341 }
XinZhangMS 0:f7f1f0d76dd6 342
XinZhangMS 0:f7f1f0d76dd6 343 CONCRETE_IO_HANDLE tlsio_mbedtls_create(void* io_create_parameters)
XinZhangMS 0:f7f1f0d76dd6 344 {
XinZhangMS 0:f7f1f0d76dd6 345 TLSIO_CONFIG* tls_io_config = io_create_parameters;
XinZhangMS 0:f7f1f0d76dd6 346 TLS_IO_INSTANCE* result;
XinZhangMS 0:f7f1f0d76dd6 347
XinZhangMS 0:f7f1f0d76dd6 348 if (tls_io_config == NULL)
XinZhangMS 0:f7f1f0d76dd6 349 {
XinZhangMS 0:f7f1f0d76dd6 350 LogError("NULL tls_io_config");
XinZhangMS 0:f7f1f0d76dd6 351 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 352 }
XinZhangMS 0:f7f1f0d76dd6 353 else
XinZhangMS 0:f7f1f0d76dd6 354 {
XinZhangMS 0:f7f1f0d76dd6 355 result = malloc(sizeof(TLS_IO_INSTANCE));
XinZhangMS 0:f7f1f0d76dd6 356 if (result != NULL)
XinZhangMS 0:f7f1f0d76dd6 357 {
XinZhangMS 0:f7f1f0d76dd6 358 SOCKETIO_CONFIG socketio_config;
XinZhangMS 0:f7f1f0d76dd6 359 const IO_INTERFACE_DESCRIPTION* underlying_io_interface;
XinZhangMS 0:f7f1f0d76dd6 360 void* io_interface_parameters;
XinZhangMS 0:f7f1f0d76dd6 361
XinZhangMS 0:f7f1f0d76dd6 362 if (tls_io_config->underlying_io_interface != NULL)
XinZhangMS 0:f7f1f0d76dd6 363 {
XinZhangMS 0:f7f1f0d76dd6 364 underlying_io_interface = tls_io_config->underlying_io_interface;
XinZhangMS 0:f7f1f0d76dd6 365 io_interface_parameters = tls_io_config->underlying_io_parameters;
XinZhangMS 0:f7f1f0d76dd6 366 }
XinZhangMS 0:f7f1f0d76dd6 367 else
XinZhangMS 0:f7f1f0d76dd6 368 {
XinZhangMS 0:f7f1f0d76dd6 369 socketio_config.hostname = tls_io_config->hostname;
XinZhangMS 0:f7f1f0d76dd6 370 socketio_config.port = tls_io_config->port;
XinZhangMS 0:f7f1f0d76dd6 371 socketio_config.accepted_socket = NULL;
XinZhangMS 0:f7f1f0d76dd6 372
XinZhangMS 0:f7f1f0d76dd6 373 underlying_io_interface = socketio_get_interface_description();
XinZhangMS 0:f7f1f0d76dd6 374 io_interface_parameters = &socketio_config;
XinZhangMS 0:f7f1f0d76dd6 375 }
XinZhangMS 0:f7f1f0d76dd6 376
XinZhangMS 0:f7f1f0d76dd6 377 if (underlying_io_interface == NULL)
XinZhangMS 0:f7f1f0d76dd6 378 {
XinZhangMS 0:f7f1f0d76dd6 379 free(result);
XinZhangMS 0:f7f1f0d76dd6 380 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 381 LogError("Failed getting socket IO interface description.");
XinZhangMS 0:f7f1f0d76dd6 382 }
XinZhangMS 0:f7f1f0d76dd6 383 else
XinZhangMS 0:f7f1f0d76dd6 384 {
XinZhangMS 0:f7f1f0d76dd6 385 result->on_bytes_received = NULL;
XinZhangMS 0:f7f1f0d76dd6 386 result->on_bytes_received_context = NULL;
XinZhangMS 0:f7f1f0d76dd6 387
XinZhangMS 0:f7f1f0d76dd6 388 result->on_io_open_complete = NULL;
XinZhangMS 0:f7f1f0d76dd6 389 result->on_io_open_complete_context = NULL;
XinZhangMS 0:f7f1f0d76dd6 390
XinZhangMS 0:f7f1f0d76dd6 391 result->on_io_close_complete = NULL;
XinZhangMS 0:f7f1f0d76dd6 392 result->on_io_close_complete_context = NULL;
XinZhangMS 0:f7f1f0d76dd6 393
XinZhangMS 0:f7f1f0d76dd6 394 result->on_io_error = NULL;
XinZhangMS 0:f7f1f0d76dd6 395 result->on_io_error_context = NULL;
XinZhangMS 0:f7f1f0d76dd6 396
XinZhangMS 0:f7f1f0d76dd6 397 result->trusted_certificates = NULL;
XinZhangMS 0:f7f1f0d76dd6 398
XinZhangMS 0:f7f1f0d76dd6 399 result->socket_io = xio_create(underlying_io_interface, io_interface_parameters);
XinZhangMS 0:f7f1f0d76dd6 400 if (result->socket_io == NULL)
XinZhangMS 0:f7f1f0d76dd6 401 {
XinZhangMS 0:f7f1f0d76dd6 402 LogError("socket xio create failed");
XinZhangMS 0:f7f1f0d76dd6 403 free(result);
XinZhangMS 0:f7f1f0d76dd6 404 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 405 }
XinZhangMS 0:f7f1f0d76dd6 406 else
XinZhangMS 0:f7f1f0d76dd6 407 {
XinZhangMS 0:f7f1f0d76dd6 408 result->socket_io_read_bytes = NULL;
XinZhangMS 0:f7f1f0d76dd6 409 result->socket_io_read_byte_count = 0;
XinZhangMS 0:f7f1f0d76dd6 410 result->on_send_complete = NULL;
XinZhangMS 0:f7f1f0d76dd6 411 result->on_send_complete_callback_context = NULL;
XinZhangMS 0:f7f1f0d76dd6 412
XinZhangMS 0:f7f1f0d76dd6 413 // mbeTLS initialize
XinZhangMS 0:f7f1f0d76dd6 414 mbedtls_init((void *)result, tls_io_config->hostname);
XinZhangMS 0:f7f1f0d76dd6 415 result->tlsio_state = TLSIO_STATE_NOT_OPEN;
XinZhangMS 0:f7f1f0d76dd6 416 }
XinZhangMS 0:f7f1f0d76dd6 417 }
XinZhangMS 0:f7f1f0d76dd6 418 }
XinZhangMS 0:f7f1f0d76dd6 419 }
XinZhangMS 0:f7f1f0d76dd6 420
XinZhangMS 0:f7f1f0d76dd6 421 return result;
XinZhangMS 0:f7f1f0d76dd6 422 }
XinZhangMS 0:f7f1f0d76dd6 423
XinZhangMS 0:f7f1f0d76dd6 424 void tlsio_mbedtls_destroy(CONCRETE_IO_HANDLE tls_io)
XinZhangMS 0:f7f1f0d76dd6 425 {
XinZhangMS 0:f7f1f0d76dd6 426 if (tls_io != NULL)
XinZhangMS 0:f7f1f0d76dd6 427 {
XinZhangMS 0:f7f1f0d76dd6 428 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
XinZhangMS 0:f7f1f0d76dd6 429
XinZhangMS 0:f7f1f0d76dd6 430 // mbedTLS cleanup...
XinZhangMS 0:f7f1f0d76dd6 431 mbedtls_ssl_close_notify(&tls_io_instance->ssl);
XinZhangMS 0:f7f1f0d76dd6 432 mbedtls_ssl_free(&tls_io_instance->ssl);
XinZhangMS 0:f7f1f0d76dd6 433 mbedtls_ssl_config_free(&tls_io_instance->config);
XinZhangMS 0:f7f1f0d76dd6 434 mbedtls_x509_crt_free(&tls_io_instance->trusted_certificates_parsed);
XinZhangMS 0:f7f1f0d76dd6 435 mbedtls_ctr_drbg_free(&tls_io_instance->ctr_drbg);
XinZhangMS 0:f7f1f0d76dd6 436 mbedtls_entropy_free(&tls_io_instance->entropy);
XinZhangMS 0:f7f1f0d76dd6 437
XinZhangMS 0:f7f1f0d76dd6 438 xio_close(tls_io_instance->socket_io, NULL, NULL);
XinZhangMS 0:f7f1f0d76dd6 439
XinZhangMS 0:f7f1f0d76dd6 440 if (tls_io_instance->socket_io_read_bytes != NULL)
XinZhangMS 0:f7f1f0d76dd6 441 {
XinZhangMS 0:f7f1f0d76dd6 442 free(tls_io_instance->socket_io_read_bytes);
XinZhangMS 0:f7f1f0d76dd6 443 }
XinZhangMS 0:f7f1f0d76dd6 444
XinZhangMS 0:f7f1f0d76dd6 445 xio_destroy(tls_io_instance->socket_io);
XinZhangMS 0:f7f1f0d76dd6 446 if (tls_io_instance->trusted_certificates != NULL)
XinZhangMS 0:f7f1f0d76dd6 447 {
XinZhangMS 0:f7f1f0d76dd6 448 free(tls_io_instance->trusted_certificates);
XinZhangMS 0:f7f1f0d76dd6 449 }
XinZhangMS 0:f7f1f0d76dd6 450 free(tls_io);
XinZhangMS 0:f7f1f0d76dd6 451 }
XinZhangMS 0:f7f1f0d76dd6 452 }
XinZhangMS 0:f7f1f0d76dd6 453
XinZhangMS 0:f7f1f0d76dd6 454 int tlsio_mbedtls_open(CONCRETE_IO_HANDLE tls_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
XinZhangMS 0:f7f1f0d76dd6 455 {
XinZhangMS 0:f7f1f0d76dd6 456 int result = 0;
XinZhangMS 0:f7f1f0d76dd6 457
XinZhangMS 0:f7f1f0d76dd6 458 if (tls_io == NULL)
XinZhangMS 0:f7f1f0d76dd6 459 {
XinZhangMS 0:f7f1f0d76dd6 460 LogError("NULL tls_io");
XinZhangMS 0:f7f1f0d76dd6 461 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 462 }
XinZhangMS 0:f7f1f0d76dd6 463 else
XinZhangMS 0:f7f1f0d76dd6 464 {
XinZhangMS 0:f7f1f0d76dd6 465 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
XinZhangMS 0:f7f1f0d76dd6 466
XinZhangMS 0:f7f1f0d76dd6 467 if (tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN)
XinZhangMS 0:f7f1f0d76dd6 468 {
XinZhangMS 0:f7f1f0d76dd6 469 LogError("IO should not be open: %d\n", tls_io_instance->tlsio_state);
XinZhangMS 0:f7f1f0d76dd6 470 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 471 }
XinZhangMS 0:f7f1f0d76dd6 472 else
XinZhangMS 0:f7f1f0d76dd6 473 {
XinZhangMS 0:f7f1f0d76dd6 474 tls_io_instance->on_bytes_received = on_bytes_received;
XinZhangMS 0:f7f1f0d76dd6 475 tls_io_instance->on_bytes_received_context = on_bytes_received_context;
XinZhangMS 0:f7f1f0d76dd6 476
XinZhangMS 0:f7f1f0d76dd6 477 tls_io_instance->on_io_open_complete = on_io_open_complete;
XinZhangMS 0:f7f1f0d76dd6 478 tls_io_instance->on_io_open_complete_context = on_io_open_complete_context;
XinZhangMS 0:f7f1f0d76dd6 479
XinZhangMS 0:f7f1f0d76dd6 480 tls_io_instance->on_io_error = on_io_error;
XinZhangMS 0:f7f1f0d76dd6 481 tls_io_instance->on_io_error_context = on_io_error_context;
XinZhangMS 0:f7f1f0d76dd6 482
XinZhangMS 0:f7f1f0d76dd6 483 tls_io_instance->tlsio_state = TLSIO_STATE_OPENING_UNDERLYING_IO;
XinZhangMS 0:f7f1f0d76dd6 484
XinZhangMS 0:f7f1f0d76dd6 485 if (xio_open(tls_io_instance->socket_io, on_underlying_io_open_complete, tls_io_instance, on_underlying_io_bytes_received, tls_io_instance, on_underlying_io_error, tls_io_instance) != 0)
XinZhangMS 0:f7f1f0d76dd6 486 {
XinZhangMS 0:f7f1f0d76dd6 487 LogError("Underlying IO open failed");
XinZhangMS 0:f7f1f0d76dd6 488 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
XinZhangMS 0:f7f1f0d76dd6 489 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 490 }
XinZhangMS 0:f7f1f0d76dd6 491 else
XinZhangMS 0:f7f1f0d76dd6 492 {
XinZhangMS 0:f7f1f0d76dd6 493 result = 0;
XinZhangMS 0:f7f1f0d76dd6 494 }
XinZhangMS 0:f7f1f0d76dd6 495 }
XinZhangMS 0:f7f1f0d76dd6 496 }
XinZhangMS 0:f7f1f0d76dd6 497
XinZhangMS 0:f7f1f0d76dd6 498 return result;
XinZhangMS 0:f7f1f0d76dd6 499 }
XinZhangMS 0:f7f1f0d76dd6 500
XinZhangMS 0:f7f1f0d76dd6 501 int tlsio_mbedtls_close(CONCRETE_IO_HANDLE tls_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
XinZhangMS 0:f7f1f0d76dd6 502 {
XinZhangMS 0:f7f1f0d76dd6 503 int result = 0;
XinZhangMS 0:f7f1f0d76dd6 504
XinZhangMS 0:f7f1f0d76dd6 505 if (tls_io == NULL)
XinZhangMS 0:f7f1f0d76dd6 506 {
XinZhangMS 0:f7f1f0d76dd6 507 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 508 }
XinZhangMS 0:f7f1f0d76dd6 509 else
XinZhangMS 0:f7f1f0d76dd6 510 {
XinZhangMS 0:f7f1f0d76dd6 511 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
XinZhangMS 0:f7f1f0d76dd6 512
XinZhangMS 0:f7f1f0d76dd6 513 if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) ||
XinZhangMS 0:f7f1f0d76dd6 514 (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING))
XinZhangMS 0:f7f1f0d76dd6 515 {
XinZhangMS 0:f7f1f0d76dd6 516 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 517 }
XinZhangMS 0:f7f1f0d76dd6 518 else
XinZhangMS 0:f7f1f0d76dd6 519 {
XinZhangMS 0:f7f1f0d76dd6 520 tls_io_instance->tlsio_state = TLSIO_STATE_CLOSING;
XinZhangMS 0:f7f1f0d76dd6 521 tls_io_instance->on_io_close_complete = on_io_close_complete;
XinZhangMS 0:f7f1f0d76dd6 522 tls_io_instance->on_io_close_complete_context = callback_context;
XinZhangMS 0:f7f1f0d76dd6 523
XinZhangMS 0:f7f1f0d76dd6 524 if (xio_close(tls_io_instance->socket_io,
XinZhangMS 0:f7f1f0d76dd6 525 on_underlying_io_close_complete_during_close, tls_io_instance) != 0)
XinZhangMS 0:f7f1f0d76dd6 526 {
XinZhangMS 0:f7f1f0d76dd6 527 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 528 }
XinZhangMS 0:f7f1f0d76dd6 529 else
XinZhangMS 0:f7f1f0d76dd6 530 {
XinZhangMS 0:f7f1f0d76dd6 531 result = 0;
XinZhangMS 0:f7f1f0d76dd6 532 }
XinZhangMS 0:f7f1f0d76dd6 533 }
XinZhangMS 0:f7f1f0d76dd6 534 }
XinZhangMS 0:f7f1f0d76dd6 535
XinZhangMS 0:f7f1f0d76dd6 536 return result;
XinZhangMS 0:f7f1f0d76dd6 537 }
XinZhangMS 0:f7f1f0d76dd6 538
XinZhangMS 0:f7f1f0d76dd6 539 int tlsio_mbedtls_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
XinZhangMS 0:f7f1f0d76dd6 540 {
XinZhangMS 0:f7f1f0d76dd6 541 int result;
XinZhangMS 0:f7f1f0d76dd6 542
XinZhangMS 0:f7f1f0d76dd6 543 if (tls_io == NULL)
XinZhangMS 0:f7f1f0d76dd6 544 {
XinZhangMS 0:f7f1f0d76dd6 545 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 546 }
XinZhangMS 0:f7f1f0d76dd6 547 else
XinZhangMS 0:f7f1f0d76dd6 548 {
XinZhangMS 0:f7f1f0d76dd6 549 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
XinZhangMS 0:f7f1f0d76dd6 550
XinZhangMS 0:f7f1f0d76dd6 551 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN)
XinZhangMS 0:f7f1f0d76dd6 552 {
XinZhangMS 0:f7f1f0d76dd6 553 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 554 }
XinZhangMS 0:f7f1f0d76dd6 555 else
XinZhangMS 0:f7f1f0d76dd6 556 {
XinZhangMS 0:f7f1f0d76dd6 557 tls_io_instance->on_send_complete = on_send_complete;
XinZhangMS 0:f7f1f0d76dd6 558 tls_io_instance->on_send_complete_callback_context = callback_context;
XinZhangMS 0:f7f1f0d76dd6 559
XinZhangMS 0:f7f1f0d76dd6 560 int res = mbedtls_ssl_write(&tls_io_instance->ssl, buffer, size);
XinZhangMS 0:f7f1f0d76dd6 561 if (res != size)
XinZhangMS 0:f7f1f0d76dd6 562 {
XinZhangMS 0:f7f1f0d76dd6 563 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 564 }
XinZhangMS 0:f7f1f0d76dd6 565 else
XinZhangMS 0:f7f1f0d76dd6 566 {
XinZhangMS 0:f7f1f0d76dd6 567 result = 0;
XinZhangMS 0:f7f1f0d76dd6 568 }
XinZhangMS 0:f7f1f0d76dd6 569 }
XinZhangMS 0:f7f1f0d76dd6 570 }
XinZhangMS 0:f7f1f0d76dd6 571
XinZhangMS 0:f7f1f0d76dd6 572 return result;
XinZhangMS 0:f7f1f0d76dd6 573 }
XinZhangMS 0:f7f1f0d76dd6 574
XinZhangMS 0:f7f1f0d76dd6 575 void tlsio_mbedtls_dowork(CONCRETE_IO_HANDLE tls_io)
XinZhangMS 0:f7f1f0d76dd6 576 {
XinZhangMS 0:f7f1f0d76dd6 577 if (tls_io != NULL)
XinZhangMS 0:f7f1f0d76dd6 578 {
XinZhangMS 0:f7f1f0d76dd6 579 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
XinZhangMS 0:f7f1f0d76dd6 580
XinZhangMS 0:f7f1f0d76dd6 581 if ((tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) &&
XinZhangMS 0:f7f1f0d76dd6 582 (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR))
XinZhangMS 0:f7f1f0d76dd6 583 {
XinZhangMS 0:f7f1f0d76dd6 584 decode_ssl_received_bytes(tls_io_instance);
XinZhangMS 0:f7f1f0d76dd6 585 xio_dowork(tls_io_instance->socket_io);
XinZhangMS 0:f7f1f0d76dd6 586 }
XinZhangMS 0:f7f1f0d76dd6 587 }
XinZhangMS 0:f7f1f0d76dd6 588 }
XinZhangMS 0:f7f1f0d76dd6 589
XinZhangMS 0:f7f1f0d76dd6 590 const IO_INTERFACE_DESCRIPTION* tlsio_mbedtls_get_interface_description(void)
XinZhangMS 0:f7f1f0d76dd6 591 {
XinZhangMS 0:f7f1f0d76dd6 592 return &tlsio_mbedtls_interface_description;
XinZhangMS 0:f7f1f0d76dd6 593 }
XinZhangMS 0:f7f1f0d76dd6 594
XinZhangMS 0:f7f1f0d76dd6 595 /*this function will clone an option given by name and value*/
XinZhangMS 0:f7f1f0d76dd6 596 static void* tlsio_mbedtls_CloneOption(const char* name, const void* value)
XinZhangMS 0:f7f1f0d76dd6 597 {
XinZhangMS 0:f7f1f0d76dd6 598 void* result;
XinZhangMS 0:f7f1f0d76dd6 599 if (
XinZhangMS 0:f7f1f0d76dd6 600 (name == NULL) || (value == NULL)
XinZhangMS 0:f7f1f0d76dd6 601 )
XinZhangMS 0:f7f1f0d76dd6 602 {
XinZhangMS 0:f7f1f0d76dd6 603 LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value);
XinZhangMS 0:f7f1f0d76dd6 604 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 605 }
XinZhangMS 0:f7f1f0d76dd6 606 else
XinZhangMS 0:f7f1f0d76dd6 607 {
XinZhangMS 0:f7f1f0d76dd6 608 if (strcmp(name, OPTION_UNDERLYING_IO_OPTIONS) == 0)
XinZhangMS 0:f7f1f0d76dd6 609 {
XinZhangMS 0:f7f1f0d76dd6 610 result = (void*)value;
XinZhangMS 0:f7f1f0d76dd6 611 }
XinZhangMS 0:f7f1f0d76dd6 612 else if (strcmp(name, OPTION_TRUSTED_CERT) == 0)
XinZhangMS 0:f7f1f0d76dd6 613 {
XinZhangMS 0:f7f1f0d76dd6 614 if (mallocAndStrcpy_s((char**)&result, value) != 0)
XinZhangMS 0:f7f1f0d76dd6 615 {
XinZhangMS 0:f7f1f0d76dd6 616 LogError("unable to mallocAndStrcpy_s TrustedCerts value");
XinZhangMS 0:f7f1f0d76dd6 617 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 618 }
XinZhangMS 0:f7f1f0d76dd6 619 else
XinZhangMS 0:f7f1f0d76dd6 620 {
XinZhangMS 0:f7f1f0d76dd6 621 /*return as is*/
XinZhangMS 0:f7f1f0d76dd6 622 }
XinZhangMS 0:f7f1f0d76dd6 623 }
XinZhangMS 0:f7f1f0d76dd6 624 else
XinZhangMS 0:f7f1f0d76dd6 625 {
XinZhangMS 0:f7f1f0d76dd6 626 LogError("not handled option : %s", name);
XinZhangMS 0:f7f1f0d76dd6 627 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 628 }
XinZhangMS 0:f7f1f0d76dd6 629 }
XinZhangMS 0:f7f1f0d76dd6 630 return result;
XinZhangMS 0:f7f1f0d76dd6 631 }
XinZhangMS 0:f7f1f0d76dd6 632
XinZhangMS 0:f7f1f0d76dd6 633 /*this function destroys an option previously created*/
XinZhangMS 0:f7f1f0d76dd6 634 static void tlsio_mbedtls_DestroyOption(const char* name, const void* value)
XinZhangMS 0:f7f1f0d76dd6 635 {
XinZhangMS 0:f7f1f0d76dd6 636 /*since all options for this layer are actually string copies., disposing of one is just calling free*/
XinZhangMS 0:f7f1f0d76dd6 637 if (name == NULL || value == NULL)
XinZhangMS 0:f7f1f0d76dd6 638 {
XinZhangMS 0:f7f1f0d76dd6 639 LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value);
XinZhangMS 0:f7f1f0d76dd6 640 }
XinZhangMS 0:f7f1f0d76dd6 641 else
XinZhangMS 0:f7f1f0d76dd6 642 {
XinZhangMS 0:f7f1f0d76dd6 643 if (strcmp(name, OPTION_TRUSTED_CERT) == 0)
XinZhangMS 0:f7f1f0d76dd6 644 {
XinZhangMS 0:f7f1f0d76dd6 645 free((void*)value);
XinZhangMS 0:f7f1f0d76dd6 646 }
XinZhangMS 0:f7f1f0d76dd6 647 else if (strcmp(name, OPTION_UNDERLYING_IO_OPTIONS) == 0)
XinZhangMS 0:f7f1f0d76dd6 648 {
XinZhangMS 0:f7f1f0d76dd6 649 OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value);
XinZhangMS 0:f7f1f0d76dd6 650 }
XinZhangMS 0:f7f1f0d76dd6 651 else
XinZhangMS 0:f7f1f0d76dd6 652 {
XinZhangMS 0:f7f1f0d76dd6 653 LogError("not handled option : %s", name);
XinZhangMS 0:f7f1f0d76dd6 654 }
XinZhangMS 0:f7f1f0d76dd6 655 }
XinZhangMS 0:f7f1f0d76dd6 656 }
XinZhangMS 0:f7f1f0d76dd6 657
XinZhangMS 0:f7f1f0d76dd6 658 OPTIONHANDLER_HANDLE tlsio_mbedtls_retrieveoptions(CONCRETE_IO_HANDLE handle)
XinZhangMS 0:f7f1f0d76dd6 659 {
XinZhangMS 0:f7f1f0d76dd6 660 OPTIONHANDLER_HANDLE result;
XinZhangMS 0:f7f1f0d76dd6 661 if (handle == NULL)
XinZhangMS 0:f7f1f0d76dd6 662 {
XinZhangMS 0:f7f1f0d76dd6 663 LogError("invalid parameter detected: CONCRETE_IO_HANDLE handle=%p", handle);
XinZhangMS 0:f7f1f0d76dd6 664 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 665 }
XinZhangMS 0:f7f1f0d76dd6 666 else
XinZhangMS 0:f7f1f0d76dd6 667 {
XinZhangMS 0:f7f1f0d76dd6 668 result = OptionHandler_Create(tlsio_mbedtls_CloneOption, tlsio_mbedtls_DestroyOption, tlsio_mbedtls_setoption);
XinZhangMS 0:f7f1f0d76dd6 669 if (result == NULL)
XinZhangMS 0:f7f1f0d76dd6 670 {
XinZhangMS 0:f7f1f0d76dd6 671 LogError("unable to OptionHandler_Create");
XinZhangMS 0:f7f1f0d76dd6 672 /*return as is*/
XinZhangMS 0:f7f1f0d76dd6 673 }
XinZhangMS 0:f7f1f0d76dd6 674 else
XinZhangMS 0:f7f1f0d76dd6 675 {
XinZhangMS 0:f7f1f0d76dd6 676 /*this layer cares about the certificates*/
XinZhangMS 0:f7f1f0d76dd6 677 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)handle;
XinZhangMS 0:f7f1f0d76dd6 678 OPTIONHANDLER_HANDLE underlying_io_options;
XinZhangMS 0:f7f1f0d76dd6 679
XinZhangMS 0:f7f1f0d76dd6 680 if ((underlying_io_options = xio_retrieveoptions(tls_io_instance->socket_io)) == NULL ||
XinZhangMS 0:f7f1f0d76dd6 681 OptionHandler_AddOption(result, OPTION_UNDERLYING_IO_OPTIONS, underlying_io_options) != OPTIONHANDLER_OK)
XinZhangMS 0:f7f1f0d76dd6 682 {
XinZhangMS 0:f7f1f0d76dd6 683 LogError("unable to save underlying_io options");
XinZhangMS 0:f7f1f0d76dd6 684 OptionHandler_Destroy(underlying_io_options);
XinZhangMS 0:f7f1f0d76dd6 685 OptionHandler_Destroy(result);
XinZhangMS 0:f7f1f0d76dd6 686 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 687 }
XinZhangMS 0:f7f1f0d76dd6 688 else if (tls_io_instance->trusted_certificates != NULL &&
XinZhangMS 0:f7f1f0d76dd6 689 OptionHandler_AddOption(result, OPTION_TRUSTED_CERT, tls_io_instance->trusted_certificates) != OPTIONHANDLER_OK)
XinZhangMS 0:f7f1f0d76dd6 690 {
XinZhangMS 0:f7f1f0d76dd6 691 LogError("unable to save TrustedCerts option");
XinZhangMS 0:f7f1f0d76dd6 692 OptionHandler_Destroy(result);
XinZhangMS 0:f7f1f0d76dd6 693 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 694 }
XinZhangMS 0:f7f1f0d76dd6 695 else
XinZhangMS 0:f7f1f0d76dd6 696 {
XinZhangMS 0:f7f1f0d76dd6 697 /*all is fine, all interesting options have been saved*/
XinZhangMS 0:f7f1f0d76dd6 698 /*return as is*/
XinZhangMS 0:f7f1f0d76dd6 699 }
XinZhangMS 0:f7f1f0d76dd6 700 }
XinZhangMS 0:f7f1f0d76dd6 701 }
XinZhangMS 0:f7f1f0d76dd6 702 return result;
XinZhangMS 0:f7f1f0d76dd6 703 }
XinZhangMS 0:f7f1f0d76dd6 704
XinZhangMS 0:f7f1f0d76dd6 705 int tlsio_mbedtls_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value)
XinZhangMS 0:f7f1f0d76dd6 706 {
XinZhangMS 0:f7f1f0d76dd6 707 int result;
XinZhangMS 0:f7f1f0d76dd6 708
XinZhangMS 0:f7f1f0d76dd6 709 if (tls_io == NULL || optionName == NULL)
XinZhangMS 0:f7f1f0d76dd6 710 {
XinZhangMS 0:f7f1f0d76dd6 711 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 712 }
XinZhangMS 0:f7f1f0d76dd6 713 else
XinZhangMS 0:f7f1f0d76dd6 714 {
XinZhangMS 0:f7f1f0d76dd6 715 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
XinZhangMS 0:f7f1f0d76dd6 716
XinZhangMS 0:f7f1f0d76dd6 717 if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
XinZhangMS 0:f7f1f0d76dd6 718 {
XinZhangMS 0:f7f1f0d76dd6 719 if (tls_io_instance->trusted_certificates != NULL)
XinZhangMS 0:f7f1f0d76dd6 720 {
XinZhangMS 0:f7f1f0d76dd6 721 // Free the memory if it has been previously allocated
XinZhangMS 0:f7f1f0d76dd6 722 free(tls_io_instance->trusted_certificates);
XinZhangMS 0:f7f1f0d76dd6 723 tls_io_instance->trusted_certificates = NULL;
XinZhangMS 0:f7f1f0d76dd6 724 }
XinZhangMS 0:f7f1f0d76dd6 725 if (mallocAndStrcpy_s(&tls_io_instance->trusted_certificates, (const char*)value) != 0)
XinZhangMS 0:f7f1f0d76dd6 726 {
XinZhangMS 0:f7f1f0d76dd6 727 LogError("unable to mallocAndStrcpy_s");
XinZhangMS 0:f7f1f0d76dd6 728 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 729 }
XinZhangMS 0:f7f1f0d76dd6 730 else
XinZhangMS 0:f7f1f0d76dd6 731 {
XinZhangMS 0:f7f1f0d76dd6 732 int parse_result = mbedtls_x509_crt_parse(&tls_io_instance->trusted_certificates_parsed, (const unsigned char *)value, (int)(strlen(value) + 1));
XinZhangMS 0:f7f1f0d76dd6 733 if (parse_result != 0)
XinZhangMS 0:f7f1f0d76dd6 734 {
XinZhangMS 0:f7f1f0d76dd6 735 LogInfo("Malformed pem certificate");
XinZhangMS 0:f7f1f0d76dd6 736 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 737 }
XinZhangMS 0:f7f1f0d76dd6 738 else
XinZhangMS 0:f7f1f0d76dd6 739 {
XinZhangMS 0:f7f1f0d76dd6 740 mbedtls_ssl_conf_ca_chain(&tls_io_instance->config, &tls_io_instance->trusted_certificates_parsed, NULL);
XinZhangMS 0:f7f1f0d76dd6 741 result = 0;
XinZhangMS 0:f7f1f0d76dd6 742 }
XinZhangMS 0:f7f1f0d76dd6 743 }
XinZhangMS 0:f7f1f0d76dd6 744 }
XinZhangMS 0:f7f1f0d76dd6 745 else
XinZhangMS 0:f7f1f0d76dd6 746 {
XinZhangMS 0:f7f1f0d76dd6 747 // tls_io_instance->socket_io is never NULL
XinZhangMS 0:f7f1f0d76dd6 748 result = xio_setoption(tls_io_instance->socket_io, optionName, value);
XinZhangMS 0:f7f1f0d76dd6 749 }
XinZhangMS 0:f7f1f0d76dd6 750 }
XinZhangMS 0:f7f1f0d76dd6 751
XinZhangMS 0:f7f1f0d76dd6 752 return result;
XinZhangMS 0:f7f1f0d76dd6 753 }
XinZhangMS 0:f7f1f0d76dd6 754
XinZhangMS 0:f7f1f0d76dd6 755 // DEPRECATED: the USE_MBED_TLS #define is deprecated.
XinZhangMS 0:f7f1f0d76dd6 756 #endif // USE_MBED_TLS