V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

Committer:
ampembeng
Date:
Thu Dec 01 18:05:38 2016 +0000
Revision:
15:6f2798e45099
Child:
18:6370da1de572
Initial commit.  Demo works with both the FRDM wired Ethernet and the Avnet Shield wireless modem.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ampembeng 15:6f2798e45099 1 /*
ampembeng 15:6f2798e45099 2 * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
ampembeng 15:6f2798e45099 3 *
ampembeng 15:6f2798e45099 4 * Licensed under the Apache License, Version 2.0 (the "License").
ampembeng 15:6f2798e45099 5 * You may not use this file except in compliance with the License.
ampembeng 15:6f2798e45099 6 * A copy of the License is located at
ampembeng 15:6f2798e45099 7 *
ampembeng 15:6f2798e45099 8 * http://aws.amazon.com/apache2.0
ampembeng 15:6f2798e45099 9 *
ampembeng 15:6f2798e45099 10 * or in the "license" file accompanying this file. This file is distributed
ampembeng 15:6f2798e45099 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
ampembeng 15:6f2798e45099 12 * express or implied. See the License for the specific language governing
ampembeng 15:6f2798e45099 13 * permissions and limitations under the License.
ampembeng 15:6f2798e45099 14 */
ampembeng 15:6f2798e45099 15
ampembeng 15:6f2798e45099 16 #include <stdbool.h>
ampembeng 15:6f2798e45099 17 #include <string.h>
ampembeng 15:6f2798e45099 18
ampembeng 15:6f2798e45099 19
ampembeng 15:6f2798e45099 20 #include "aws_iot_config.h"
ampembeng 15:6f2798e45099 21 #include "aws_iot_error.h"
ampembeng 15:6f2798e45099 22 #include "aws_iot_log.h"
ampembeng 15:6f2798e45099 23 #include "network_interface.h"
ampembeng 15:6f2798e45099 24 #include "mbedtls/config.h"
ampembeng 15:6f2798e45099 25
ampembeng 15:6f2798e45099 26 #include "mbedtls/net.h"
ampembeng 15:6f2798e45099 27 #include "mbedtls/ssl.h"
ampembeng 15:6f2798e45099 28 #include "mbedtls/entropy.h"
ampembeng 15:6f2798e45099 29 #include "mbedtls/ctr_drbg.h"
ampembeng 15:6f2798e45099 30 #include "mbedtls/certs.h"
ampembeng 15:6f2798e45099 31 #include "mbedtls/x509.h"
ampembeng 15:6f2798e45099 32 #include "mbedtls/error.h"
ampembeng 15:6f2798e45099 33 #include "mbedtls/debug.h"
ampembeng 15:6f2798e45099 34 #include "mbedtls/timing.h"
ampembeng 15:6f2798e45099 35 #include "mbedtls/net_sockets.h"
ampembeng 15:6f2798e45099 36 #include "pem.h"
ampembeng 15:6f2798e45099 37
ampembeng 15:6f2798e45099 38 #include "platform.h"
ampembeng 15:6f2798e45099 39 #include "WNCTCPSocketConnection.h"
ampembeng 15:6f2798e45099 40
ampembeng 15:6f2798e45099 41 #ifdef USING_AVNET_SHIELD
ampembeng 15:6f2798e45099 42 // Used for BIO connections
ampembeng 15:6f2798e45099 43 extern WNCTCPSocketConnection* _tcpsocket;
ampembeng 15:6f2798e45099 44 #endif
ampembeng 15:6f2798e45099 45
ampembeng 15:6f2798e45099 46 /*
ampembeng 15:6f2798e45099 47 * This is a function to do further verification if needed on the cert received
ampembeng 15:6f2798e45099 48 */
ampembeng 15:6f2798e45099 49 static int myCertVerify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
ampembeng 15:6f2798e45099 50 char buf[1024];
ampembeng 15:6f2798e45099 51 ((void) data);
ampembeng 15:6f2798e45099 52
ampembeng 15:6f2798e45099 53 DEBUG("\nVerify requested for (Depth %d):\n", depth);
ampembeng 15:6f2798e45099 54 mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
ampembeng 15:6f2798e45099 55 DEBUG("%s", buf);
ampembeng 15:6f2798e45099 56
ampembeng 15:6f2798e45099 57 if ((*flags) == 0) {
ampembeng 15:6f2798e45099 58 DEBUG(" This certificate has no flags\n");
ampembeng 15:6f2798e45099 59 } else {
ampembeng 15:6f2798e45099 60 DEBUG(buf, sizeof(buf), " ! ", *flags); DEBUG("%s\n", buf);
ampembeng 15:6f2798e45099 61 }
ampembeng 15:6f2798e45099 62
ampembeng 15:6f2798e45099 63 return (0);
ampembeng 15:6f2798e45099 64 }
ampembeng 15:6f2798e45099 65
ampembeng 15:6f2798e45099 66 static int ret = 0, i;
ampembeng 15:6f2798e45099 67 static mbedtls_entropy_context entropy;
ampembeng 15:6f2798e45099 68 static mbedtls_ctr_drbg_context ctr_drbg;
ampembeng 15:6f2798e45099 69 static mbedtls_ssl_context ssl;
ampembeng 15:6f2798e45099 70 static mbedtls_ssl_config conf;
ampembeng 15:6f2798e45099 71 static uint32_t flags;
ampembeng 15:6f2798e45099 72 static mbedtls_x509_crt cacert;
ampembeng 15:6f2798e45099 73 static mbedtls_x509_crt clicert;
ampembeng 15:6f2798e45099 74 static mbedtls_pk_context pkey;
ampembeng 15:6f2798e45099 75 static mbedtls_net_context server_fd;
ampembeng 15:6f2798e45099 76
ampembeng 15:6f2798e45099 77 // TODO: We can modify these functions to pull certs from an SD card
ampembeng 15:6f2798e45099 78 int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
ampembeng 15:6f2798e45099 79 {
ampembeng 15:6f2798e45099 80 //FILE *f;
ampembeng 15:6f2798e45099 81 //long size;
ampembeng 15:6f2798e45099 82
ampembeng 15:6f2798e45099 83 // Assign cert/key based on 'path'
ampembeng 15:6f2798e45099 84 /*
ampembeng 15:6f2798e45099 85 switch (path[0])
ampembeng 15:6f2798e45099 86 {
ampembeng 15:6f2798e45099 87 case 'r':
ampembeng 15:6f2798e45099 88 *n = (size_t)(sizeof(AWS_IOT_ROOT_CA)/sizeof(AWS_IOT_ROOT_CA[0]));
ampembeng 15:6f2798e45099 89 *buf = AWS_IOT_ROOT_CA;
ampembeng 15:6f2798e45099 90 break;
ampembeng 15:6f2798e45099 91 case 'c':
ampembeng 15:6f2798e45099 92 *n = (size_t)(sizeof(AWS_IOT_CERTIFICATE)/sizeof(AWS_IOT_CERTIFICATE[0]));
ampembeng 15:6f2798e45099 93 *buf = AWS_IOT_CERTIFICATE;
ampembeng 15:6f2798e45099 94 break;
ampembeng 15:6f2798e45099 95 case 'p':
ampembeng 15:6f2798e45099 96 *n = (size_t)sizeof (AWS_IOT_PRIVATE_KEY);
ampembeng 15:6f2798e45099 97 *buf = (unsigned char *) AWS_IOT_PRIVATE_KEY;
ampembeng 15:6f2798e45099 98
ampembeng 15:6f2798e45099 99 //ret = mbedtls_pk_parse_key(&pkey, (unsigned char *) AWS_IOT_PRIVATE_KEY, sizeof (AWS_IOT_PRIVATE_KEY), NULL, 0 );
ampembeng 15:6f2798e45099 100 break;
ampembeng 15:6f2798e45099 101 default:
ampembeng 15:6f2798e45099 102 ERROR(" failed\n ! Unknown option for cert/key\n\r");
ampembeng 15:6f2798e45099 103 }*/
ampembeng 15:6f2798e45099 104
ampembeng 15:6f2798e45099 105 /*
ampembeng 15:6f2798e45099 106 if( ( f = fopen( path, "rb" ) ) == NULL )
ampembeng 15:6f2798e45099 107 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
ampembeng 15:6f2798e45099 108
ampembeng 15:6f2798e45099 109 fseek( f, 0, SEEK_END );
ampembeng 15:6f2798e45099 110 if( ( size = ftell( f ) ) == -1 )
ampembeng 15:6f2798e45099 111 {
ampembeng 15:6f2798e45099 112 fclose( f );
ampembeng 15:6f2798e45099 113 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
ampembeng 15:6f2798e45099 114 }
ampembeng 15:6f2798e45099 115 fseek( f, 0, SEEK_SET );
ampembeng 15:6f2798e45099 116
ampembeng 15:6f2798e45099 117 *n = (size_t) size;
ampembeng 15:6f2798e45099 118
ampembeng 15:6f2798e45099 119 if( *n + 1 == 0 ||
ampembeng 15:6f2798e45099 120 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
ampembeng 15:6f2798e45099 121 {
ampembeng 15:6f2798e45099 122 //fclose( f );
ampembeng 15:6f2798e45099 123 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
ampembeng 15:6f2798e45099 124 }
ampembeng 15:6f2798e45099 125
ampembeng 15:6f2798e45099 126 if( fread( *buf, 1, *n, f ) != *n )
ampembeng 15:6f2798e45099 127 {
ampembeng 15:6f2798e45099 128 fclose( f );
ampembeng 15:6f2798e45099 129 mbedtls_free( *buf );
ampembeng 15:6f2798e45099 130 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
ampembeng 15:6f2798e45099 131 }
ampembeng 15:6f2798e45099 132
ampembeng 15:6f2798e45099 133 fclose( f );
ampembeng 15:6f2798e45099 134
ampembeng 15:6f2798e45099 135 (*buf)[*n] = '\0';
ampembeng 15:6f2798e45099 136
ampembeng 15:6f2798e45099 137 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
ampembeng 15:6f2798e45099 138 ++*n;
ampembeng 15:6f2798e45099 139 */
ampembeng 15:6f2798e45099 140
ampembeng 15:6f2798e45099 141 return( 0 );
ampembeng 15:6f2798e45099 142 }
ampembeng 15:6f2798e45099 143 // Implementation that should never be optimized out by the compiler
ampembeng 15:6f2798e45099 144 static void mbedtls_zeroize( unsigned char *v, size_t n ) {
ampembeng 15:6f2798e45099 145 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
ampembeng 15:6f2798e45099 146 }
ampembeng 15:6f2798e45099 147 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
ampembeng 15:6f2798e45099 148 {
ampembeng 15:6f2798e45099 149 int ret;
ampembeng 15:6f2798e45099 150 size_t n;
ampembeng 15:6f2798e45099 151 unsigned char *buf;
ampembeng 15:6f2798e45099 152
ampembeng 15:6f2798e45099 153 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
ampembeng 15:6f2798e45099 154 return( ret );
ampembeng 15:6f2798e45099 155
ampembeng 15:6f2798e45099 156 DEBUG("...CRT Parse");
ampembeng 15:6f2798e45099 157 ret = mbedtls_x509_crt_parse( chain, buf, n );
ampembeng 15:6f2798e45099 158
ampembeng 15:6f2798e45099 159 //mbedtls_zeroize( buf, n );
ampembeng 15:6f2798e45099 160 //mbedtls_free( buf );
ampembeng 15:6f2798e45099 161
ampembeng 15:6f2798e45099 162 return( ret );
ampembeng 15:6f2798e45099 163 }
ampembeng 15:6f2798e45099 164 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
ampembeng 15:6f2798e45099 165 const char *path, const char *pwd )
ampembeng 15:6f2798e45099 166 {
ampembeng 15:6f2798e45099 167 int ret;
ampembeng 15:6f2798e45099 168 size_t n;
ampembeng 15:6f2798e45099 169 unsigned char *buf;
ampembeng 15:6f2798e45099 170
ampembeng 15:6f2798e45099 171 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
ampembeng 15:6f2798e45099 172 return( ret );
ampembeng 15:6f2798e45099 173
ampembeng 15:6f2798e45099 174 DEBUG("...Key Parse");
ampembeng 15:6f2798e45099 175 if( pwd == NULL ) {
ampembeng 15:6f2798e45099 176 DEBUG("...Using PWD");
ampembeng 15:6f2798e45099 177 ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
ampembeng 15:6f2798e45099 178 }
ampembeng 15:6f2798e45099 179 else {
ampembeng 15:6f2798e45099 180 DEBUG("...No PWD");
ampembeng 15:6f2798e45099 181 ret = mbedtls_pk_parse_key( ctx, buf, n, (const unsigned char *) pwd, strlen( pwd ) );
ampembeng 15:6f2798e45099 182 }
ampembeng 15:6f2798e45099 183
ampembeng 15:6f2798e45099 184 //mbedtls_zeroize( buf, n );
ampembeng 15:6f2798e45099 185 //mbedtls_free( buf );
ampembeng 15:6f2798e45099 186
ampembeng 15:6f2798e45099 187 return( ret );
ampembeng 15:6f2798e45099 188 }
ampembeng 15:6f2798e45099 189 // TODO: File system functions end
ampembeng 15:6f2798e45099 190
ampembeng 15:6f2798e45099 191 /* personalization string for the drbg */
ampembeng 15:6f2798e45099 192 const char *DRBG_PERS = "mbed TLS helloword client";
ampembeng 15:6f2798e45099 193
ampembeng 15:6f2798e45099 194 int iot_tls_init(Network *pNetwork) {
ampembeng 15:6f2798e45099 195 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 196 const char *pers = "aws_iot_tls_wrapper";
ampembeng 15:6f2798e45099 197 unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1];
ampembeng 15:6f2798e45099 198
ampembeng 15:6f2798e45099 199 mbedtls_net_init(&server_fd);
ampembeng 15:6f2798e45099 200 mbedtls_ssl_init(&ssl);
ampembeng 15:6f2798e45099 201 mbedtls_ssl_config_init(&conf);
ampembeng 15:6f2798e45099 202 mbedtls_ctr_drbg_init(&ctr_drbg);
ampembeng 15:6f2798e45099 203 mbedtls_x509_crt_init(&cacert);
ampembeng 15:6f2798e45099 204 mbedtls_x509_crt_init(&clicert);
ampembeng 15:6f2798e45099 205 mbedtls_pk_init(&pkey);
ampembeng 15:6f2798e45099 206
ampembeng 15:6f2798e45099 207 DEBUG("...Seeding the random number generator");
ampembeng 15:6f2798e45099 208 mbedtls_entropy_init(&entropy);
ampembeng 15:6f2798e45099 209 if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) DRBG_PERS, sizeof (DRBG_PERS))) != 0) {
ampembeng 15:6f2798e45099 210 ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret);
ampembeng 15:6f2798e45099 211 return ret_val;
ampembeng 15:6f2798e45099 212 }
ampembeng 15:6f2798e45099 213 DEBUG(" ok\n");
ampembeng 15:6f2798e45099 214
ampembeng 15:6f2798e45099 215 pNetwork->my_socket = 0;
ampembeng 15:6f2798e45099 216 pNetwork->connect = iot_tls_connect;
ampembeng 15:6f2798e45099 217 pNetwork->mqttread = iot_tls_read;
ampembeng 15:6f2798e45099 218 pNetwork->mqttwrite = iot_tls_write;
ampembeng 15:6f2798e45099 219 pNetwork->disconnect = iot_tls_disconnect;
ampembeng 15:6f2798e45099 220 pNetwork->isConnected = iot_tls_is_connected;
ampembeng 15:6f2798e45099 221 pNetwork->destroy = iot_tls_destroy;
ampembeng 15:6f2798e45099 222
ampembeng 15:6f2798e45099 223 return ret_val;
ampembeng 15:6f2798e45099 224 }
ampembeng 15:6f2798e45099 225
ampembeng 15:6f2798e45099 226 int iot_tls_is_connected(Network *pNetwork) {
ampembeng 15:6f2798e45099 227 /* Use this to add implementation which can check for physical layer disconnect */
ampembeng 15:6f2798e45099 228 return 1;
ampembeng 15:6f2798e45099 229 }
ampembeng 15:6f2798e45099 230
ampembeng 15:6f2798e45099 231 int iot_tls_connect(Network *pNetwork, TLSConnectParams params) {
ampembeng 15:6f2798e45099 232 const char *pers = "aws_iot_tls_wrapper";
ampembeng 15:6f2798e45099 233
ampembeng 15:6f2798e45099 234 DEBUG("...Loading the CA root certificate");
ampembeng 15:6f2798e45099 235 // TODO: We can pull the cert from an SD card
ampembeng 15:6f2798e45099 236 //ret = mbedtls_x509_crt_parse_file(&cacert, params.pRootCALocation);
ampembeng 15:6f2798e45099 237 ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)AWS_IOT_ROOT_CA, strlen ((const char *)AWS_IOT_ROOT_CA)+1);
ampembeng 15:6f2798e45099 238
ampembeng 15:6f2798e45099 239 if (ret < 0) {
ampembeng 15:6f2798e45099 240 ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 241 return ret;
ampembeng 15:6f2798e45099 242 }
ampembeng 15:6f2798e45099 243 DEBUG(" ok (%d skipped)", ret);
ampembeng 15:6f2798e45099 244
ampembeng 15:6f2798e45099 245
ampembeng 15:6f2798e45099 246 DEBUG("...Loading the client cert");
ampembeng 15:6f2798e45099 247 // TODO: We can pull the cert from an SD card
ampembeng 15:6f2798e45099 248 //ret = mbedtls_x509_crt_parse_file(&clicert, params.pDeviceCertLocation);
ampembeng 15:6f2798e45099 249 ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *)AWS_IOT_CERTIFICATE, strlen ((const char *)AWS_IOT_CERTIFICATE)+1);
ampembeng 15:6f2798e45099 250 if (ret != 0) {
ampembeng 15:6f2798e45099 251 ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 252 return ret;
ampembeng 15:6f2798e45099 253 }
ampembeng 15:6f2798e45099 254 DEBUG(" ok");
ampembeng 15:6f2798e45099 255
ampembeng 15:6f2798e45099 256
ampembeng 15:6f2798e45099 257 DEBUG("...Loading the client key");
ampembeng 15:6f2798e45099 258 // TODO: We can pull the cert from an SD card
ampembeng 15:6f2798e45099 259 //ret = mbedtls_pk_parse_keyfile(&pkey, params.pDevicePrivateKeyLocation, "");
ampembeng 15:6f2798e45099 260 ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)AWS_IOT_PRIVATE_KEY, strlen ((const char *)AWS_IOT_PRIVATE_KEY)+1, NULL, 0 );
ampembeng 15:6f2798e45099 261 if (ret != 0) {
ampembeng 15:6f2798e45099 262 ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 263 return ret;
ampembeng 15:6f2798e45099 264 }
ampembeng 15:6f2798e45099 265 DEBUG(" ok");
ampembeng 15:6f2798e45099 266
ampembeng 15:6f2798e45099 267
ampembeng 15:6f2798e45099 268 char portBuffer[6];
ampembeng 15:6f2798e45099 269 sprintf(portBuffer, "%d", params.DestinationPort);
ampembeng 15:6f2798e45099 270 DEBUG("...Connecting to %s/%s", params.pDestinationURL, portBuffer);
ampembeng 15:6f2798e45099 271 if ((ret = mbedtls_net_connect(&server_fd, params.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) {
ampembeng 15:6f2798e45099 272 ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 273 return ret;
ampembeng 15:6f2798e45099 274 }
ampembeng 15:6f2798e45099 275
ampembeng 15:6f2798e45099 276
ampembeng 15:6f2798e45099 277 ret = mbedtls_net_set_block(&server_fd);
ampembeng 15:6f2798e45099 278 if (ret != 0) {
ampembeng 15:6f2798e45099 279 ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 280 return ret;
ampembeng 15:6f2798e45099 281 }
ampembeng 15:6f2798e45099 282 DEBUG(" ok");
ampembeng 15:6f2798e45099 283
ampembeng 15:6f2798e45099 284
ampembeng 15:6f2798e45099 285 DEBUG("...Setting up the SSL/TLS structure");
ampembeng 15:6f2798e45099 286 if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
ampembeng 15:6f2798e45099 287 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
ampembeng 15:6f2798e45099 288 ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 289 return ret;
ampembeng 15:6f2798e45099 290 }
ampembeng 15:6f2798e45099 291
ampembeng 15:6f2798e45099 292
ampembeng 15:6f2798e45099 293 mbedtls_ssl_conf_verify(&conf, myCertVerify, NULL);
ampembeng 15:6f2798e45099 294 if (params.ServerVerificationFlag == true) {
ampembeng 15:6f2798e45099 295 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
ampembeng 15:6f2798e45099 296 } else {
ampembeng 15:6f2798e45099 297 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
ampembeng 15:6f2798e45099 298 }
ampembeng 15:6f2798e45099 299 mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
ampembeng 15:6f2798e45099 300
ampembeng 15:6f2798e45099 301 mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
ampembeng 15:6f2798e45099 302 if ((ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey)) != 0) {
ampembeng 15:6f2798e45099 303 ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
ampembeng 15:6f2798e45099 304 return ret;
ampembeng 15:6f2798e45099 305 }
ampembeng 15:6f2798e45099 306
ampembeng 15:6f2798e45099 307 mbedtls_ssl_conf_read_timeout(&conf, params.timeout_ms);
ampembeng 15:6f2798e45099 308
ampembeng 15:6f2798e45099 309 if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
ampembeng 15:6f2798e45099 310 ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 311 return ret;
ampembeng 15:6f2798e45099 312 }
ampembeng 15:6f2798e45099 313 if ((ret = mbedtls_ssl_set_hostname(&ssl, params.pDestinationURL)) != 0) {
ampembeng 15:6f2798e45099 314 ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
ampembeng 15:6f2798e45099 315 return ret;
ampembeng 15:6f2798e45099 316 }
ampembeng 15:6f2798e45099 317
ampembeng 15:6f2798e45099 318 DEBUG("...Set Socket I/O Functions");
ampembeng 15:6f2798e45099 319 mbedtls_ssl_set_bio(&ssl, static_cast<void *>(_tcpsocket), mbedtls_net_send, NULL, mbedtls_net_recv_timeout );
ampembeng 15:6f2798e45099 320 DEBUG(" ok");
ampembeng 15:6f2798e45099 321
ampembeng 15:6f2798e45099 322
ampembeng 15:6f2798e45099 323 DEBUG("...Performing the SSL/TLS handshake");
ampembeng 15:6f2798e45099 324 while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
ampembeng 15:6f2798e45099 325 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
ampembeng 15:6f2798e45099 326 ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret);
ampembeng 15:6f2798e45099 327 if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
ampembeng 15:6f2798e45099 328 ERROR(" Unable to verify the server's certificate. "
ampembeng 15:6f2798e45099 329 "Either it is invalid,\n"
ampembeng 15:6f2798e45099 330 " or you didn't set ca_file or ca_path "
ampembeng 15:6f2798e45099 331 "to an appropriate value.\n"
ampembeng 15:6f2798e45099 332 " Alternatively, you may want to use "
ampembeng 15:6f2798e45099 333 "auth_mode=optional for testing purposes.\n");
ampembeng 15:6f2798e45099 334 }
ampembeng 15:6f2798e45099 335 return ret;
ampembeng 15:6f2798e45099 336 }
ampembeng 15:6f2798e45099 337 }
ampembeng 15:6f2798e45099 338
ampembeng 15:6f2798e45099 339
ampembeng 15:6f2798e45099 340 DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&ssl), mbedtls_ssl_get_ciphersuite(&ssl));
ampembeng 15:6f2798e45099 341 if ((ret = mbedtls_ssl_get_record_expansion(&ssl)) >= 0) {
ampembeng 15:6f2798e45099 342 DEBUG(" [ Record expansion is %d ]\n", ret);
ampembeng 15:6f2798e45099 343 } else {
ampembeng 15:6f2798e45099 344 DEBUG(" [ Record expansion is unknown (compression) ]\n");
ampembeng 15:6f2798e45099 345 }
ampembeng 15:6f2798e45099 346
ampembeng 15:6f2798e45099 347
ampembeng 15:6f2798e45099 348 DEBUG("...Verifying peer X.509 certificate");
ampembeng 15:6f2798e45099 349 if (params.ServerVerificationFlag == true) {
ampembeng 15:6f2798e45099 350 if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) {
ampembeng 15:6f2798e45099 351 char vrfy_buf[512];
ampembeng 15:6f2798e45099 352 ERROR(" failed\n");
ampembeng 15:6f2798e45099 353 mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
ampembeng 15:6f2798e45099 354 ERROR("%s\n", vrfy_buf);
ampembeng 15:6f2798e45099 355 } else {
ampembeng 15:6f2798e45099 356 DEBUG(" ok\n");
ampembeng 15:6f2798e45099 357 ret = NONE_ERROR;
ampembeng 15:6f2798e45099 358 }
ampembeng 15:6f2798e45099 359 } else {
ampembeng 15:6f2798e45099 360 DEBUG(" Server Verification skipped\n");
ampembeng 15:6f2798e45099 361 ret = NONE_ERROR;
ampembeng 15:6f2798e45099 362 }
ampembeng 15:6f2798e45099 363
ampembeng 15:6f2798e45099 364
ampembeng 15:6f2798e45099 365 DEBUG("...SSL get peer cert");
ampembeng 15:6f2798e45099 366 if (mbedtls_ssl_get_peer_cert(&ssl) != NULL) {
ampembeng 15:6f2798e45099 367 DEBUG("...Peer certificate information");
ampembeng 15:6f2798e45099 368 const uint32_t buf_size = 1024;
ampembeng 15:6f2798e45099 369 char *buf = new char[buf_size];
ampembeng 15:6f2798e45099 370 mbedtls_x509_crt_info(buf, buf_size, " ", mbedtls_ssl_get_peer_cert(&ssl));
ampembeng 15:6f2798e45099 371 DEBUG("...Server certificate:\r\n%s\r", buf);
ampembeng 15:6f2798e45099 372 }
ampembeng 15:6f2798e45099 373
ampembeng 15:6f2798e45099 374 mbedtls_ssl_conf_read_timeout(&conf, 10);
ampembeng 15:6f2798e45099 375
ampembeng 15:6f2798e45099 376 return ret;
ampembeng 15:6f2798e45099 377 }
ampembeng 15:6f2798e45099 378
ampembeng 15:6f2798e45099 379 int iot_tls_write(Network *pNetwork, unsigned char *pMsg, int len, int timeout_ms) {
ampembeng 15:6f2798e45099 380
ampembeng 15:6f2798e45099 381 int written;
ampembeng 15:6f2798e45099 382 int frags;
ampembeng 15:6f2798e45099 383
ampembeng 15:6f2798e45099 384 for (written = 0, frags = 0; written < len; written += ret, frags++) {
ampembeng 15:6f2798e45099 385 while ((ret = mbedtls_ssl_write(&ssl, pMsg + written, len - written)) <= 0) {
ampembeng 15:6f2798e45099 386 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
ampembeng 15:6f2798e45099 387 ERROR(" failed\n ! mbedtls_ssl_write returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 388 return ret;
ampembeng 15:6f2798e45099 389 }
ampembeng 15:6f2798e45099 390 }
ampembeng 15:6f2798e45099 391 }
ampembeng 15:6f2798e45099 392
ampembeng 15:6f2798e45099 393 return written;
ampembeng 15:6f2798e45099 394 }
ampembeng 15:6f2798e45099 395
ampembeng 15:6f2798e45099 396 int iot_tls_read(Network *pNetwork, unsigned char *pMsg, int len, int timeout_ms) {
ampembeng 15:6f2798e45099 397 int rxLen = 0;
ampembeng 15:6f2798e45099 398 bool isErrorFlag = false;
ampembeng 15:6f2798e45099 399 bool isCompleteFlag = false;
ampembeng 15:6f2798e45099 400
ampembeng 15:6f2798e45099 401 // TODO check this against base
ampembeng 15:6f2798e45099 402 //mbedtls_ssl_conf_read_timeout(&conf, timeout_ms);
ampembeng 15:6f2798e45099 403
ampembeng 15:6f2798e45099 404 do {
ampembeng 15:6f2798e45099 405 ret = mbedtls_ssl_read(&ssl, pMsg, len);
ampembeng 15:6f2798e45099 406 if (ret > 0) {
ampembeng 15:6f2798e45099 407 rxLen += ret;
ampembeng 15:6f2798e45099 408 } else if (ret != MBEDTLS_ERR_SSL_WANT_READ) {
ampembeng 15:6f2798e45099 409 isErrorFlag = true;
ampembeng 15:6f2798e45099 410 }
ampembeng 15:6f2798e45099 411 if (rxLen >= len) {
ampembeng 15:6f2798e45099 412 isCompleteFlag = true;
ampembeng 15:6f2798e45099 413 }
ampembeng 15:6f2798e45099 414 } while (!isErrorFlag && !isCompleteFlag);
ampembeng 15:6f2798e45099 415
ampembeng 15:6f2798e45099 416 return ret;
ampembeng 15:6f2798e45099 417 }
ampembeng 15:6f2798e45099 418
ampembeng 15:6f2798e45099 419 void iot_tls_disconnect(Network *pNetwork) {
ampembeng 15:6f2798e45099 420 do {
ampembeng 15:6f2798e45099 421 ret = mbedtls_ssl_close_notify(&ssl);
ampembeng 15:6f2798e45099 422 } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
ampembeng 15:6f2798e45099 423 }
ampembeng 15:6f2798e45099 424
ampembeng 15:6f2798e45099 425 int iot_tls_destroy(Network *pNetwork) {
ampembeng 15:6f2798e45099 426
ampembeng 15:6f2798e45099 427 mbedtls_net_free(&server_fd);
ampembeng 15:6f2798e45099 428
ampembeng 15:6f2798e45099 429 mbedtls_x509_crt_free(&clicert);
ampembeng 15:6f2798e45099 430 mbedtls_x509_crt_free(&cacert);
ampembeng 15:6f2798e45099 431 mbedtls_pk_free(&pkey);
ampembeng 15:6f2798e45099 432 mbedtls_ssl_free(&ssl);
ampembeng 15:6f2798e45099 433 mbedtls_ssl_config_free(&conf);
ampembeng 15:6f2798e45099 434 mbedtls_ctr_drbg_free(&ctr_drbg);
ampembeng 15:6f2798e45099 435 mbedtls_entropy_free(&entropy);
ampembeng 15:6f2798e45099 436
ampembeng 15:6f2798e45099 437 return 0;
ampembeng 15:6f2798e45099 438 }
ampembeng 15:6f2798e45099 439
ampembeng 15:6f2798e45099 440