This is a fork due to permission issues

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

Committer:
maclobdell
Date:
Wed May 18 19:06:32 2016 +0000
Revision:
0:f7c60d3e7b8a
clean version

Who changed what in which revision?

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