V.06 11/3
Dependencies: FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts
Fork of ATT_AWS_IoT_demo by
network_mbedtls_wrapper.cpp
00001 /* 00002 * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"). 00005 * You may not use this file except in compliance with the License. 00006 * A copy of the License is located at 00007 * 00008 * http://aws.amazon.com/apache2.0 00009 * 00010 * or in the "license" file accompanying this file. This file is distributed 00011 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 00012 * express or implied. See the License for the specific language governing 00013 * permissions and limitations under the License. 00014 */ 00015 00016 #include <stdbool.h> 00017 #include <string.h> 00018 00019 #include "aws_iot_config.h" 00020 #include "aws_iot_error.h" 00021 #include "aws_iot_log.h" 00022 #include "network_interface.h" 00023 #include "mbedtls/config.h" 00024 00025 #include "mbedtls/net.h" 00026 #include "mbedtls/ssl.h" 00027 #include "mbedtls/entropy.h" 00028 #include "mbedtls/ctr_drbg.h" 00029 #include "mbedtls/certs.h" 00030 #include "mbedtls/x509.h" 00031 #include "mbedtls/error.h" 00032 #include "mbedtls/debug.h" 00033 #include "mbedtls/timing.h" 00034 #include "mbedtls/net_sockets.h" 00035 #include "pem.h" 00036 00037 #include "platform.h" 00038 #include "WNCTCPSocketConnection.h" 00039 00040 #ifdef USING_AVNET_SHIELD 00041 // Used for BIO connections 00042 extern WNCTCPSocketConnection* _tcpsocket; 00043 #endif 00044 00045 // SD File System 00046 #include "SDFileSystem.h" 00047 00048 // SD defines 00049 #define CERT_MAX_SIZE 4096 00050 00051 // SD file pointer/buffer 00052 FILE *fp; 00053 char fp_buffer[CERT_MAX_SIZE]; 00054 00055 unsigned char cSubject[100]; 00056 00057 // From main.cpp 00058 extern char HostAddress[255]; 00059 extern char MqttClientID[32]; 00060 extern char ThingName[32]; 00061 extern char PortString[4]; 00062 00063 /* 00064 * This is a function to do further verification if needed on the cert received 00065 */ 00066 static int myCertVerify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) { 00067 char buf[1024]; 00068 ((void) data); 00069 00070 DEBUG("\nVerify requested for (Depth %d):\n", depth); 00071 mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt); 00072 DEBUG("%s", buf); 00073 00074 if ((*flags) == 0) { 00075 DEBUG(" This certificate has no flags\n"); 00076 } else { 00077 DEBUG(buf, sizeof(buf), " ! ", *flags); DEBUG("%s\n", buf); 00078 } 00079 00080 return (0); 00081 } 00082 00083 static int ret = 0, i; 00084 static mbedtls_entropy_context entropy; 00085 static mbedtls_ctr_drbg_context ctr_drbg; 00086 static mbedtls_ssl_context ssl; 00087 static mbedtls_ssl_config conf; 00088 static uint32_t flags; 00089 static mbedtls_x509_crt cacert; 00090 static mbedtls_x509_crt clicert; 00091 static mbedtls_pk_context pkey; 00092 static mbedtls_net_context server_fd; 00093 00094 // Used to zero the given buffer 00095 static void mbedtls_zeroize( char *v, size_t n ) { 00096 volatile char *p = v; while( n-- ) *p++ = 0; 00097 } 00098 00099 // Parser sub function 00100 int mqtt_parse_sub(std::string *search_str, char *param, const char *str_to_find) 00101 { 00102 int index_start, index_end; 00103 mbedtls_zeroize(param, strlen(param)); 00104 00105 index_start = search_str->find(str_to_find); 00106 if (index_start < 0) 00107 return -1; 00108 00109 index_end = search_str->find("\n", index_start); 00110 if (index_end < 0) 00111 index_end = search_str->find("\0", index_start); 00112 00113 if (index_end < 0) 00114 return -1; 00115 00116 index_start += strlen(str_to_find); 00117 strcpy(param, search_str->substr(index_start, index_end-index_start-1).c_str()); 00118 00119 return 0; 00120 } 00121 00122 // Read MQTT config info 00123 int mbedtls_mqtt_config_parse_file(ShadowParameters_t *sp, const char *path ) 00124 { 00125 int ret, size; 00126 mbedtls_zeroize(fp_buffer, CERT_MAX_SIZE); 00127 00128 INFO("...Reading MQTT data from SD"); 00129 fp = fopen(path, "r"); 00130 if (fp != NULL) { 00131 size = fread(fp_buffer, sizeof(char), CERT_MAX_SIZE, fp); 00132 DEBUG("...Number of data read: %d, text from file: %s", size, fp_buffer); 00133 fclose(fp); 00134 } 00135 else { 00136 ERROR("Could not open file: %s", path); 00137 return -1; 00138 } 00139 00140 std::string filestr(fp_buffer); 00141 00142 ret = mqtt_parse_sub(&filestr, HostAddress, "AWS_IOT_MQTT_HOST="); 00143 sp->pHost = HostAddress; 00144 INFO("...Host=%s", sp->pHost); 00145 if (ret < 0) { 00146 ERROR("Could not parse AWS_IOT_MQTT_HOST string."); 00147 return ret; 00148 } 00149 00150 ret = mqtt_parse_sub(&filestr, PortString, "AWS_IOT_MQTT_PORT="); 00151 sp->port = atoi(PortString); 00152 INFO("...Port=%d", sp->port); 00153 if (ret < 0) { 00154 ERROR("Could not parse AWS_IOT_MQTT_PORT string."); 00155 return ret; 00156 } 00157 00158 ret = mqtt_parse_sub(&filestr, MqttClientID, "AWS_IOT_MQTT_CLIENT_ID="); 00159 sp->pMqttClientId = MqttClientID; 00160 INFO("...pMqttClientId=%s", sp->pMqttClientId); 00161 if (ret < 0) { 00162 ERROR("Could not parse AWS_IOT_MQTT_CLIENT_ID string."); 00163 return ret; 00164 } 00165 00166 ret = mqtt_parse_sub(&filestr, ThingName, "AWS_IOT_MY_THING_NAME="); 00167 sp->pMyThingName = ThingName; 00168 INFO("...pMyThingName=%s", sp->pMyThingName); 00169 if (ret < 0) { 00170 ERROR("Could not parse AWS_IOT_MY_THING_NAME string."); 00171 return ret; 00172 } 00173 00174 return( ret ); 00175 } 00176 00177 // Override function: Parses CRT from SD 00178 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ) 00179 { 00180 int ret, size; 00181 mbedtls_zeroize(fp_buffer, CERT_MAX_SIZE); 00182 00183 INFO("...Reading CERT data from SD"); 00184 fp = fopen(path, "r"); 00185 if (fp != NULL) { 00186 size = fread(fp_buffer, sizeof(char), CERT_MAX_SIZE, fp); 00187 DEBUG("...Number of data read: %d, text from file: %s", size, fp_buffer); 00188 fclose(fp); 00189 } 00190 else { 00191 ERROR("Could not open file: %s", path); 00192 return -1; 00193 } 00194 00195 DEBUG("...CRT Parse"); 00196 ret = mbedtls_x509_crt_parse( chain, (unsigned char *)fp_buffer, size+2); 00197 00198 return( ret ); 00199 } 00200 00201 // Override function: Parses KEY from SD 00202 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, 00203 const char *path, const char *pwd ) 00204 { 00205 int ret, size; 00206 mbedtls_zeroize(fp_buffer, CERT_MAX_SIZE); 00207 00208 INFO("...Reading KEY data from SD"); 00209 fp = fopen(path, "r"); 00210 if (fp != NULL) { 00211 size = fread(fp_buffer, sizeof(char), CERT_MAX_SIZE, fp); 00212 DEBUG("...Number of data read: %d, text from file: %s", size, fp_buffer); 00213 fclose(fp); 00214 } 00215 else { 00216 ERROR("Could not open file: %s", path); 00217 return -1; 00218 } 00219 00220 DEBUG("...Key Parse"); 00221 if( pwd == NULL ) { 00222 DEBUG("...Using PWD"); 00223 ret = mbedtls_pk_parse_key( ctx, (unsigned char *)fp_buffer, size+1, NULL, 0 ); 00224 } 00225 else { 00226 DEBUG("...No PWD"); 00227 ret = mbedtls_pk_parse_key( ctx, (unsigned char *)fp_buffer, size+1, (const unsigned char *) pwd, strlen( pwd ) ); 00228 } 00229 00230 return( ret ); 00231 } 00232 00233 00234 /* personalization string for the drbg */ 00235 const char *DRBG_PERS = "mbed TLS helloword client"; 00236 00237 int iot_tls_init(Network *pNetwork) { 00238 IoT_Error_t ret_val = NONE_ERROR; 00239 const char *pers = "aws_iot_tls_wrapper"; 00240 unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; 00241 00242 mbedtls_net_init(&server_fd); 00243 mbedtls_ssl_init(&ssl); 00244 mbedtls_ssl_config_init(&conf); 00245 mbedtls_ctr_drbg_init(&ctr_drbg); 00246 mbedtls_x509_crt_init(&cacert); 00247 mbedtls_x509_crt_init(&clicert); 00248 mbedtls_pk_init(&pkey); 00249 00250 DEBUG("...Seeding the random number generator"); 00251 mbedtls_entropy_init(&entropy); 00252 if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) DRBG_PERS, sizeof (DRBG_PERS))) != 0) { 00253 ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret); 00254 return ret_val; 00255 } 00256 DEBUG(" ok\n"); 00257 00258 pNetwork->my_socket = 0; 00259 pNetwork->connect = iot_tls_connect; 00260 pNetwork->mqttread = iot_tls_read; 00261 pNetwork->mqttwrite = iot_tls_write; 00262 pNetwork->disconnect = iot_tls_disconnect; 00263 pNetwork->isConnected = iot_tls_is_connected; 00264 pNetwork->destroy = iot_tls_destroy; 00265 00266 return ret_val; 00267 } 00268 00269 int iot_tls_is_connected(Network *pNetwork) { 00270 /* Use this to add implementation which can check for physical layer disconnect */ 00271 return 1; 00272 } 00273 00274 int iot_tls_connect(Network *pNetwork, TLSConnectParams params) { 00275 const char *pers = "aws_iot_tls_wrapper"; 00276 00277 DEBUG("...Loading the CA root certificate"); 00278 #ifdef USING_SD_CARD 00279 ret = mbedtls_x509_crt_parse_file(&cacert, AWS_IOT_ROOT_CA_FILENAME); 00280 #else 00281 ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)AWS_IOT_ROOT_CA, AWS_IOT_ROOT_CA_LENGTH); 00282 //ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)AWS_IOT_ROOT_CA, 1239); 00283 //ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)AWS_IOT_ROOT_CA, strlen ((const char *)AWS_IOT_ROOT_CA)+1); 00284 #endif 00285 if (ret < 0) { 00286 ERROR(" failed\n ! mbedtls_x509_crt_parse for root returned -0x%x\n\n", -ret); 00287 return ret; 00288 } 00289 DEBUG(" ok (%d skipped)", ret); 00290 00291 00292 DEBUG("...Loading the client cert"); 00293 #ifdef USING_SD_CARD 00294 ret = mbedtls_x509_crt_parse_file(&clicert, AWS_IOT_CERTIFICATE_FILENAME); 00295 #else 00296 ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *)AWS_IOT_CERTIFICATE, AWS_IOT_CERTIFICATE_LENGTH); 00297 DEBUG ("cert version = %d", clicert.version); 00298 00299 00300 00301 /* 00302 for (int k = 0; k < clicert.subject_raw.len; k++) 00303 { 00304 DEBUG ("%02X", clicert.subject_raw.p[k]); 00305 } 00306 */ 00307 00308 for (int i = 0; i < clicert.subject_raw.len; i++) 00309 { 00310 if (clicert.subject_raw.p[i] == 0x0C) 00311 { 00312 i++; 00313 unsigned char cLength = clicert.subject_raw.p[i]; 00314 DEBUG ("subject length = %d", cLength); 00315 i++; 00316 for (int j = 0; j < (int) cLength; j++) 00317 { 00318 cSubject[j] = clicert.subject_raw.p[i]; 00319 i++; 00320 } 00321 cSubject[cLength] = 0x00; 00322 break; 00323 } 00324 } 00325 00326 00327 DEBUG ("Subject = %s", cSubject); 00328 //ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *)AWS_IOT_CERTIFICATE, 862); 00329 //ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *)AWS_IOT_CERTIFICATE, strlen ((const char *)AWS_IOT_CERTIFICATE)+1); 00330 #endif 00331 if (ret != 0) { 00332 ERROR(" failed\n ! mbedtls_x509_crt_parse IOT returned -0x%x\n\n", -ret); 00333 return ret; 00334 } 00335 DEBUG(" ok"); 00336 00337 DEBUG("...Loading the client key"); 00338 #ifdef USING_SD_CARD 00339 ret = mbedtls_pk_parse_keyfile(&pkey, AWS_IOT_PRIVATE_KEY_FILENAME, ""); 00340 #else 00341 ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)AWS_IOT_PRIVATE_KEY, AWS_IOT_PRIVATE_KEY_LENGTH, NULL, 0 ); 00342 //ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)AWS_IOT_PRIVATE_KEY, 1191, NULL, 0 ); 00343 //ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)AWS_IOT_PRIVATE_KEY, strlen ((const char *)AWS_IOT_PRIVATE_KEY)+1, NULL, 0 ); 00344 #endif 00345 if (ret != 0) { 00346 ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x\n\n", -ret); 00347 return ret; 00348 } 00349 DEBUG(" ok"); 00350 00351 char portBuffer[6]; 00352 sprintf(portBuffer, "%d", params.DestinationPort); 00353 DEBUG("...Connecting to %s/%s", params.pDestinationURL, portBuffer); 00354 if ((ret = mbedtls_net_connect(&server_fd, params.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { 00355 ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret); 00356 return ret; 00357 } 00358 00359 00360 ret = mbedtls_net_set_block(&server_fd); 00361 if (ret != 0) { 00362 ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret); 00363 return ret; 00364 } 00365 DEBUG(" ok"); 00366 00367 00368 DEBUG("...Setting up the SSL/TLS structure"); 00369 if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, 00370 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { 00371 ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret); 00372 return ret; 00373 } 00374 00375 00376 mbedtls_ssl_conf_verify(&conf, myCertVerify, NULL); 00377 if (params.ServerVerificationFlag == true) { 00378 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); 00379 } else { 00380 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); 00381 } 00382 mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); 00383 00384 mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); 00385 if ((ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey)) != 0) { 00386 ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); 00387 return ret; 00388 } 00389 00390 mbedtls_ssl_conf_read_timeout(&conf, params.timeout_ms); 00391 00392 if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { 00393 ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret); 00394 return ret; 00395 } 00396 if ((ret = mbedtls_ssl_set_hostname(&ssl, params.pDestinationURL)) != 0) { 00397 ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); 00398 return ret; 00399 } 00400 00401 DEBUG("...Set Socket I/O Functions"); 00402 mbedtls_ssl_set_bio(&ssl, static_cast<void *>(_tcpsocket), mbedtls_net_send, NULL, mbedtls_net_recv_timeout ); 00403 DEBUG(" ok"); 00404 00405 00406 DEBUG("...Performing the SSL/TLS handshake"); 00407 while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { 00408 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 00409 ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret); 00410 if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { 00411 ERROR(" Unable to verify the server's certificate. " 00412 "Either it is invalid,\n" 00413 " or you didn't set ca_file or ca_path " 00414 "to an appropriate value.\n" 00415 " Alternatively, you may want to use " 00416 "auth_mode=optional for testing purposes.\n"); 00417 } 00418 return ret; 00419 } 00420 } 00421 00422 00423 DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&ssl), mbedtls_ssl_get_ciphersuite(&ssl)); 00424 if ((ret = mbedtls_ssl_get_record_expansion(&ssl)) >= 0) { 00425 DEBUG(" [ Record expansion is %d ]\n", ret); 00426 } else { 00427 DEBUG(" [ Record expansion is unknown (compression) ]\n"); 00428 } 00429 00430 00431 DEBUG("...Verifying peer X.509 certificate"); 00432 if (params.ServerVerificationFlag == true) { 00433 if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) { 00434 char vrfy_buf[512]; 00435 ERROR(" failed\n"); 00436 mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags); 00437 ERROR("%s\n", vrfy_buf); 00438 } else { 00439 DEBUG(" ok\n"); 00440 ret = NONE_ERROR; 00441 } 00442 } else { 00443 DEBUG(" Server Verification skipped\n"); 00444 ret = NONE_ERROR; 00445 } 00446 00447 00448 DEBUG("...SSL get peer cert"); 00449 if (mbedtls_ssl_get_peer_cert(&ssl) != NULL) { 00450 DEBUG("...Peer certificate information"); 00451 const uint32_t buf_size = 1024; 00452 char *buf = new char[buf_size]; 00453 mbedtls_x509_crt_info(buf, buf_size, " ", mbedtls_ssl_get_peer_cert(&ssl)); 00454 DEBUG("...Server certificate:\r\n%s\r", buf); 00455 } 00456 00457 mbedtls_ssl_conf_read_timeout(&conf, 10); 00458 00459 return ret; 00460 } 00461 00462 int iot_tls_write(Network *pNetwork, unsigned char *pMsg, int len, int timeout_ms) { 00463 00464 int written; 00465 int frags; 00466 00467 for (written = 0, frags = 0; written < len; written += ret, frags++) { 00468 while ((ret = mbedtls_ssl_write(&ssl, pMsg + written, len - written)) <= 0) { 00469 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 00470 ERROR(" failed\n ! mbedtls_ssl_write returned -0x%x\n\n", -ret); 00471 return ret; 00472 } 00473 } 00474 } 00475 00476 return written; 00477 } 00478 00479 int iot_tls_read(Network *pNetwork, unsigned char *pMsg, int len, int timeout_ms) { 00480 int rxLen = 0; 00481 bool isErrorFlag = false; 00482 bool isCompleteFlag = false; 00483 00484 // TODO check this against base 00485 //mbedtls_ssl_conf_read_timeout(&conf, timeout_ms); 00486 00487 do { 00488 ret = mbedtls_ssl_read(&ssl, pMsg, len); 00489 if (ret > 0) { 00490 rxLen += ret; 00491 } else if (ret != MBEDTLS_ERR_SSL_WANT_READ) { 00492 isErrorFlag = true; 00493 } 00494 if (rxLen >= len) { 00495 isCompleteFlag = true; 00496 } 00497 } while (!isErrorFlag && !isCompleteFlag); 00498 00499 return ret; 00500 } 00501 00502 void iot_tls_disconnect(Network *pNetwork) { 00503 do { 00504 ret = mbedtls_ssl_close_notify(&ssl); 00505 } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE); 00506 } 00507 00508 int iot_tls_destroy(Network *pNetwork) { 00509 00510 mbedtls_net_free(&server_fd); 00511 00512 mbedtls_x509_crt_free(&clicert); 00513 mbedtls_x509_crt_free(&cacert); 00514 mbedtls_pk_free(&pkey); 00515 mbedtls_ssl_free(&ssl); 00516 mbedtls_ssl_config_free(&conf); 00517 mbedtls_ctr_drbg_free(&ctr_drbg); 00518 mbedtls_entropy_free(&entropy); 00519 00520 return 0; 00521 } 00522 00523
Generated on Tue Jul 12 2022 14:16:20 by 1.7.2