V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

Committer:
ampembeng
Date:
Tue Dec 06 22:31:15 2016 +0000
Revision:
18:6370da1de572
Parent:
15:6f2798e45099
Child:
28:54d9a550adf1
Added code to support SD card access.  The key/cert and MQTT information required for the demo can now be pulled from the SD card file system.

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 #include "aws_iot_config.h"
ampembeng 15:6f2798e45099 20 #include "aws_iot_error.h"
ampembeng 15:6f2798e45099 21 #include "aws_iot_log.h"
ampembeng 15:6f2798e45099 22 #include "network_interface.h"
ampembeng 15:6f2798e45099 23 #include "mbedtls/config.h"
ampembeng 15:6f2798e45099 24
ampembeng 15:6f2798e45099 25 #include "mbedtls/net.h"
ampembeng 15:6f2798e45099 26 #include "mbedtls/ssl.h"
ampembeng 15:6f2798e45099 27 #include "mbedtls/entropy.h"
ampembeng 15:6f2798e45099 28 #include "mbedtls/ctr_drbg.h"
ampembeng 15:6f2798e45099 29 #include "mbedtls/certs.h"
ampembeng 15:6f2798e45099 30 #include "mbedtls/x509.h"
ampembeng 15:6f2798e45099 31 #include "mbedtls/error.h"
ampembeng 15:6f2798e45099 32 #include "mbedtls/debug.h"
ampembeng 15:6f2798e45099 33 #include "mbedtls/timing.h"
ampembeng 15:6f2798e45099 34 #include "mbedtls/net_sockets.h"
ampembeng 15:6f2798e45099 35 #include "pem.h"
ampembeng 15:6f2798e45099 36
ampembeng 15:6f2798e45099 37 #include "platform.h"
ampembeng 15:6f2798e45099 38 #include "WNCTCPSocketConnection.h"
ampembeng 15:6f2798e45099 39
ampembeng 15:6f2798e45099 40 #ifdef USING_AVNET_SHIELD
ampembeng 15:6f2798e45099 41 // Used for BIO connections
ampembeng 15:6f2798e45099 42 extern WNCTCPSocketConnection* _tcpsocket;
ampembeng 15:6f2798e45099 43 #endif
ampembeng 15:6f2798e45099 44
ampembeng 18:6370da1de572 45 // SD File System
ampembeng 18:6370da1de572 46 #include "SDFileSystem.h"
ampembeng 18:6370da1de572 47
ampembeng 18:6370da1de572 48 // SD defines
ampembeng 18:6370da1de572 49 #define CERT_MAX_SIZE 4096
ampembeng 18:6370da1de572 50
ampembeng 18:6370da1de572 51 // SD file pointer/buffer
ampembeng 18:6370da1de572 52 FILE *fp;
ampembeng 18:6370da1de572 53 char fp_buffer[CERT_MAX_SIZE];
ampembeng 18:6370da1de572 54
ampembeng 18:6370da1de572 55 // From main.cpp
ampembeng 18:6370da1de572 56 extern char HostAddress[255];
ampembeng 18:6370da1de572 57 extern char MqttClientID[32];
ampembeng 18:6370da1de572 58 extern char ThingName[32];
ampembeng 18:6370da1de572 59 extern char PortString[4];
ampembeng 18:6370da1de572 60
ampembeng 15:6f2798e45099 61 /*
ampembeng 15:6f2798e45099 62 * This is a function to do further verification if needed on the cert received
ampembeng 15:6f2798e45099 63 */
ampembeng 15:6f2798e45099 64 static int myCertVerify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
ampembeng 15:6f2798e45099 65 char buf[1024];
ampembeng 15:6f2798e45099 66 ((void) data);
ampembeng 15:6f2798e45099 67
ampembeng 15:6f2798e45099 68 DEBUG("\nVerify requested for (Depth %d):\n", depth);
ampembeng 15:6f2798e45099 69 mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
ampembeng 15:6f2798e45099 70 DEBUG("%s", buf);
ampembeng 15:6f2798e45099 71
ampembeng 15:6f2798e45099 72 if ((*flags) == 0) {
ampembeng 15:6f2798e45099 73 DEBUG(" This certificate has no flags\n");
ampembeng 15:6f2798e45099 74 } else {
ampembeng 15:6f2798e45099 75 DEBUG(buf, sizeof(buf), " ! ", *flags); DEBUG("%s\n", buf);
ampembeng 15:6f2798e45099 76 }
ampembeng 15:6f2798e45099 77
ampembeng 15:6f2798e45099 78 return (0);
ampembeng 15:6f2798e45099 79 }
ampembeng 15:6f2798e45099 80
ampembeng 15:6f2798e45099 81 static int ret = 0, i;
ampembeng 15:6f2798e45099 82 static mbedtls_entropy_context entropy;
ampembeng 15:6f2798e45099 83 static mbedtls_ctr_drbg_context ctr_drbg;
ampembeng 15:6f2798e45099 84 static mbedtls_ssl_context ssl;
ampembeng 15:6f2798e45099 85 static mbedtls_ssl_config conf;
ampembeng 15:6f2798e45099 86 static uint32_t flags;
ampembeng 15:6f2798e45099 87 static mbedtls_x509_crt cacert;
ampembeng 15:6f2798e45099 88 static mbedtls_x509_crt clicert;
ampembeng 15:6f2798e45099 89 static mbedtls_pk_context pkey;
ampembeng 15:6f2798e45099 90 static mbedtls_net_context server_fd;
ampembeng 15:6f2798e45099 91
ampembeng 18:6370da1de572 92 // Used to zero the given buffer
ampembeng 18:6370da1de572 93 static void mbedtls_zeroize( char *v, size_t n ) {
ampembeng 18:6370da1de572 94 volatile char *p = v; while( n-- ) *p++ = 0;
ampembeng 18:6370da1de572 95 }
ampembeng 18:6370da1de572 96
ampembeng 18:6370da1de572 97 // Parser sub function
ampembeng 18:6370da1de572 98 int mqtt_parse_sub(std::string *search_str, char *param, const char *str_to_find)
ampembeng 15:6f2798e45099 99 {
ampembeng 18:6370da1de572 100 int index_start, index_end;
ampembeng 18:6370da1de572 101 mbedtls_zeroize(param, strlen(param));
ampembeng 18:6370da1de572 102
ampembeng 18:6370da1de572 103 index_start = search_str->find(str_to_find);
ampembeng 18:6370da1de572 104 if (index_start < 0)
ampembeng 18:6370da1de572 105 return -1;
ampembeng 18:6370da1de572 106
ampembeng 18:6370da1de572 107 index_end = search_str->find("\n", index_start);
ampembeng 18:6370da1de572 108 if (index_end < 0)
ampembeng 18:6370da1de572 109 index_end = search_str->find("\0", index_start);
ampembeng 18:6370da1de572 110
ampembeng 18:6370da1de572 111 if (index_end < 0)
ampembeng 18:6370da1de572 112 return -1;
ampembeng 18:6370da1de572 113
ampembeng 18:6370da1de572 114 index_start += strlen(str_to_find);
ampembeng 18:6370da1de572 115 strcpy(param, search_str->substr(index_start, index_end-index_start-1).c_str());
ampembeng 18:6370da1de572 116
ampembeng 18:6370da1de572 117 return 0;
ampembeng 18:6370da1de572 118 }
ampembeng 18:6370da1de572 119
ampembeng 18:6370da1de572 120 // Read MQTT config info
ampembeng 18:6370da1de572 121 int mbedtls_mqtt_config_parse_file(ShadowParameters_t *sp, const char *path )
ampembeng 18:6370da1de572 122 {
ampembeng 18:6370da1de572 123 int ret, size;
ampembeng 18:6370da1de572 124 mbedtls_zeroize(fp_buffer, CERT_MAX_SIZE);
ampembeng 15:6f2798e45099 125
ampembeng 18:6370da1de572 126 INFO("...Reading MQTT data from SD");
ampembeng 18:6370da1de572 127 fp = fopen(path, "r");
ampembeng 18:6370da1de572 128 if (fp != NULL) {
ampembeng 18:6370da1de572 129 size = fread(fp_buffer, sizeof(char), CERT_MAX_SIZE, fp);
ampembeng 18:6370da1de572 130 DEBUG("...Number of data read: %d, text from file: %s", size, fp_buffer);
ampembeng 18:6370da1de572 131 fclose(fp);
ampembeng 18:6370da1de572 132 }
ampembeng 18:6370da1de572 133 else {
ampembeng 18:6370da1de572 134 ERROR("Could not open file: %s", path);
ampembeng 18:6370da1de572 135 return -1;
ampembeng 18:6370da1de572 136 }
ampembeng 18:6370da1de572 137
ampembeng 18:6370da1de572 138 std::string filestr(fp_buffer);
ampembeng 18:6370da1de572 139
ampembeng 18:6370da1de572 140 ret = mqtt_parse_sub(&filestr, HostAddress, "AWS_IOT_MQTT_HOST=");
ampembeng 18:6370da1de572 141 sp->pHost = HostAddress;
ampembeng 18:6370da1de572 142 INFO("...Host=%s", sp->pHost);
ampembeng 18:6370da1de572 143 if (ret < 0) {
ampembeng 18:6370da1de572 144 ERROR("Could not parse AWS_IOT_MQTT_HOST string.");
ampembeng 18:6370da1de572 145 return ret;
ampembeng 15:6f2798e45099 146 }
ampembeng 15:6f2798e45099 147
ampembeng 18:6370da1de572 148 ret = mqtt_parse_sub(&filestr, PortString, "AWS_IOT_MQTT_PORT=");
ampembeng 18:6370da1de572 149 sp->port = atoi(PortString);
ampembeng 18:6370da1de572 150 INFO("...Port=%d", sp->port);
ampembeng 18:6370da1de572 151 if (ret < 0) {
ampembeng 18:6370da1de572 152 ERROR("Could not parse AWS_IOT_MQTT_PORT string.");
ampembeng 18:6370da1de572 153 return ret;
ampembeng 18:6370da1de572 154 }
ampembeng 15:6f2798e45099 155
ampembeng 18:6370da1de572 156 ret = mqtt_parse_sub(&filestr, MqttClientID, "AWS_IOT_MQTT_CLIENT_ID=");
ampembeng 18:6370da1de572 157 sp->pMqttClientId = MqttClientID;
ampembeng 18:6370da1de572 158 INFO("...pMqttClientId=%s", sp->pMqttClientId);
ampembeng 18:6370da1de572 159 if (ret < 0) {
ampembeng 18:6370da1de572 160 ERROR("Could not parse AWS_IOT_MQTT_CLIENT_ID string.");
ampembeng 18:6370da1de572 161 return ret;
ampembeng 18:6370da1de572 162 }
ampembeng 18:6370da1de572 163
ampembeng 18:6370da1de572 164 ret = mqtt_parse_sub(&filestr, ThingName, "AWS_IOT_MY_THING_NAME=");
ampembeng 18:6370da1de572 165 sp->pMyThingName = ThingName;
ampembeng 18:6370da1de572 166 INFO("...pMyThingName=%s", sp->pMyThingName);
ampembeng 18:6370da1de572 167 if (ret < 0) {
ampembeng 18:6370da1de572 168 ERROR("Could not parse AWS_IOT_MY_THING_NAME string.");
ampembeng 18:6370da1de572 169 return ret;
ampembeng 15:6f2798e45099 170 }
ampembeng 15:6f2798e45099 171
ampembeng 18:6370da1de572 172 return( ret );
ampembeng 18:6370da1de572 173 }
ampembeng 15:6f2798e45099 174
ampembeng 18:6370da1de572 175 // Override function: Parses CRT from SD
ampembeng 15:6f2798e45099 176 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
ampembeng 15:6f2798e45099 177 {
ampembeng 18:6370da1de572 178 int ret, size;
ampembeng 18:6370da1de572 179 mbedtls_zeroize(fp_buffer, CERT_MAX_SIZE);
ampembeng 18:6370da1de572 180
ampembeng 18:6370da1de572 181 INFO("...Reading CERT data from SD");
ampembeng 18:6370da1de572 182 fp = fopen(path, "r");
ampembeng 18:6370da1de572 183 if (fp != NULL) {
ampembeng 18:6370da1de572 184 size = fread(fp_buffer, sizeof(char), CERT_MAX_SIZE, fp);
ampembeng 18:6370da1de572 185 DEBUG("...Number of data read: %d, text from file: %s", size, fp_buffer);
ampembeng 18:6370da1de572 186 fclose(fp);
ampembeng 18:6370da1de572 187 }
ampembeng 18:6370da1de572 188 else {
ampembeng 18:6370da1de572 189 ERROR("Could not open file: %s", path);
ampembeng 18:6370da1de572 190 return -1;
ampembeng 18:6370da1de572 191 }
ampembeng 15:6f2798e45099 192
ampembeng 15:6f2798e45099 193 DEBUG("...CRT Parse");
ampembeng 18:6370da1de572 194 ret = mbedtls_x509_crt_parse( chain, (unsigned char *)fp_buffer, size+2);
ampembeng 18:6370da1de572 195
ampembeng 15:6f2798e45099 196 return( ret );
ampembeng 15:6f2798e45099 197 }
ampembeng 18:6370da1de572 198
ampembeng 18:6370da1de572 199 // Override function: Parses KEY from SD
ampembeng 15:6f2798e45099 200 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
ampembeng 18:6370da1de572 201 const char *path, const char *pwd )
ampembeng 15:6f2798e45099 202 {
ampembeng 18:6370da1de572 203 int ret, size;
ampembeng 18:6370da1de572 204 mbedtls_zeroize(fp_buffer, CERT_MAX_SIZE);
ampembeng 15:6f2798e45099 205
ampembeng 18:6370da1de572 206 INFO("...Reading KEY data from SD");
ampembeng 18:6370da1de572 207 fp = fopen(path, "r");
ampembeng 18:6370da1de572 208 if (fp != NULL) {
ampembeng 18:6370da1de572 209 size = fread(fp_buffer, sizeof(char), CERT_MAX_SIZE, fp);
ampembeng 18:6370da1de572 210 DEBUG("...Number of data read: %d, text from file: %s", size, fp_buffer);
ampembeng 18:6370da1de572 211 fclose(fp);
ampembeng 18:6370da1de572 212 }
ampembeng 18:6370da1de572 213 else {
ampembeng 18:6370da1de572 214 ERROR("Could not open file: %s", path);
ampembeng 18:6370da1de572 215 return -1;
ampembeng 18:6370da1de572 216 }
ampembeng 15:6f2798e45099 217
ampembeng 15:6f2798e45099 218 DEBUG("...Key Parse");
ampembeng 15:6f2798e45099 219 if( pwd == NULL ) {
ampembeng 15:6f2798e45099 220 DEBUG("...Using PWD");
ampembeng 18:6370da1de572 221 ret = mbedtls_pk_parse_key( ctx, (unsigned char *)fp_buffer, size+1, NULL, 0 );
ampembeng 15:6f2798e45099 222 }
ampembeng 15:6f2798e45099 223 else {
ampembeng 15:6f2798e45099 224 DEBUG("...No PWD");
ampembeng 18:6370da1de572 225 ret = mbedtls_pk_parse_key( ctx, (unsigned char *)fp_buffer, size+1, (const unsigned char *) pwd, strlen( pwd ) );
ampembeng 15:6f2798e45099 226 }
ampembeng 18:6370da1de572 227
ampembeng 15:6f2798e45099 228 return( ret );
ampembeng 15:6f2798e45099 229 }
ampembeng 18:6370da1de572 230
ampembeng 15:6f2798e45099 231
ampembeng 15:6f2798e45099 232 /* personalization string for the drbg */
ampembeng 15:6f2798e45099 233 const char *DRBG_PERS = "mbed TLS helloword client";
ampembeng 15:6f2798e45099 234
ampembeng 15:6f2798e45099 235 int iot_tls_init(Network *pNetwork) {
ampembeng 15:6f2798e45099 236 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 237 const char *pers = "aws_iot_tls_wrapper";
ampembeng 15:6f2798e45099 238 unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1];
ampembeng 15:6f2798e45099 239
ampembeng 15:6f2798e45099 240 mbedtls_net_init(&server_fd);
ampembeng 15:6f2798e45099 241 mbedtls_ssl_init(&ssl);
ampembeng 15:6f2798e45099 242 mbedtls_ssl_config_init(&conf);
ampembeng 15:6f2798e45099 243 mbedtls_ctr_drbg_init(&ctr_drbg);
ampembeng 15:6f2798e45099 244 mbedtls_x509_crt_init(&cacert);
ampembeng 15:6f2798e45099 245 mbedtls_x509_crt_init(&clicert);
ampembeng 15:6f2798e45099 246 mbedtls_pk_init(&pkey);
ampembeng 15:6f2798e45099 247
ampembeng 15:6f2798e45099 248 DEBUG("...Seeding the random number generator");
ampembeng 15:6f2798e45099 249 mbedtls_entropy_init(&entropy);
ampembeng 15:6f2798e45099 250 if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) DRBG_PERS, sizeof (DRBG_PERS))) != 0) {
ampembeng 15:6f2798e45099 251 ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret);
ampembeng 15:6f2798e45099 252 return ret_val;
ampembeng 15:6f2798e45099 253 }
ampembeng 15:6f2798e45099 254 DEBUG(" ok\n");
ampembeng 15:6f2798e45099 255
ampembeng 15:6f2798e45099 256 pNetwork->my_socket = 0;
ampembeng 15:6f2798e45099 257 pNetwork->connect = iot_tls_connect;
ampembeng 15:6f2798e45099 258 pNetwork->mqttread = iot_tls_read;
ampembeng 15:6f2798e45099 259 pNetwork->mqttwrite = iot_tls_write;
ampembeng 15:6f2798e45099 260 pNetwork->disconnect = iot_tls_disconnect;
ampembeng 15:6f2798e45099 261 pNetwork->isConnected = iot_tls_is_connected;
ampembeng 15:6f2798e45099 262 pNetwork->destroy = iot_tls_destroy;
ampembeng 15:6f2798e45099 263
ampembeng 15:6f2798e45099 264 return ret_val;
ampembeng 15:6f2798e45099 265 }
ampembeng 15:6f2798e45099 266
ampembeng 15:6f2798e45099 267 int iot_tls_is_connected(Network *pNetwork) {
ampembeng 15:6f2798e45099 268 /* Use this to add implementation which can check for physical layer disconnect */
ampembeng 15:6f2798e45099 269 return 1;
ampembeng 15:6f2798e45099 270 }
ampembeng 15:6f2798e45099 271
ampembeng 15:6f2798e45099 272 int iot_tls_connect(Network *pNetwork, TLSConnectParams params) {
ampembeng 15:6f2798e45099 273 const char *pers = "aws_iot_tls_wrapper";
ampembeng 15:6f2798e45099 274
ampembeng 15:6f2798e45099 275 DEBUG("...Loading the CA root certificate");
ampembeng 18:6370da1de572 276 #ifdef USING_SD_CARD
ampembeng 18:6370da1de572 277 ret = mbedtls_x509_crt_parse_file(&cacert, AWS_IOT_ROOT_CA_FILENAME);
ampembeng 18:6370da1de572 278 #else
ampembeng 15:6f2798e45099 279 ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)AWS_IOT_ROOT_CA, strlen ((const char *)AWS_IOT_ROOT_CA)+1);
ampembeng 18:6370da1de572 280 #endif
ampembeng 15:6f2798e45099 281 if (ret < 0) {
ampembeng 15:6f2798e45099 282 ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 283 return ret;
ampembeng 15:6f2798e45099 284 }
ampembeng 15:6f2798e45099 285 DEBUG(" ok (%d skipped)", ret);
ampembeng 15:6f2798e45099 286
ampembeng 15:6f2798e45099 287
ampembeng 15:6f2798e45099 288 DEBUG("...Loading the client cert");
ampembeng 18:6370da1de572 289 #ifdef USING_SD_CARD
ampembeng 18:6370da1de572 290 ret = mbedtls_x509_crt_parse_file(&clicert, AWS_IOT_CERTIFICATE_FILENAME);
ampembeng 18:6370da1de572 291 #else
ampembeng 15:6f2798e45099 292 ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *)AWS_IOT_CERTIFICATE, strlen ((const char *)AWS_IOT_CERTIFICATE)+1);
ampembeng 18:6370da1de572 293 #endif
ampembeng 15:6f2798e45099 294 if (ret != 0) {
ampembeng 15:6f2798e45099 295 ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 296 return ret;
ampembeng 15:6f2798e45099 297 }
ampembeng 15:6f2798e45099 298 DEBUG(" ok");
ampembeng 15:6f2798e45099 299
ampembeng 15:6f2798e45099 300 DEBUG("...Loading the client key");
ampembeng 18:6370da1de572 301 #ifdef USING_SD_CARD
ampembeng 18:6370da1de572 302 ret = mbedtls_pk_parse_keyfile(&pkey, AWS_IOT_PRIVATE_KEY_FILENAME, "");
ampembeng 18:6370da1de572 303 #else
ampembeng 15:6f2798e45099 304 ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)AWS_IOT_PRIVATE_KEY, strlen ((const char *)AWS_IOT_PRIVATE_KEY)+1, NULL, 0 );
ampembeng 18:6370da1de572 305 #endif
ampembeng 15:6f2798e45099 306 if (ret != 0) {
ampembeng 15:6f2798e45099 307 ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 308 return ret;
ampembeng 15:6f2798e45099 309 }
ampembeng 15:6f2798e45099 310 DEBUG(" ok");
ampembeng 15:6f2798e45099 311
ampembeng 15:6f2798e45099 312 char portBuffer[6];
ampembeng 15:6f2798e45099 313 sprintf(portBuffer, "%d", params.DestinationPort);
ampembeng 15:6f2798e45099 314 DEBUG("...Connecting to %s/%s", params.pDestinationURL, portBuffer);
ampembeng 15:6f2798e45099 315 if ((ret = mbedtls_net_connect(&server_fd, params.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) {
ampembeng 15:6f2798e45099 316 ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 317 return ret;
ampembeng 15:6f2798e45099 318 }
ampembeng 15:6f2798e45099 319
ampembeng 15:6f2798e45099 320
ampembeng 15:6f2798e45099 321 ret = mbedtls_net_set_block(&server_fd);
ampembeng 15:6f2798e45099 322 if (ret != 0) {
ampembeng 15:6f2798e45099 323 ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 324 return ret;
ampembeng 15:6f2798e45099 325 }
ampembeng 15:6f2798e45099 326 DEBUG(" ok");
ampembeng 15:6f2798e45099 327
ampembeng 15:6f2798e45099 328
ampembeng 15:6f2798e45099 329 DEBUG("...Setting up the SSL/TLS structure");
ampembeng 15:6f2798e45099 330 if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
ampembeng 15:6f2798e45099 331 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
ampembeng 15:6f2798e45099 332 ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 333 return ret;
ampembeng 15:6f2798e45099 334 }
ampembeng 15:6f2798e45099 335
ampembeng 15:6f2798e45099 336
ampembeng 15:6f2798e45099 337 mbedtls_ssl_conf_verify(&conf, myCertVerify, NULL);
ampembeng 15:6f2798e45099 338 if (params.ServerVerificationFlag == true) {
ampembeng 15:6f2798e45099 339 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
ampembeng 15:6f2798e45099 340 } else {
ampembeng 15:6f2798e45099 341 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
ampembeng 15:6f2798e45099 342 }
ampembeng 15:6f2798e45099 343 mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
ampembeng 15:6f2798e45099 344
ampembeng 15:6f2798e45099 345 mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
ampembeng 15:6f2798e45099 346 if ((ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey)) != 0) {
ampembeng 15:6f2798e45099 347 ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
ampembeng 15:6f2798e45099 348 return ret;
ampembeng 15:6f2798e45099 349 }
ampembeng 15:6f2798e45099 350
ampembeng 15:6f2798e45099 351 mbedtls_ssl_conf_read_timeout(&conf, params.timeout_ms);
ampembeng 15:6f2798e45099 352
ampembeng 15:6f2798e45099 353 if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
ampembeng 15:6f2798e45099 354 ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 355 return ret;
ampembeng 15:6f2798e45099 356 }
ampembeng 15:6f2798e45099 357 if ((ret = mbedtls_ssl_set_hostname(&ssl, params.pDestinationURL)) != 0) {
ampembeng 15:6f2798e45099 358 ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
ampembeng 15:6f2798e45099 359 return ret;
ampembeng 15:6f2798e45099 360 }
ampembeng 15:6f2798e45099 361
ampembeng 15:6f2798e45099 362 DEBUG("...Set Socket I/O Functions");
ampembeng 15:6f2798e45099 363 mbedtls_ssl_set_bio(&ssl, static_cast<void *>(_tcpsocket), mbedtls_net_send, NULL, mbedtls_net_recv_timeout );
ampembeng 15:6f2798e45099 364 DEBUG(" ok");
ampembeng 15:6f2798e45099 365
ampembeng 15:6f2798e45099 366
ampembeng 15:6f2798e45099 367 DEBUG("...Performing the SSL/TLS handshake");
ampembeng 15:6f2798e45099 368 while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
ampembeng 15:6f2798e45099 369 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
ampembeng 15:6f2798e45099 370 ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret);
ampembeng 15:6f2798e45099 371 if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
ampembeng 15:6f2798e45099 372 ERROR(" Unable to verify the server's certificate. "
ampembeng 15:6f2798e45099 373 "Either it is invalid,\n"
ampembeng 15:6f2798e45099 374 " or you didn't set ca_file or ca_path "
ampembeng 15:6f2798e45099 375 "to an appropriate value.\n"
ampembeng 15:6f2798e45099 376 " Alternatively, you may want to use "
ampembeng 15:6f2798e45099 377 "auth_mode=optional for testing purposes.\n");
ampembeng 15:6f2798e45099 378 }
ampembeng 15:6f2798e45099 379 return ret;
ampembeng 15:6f2798e45099 380 }
ampembeng 15:6f2798e45099 381 }
ampembeng 15:6f2798e45099 382
ampembeng 15:6f2798e45099 383
ampembeng 15:6f2798e45099 384 DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&ssl), mbedtls_ssl_get_ciphersuite(&ssl));
ampembeng 15:6f2798e45099 385 if ((ret = mbedtls_ssl_get_record_expansion(&ssl)) >= 0) {
ampembeng 15:6f2798e45099 386 DEBUG(" [ Record expansion is %d ]\n", ret);
ampembeng 15:6f2798e45099 387 } else {
ampembeng 15:6f2798e45099 388 DEBUG(" [ Record expansion is unknown (compression) ]\n");
ampembeng 15:6f2798e45099 389 }
ampembeng 15:6f2798e45099 390
ampembeng 15:6f2798e45099 391
ampembeng 15:6f2798e45099 392 DEBUG("...Verifying peer X.509 certificate");
ampembeng 15:6f2798e45099 393 if (params.ServerVerificationFlag == true) {
ampembeng 15:6f2798e45099 394 if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) {
ampembeng 15:6f2798e45099 395 char vrfy_buf[512];
ampembeng 15:6f2798e45099 396 ERROR(" failed\n");
ampembeng 15:6f2798e45099 397 mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
ampembeng 15:6f2798e45099 398 ERROR("%s\n", vrfy_buf);
ampembeng 15:6f2798e45099 399 } else {
ampembeng 15:6f2798e45099 400 DEBUG(" ok\n");
ampembeng 15:6f2798e45099 401 ret = NONE_ERROR;
ampembeng 15:6f2798e45099 402 }
ampembeng 15:6f2798e45099 403 } else {
ampembeng 15:6f2798e45099 404 DEBUG(" Server Verification skipped\n");
ampembeng 15:6f2798e45099 405 ret = NONE_ERROR;
ampembeng 15:6f2798e45099 406 }
ampembeng 15:6f2798e45099 407
ampembeng 15:6f2798e45099 408
ampembeng 15:6f2798e45099 409 DEBUG("...SSL get peer cert");
ampembeng 15:6f2798e45099 410 if (mbedtls_ssl_get_peer_cert(&ssl) != NULL) {
ampembeng 15:6f2798e45099 411 DEBUG("...Peer certificate information");
ampembeng 15:6f2798e45099 412 const uint32_t buf_size = 1024;
ampembeng 15:6f2798e45099 413 char *buf = new char[buf_size];
ampembeng 15:6f2798e45099 414 mbedtls_x509_crt_info(buf, buf_size, " ", mbedtls_ssl_get_peer_cert(&ssl));
ampembeng 15:6f2798e45099 415 DEBUG("...Server certificate:\r\n%s\r", buf);
ampembeng 15:6f2798e45099 416 }
ampembeng 15:6f2798e45099 417
ampembeng 15:6f2798e45099 418 mbedtls_ssl_conf_read_timeout(&conf, 10);
ampembeng 15:6f2798e45099 419
ampembeng 15:6f2798e45099 420 return ret;
ampembeng 15:6f2798e45099 421 }
ampembeng 15:6f2798e45099 422
ampembeng 15:6f2798e45099 423 int iot_tls_write(Network *pNetwork, unsigned char *pMsg, int len, int timeout_ms) {
ampembeng 15:6f2798e45099 424
ampembeng 15:6f2798e45099 425 int written;
ampembeng 15:6f2798e45099 426 int frags;
ampembeng 15:6f2798e45099 427
ampembeng 15:6f2798e45099 428 for (written = 0, frags = 0; written < len; written += ret, frags++) {
ampembeng 15:6f2798e45099 429 while ((ret = mbedtls_ssl_write(&ssl, pMsg + written, len - written)) <= 0) {
ampembeng 15:6f2798e45099 430 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
ampembeng 15:6f2798e45099 431 ERROR(" failed\n ! mbedtls_ssl_write returned -0x%x\n\n", -ret);
ampembeng 15:6f2798e45099 432 return ret;
ampembeng 15:6f2798e45099 433 }
ampembeng 15:6f2798e45099 434 }
ampembeng 15:6f2798e45099 435 }
ampembeng 15:6f2798e45099 436
ampembeng 15:6f2798e45099 437 return written;
ampembeng 15:6f2798e45099 438 }
ampembeng 15:6f2798e45099 439
ampembeng 15:6f2798e45099 440 int iot_tls_read(Network *pNetwork, unsigned char *pMsg, int len, int timeout_ms) {
ampembeng 15:6f2798e45099 441 int rxLen = 0;
ampembeng 15:6f2798e45099 442 bool isErrorFlag = false;
ampembeng 15:6f2798e45099 443 bool isCompleteFlag = false;
ampembeng 15:6f2798e45099 444
ampembeng 15:6f2798e45099 445 // TODO check this against base
ampembeng 15:6f2798e45099 446 //mbedtls_ssl_conf_read_timeout(&conf, timeout_ms);
ampembeng 15:6f2798e45099 447
ampembeng 15:6f2798e45099 448 do {
ampembeng 15:6f2798e45099 449 ret = mbedtls_ssl_read(&ssl, pMsg, len);
ampembeng 15:6f2798e45099 450 if (ret > 0) {
ampembeng 15:6f2798e45099 451 rxLen += ret;
ampembeng 15:6f2798e45099 452 } else if (ret != MBEDTLS_ERR_SSL_WANT_READ) {
ampembeng 15:6f2798e45099 453 isErrorFlag = true;
ampembeng 15:6f2798e45099 454 }
ampembeng 15:6f2798e45099 455 if (rxLen >= len) {
ampembeng 15:6f2798e45099 456 isCompleteFlag = true;
ampembeng 15:6f2798e45099 457 }
ampembeng 15:6f2798e45099 458 } while (!isErrorFlag && !isCompleteFlag);
ampembeng 15:6f2798e45099 459
ampembeng 15:6f2798e45099 460 return ret;
ampembeng 15:6f2798e45099 461 }
ampembeng 15:6f2798e45099 462
ampembeng 15:6f2798e45099 463 void iot_tls_disconnect(Network *pNetwork) {
ampembeng 15:6f2798e45099 464 do {
ampembeng 15:6f2798e45099 465 ret = mbedtls_ssl_close_notify(&ssl);
ampembeng 15:6f2798e45099 466 } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
ampembeng 15:6f2798e45099 467 }
ampembeng 15:6f2798e45099 468
ampembeng 15:6f2798e45099 469 int iot_tls_destroy(Network *pNetwork) {
ampembeng 15:6f2798e45099 470
ampembeng 15:6f2798e45099 471 mbedtls_net_free(&server_fd);
ampembeng 15:6f2798e45099 472
ampembeng 15:6f2798e45099 473 mbedtls_x509_crt_free(&clicert);
ampembeng 15:6f2798e45099 474 mbedtls_x509_crt_free(&cacert);
ampembeng 15:6f2798e45099 475 mbedtls_pk_free(&pkey);
ampembeng 15:6f2798e45099 476 mbedtls_ssl_free(&ssl);
ampembeng 15:6f2798e45099 477 mbedtls_ssl_config_free(&conf);
ampembeng 15:6f2798e45099 478 mbedtls_ctr_drbg_free(&ctr_drbg);
ampembeng 15:6f2798e45099 479 mbedtls_entropy_free(&entropy);
ampembeng 15:6f2798e45099 480
ampembeng 15:6f2798e45099 481 return 0;
ampembeng 15:6f2798e45099 482 }
ampembeng 15:6f2798e45099 483
ampembeng 15:6f2798e45099 484