
This is a fork due to permission issues
Dependencies: mbed Socket lwip-eth lwip-sys lwip
Fork of 6_songs-from-the-cloud by
mbed-client/mbed-client-mbedtls/source/m2mconnectionsecuritypimpl.cpp@0:f7c60d3e7b8a, 2016-05-18 (annotated)
- Committer:
- maclobdell
- Date:
- Wed May 18 19:06:32 2016 +0000
- Revision:
- 0:f7c60d3e7b8a
clean version
Who changed what in which revision?
User | Revision | Line number | New 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 | } |