test

Dependencies:   MQTT

Committer:
kernel2418
Date:
Wed Mar 14 03:03:16 2018 +0000
Revision:
0:9d5f28595388
test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kernel2418 0:9d5f28595388 1 #ifndef _TLS_SOCKET_H_
kernel2418 0:9d5f28595388 2 #define _TLS_SOCKET_H_
kernel2418 0:9d5f28595388 3
kernel2418 0:9d5f28595388 4 /* Change to a number between 1 and 4 to debug the TLS connection */
kernel2418 0:9d5f28595388 5 #define DEBUG_LEVEL 0
kernel2418 0:9d5f28595388 6
kernel2418 0:9d5f28595388 7 #include "mbedtls/platform.h"
kernel2418 0:9d5f28595388 8 #include "mbedtls/ssl.h"
kernel2418 0:9d5f28595388 9 #include "mbedtls/entropy.h"
kernel2418 0:9d5f28595388 10 #include "mbedtls/ctr_drbg.h"
kernel2418 0:9d5f28595388 11 #include "mbedtls/error.h"
kernel2418 0:9d5f28595388 12
kernel2418 0:9d5f28595388 13 #if DEBUG_LEVEL > 0
kernel2418 0:9d5f28595388 14 #include "mbedtls/debug.h"
kernel2418 0:9d5f28595388 15 #endif
kernel2418 0:9d5f28595388 16
kernel2418 0:9d5f28595388 17 #include "mbedtls_utils.h"
kernel2418 0:9d5f28595388 18
kernel2418 0:9d5f28595388 19 /**
kernel2418 0:9d5f28595388 20 * \brief TLSSocket a wrapper around TCPSocket for interacting with TLS servers
kernel2418 0:9d5f28595388 21 */
kernel2418 0:9d5f28595388 22 class TLSSocket {
kernel2418 0:9d5f28595388 23 public:
kernel2418 0:9d5f28595388 24 TLSSocket(NetworkInterface* net_iface, const char* ssl_ca_pem, const char* ssl_owncert_pem, const char* ssl_own_priv_key_pem) {
kernel2418 0:9d5f28595388 25 _tcpsocket = new TCPSocket(net_iface);
kernel2418 0:9d5f28595388 26 _ssl_ca_pem = ssl_ca_pem;
kernel2418 0:9d5f28595388 27 _ssl_owncert_pem = ssl_owncert_pem;
kernel2418 0:9d5f28595388 28 _ssl_own_priv_key_pem = ssl_own_priv_key_pem;
kernel2418 0:9d5f28595388 29 _is_connected = false;
kernel2418 0:9d5f28595388 30 _debug = false;
kernel2418 0:9d5f28595388 31 _hostname = NULL;
kernel2418 0:9d5f28595388 32 _port = 0;
kernel2418 0:9d5f28595388 33 _error = 0;
kernel2418 0:9d5f28595388 34
kernel2418 0:9d5f28595388 35 DRBG_PERS = "mbed TLS helloword client";
kernel2418 0:9d5f28595388 36
kernel2418 0:9d5f28595388 37 mbedtls_entropy_init(&_entropy);
kernel2418 0:9d5f28595388 38 mbedtls_ctr_drbg_init(&_ctr_drbg);
kernel2418 0:9d5f28595388 39 mbedtls_x509_crt_init(&_cacert);
kernel2418 0:9d5f28595388 40 mbedtls_x509_crt_init(&_owncert);
kernel2418 0:9d5f28595388 41 mbedtls_pk_init(&_own_priv_key);
kernel2418 0:9d5f28595388 42 mbedtls_ssl_init(&_ssl);
kernel2418 0:9d5f28595388 43 mbedtls_ssl_config_init(&_ssl_conf);
kernel2418 0:9d5f28595388 44 }
kernel2418 0:9d5f28595388 45
kernel2418 0:9d5f28595388 46 ~TLSSocket() {
kernel2418 0:9d5f28595388 47 mbedtls_entropy_free(&_entropy);
kernel2418 0:9d5f28595388 48 mbedtls_ctr_drbg_free(&_ctr_drbg);
kernel2418 0:9d5f28595388 49 mbedtls_x509_crt_free(&_cacert);
kernel2418 0:9d5f28595388 50 mbedtls_x509_crt_free(&_owncert);
kernel2418 0:9d5f28595388 51 mbedtls_pk_free(&_own_priv_key);
kernel2418 0:9d5f28595388 52 mbedtls_ssl_free(&_ssl);
kernel2418 0:9d5f28595388 53 mbedtls_ssl_config_free(&_ssl_conf);
kernel2418 0:9d5f28595388 54
kernel2418 0:9d5f28595388 55 if (_tcpsocket) {
kernel2418 0:9d5f28595388 56 _tcpsocket->close();
kernel2418 0:9d5f28595388 57 delete _tcpsocket;
kernel2418 0:9d5f28595388 58 }
kernel2418 0:9d5f28595388 59
kernel2418 0:9d5f28595388 60 // @todo: free DRBG_PERS ?
kernel2418 0:9d5f28595388 61 }
kernel2418 0:9d5f28595388 62
kernel2418 0:9d5f28595388 63 /** Close the socket
kernel2418 0:9d5f28595388 64 *
kernel2418 0:9d5f28595388 65 * Closes any open connection and deallocates any memory associated
kernel2418 0:9d5f28595388 66 * with the socket. Called from destructor if socket is not closed.
kernel2418 0:9d5f28595388 67 *
kernel2418 0:9d5f28595388 68 * @return 0 on success, negative error code on failure
kernel2418 0:9d5f28595388 69 */
kernel2418 0:9d5f28595388 70 nsapi_error_t close() {
kernel2418 0:9d5f28595388 71 return _tcpsocket->close();
kernel2418 0:9d5f28595388 72 }
kernel2418 0:9d5f28595388 73
kernel2418 0:9d5f28595388 74 nsapi_error_t connect(const char *hostname, uint16_t port) {
kernel2418 0:9d5f28595388 75 _hostname = hostname;
kernel2418 0:9d5f28595388 76 _port = port;
kernel2418 0:9d5f28595388 77
kernel2418 0:9d5f28595388 78 /* Initialize the flags */
kernel2418 0:9d5f28595388 79 /*
kernel2418 0:9d5f28595388 80 * Initialize TLS-related stuf.
kernel2418 0:9d5f28595388 81 */
kernel2418 0:9d5f28595388 82 int ret;
kernel2418 0:9d5f28595388 83 if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy,
kernel2418 0:9d5f28595388 84 (const unsigned char *) DRBG_PERS,
kernel2418 0:9d5f28595388 85 sizeof (DRBG_PERS))) != 0) {
kernel2418 0:9d5f28595388 86 print_mbedtls_error("mbedtls_crt_drbg_init", ret);
kernel2418 0:9d5f28595388 87 _error = ret;
kernel2418 0:9d5f28595388 88 return _error;
kernel2418 0:9d5f28595388 89 }
kernel2418 0:9d5f28595388 90
kernel2418 0:9d5f28595388 91 if ((ret = mbedtls_x509_crt_parse(&_cacert, (const unsigned char *)_ssl_ca_pem,
kernel2418 0:9d5f28595388 92 strlen(_ssl_ca_pem) + 1)) != 0) {
kernel2418 0:9d5f28595388 93 print_mbedtls_error("mbedtls_x509_crt_parse", ret);
kernel2418 0:9d5f28595388 94 _error = ret;
kernel2418 0:9d5f28595388 95 return _error;
kernel2418 0:9d5f28595388 96 }
kernel2418 0:9d5f28595388 97
kernel2418 0:9d5f28595388 98 if ((ret = mbedtls_x509_crt_parse(&_owncert, (const unsigned char *) _ssl_owncert_pem,
kernel2418 0:9d5f28595388 99 strlen(_ssl_owncert_pem) + 1)) != 0) {
kernel2418 0:9d5f28595388 100 print_mbedtls_error("mbedtls_x509_crt_parse", ret);
kernel2418 0:9d5f28595388 101 _error = ret;
kernel2418 0:9d5f28595388 102 return _error;
kernel2418 0:9d5f28595388 103 }
kernel2418 0:9d5f28595388 104
kernel2418 0:9d5f28595388 105 if ((ret = mbedtls_pk_parse_key(&_own_priv_key, (const unsigned char *) _ssl_own_priv_key_pem,
kernel2418 0:9d5f28595388 106 strlen(_ssl_own_priv_key_pem) + 1, NULL, 0)) != 0) {
kernel2418 0:9d5f28595388 107 print_mbedtls_error("mbedtls_pk_parse_key", ret);
kernel2418 0:9d5f28595388 108 _error = ret;
kernel2418 0:9d5f28595388 109 return _error;
kernel2418 0:9d5f28595388 110 }
kernel2418 0:9d5f28595388 111
kernel2418 0:9d5f28595388 112 if ((ret = mbedtls_ssl_config_defaults(&_ssl_conf,
kernel2418 0:9d5f28595388 113 MBEDTLS_SSL_IS_CLIENT,
kernel2418 0:9d5f28595388 114 MBEDTLS_SSL_TRANSPORT_STREAM,
kernel2418 0:9d5f28595388 115 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
kernel2418 0:9d5f28595388 116 print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
kernel2418 0:9d5f28595388 117 _error = ret;
kernel2418 0:9d5f28595388 118 return _error;
kernel2418 0:9d5f28595388 119 }
kernel2418 0:9d5f28595388 120
kernel2418 0:9d5f28595388 121 mbedtls_ssl_conf_ca_chain(&_ssl_conf, &_cacert, NULL);
kernel2418 0:9d5f28595388 122 mbedtls_ssl_conf_own_cert(&_ssl_conf, &_owncert, &_own_priv_key);
kernel2418 0:9d5f28595388 123 mbedtls_ssl_conf_rng(&_ssl_conf, mbedtls_ctr_drbg_random, &_ctr_drbg);
kernel2418 0:9d5f28595388 124
kernel2418 0:9d5f28595388 125 /* It is possible to disable authentication by passing
kernel2418 0:9d5f28595388 126 * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
kernel2418 0:9d5f28595388 127 */
kernel2418 0:9d5f28595388 128 mbedtls_ssl_conf_authmode(&_ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
kernel2418 0:9d5f28595388 129
kernel2418 0:9d5f28595388 130 #if DEBUG_LEVEL > 0
kernel2418 0:9d5f28595388 131 mbedtls_ssl_conf_verify(&_ssl_conf, my_verify, NULL);
kernel2418 0:9d5f28595388 132 mbedtls_ssl_conf_dbg(&_ssl_conf, my_debug, NULL);
kernel2418 0:9d5f28595388 133 mbedtls_debug_set_threshold(DEBUG_LEVEL);
kernel2418 0:9d5f28595388 134 #endif
kernel2418 0:9d5f28595388 135
kernel2418 0:9d5f28595388 136 if ((ret = mbedtls_ssl_setup(&_ssl, &_ssl_conf)) != 0) {
kernel2418 0:9d5f28595388 137 print_mbedtls_error("mbedtls_ssl_setup", ret);
kernel2418 0:9d5f28595388 138 _error = ret;
kernel2418 0:9d5f28595388 139 return _error;
kernel2418 0:9d5f28595388 140 }
kernel2418 0:9d5f28595388 141
kernel2418 0:9d5f28595388 142 mbedtls_ssl_set_hostname(&_ssl, _hostname);
kernel2418 0:9d5f28595388 143
kernel2418 0:9d5f28595388 144 mbedtls_ssl_set_bio(&_ssl, static_cast<void *>(_tcpsocket),
kernel2418 0:9d5f28595388 145 ssl_send, ssl_recv, NULL );
kernel2418 0:9d5f28595388 146
kernel2418 0:9d5f28595388 147 /* Connect to the server */
kernel2418 0:9d5f28595388 148 if (_debug) mbedtls_printf("Connecting to %s:%d\r\n", _hostname, _port);
kernel2418 0:9d5f28595388 149 ret = _tcpsocket->connect(_hostname, _port);
kernel2418 0:9d5f28595388 150 if (ret != NSAPI_ERROR_OK) {
kernel2418 0:9d5f28595388 151 if (_debug) mbedtls_printf("Failed to connect\r\n");
kernel2418 0:9d5f28595388 152 onError(_tcpsocket, -1);
kernel2418 0:9d5f28595388 153 return _error;
kernel2418 0:9d5f28595388 154 }
kernel2418 0:9d5f28595388 155
kernel2418 0:9d5f28595388 156 /* Start the handshake, the rest will be done in onReceive() */
kernel2418 0:9d5f28595388 157 if (_debug) mbedtls_printf("Starting the TLS handshake...\r\n");
kernel2418 0:9d5f28595388 158 do {
kernel2418 0:9d5f28595388 159 ret = mbedtls_ssl_handshake(&_ssl);
kernel2418 0:9d5f28595388 160 } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);
kernel2418 0:9d5f28595388 161 if (ret < 0) {
kernel2418 0:9d5f28595388 162 print_mbedtls_error("mbedtls_ssl_handshake", ret);
kernel2418 0:9d5f28595388 163 onError(_tcpsocket, ret);
kernel2418 0:9d5f28595388 164 return ret;
kernel2418 0:9d5f28595388 165 }
kernel2418 0:9d5f28595388 166
kernel2418 0:9d5f28595388 167 /* It also means the handshake is done, time to print info */
kernel2418 0:9d5f28595388 168 if (_debug) mbedtls_printf("TLS connection to %s:%d established\r\n", _hostname, _port);
kernel2418 0:9d5f28595388 169
kernel2418 0:9d5f28595388 170 const uint32_t buf_size = 1024;
kernel2418 0:9d5f28595388 171 char *buf = new char[buf_size];
kernel2418 0:9d5f28595388 172 mbedtls_x509_crt_info(buf, buf_size, "\r ",
kernel2418 0:9d5f28595388 173 mbedtls_ssl_get_peer_cert(&_ssl));
kernel2418 0:9d5f28595388 174 if (_debug) mbedtls_printf("Server certificate:\r\n%s\r", buf);
kernel2418 0:9d5f28595388 175
kernel2418 0:9d5f28595388 176 uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl);
kernel2418 0:9d5f28595388 177 if( flags != 0 )
kernel2418 0:9d5f28595388 178 {
kernel2418 0:9d5f28595388 179 mbedtls_x509_crt_verify_info(buf, buf_size, "\r ! ", flags);
kernel2418 0:9d5f28595388 180 if (_debug) mbedtls_printf("Certificate verification failed:\r\n%s\r\r\n", buf);
kernel2418 0:9d5f28595388 181 }
kernel2418 0:9d5f28595388 182 else {
kernel2418 0:9d5f28595388 183 if (_debug) mbedtls_printf("Certificate verification passed\r\n\r\n");
kernel2418 0:9d5f28595388 184 }
kernel2418 0:9d5f28595388 185 delete [] buf;
kernel2418 0:9d5f28595388 186 buf = NULL;
kernel2418 0:9d5f28595388 187
kernel2418 0:9d5f28595388 188 _is_connected = true;
kernel2418 0:9d5f28595388 189
kernel2418 0:9d5f28595388 190 return 0;
kernel2418 0:9d5f28595388 191 }
kernel2418 0:9d5f28595388 192
kernel2418 0:9d5f28595388 193 /** Send data over a TCP socket
kernel2418 0:9d5f28595388 194 *
kernel2418 0:9d5f28595388 195 * The socket must be connected to a remote host. Returns the number of
kernel2418 0:9d5f28595388 196 * bytes sent from the buffer.
kernel2418 0:9d5f28595388 197 *
kernel2418 0:9d5f28595388 198 * By default, send blocks until all data is sent. If socket is set to
kernel2418 0:9d5f28595388 199 * non-blocking or times out, a partial amount can be written.
kernel2418 0:9d5f28595388 200 * NSAPI_ERROR_WOULD_BLOCK is returned if no data was written.
kernel2418 0:9d5f28595388 201 *
kernel2418 0:9d5f28595388 202 * @param data Buffer of data to send to the host
kernel2418 0:9d5f28595388 203 * @param size Size of the buffer in bytes
kernel2418 0:9d5f28595388 204 * @return Number of sent bytes on success, negative error
kernel2418 0:9d5f28595388 205 * code on failure
kernel2418 0:9d5f28595388 206 */
kernel2418 0:9d5f28595388 207 nsapi_size_or_error_t send(const void *data, nsapi_size_t size) {
kernel2418 0:9d5f28595388 208 return mbedtls_ssl_write(&_ssl, (const uint8_t *) data, size);
kernel2418 0:9d5f28595388 209 }
kernel2418 0:9d5f28595388 210
kernel2418 0:9d5f28595388 211 /** Receive data over a TCP socket
kernel2418 0:9d5f28595388 212 *
kernel2418 0:9d5f28595388 213 * The socket must be connected to a remote host. Returns the number of
kernel2418 0:9d5f28595388 214 * bytes received into the buffer.
kernel2418 0:9d5f28595388 215 *
kernel2418 0:9d5f28595388 216 * By default, recv blocks until some data is received. If socket is set to
kernel2418 0:9d5f28595388 217 * non-blocking or times out, NSAPI_ERROR_WOULD_BLOCK can be returned to
kernel2418 0:9d5f28595388 218 * indicate no data.
kernel2418 0:9d5f28595388 219 *
kernel2418 0:9d5f28595388 220 * @param data Destination buffer for data received from the host
kernel2418 0:9d5f28595388 221 * @param size Size of the buffer in bytes
kernel2418 0:9d5f28595388 222 * @return Number of received bytes on success, negative error
kernel2418 0:9d5f28595388 223 * code on failure
kernel2418 0:9d5f28595388 224 */
kernel2418 0:9d5f28595388 225 nsapi_size_or_error_t recv(void *data, nsapi_size_t size) {
kernel2418 0:9d5f28595388 226 return mbedtls_ssl_read(&_ssl, (uint8_t *) data, size);
kernel2418 0:9d5f28595388 227 }
kernel2418 0:9d5f28595388 228
kernel2418 0:9d5f28595388 229 /** Set blocking or non-blocking mode of the socket
kernel2418 0:9d5f28595388 230 *
kernel2418 0:9d5f28595388 231 * Initially all sockets are in blocking mode. In non-blocking mode
kernel2418 0:9d5f28595388 232 * blocking operations such as send/recv/accept return
kernel2418 0:9d5f28595388 233 * NSAPI_ERROR_WOULD_BLOCK if they can not continue.
kernel2418 0:9d5f28595388 234 *
kernel2418 0:9d5f28595388 235 * set_blocking(false) is equivalent to set_timeout(-1)
kernel2418 0:9d5f28595388 236 * set_blocking(true) is equivalent to set_timeout(0)
kernel2418 0:9d5f28595388 237 *
kernel2418 0:9d5f28595388 238 * @param blocking true for blocking mode, false for non-blocking mode.
kernel2418 0:9d5f28595388 239 */
kernel2418 0:9d5f28595388 240 void set_blocking(bool blocking) {
kernel2418 0:9d5f28595388 241 _tcpsocket->set_blocking(blocking);
kernel2418 0:9d5f28595388 242 }
kernel2418 0:9d5f28595388 243
kernel2418 0:9d5f28595388 244 /** Set timeout on blocking socket operations
kernel2418 0:9d5f28595388 245 *
kernel2418 0:9d5f28595388 246 * Initially all sockets have unbounded timeouts. NSAPI_ERROR_WOULD_BLOCK
kernel2418 0:9d5f28595388 247 * is returned if a blocking operation takes longer than the specified
kernel2418 0:9d5f28595388 248 * timeout. A timeout of 0 removes the timeout from the socket. A negative
kernel2418 0:9d5f28595388 249 * value give the socket an unbounded timeout.
kernel2418 0:9d5f28595388 250 *
kernel2418 0:9d5f28595388 251 * set_timeout(0) is equivalent to set_blocking(false)
kernel2418 0:9d5f28595388 252 * set_timeout(-1) is equivalent to set_blocking(true)
kernel2418 0:9d5f28595388 253 *
kernel2418 0:9d5f28595388 254 * @param timeout Timeout in milliseconds
kernel2418 0:9d5f28595388 255 */
kernel2418 0:9d5f28595388 256 void set_timeout(int timeout) {
kernel2418 0:9d5f28595388 257 _tcpsocket->set_timeout(timeout);
kernel2418 0:9d5f28595388 258 }
kernel2418 0:9d5f28595388 259
kernel2418 0:9d5f28595388 260 bool connected() {
kernel2418 0:9d5f28595388 261 return _is_connected;
kernel2418 0:9d5f28595388 262 }
kernel2418 0:9d5f28595388 263
kernel2418 0:9d5f28595388 264 nsapi_error_t error() {
kernel2418 0:9d5f28595388 265 return _error;
kernel2418 0:9d5f28595388 266 }
kernel2418 0:9d5f28595388 267
kernel2418 0:9d5f28595388 268 TCPSocket* get_tcp_socket() {
kernel2418 0:9d5f28595388 269 return _tcpsocket;
kernel2418 0:9d5f28595388 270 }
kernel2418 0:9d5f28595388 271
kernel2418 0:9d5f28595388 272 mbedtls_ssl_context* get_ssl_context() {
kernel2418 0:9d5f28595388 273 return &_ssl;
kernel2418 0:9d5f28595388 274 }
kernel2418 0:9d5f28595388 275
kernel2418 0:9d5f28595388 276 /**
kernel2418 0:9d5f28595388 277 * Set the debug flag.
kernel2418 0:9d5f28595388 278 *
kernel2418 0:9d5f28595388 279 * If this flag is set, debug information from mbed TLS will be logged to stdout.
kernel2418 0:9d5f28595388 280 */
kernel2418 0:9d5f28595388 281 void set_debug(bool debug) {
kernel2418 0:9d5f28595388 282 _debug = debug;
kernel2418 0:9d5f28595388 283 }
kernel2418 0:9d5f28595388 284
kernel2418 0:9d5f28595388 285 /**
kernel2418 0:9d5f28595388 286 * Timed recv for MQTT lib
kernel2418 0:9d5f28595388 287 */
kernel2418 0:9d5f28595388 288 int read(unsigned char* buffer, int len, int timeout) {
kernel2418 0:9d5f28595388 289 set_timeout(timeout);
kernel2418 0:9d5f28595388 290 return recv(buffer, len);
kernel2418 0:9d5f28595388 291 }
kernel2418 0:9d5f28595388 292
kernel2418 0:9d5f28595388 293 /**
kernel2418 0:9d5f28595388 294 * Timed send for MQTT lib
kernel2418 0:9d5f28595388 295 */
kernel2418 0:9d5f28595388 296 int write(unsigned char* buffer, int len, int timeout) {
kernel2418 0:9d5f28595388 297 set_timeout(timeout);
kernel2418 0:9d5f28595388 298 return send(buffer, len);
kernel2418 0:9d5f28595388 299 }
kernel2418 0:9d5f28595388 300
kernel2418 0:9d5f28595388 301 protected:
kernel2418 0:9d5f28595388 302
kernel2418 0:9d5f28595388 303 #if DEBUG_LEVEL > 0
kernel2418 0:9d5f28595388 304 /**
kernel2418 0:9d5f28595388 305 * Debug callback for mbed TLS
kernel2418 0:9d5f28595388 306 * Just prints on the USB serial port
kernel2418 0:9d5f28595388 307 */
kernel2418 0:9d5f28595388 308 static void my_debug(void *ctx, int level, const char *file, int line,
kernel2418 0:9d5f28595388 309 const char *str)
kernel2418 0:9d5f28595388 310 {
kernel2418 0:9d5f28595388 311 const char *p, *basename;
kernel2418 0:9d5f28595388 312 (void) ctx;
kernel2418 0:9d5f28595388 313
kernel2418 0:9d5f28595388 314 /* Extract basename from file */
kernel2418 0:9d5f28595388 315 for(p = basename = file; *p != '\0'; p++) {
kernel2418 0:9d5f28595388 316 if(*p == '/' || *p == '\\') {
kernel2418 0:9d5f28595388 317 basename = p + 1;
kernel2418 0:9d5f28595388 318 }
kernel2418 0:9d5f28595388 319 }
kernel2418 0:9d5f28595388 320
kernel2418 0:9d5f28595388 321 if (_debug) {
kernel2418 0:9d5f28595388 322 mbedtls_printf("%s:%04d: |%d| %s", basename, line, level, str);
kernel2418 0:9d5f28595388 323 }
kernel2418 0:9d5f28595388 324 }
kernel2418 0:9d5f28595388 325
kernel2418 0:9d5f28595388 326 /**
kernel2418 0:9d5f28595388 327 * Certificate verification callback for mbed TLS
kernel2418 0:9d5f28595388 328 * Here we only use it to display information on each cert in the chain
kernel2418 0:9d5f28595388 329 */
kernel2418 0:9d5f28595388 330 static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
kernel2418 0:9d5f28595388 331 {
kernel2418 0:9d5f28595388 332 const uint32_t buf_size = 1024;
kernel2418 0:9d5f28595388 333 char *buf = new char[buf_size];
kernel2418 0:9d5f28595388 334 (void) data;
kernel2418 0:9d5f28595388 335
kernel2418 0:9d5f28595388 336 if (_debug) mbedtls_printf("\nVerifying certificate at depth %d:\n", depth);
kernel2418 0:9d5f28595388 337 mbedtls_x509_crt_info(buf, buf_size - 1, " ", crt);
kernel2418 0:9d5f28595388 338 if (_debug) mbedtls_printf("%s", buf);
kernel2418 0:9d5f28595388 339
kernel2418 0:9d5f28595388 340 if (*flags == 0)
kernel2418 0:9d5f28595388 341 if (_debug) mbedtls_printf("No verification issue for this certificate\n");
kernel2418 0:9d5f28595388 342 else
kernel2418 0:9d5f28595388 343 {
kernel2418 0:9d5f28595388 344 mbedtls_x509_crt_verify_info(buf, buf_size, " ! ", *flags);
kernel2418 0:9d5f28595388 345 if (_debug) mbedtls_printf("%s\n", buf);
kernel2418 0:9d5f28595388 346 }
kernel2418 0:9d5f28595388 347
kernel2418 0:9d5f28595388 348 delete[] buf;
kernel2418 0:9d5f28595388 349 return 0;
kernel2418 0:9d5f28595388 350 }
kernel2418 0:9d5f28595388 351 #endif
kernel2418 0:9d5f28595388 352
kernel2418 0:9d5f28595388 353 /**
kernel2418 0:9d5f28595388 354 * Receive callback for mbed TLS
kernel2418 0:9d5f28595388 355 */
kernel2418 0:9d5f28595388 356 static int ssl_recv(void *ctx, unsigned char *buf, size_t len) {
kernel2418 0:9d5f28595388 357 int recv = -1;
kernel2418 0:9d5f28595388 358 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
kernel2418 0:9d5f28595388 359 recv = socket->recv(buf, len);
kernel2418 0:9d5f28595388 360
kernel2418 0:9d5f28595388 361 if (NSAPI_ERROR_WOULD_BLOCK == recv) {
kernel2418 0:9d5f28595388 362 return MBEDTLS_ERR_SSL_WANT_READ;
kernel2418 0:9d5f28595388 363 }
kernel2418 0:9d5f28595388 364 else if (recv < 0) {
kernel2418 0:9d5f28595388 365 return -1;
kernel2418 0:9d5f28595388 366 }
kernel2418 0:9d5f28595388 367 else {
kernel2418 0:9d5f28595388 368 return recv;
kernel2418 0:9d5f28595388 369 }
kernel2418 0:9d5f28595388 370 }
kernel2418 0:9d5f28595388 371
kernel2418 0:9d5f28595388 372 /**
kernel2418 0:9d5f28595388 373 * Send callback for mbed TLS
kernel2418 0:9d5f28595388 374 */
kernel2418 0:9d5f28595388 375 static int ssl_send(void *ctx, const unsigned char *buf, size_t len) {
kernel2418 0:9d5f28595388 376 int size = -1;
kernel2418 0:9d5f28595388 377 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
kernel2418 0:9d5f28595388 378 size = socket->send(buf, len);
kernel2418 0:9d5f28595388 379
kernel2418 0:9d5f28595388 380 if(NSAPI_ERROR_WOULD_BLOCK == size) {
kernel2418 0:9d5f28595388 381 return MBEDTLS_ERR_SSL_WANT_WRITE;
kernel2418 0:9d5f28595388 382 }
kernel2418 0:9d5f28595388 383 else if (size < 0){
kernel2418 0:9d5f28595388 384 return -1;
kernel2418 0:9d5f28595388 385 }
kernel2418 0:9d5f28595388 386 else {
kernel2418 0:9d5f28595388 387 return size;
kernel2418 0:9d5f28595388 388 }
kernel2418 0:9d5f28595388 389 }
kernel2418 0:9d5f28595388 390
kernel2418 0:9d5f28595388 391 private:
kernel2418 0:9d5f28595388 392 void onError(TCPSocket *s, int error) {
kernel2418 0:9d5f28595388 393 s->close();
kernel2418 0:9d5f28595388 394 _error = error;
kernel2418 0:9d5f28595388 395 }
kernel2418 0:9d5f28595388 396
kernel2418 0:9d5f28595388 397 TCPSocket* _tcpsocket;
kernel2418 0:9d5f28595388 398
kernel2418 0:9d5f28595388 399 const char* DRBG_PERS;
kernel2418 0:9d5f28595388 400 const char* _ssl_ca_pem;
kernel2418 0:9d5f28595388 401 const char* _ssl_owncert_pem;
kernel2418 0:9d5f28595388 402 const char* _ssl_own_priv_key_pem;
kernel2418 0:9d5f28595388 403 const char* _hostname;
kernel2418 0:9d5f28595388 404 uint16_t _port;
kernel2418 0:9d5f28595388 405
kernel2418 0:9d5f28595388 406 bool _debug;
kernel2418 0:9d5f28595388 407 bool _is_connected;
kernel2418 0:9d5f28595388 408
kernel2418 0:9d5f28595388 409 nsapi_error_t _error;
kernel2418 0:9d5f28595388 410
kernel2418 0:9d5f28595388 411 mbedtls_entropy_context _entropy;
kernel2418 0:9d5f28595388 412 mbedtls_ctr_drbg_context _ctr_drbg;
kernel2418 0:9d5f28595388 413 mbedtls_x509_crt _cacert;
kernel2418 0:9d5f28595388 414 mbedtls_x509_crt _owncert;
kernel2418 0:9d5f28595388 415 mbedtls_pk_context _own_priv_key;
kernel2418 0:9d5f28595388 416 mbedtls_ssl_context _ssl;
kernel2418 0:9d5f28595388 417 mbedtls_ssl_config _ssl_conf;
kernel2418 0:9d5f28595388 418 };
kernel2418 0:9d5f28595388 419
kernel2418 0:9d5f28595388 420 #endif // _TLS_SOCKET_H_