sandbox / mbed-client-mbedtls

Fork of mbed-client-mbedtls by Christopher Haster

Committer:
Yogesh Pande
Date:
Thu Apr 07 02:01:28 2016 +0300
Revision:
5:840aa460b437
Parent:
4:1ca4b8bd7dd2
Child:
6:80a66815c791
Modifying mbed-client-mbedtls implementation to manage blocking receive socket call with timeouts.

Who changed what in which revision?

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