V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

Committer:
jilee
Date:
Fri Nov 03 20:28:02 2017 +0000
Revision:
29:f71a0be59b99
Parent:
28:54d9a550adf1
v.06 11/03/2016

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