FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:37:05 2017 +0000
Revision:
0:dbad57390bd1
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:dbad57390bd1 1 /*
ram54288 0:dbad57390bd1 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
ram54288 0:dbad57390bd1 3 * SPDX-License-Identifier: Apache-2.0
ram54288 0:dbad57390bd1 4 * Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:dbad57390bd1 5 * not use this file except in compliance with the License.
ram54288 0:dbad57390bd1 6 * You may obtain a copy of the License at
ram54288 0:dbad57390bd1 7 *
ram54288 0:dbad57390bd1 8 * http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:dbad57390bd1 9 *
ram54288 0:dbad57390bd1 10 * Unless required by applicable law or agreed to in writing, software
ram54288 0:dbad57390bd1 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:dbad57390bd1 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:dbad57390bd1 13 * See the License for the specific language governing permissions and
ram54288 0:dbad57390bd1 14 * limitations under the License.
ram54288 0:dbad57390bd1 15 */
ram54288 0:dbad57390bd1 16
ram54288 0:dbad57390bd1 17 #include "mbed-client/m2mconnectionhandler.h"
ram54288 0:dbad57390bd1 18 #include "mbed-client-mbedtls/m2mconnectionsecuritypimpl.h"
ram54288 0:dbad57390bd1 19 #include "mbed-client/m2mtimer.h"
ram54288 0:dbad57390bd1 20 #include "mbed-client/m2msecurity.h"
ram54288 0:dbad57390bd1 21 #include "mbed-trace/mbed_trace.h"
ram54288 0:dbad57390bd1 22 #include "mbedtls/debug.h"
ram54288 0:dbad57390bd1 23 #include <string.h>
ram54288 0:dbad57390bd1 24
ram54288 0:dbad57390bd1 25 #define TRACE_GROUP "mClt"
ram54288 0:dbad57390bd1 26
ram54288 0:dbad57390bd1 27 void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
ram54288 0:dbad57390bd1 28 int mbedtls_timing_get_delay( void *data );
ram54288 0:dbad57390bd1 29 int entropy_poll( void *data, unsigned char *output, size_t len, size_t *olen );
ram54288 0:dbad57390bd1 30 //Point these back to M2MConnectionHandler!!!
ram54288 0:dbad57390bd1 31 int f_send( void *ctx, const unsigned char *buf, size_t len );
ram54288 0:dbad57390bd1 32 int f_recv(void *ctx, unsigned char *buf, size_t len);
ram54288 0:dbad57390bd1 33 int f_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t some);
ram54288 0:dbad57390bd1 34
ram54288 0:dbad57390bd1 35 bool cancelled;
ram54288 0:dbad57390bd1 36 random_number_cb __random_number_callback;
ram54288 0:dbad57390bd1 37 entropy_cb __entropy_callback;
ram54288 0:dbad57390bd1 38
ram54288 0:dbad57390bd1 39 //Comment out following define to enable tracing from mbedtls
ram54288 0:dbad57390bd1 40 //#define ENABLE_MBED_CLIENT_MBED_TLS_DEBUGS
ram54288 0:dbad57390bd1 41 #ifdef ENABLE_MBED_CLIENT_MBED_TLS_DEBUGS
ram54288 0:dbad57390bd1 42 static void mbedtls_debug( void *ctx, int level,
ram54288 0:dbad57390bd1 43 const char *file, int line, const char *str )
ram54288 0:dbad57390bd1 44 {
ram54288 0:dbad57390bd1 45 ((void) level);
ram54288 0:dbad57390bd1 46 tr_debug("%s", str);
ram54288 0:dbad57390bd1 47 }
ram54288 0:dbad57390bd1 48
ram54288 0:dbad57390bd1 49 static int verify_cert_chains(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
ram54288 0:dbad57390bd1 50 {
ram54288 0:dbad57390bd1 51 char buf[1024];
ram54288 0:dbad57390bd1 52 (void) data;
ram54288 0:dbad57390bd1 53
ram54288 0:dbad57390bd1 54 printf("\nVerifying certificate at depth %d:\n", depth);
ram54288 0:dbad57390bd1 55 mbedtls_x509_crt_info(buf, sizeof (buf) - 1, " ", crt);
ram54288 0:dbad57390bd1 56 printf("%s", buf);
ram54288 0:dbad57390bd1 57
ram54288 0:dbad57390bd1 58 if (*flags == 0)
ram54288 0:dbad57390bd1 59 printf("No verification issue for this certificate\n");
ram54288 0:dbad57390bd1 60 else
ram54288 0:dbad57390bd1 61 {
ram54288 0:dbad57390bd1 62 mbedtls_x509_crt_verify_info(buf, sizeof (buf), " ! ", *flags);
ram54288 0:dbad57390bd1 63 printf("%s\n", buf);
ram54288 0:dbad57390bd1 64 }
ram54288 0:dbad57390bd1 65
ram54288 0:dbad57390bd1 66 return 0;
ram54288 0:dbad57390bd1 67 }
ram54288 0:dbad57390bd1 68 #endif
ram54288 0:dbad57390bd1 69
ram54288 0:dbad57390bd1 70 M2MConnectionSecurityPimpl::M2MConnectionSecurityPimpl(M2MConnectionSecurity::SecurityMode mode)
ram54288 0:dbad57390bd1 71 : _flags(0),
ram54288 0:dbad57390bd1 72 _sec_mode(mode)
ram54288 0:dbad57390bd1 73 {
ram54288 0:dbad57390bd1 74 _init_done = false;
ram54288 0:dbad57390bd1 75 cancelled = true;
ram54288 0:dbad57390bd1 76 _timer = new M2MTimer(*this);
ram54288 0:dbad57390bd1 77 mbedtls_ssl_init( &_ssl );
ram54288 0:dbad57390bd1 78 mbedtls_ssl_config_init( &_conf );
ram54288 0:dbad57390bd1 79 mbedtls_x509_crt_init( &_cacert );
ram54288 0:dbad57390bd1 80 mbedtls_x509_crt_init(&_owncert);
ram54288 0:dbad57390bd1 81 mbedtls_pk_init(&_pkey);
ram54288 0:dbad57390bd1 82 mbedtls_ctr_drbg_init( &_ctr_drbg );
ram54288 0:dbad57390bd1 83 mbedtls_entropy_init( &_entropy );
ram54288 0:dbad57390bd1 84 }
ram54288 0:dbad57390bd1 85
ram54288 0:dbad57390bd1 86 M2MConnectionSecurityPimpl::~M2MConnectionSecurityPimpl(){
ram54288 0:dbad57390bd1 87 mbedtls_ssl_config_free(&_conf);
ram54288 0:dbad57390bd1 88 mbedtls_ssl_free(&_ssl);
ram54288 0:dbad57390bd1 89 mbedtls_x509_crt_free(&_cacert);
ram54288 0:dbad57390bd1 90 mbedtls_x509_crt_free(&_owncert);
ram54288 0:dbad57390bd1 91 mbedtls_pk_free(&_pkey);
ram54288 0:dbad57390bd1 92 mbedtls_ctr_drbg_free( &_ctr_drbg );
ram54288 0:dbad57390bd1 93 mbedtls_entropy_free( &_entropy );
ram54288 0:dbad57390bd1 94 delete _timer;
ram54288 0:dbad57390bd1 95 }
ram54288 0:dbad57390bd1 96
ram54288 0:dbad57390bd1 97 void M2MConnectionSecurityPimpl::timer_expired(M2MTimerObserver::Type type){
ram54288 0:dbad57390bd1 98 tr_debug("M2MConnectionSecurityPimpl::timer_expired");
ram54288 0:dbad57390bd1 99 if(type == M2MTimerObserver::Dtls && !cancelled){
ram54288 0:dbad57390bd1 100 int error = continue_connecting();
ram54288 0:dbad57390bd1 101 if(MBEDTLS_ERR_SSL_TIMEOUT == error || error == -1) {
ram54288 0:dbad57390bd1 102 tr_error("M2MConnectionSecurityPimpl::timer_expired - handshake timeout");
ram54288 0:dbad57390bd1 103 if(_ssl.p_bio) {
ram54288 0:dbad57390bd1 104 M2MConnectionHandler* ptr = (M2MConnectionHandler*)_ssl.p_bio;
ram54288 0:dbad57390bd1 105 ptr->handle_connection_error(M2MConnectionHandler::SSL_HANDSHAKE_ERROR);
ram54288 0:dbad57390bd1 106 }
ram54288 0:dbad57390bd1 107 reset();
ram54288 0:dbad57390bd1 108 }
ram54288 0:dbad57390bd1 109 }
ram54288 0:dbad57390bd1 110 }
ram54288 0:dbad57390bd1 111
ram54288 0:dbad57390bd1 112 void M2MConnectionSecurityPimpl::reset(){
ram54288 0:dbad57390bd1 113 _init_done = false;
ram54288 0:dbad57390bd1 114 cancelled = true;
ram54288 0:dbad57390bd1 115 mbedtls_ssl_config_free(&_conf);
ram54288 0:dbad57390bd1 116 mbedtls_ssl_free(&_ssl);
ram54288 0:dbad57390bd1 117 mbedtls_x509_crt_free(&_cacert);
ram54288 0:dbad57390bd1 118 mbedtls_x509_crt_free(&_owncert);
ram54288 0:dbad57390bd1 119 mbedtls_pk_free(&_pkey);
ram54288 0:dbad57390bd1 120 mbedtls_ctr_drbg_free( &_ctr_drbg );
ram54288 0:dbad57390bd1 121 mbedtls_entropy_free( &_entropy );
ram54288 0:dbad57390bd1 122 _timer->stop_timer();
ram54288 0:dbad57390bd1 123 }
ram54288 0:dbad57390bd1 124
ram54288 0:dbad57390bd1 125 int M2MConnectionSecurityPimpl::init(const M2MSecurity *security)
ram54288 0:dbad57390bd1 126 {
ram54288 0:dbad57390bd1 127 tr_debug("M2MConnectionSecurityPimpl::init");
ram54288 0:dbad57390bd1 128 int ret = -1;
ram54288 0:dbad57390bd1 129 if (security != NULL) {
ram54288 0:dbad57390bd1 130 const char *pers = "dtls_client";
ram54288 0:dbad57390bd1 131 mbedtls_ssl_init( &_ssl );
ram54288 0:dbad57390bd1 132 mbedtls_ssl_config_init( &_conf );
ram54288 0:dbad57390bd1 133 mbedtls_x509_crt_init( &_cacert );
ram54288 0:dbad57390bd1 134 mbedtls_x509_crt_init(&_owncert);
ram54288 0:dbad57390bd1 135 mbedtls_pk_init(&_pkey);
ram54288 0:dbad57390bd1 136 mbedtls_ctr_drbg_init( &_ctr_drbg );
ram54288 0:dbad57390bd1 137 mbedtls_entropy_init( &_entropy );
ram54288 0:dbad57390bd1 138
ram54288 0:dbad57390bd1 139 int mode = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
ram54288 0:dbad57390bd1 140 if( _sec_mode == M2MConnectionSecurity::TLS ){
ram54288 0:dbad57390bd1 141 mode = MBEDTLS_SSL_TRANSPORT_STREAM;
ram54288 0:dbad57390bd1 142 }
ram54288 0:dbad57390bd1 143
ram54288 0:dbad57390bd1 144 if( mbedtls_entropy_add_source( &_entropy, entropy_poll, NULL,
ram54288 0:dbad57390bd1 145 128, 0 ) < 0 ){
ram54288 0:dbad57390bd1 146 return -1;
ram54288 0:dbad57390bd1 147 }
ram54288 0:dbad57390bd1 148 if(__entropy_callback.entropy_source_ptr) {
ram54288 0:dbad57390bd1 149 if( mbedtls_entropy_add_source( &_entropy, __entropy_callback.entropy_source_ptr,
ram54288 0:dbad57390bd1 150 __entropy_callback.p_source,__entropy_callback.threshold,
ram54288 0:dbad57390bd1 151 __entropy_callback.strong ) < 0 ){
ram54288 0:dbad57390bd1 152 return -1;
ram54288 0:dbad57390bd1 153 }
ram54288 0:dbad57390bd1 154 }
ram54288 0:dbad57390bd1 155
ram54288 0:dbad57390bd1 156 if( mbedtls_ctr_drbg_seed( &_ctr_drbg, mbedtls_entropy_func, &_entropy,
ram54288 0:dbad57390bd1 157 (const unsigned char *) pers,
ram54288 0:dbad57390bd1 158 strlen( pers ) ) != 0 ) {
ram54288 0:dbad57390bd1 159 return -1;
ram54288 0:dbad57390bd1 160 }
ram54288 0:dbad57390bd1 161
ram54288 0:dbad57390bd1 162 if( mbedtls_ssl_config_defaults( &_conf,
ram54288 0:dbad57390bd1 163 MBEDTLS_SSL_IS_CLIENT,
ram54288 0:dbad57390bd1 164 mode, 0 ) != 0 ) {
ram54288 0:dbad57390bd1 165 return -1;
ram54288 0:dbad57390bd1 166 }
ram54288 0:dbad57390bd1 167
ram54288 0:dbad57390bd1 168 M2MSecurity::SecurityModeType cert_mode =
ram54288 0:dbad57390bd1 169 (M2MSecurity::SecurityModeType)security->resource_value_int(M2MSecurity::SecurityMode);
ram54288 0:dbad57390bd1 170
ram54288 0:dbad57390bd1 171 // Note: these are relatively large buffers, no point to make copy of them here as mbedtls will make a copy of them.
ram54288 0:dbad57390bd1 172 const uint8_t *srv_public_key = NULL;
ram54288 0:dbad57390bd1 173 const uint8_t *public_key = NULL;
ram54288 0:dbad57390bd1 174 const uint8_t *sec_key = NULL;
ram54288 0:dbad57390bd1 175
ram54288 0:dbad57390bd1 176 uint32_t srv_public_key_size = security->resource_value_buffer(M2MSecurity::ServerPublicKey, srv_public_key);
ram54288 0:dbad57390bd1 177 uint32_t public_key_size = security->resource_value_buffer(M2MSecurity::PublicKey, public_key);
ram54288 0:dbad57390bd1 178 uint32_t sec_key_size = security->resource_value_buffer(M2MSecurity::Secretkey, sec_key);
ram54288 0:dbad57390bd1 179 if( srv_public_key == NULL || public_key == NULL || sec_key == NULL ||
ram54288 0:dbad57390bd1 180 srv_public_key_size == 0 || public_key_size == 0 || sec_key_size == 0 ){
ram54288 0:dbad57390bd1 181 return -1;
ram54288 0:dbad57390bd1 182 }
ram54288 0:dbad57390bd1 183
ram54288 0:dbad57390bd1 184 if( cert_mode == M2MSecurity::Certificate ){
ram54288 0:dbad57390bd1 185 if ( mbedtls_x509_crt_parse( &_cacert, (const unsigned char *) srv_public_key,
ram54288 0:dbad57390bd1 186 srv_public_key_size + 1) < 0 ||
ram54288 0:dbad57390bd1 187 mbedtls_x509_crt_parse( &_owncert, (const unsigned char *) public_key,
ram54288 0:dbad57390bd1 188 public_key_size + 1) < 0 ||
ram54288 0:dbad57390bd1 189 mbedtls_pk_parse_key(&_pkey, (const unsigned char *) sec_key,
ram54288 0:dbad57390bd1 190 sec_key_size + 1, NULL, 0 ) < 0 ) {
ram54288 0:dbad57390bd1 191 ret = -1;
ram54288 0:dbad57390bd1 192 } else {
ram54288 0:dbad57390bd1 193 ret = 0;
ram54288 0:dbad57390bd1 194 }
ram54288 0:dbad57390bd1 195
ram54288 0:dbad57390bd1 196 if ( ret == 0 ) {
ram54288 0:dbad57390bd1 197 mbedtls_ssl_conf_own_cert(&_conf, &_owncert, &_pkey);
ram54288 0:dbad57390bd1 198 mbedtls_ssl_conf_authmode( &_conf, MBEDTLS_SSL_VERIFY_REQUIRED );
ram54288 0:dbad57390bd1 199 mbedtls_ssl_conf_ca_chain( &_conf, &_cacert, NULL );
ram54288 0:dbad57390bd1 200 }
ram54288 0:dbad57390bd1 201
ram54288 0:dbad57390bd1 202 } else if ( cert_mode == M2MSecurity::Psk ){
ram54288 0:dbad57390bd1 203 if (mbedtls_ssl_conf_psk(&_conf, sec_key, sec_key_size, public_key, public_key_size) == 0) {
ram54288 0:dbad57390bd1 204 ret = 0;
ram54288 0:dbad57390bd1 205 }
ram54288 0:dbad57390bd1 206 mbedtls_ssl_conf_ciphersuites(&_conf, PSK_SUITES);
ram54288 0:dbad57390bd1 207 } else {
ram54288 0:dbad57390bd1 208 ret = -1;
ram54288 0:dbad57390bd1 209 }
ram54288 0:dbad57390bd1 210
ram54288 0:dbad57390bd1 211 #ifdef ENABLE_MBED_CLIENT_MBED_TLS_DEBUGS
ram54288 0:dbad57390bd1 212 mbedtls_ssl_conf_dbg( &_conf, mbedtls_debug, stdout );
ram54288 0:dbad57390bd1 213 mbedtls_debug_set_threshold(5);
ram54288 0:dbad57390bd1 214 mbedtls_ssl_conf_verify(&_conf, verify_cert_chains, NULL);
ram54288 0:dbad57390bd1 215 #endif
ram54288 0:dbad57390bd1 216 }
ram54288 0:dbad57390bd1 217
ram54288 0:dbad57390bd1 218 if( ret == 0 ){
ram54288 0:dbad57390bd1 219 _init_done = true;
ram54288 0:dbad57390bd1 220 }
ram54288 0:dbad57390bd1 221 tr_debug("M2MConnectionSecurityPimpl::init - ret %d", ret);
ram54288 0:dbad57390bd1 222 return ret;
ram54288 0:dbad57390bd1 223 }
ram54288 0:dbad57390bd1 224
ram54288 0:dbad57390bd1 225
ram54288 0:dbad57390bd1 226 int M2MConnectionSecurityPimpl::start_handshake(){
ram54288 0:dbad57390bd1 227 tr_debug("M2MConnectionSecurityPimpl::start_handshake");
ram54288 0:dbad57390bd1 228 int ret = -1;
ram54288 0:dbad57390bd1 229 do
ram54288 0:dbad57390bd1 230 {
ram54288 0:dbad57390bd1 231 ret = mbedtls_ssl_handshake( &_ssl );
ram54288 0:dbad57390bd1 232 }
ram54288 0:dbad57390bd1 233 while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
ram54288 0:dbad57390bd1 234 ret == MBEDTLS_ERR_SSL_WANT_WRITE);
ram54288 0:dbad57390bd1 235
ram54288 0:dbad57390bd1 236 if( ret != 0 ) {
ram54288 0:dbad57390bd1 237 ret = -1;
ram54288 0:dbad57390bd1 238 }else {
ram54288 0:dbad57390bd1 239 if( ( _flags = mbedtls_ssl_get_verify_result( &_ssl ) ) != 0 ) {
ram54288 0:dbad57390bd1 240 ret = -1;
ram54288 0:dbad57390bd1 241 }
ram54288 0:dbad57390bd1 242 }
ram54288 0:dbad57390bd1 243 tr_debug("M2MConnectionSecurityPimpl::start_handshake - OUT");
ram54288 0:dbad57390bd1 244 return ret;
ram54288 0:dbad57390bd1 245 }
ram54288 0:dbad57390bd1 246
ram54288 0:dbad57390bd1 247 int M2MConnectionSecurityPimpl::connect(M2MConnectionHandler* connHandler){
ram54288 0:dbad57390bd1 248
ram54288 0:dbad57390bd1 249 tr_debug("M2MConnectionSecurityPimpl::connect");
ram54288 0:dbad57390bd1 250 int ret=-1;
ram54288 0:dbad57390bd1 251 if(!_init_done){
ram54288 0:dbad57390bd1 252 return ret;
ram54288 0:dbad57390bd1 253 }
ram54288 0:dbad57390bd1 254
ram54288 0:dbad57390bd1 255 mbedtls_ssl_conf_rng( &_conf, mbedtls_ctr_drbg_random, &_ctr_drbg );
ram54288 0:dbad57390bd1 256
ram54288 0:dbad57390bd1 257 if( ( ret = mbedtls_ssl_setup( &_ssl, &_conf ) ) != 0 ) {
ram54288 0:dbad57390bd1 258 return -1;
ram54288 0:dbad57390bd1 259 }
ram54288 0:dbad57390bd1 260
ram54288 0:dbad57390bd1 261 mbedtls_ssl_set_bio( &_ssl, connHandler,
ram54288 0:dbad57390bd1 262 f_send, f_recv, f_recv_timeout );
ram54288 0:dbad57390bd1 263
ram54288 0:dbad57390bd1 264 mbedtls_ssl_set_timer_cb( &_ssl, _timer, mbedtls_timing_set_delay,
ram54288 0:dbad57390bd1 265 mbedtls_timing_get_delay );
ram54288 0:dbad57390bd1 266
ram54288 0:dbad57390bd1 267 ret = start_handshake();
ram54288 0:dbad57390bd1 268 _timer->stop_timer();
ram54288 0:dbad57390bd1 269 tr_debug("M2MConnectionSecurityPimpl::connect - handshake ret: %d, ssl state: %d", ret, _ssl.state);
ram54288 0:dbad57390bd1 270 return ret;
ram54288 0:dbad57390bd1 271 }
ram54288 0:dbad57390bd1 272
ram54288 0:dbad57390bd1 273 int M2MConnectionSecurityPimpl::start_connecting_non_blocking(M2MConnectionHandler* connHandler)
ram54288 0:dbad57390bd1 274 {
ram54288 0:dbad57390bd1 275 tr_debug("M2MConnectionSecurityPimpl::start_connecting_non_blocking");
ram54288 0:dbad57390bd1 276 int ret=-1;
ram54288 0:dbad57390bd1 277 if(!_init_done){
ram54288 0:dbad57390bd1 278 return ret;
ram54288 0:dbad57390bd1 279 }
ram54288 0:dbad57390bd1 280
ram54288 0:dbad57390bd1 281 int mode = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
ram54288 0:dbad57390bd1 282 if( _sec_mode == M2MConnectionSecurity::TLS ){
ram54288 0:dbad57390bd1 283 mode = MBEDTLS_SSL_TRANSPORT_STREAM;
ram54288 0:dbad57390bd1 284 }
ram54288 0:dbad57390bd1 285
ram54288 0:dbad57390bd1 286 if( ( ret = mbedtls_ssl_config_defaults( &_conf,
ram54288 0:dbad57390bd1 287 MBEDTLS_SSL_IS_CLIENT,
ram54288 0:dbad57390bd1 288 mode, 0 ) ) != 0 )
ram54288 0:dbad57390bd1 289 {
ram54288 0:dbad57390bd1 290 return -1;
ram54288 0:dbad57390bd1 291 }
ram54288 0:dbad57390bd1 292
ram54288 0:dbad57390bd1 293 // This is for non-blocking sockets total timeout is 1+2+4+8+16+29=60 seconds
ram54288 0:dbad57390bd1 294 mbedtls_ssl_conf_handshake_timeout( &_conf, 10000, 29000 );
ram54288 0:dbad57390bd1 295 mbedtls_ssl_conf_rng( &_conf, mbedtls_ctr_drbg_random, &_ctr_drbg );
ram54288 0:dbad57390bd1 296
ram54288 0:dbad57390bd1 297 if( ( ret = mbedtls_ssl_setup( &_ssl, &_conf ) ) != 0 )
ram54288 0:dbad57390bd1 298 {
ram54288 0:dbad57390bd1 299 return -1;
ram54288 0:dbad57390bd1 300 }
ram54288 0:dbad57390bd1 301
ram54288 0:dbad57390bd1 302 mbedtls_ssl_set_bio( &_ssl, connHandler,
ram54288 0:dbad57390bd1 303 f_send, f_recv, f_recv_timeout );
ram54288 0:dbad57390bd1 304
ram54288 0:dbad57390bd1 305 mbedtls_ssl_set_timer_cb( &_ssl, _timer, mbedtls_timing_set_delay,
ram54288 0:dbad57390bd1 306 mbedtls_timing_get_delay );
ram54288 0:dbad57390bd1 307
ram54288 0:dbad57390bd1 308 ret = mbedtls_ssl_handshake_step( &_ssl );
ram54288 0:dbad57390bd1 309 if( ret == 0 ){
ram54288 0:dbad57390bd1 310 ret = mbedtls_ssl_handshake_step( &_ssl );
ram54288 0:dbad57390bd1 311 }
ram54288 0:dbad57390bd1 312
ram54288 0:dbad57390bd1 313 if( ret >= 0){
ram54288 0:dbad57390bd1 314 ret = 1;
ram54288 0:dbad57390bd1 315 } else {
ram54288 0:dbad57390bd1 316 ret = -1;
ram54288 0:dbad57390bd1 317 }
ram54288 0:dbad57390bd1 318 tr_debug("M2MConnectionSecurityPimpl::start_connecting_non_blocking - handshake ret: %d, ssl state: %d", ret, _ssl.state);
ram54288 0:dbad57390bd1 319 return ret;
ram54288 0:dbad57390bd1 320 }
ram54288 0:dbad57390bd1 321
ram54288 0:dbad57390bd1 322 int M2MConnectionSecurityPimpl::continue_connecting()
ram54288 0:dbad57390bd1 323 {
ram54288 0:dbad57390bd1 324 tr_debug("M2MConnectionSecurityPimpl::continue_connecting");
ram54288 0:dbad57390bd1 325 int ret=-1;
ram54288 0:dbad57390bd1 326 while( ret != M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ ){
ram54288 0:dbad57390bd1 327 ret = mbedtls_ssl_handshake_step( &_ssl );
ram54288 0:dbad57390bd1 328 if( MBEDTLS_ERR_SSL_WANT_READ == ret ){
ram54288 0:dbad57390bd1 329 ret = M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ;
ram54288 0:dbad57390bd1 330 }
ram54288 0:dbad57390bd1 331 else if (ret != 0) {
ram54288 0:dbad57390bd1 332 break;
ram54288 0:dbad57390bd1 333 }
ram54288 0:dbad57390bd1 334
ram54288 0:dbad57390bd1 335 if( _ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER ){
ram54288 0:dbad57390bd1 336 return 0;
ram54288 0:dbad57390bd1 337 }
ram54288 0:dbad57390bd1 338 }
ram54288 0:dbad57390bd1 339 tr_debug("M2MConnectionSecurityPimpl::continue_connecting, ret: %d", ret);
ram54288 0:dbad57390bd1 340 return ret;
ram54288 0:dbad57390bd1 341 }
ram54288 0:dbad57390bd1 342
ram54288 0:dbad57390bd1 343 int M2MConnectionSecurityPimpl::send_message(unsigned char *message, int len){
ram54288 0:dbad57390bd1 344 tr_debug("M2MConnectionSecurityPimpl::send_message");
ram54288 0:dbad57390bd1 345 int ret=-1;
ram54288 0:dbad57390bd1 346 if(!_init_done){
ram54288 0:dbad57390bd1 347 return ret;
ram54288 0:dbad57390bd1 348 }
ram54288 0:dbad57390bd1 349
ram54288 0:dbad57390bd1 350 do ret = mbedtls_ssl_write( &_ssl, (unsigned char *) message, len );
ram54288 0:dbad57390bd1 351 while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
ram54288 0:dbad57390bd1 352 ret == MBEDTLS_ERR_SSL_WANT_WRITE );
ram54288 0:dbad57390bd1 353
ram54288 0:dbad57390bd1 354 tr_debug("M2MConnectionSecurityPimpl::send_message - ret: %d", ret);
ram54288 0:dbad57390bd1 355 return ret; //bytes written
ram54288 0:dbad57390bd1 356 }
ram54288 0:dbad57390bd1 357
ram54288 0:dbad57390bd1 358 int M2MConnectionSecurityPimpl::read(unsigned char* buffer, uint16_t len){
ram54288 0:dbad57390bd1 359 int ret=-1;
ram54288 0:dbad57390bd1 360 if(!_init_done){
ram54288 0:dbad57390bd1 361 tr_error("M2MConnectionSecurityPimpl::read - init not done!");
ram54288 0:dbad57390bd1 362 return ret;
ram54288 0:dbad57390bd1 363 }
ram54288 0:dbad57390bd1 364
ram54288 0:dbad57390bd1 365 memset( buffer, 0, len );
ram54288 0:dbad57390bd1 366 do ret = mbedtls_ssl_read( &_ssl, buffer, len-1 );
ram54288 0:dbad57390bd1 367 while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
ram54288 0:dbad57390bd1 368 ret == MBEDTLS_ERR_SSL_WANT_WRITE );
ram54288 0:dbad57390bd1 369
ram54288 0:dbad57390bd1 370 return ret; //bytes read
ram54288 0:dbad57390bd1 371 }
ram54288 0:dbad57390bd1 372
ram54288 0:dbad57390bd1 373 int f_send( void *ctx, const unsigned char *buf, size_t len){
ram54288 0:dbad57390bd1 374 M2MConnectionHandler* handler = ((M2MConnectionHandler *) ctx);
ram54288 0:dbad57390bd1 375 return handler->send_to_socket(buf, len);
ram54288 0:dbad57390bd1 376 }
ram54288 0:dbad57390bd1 377
ram54288 0:dbad57390bd1 378 int f_recv(void *ctx, unsigned char *buf, size_t len){
ram54288 0:dbad57390bd1 379 M2MConnectionHandler* handler = ((M2MConnectionHandler *) ctx);
ram54288 0:dbad57390bd1 380 return handler->receive_from_socket(buf, len);
ram54288 0:dbad57390bd1 381 }
ram54288 0:dbad57390bd1 382
ram54288 0:dbad57390bd1 383 int f_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t /*some*/){
ram54288 0:dbad57390bd1 384 return f_recv(ctx, buf, len);
ram54288 0:dbad57390bd1 385 }
ram54288 0:dbad57390bd1 386
ram54288 0:dbad57390bd1 387 int entropy_poll( void *, unsigned char *output, size_t len,
ram54288 0:dbad57390bd1 388 size_t *olen )
ram54288 0:dbad57390bd1 389 {
ram54288 0:dbad57390bd1 390 uint32_t rdm = 0;
ram54288 0:dbad57390bd1 391 if(__random_number_callback) {
ram54288 0:dbad57390bd1 392 rdm = __random_number_callback();
ram54288 0:dbad57390bd1 393 } else {
ram54288 0:dbad57390bd1 394 rdm = time(NULL);
ram54288 0:dbad57390bd1 395 }
ram54288 0:dbad57390bd1 396 for(uint16_t i=0; i < len; i++){
ram54288 0:dbad57390bd1 397 srand(rdm);
ram54288 0:dbad57390bd1 398 output[i] = rand() % 256;
ram54288 0:dbad57390bd1 399 }
ram54288 0:dbad57390bd1 400 *olen = len;
ram54288 0:dbad57390bd1 401
ram54288 0:dbad57390bd1 402 return( 0 );
ram54288 0:dbad57390bd1 403 }
ram54288 0:dbad57390bd1 404
ram54288 0:dbad57390bd1 405 void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ){
ram54288 0:dbad57390bd1 406 tr_debug("mbedtls_timing_set_delay - intermediate: %d", int_ms);
ram54288 0:dbad57390bd1 407 tr_debug("mbedtls_timing_set_delay - final: %d", fin_ms);
ram54288 0:dbad57390bd1 408 M2MTimer* timer = static_cast<M2MTimer*> (data);
ram54288 0:dbad57390bd1 409 if(!timer) {
ram54288 0:dbad57390bd1 410 return;
ram54288 0:dbad57390bd1 411 }
ram54288 0:dbad57390bd1 412 if( int_ms > 0 && fin_ms > 0 ){
ram54288 0:dbad57390bd1 413 tr_debug("mbedtls_timing_set_delay - start");
ram54288 0:dbad57390bd1 414 cancelled = false;
ram54288 0:dbad57390bd1 415 timer->stop_timer();
ram54288 0:dbad57390bd1 416 timer->start_dtls_timer(int_ms, fin_ms);
ram54288 0:dbad57390bd1 417 }else{
ram54288 0:dbad57390bd1 418 tr_debug("mbedtls_timing_set_delay - stop");
ram54288 0:dbad57390bd1 419 cancelled = true;
ram54288 0:dbad57390bd1 420 timer->stop_timer();
ram54288 0:dbad57390bd1 421 }
ram54288 0:dbad57390bd1 422 }
ram54288 0:dbad57390bd1 423
ram54288 0:dbad57390bd1 424 int mbedtls_timing_get_delay( void *data ){
ram54288 0:dbad57390bd1 425 tr_debug("mbedtls_timing_get_delay");
ram54288 0:dbad57390bd1 426 M2MTimer* timer = static_cast<M2MTimer*> (data);
ram54288 0:dbad57390bd1 427 if(!timer){
ram54288 0:dbad57390bd1 428 return 0;
ram54288 0:dbad57390bd1 429 }
ram54288 0:dbad57390bd1 430 if(true == cancelled) {
ram54288 0:dbad57390bd1 431 tr_debug("mbedtls_timing_get_delay - ret -1");
ram54288 0:dbad57390bd1 432 return -1;
ram54288 0:dbad57390bd1 433 } else if( timer->is_total_interval_passed() ){
ram54288 0:dbad57390bd1 434 tr_debug("mbedtls_timing_get_delay - ret 2");
ram54288 0:dbad57390bd1 435 return 2;
ram54288 0:dbad57390bd1 436 }else if( timer->is_intermediate_interval_passed() ){
ram54288 0:dbad57390bd1 437 tr_debug("mbedtls_timing_get_delay - ret 1");
ram54288 0:dbad57390bd1 438 return 1;
ram54288 0:dbad57390bd1 439 }else{
ram54288 0:dbad57390bd1 440 tr_debug("mbedtls_timing_get_delay - ret 0");
ram54288 0:dbad57390bd1 441 return 0;
ram54288 0:dbad57390bd1 442 }
ram54288 0:dbad57390bd1 443 }
ram54288 0:dbad57390bd1 444
ram54288 0:dbad57390bd1 445 void M2MConnectionSecurityPimpl::set_random_number_callback(random_number_cb callback)
ram54288 0:dbad57390bd1 446 {
ram54288 0:dbad57390bd1 447 __random_number_callback = callback;
ram54288 0:dbad57390bd1 448 }
ram54288 0:dbad57390bd1 449
ram54288 0:dbad57390bd1 450 void M2MConnectionSecurityPimpl::set_entropy_callback(entropy_cb callback)
ram54288 0:dbad57390bd1 451 {
ram54288 0:dbad57390bd1 452 __entropy_callback = callback;
ram54288 0:dbad57390bd1 453 }
ram54288 0:dbad57390bd1 454