Jeon byungchul
/
aws-iot-example
this is fork and i will modify for STM32
Fork of AWS-test by
Embed:
(wiki syntax)
Show/hide line numbers
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 #ifdef __cplusplus 00017 extern "C" { 00018 #endif 00019 00020 #include <stdbool.h> 00021 #include <string.h> 00022 #include <timer_platform.h> 00023 #include <network_interface.h> 00024 00025 #include "aws_iot_error.h" 00026 #include "aws_iot_log.h" 00027 #include "network_interface.h" 00028 #include "network_platform.h" 00029 00030 #include "aws_iot_config.h" 00031 00032 /* This is the value used for ssl read timeout */ 00033 #define IOT_SSL_READ_TIMEOUT 10 00034 00035 /* 00036 * This is a function to do further verification if needed on the cert received 00037 */ 00038 00039 static int _iot_tls_verify_cert(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) { 00040 char buf[1024]; 00041 ((void) data); 00042 00043 IOT_DEBUG("\nVerify requested for (Depth %d):\n", depth); 00044 mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt); 00045 IOT_DEBUG("%s", buf); 00046 00047 if((*flags) == 0) { 00048 IOT_DEBUG(" This certificate has no flags\n"); 00049 } else { 00050 IOT_DEBUG(buf, sizeof(buf), " ! ", *flags); 00051 IOT_DEBUG("%s\n", buf); 00052 } 00053 00054 return 0; 00055 } 00056 00057 void _iot_tls_set_connect_params(Network *pNetwork, char *pRootCALocation, char *pDeviceCertLocation, 00058 char *pDevicePrivateKeyLocation, char *pDestinationURL, 00059 uint16_t destinationPort, uint32_t timeout_ms, bool ServerVerificationFlag) { 00060 pNetwork->tlsConnectParams.DestinationPort = destinationPort; 00061 pNetwork->tlsConnectParams.pDestinationURL = pDestinationURL; 00062 pNetwork->tlsConnectParams.pDeviceCertLocation = pDeviceCertLocation; 00063 pNetwork->tlsConnectParams.pDevicePrivateKeyLocation = pDevicePrivateKeyLocation; 00064 pNetwork->tlsConnectParams.pRootCALocation = pRootCALocation; 00065 pNetwork->tlsConnectParams.timeout_ms = timeout_ms; 00066 pNetwork->tlsConnectParams.ServerVerificationFlag = ServerVerificationFlag; 00067 } 00068 00069 IoT_Error_t iot_tls_init(Network *pNetwork, char *pRootCALocation, char *pDeviceCertLocation, 00070 char *pDevicePrivateKeyLocation, char *pDestinationURL, 00071 uint16_t destinationPort, uint32_t timeout_ms, bool ServerVerificationFlag) { 00072 _iot_tls_set_connect_params(pNetwork, pRootCALocation, pDeviceCertLocation, pDevicePrivateKeyLocation, 00073 pDestinationURL, destinationPort, timeout_ms, ServerVerificationFlag); 00074 00075 pNetwork->connect = iot_tls_connect; 00076 pNetwork->read = iot_tls_read; 00077 pNetwork->write = iot_tls_write; 00078 pNetwork->disconnect = iot_tls_disconnect; 00079 pNetwork->isConnected = iot_tls_is_connected; 00080 pNetwork->destroy = iot_tls_destroy; 00081 00082 pNetwork->tlsDataParams.flags = 0; 00083 00084 return IOT_SUCCESS; 00085 } 00086 00087 IoT_Error_t iot_tls_is_connected(Network *pNetwork) { 00088 /* Use this to add implementation which can check for physical layer disconnect */ 00089 return NETWORK_PHYSICAL_LAYER_CONNECTED; 00090 } 00091 00092 IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { 00093 int ret = 0; 00094 const char *pers = "aws_iot_tls_wrapper"; 00095 TLSDataParams *tlsDataParams = NULL; 00096 char portBuffer[6]; 00097 char vrfy_buf[512]; 00098 #ifdef IOT_DEBUG 00099 unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; 00100 #endif 00101 00102 if(NULL == pNetwork) { 00103 return NULL_VALUE_ERROR; 00104 } 00105 00106 if(NULL != params) { 00107 _iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation, 00108 params->pDevicePrivateKeyLocation, params->pDestinationURL, 00109 params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag); 00110 } 00111 00112 tlsDataParams = &(pNetwork->tlsDataParams); 00113 00114 mbedtls_net_init(&(tlsDataParams->server_fd)); 00115 mbedtls_ssl_init(&(tlsDataParams->ssl)); 00116 mbedtls_ssl_config_init(&(tlsDataParams->conf)); 00117 mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg)); 00118 mbedtls_x509_crt_init(&(tlsDataParams->cacert)); 00119 mbedtls_x509_crt_init(&(tlsDataParams->clicert)); 00120 mbedtls_pk_init(&(tlsDataParams->pkey)); 00121 00122 IOT_DEBUG("\n . Seeding the random number generator..."); 00123 mbedtls_entropy_init(&(tlsDataParams->entropy)); 00124 if((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy), 00125 (const unsigned char *) pers, strlen(pers))) != 0) { 00126 IOT_ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret); 00127 return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; 00128 } 00129 00130 IOT_DEBUG(" . Loading the CA root certificate ..."); 00131 ret = mbedtls_x509_crt_parse(&(tlsDataParams->cacert), (const unsigned char *)AWS_IOT_ROOT_CA, strlen(AWS_IOT_ROOT_CA)); 00132 if(ret < 0) { 00133 IOT_ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing root cert\n\n", -ret); 00134 return NETWORK_X509_ROOT_CRT_PARSE_ERROR; 00135 } 00136 IOT_DEBUG(" ok (%d skipped)\n", ret); 00137 00138 IOT_DEBUG(" . Loading the client cert. and key..."); 00139 ret = mbedtls_x509_crt_parse(&(tlsDataParams->clicert), (const unsigned char *)AWS_IOT_CERTIFICATE, strlen(AWS_IOT_CERTIFICATE)); 00140 if(ret != 0) { 00141 IOT_ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing device cert\n\n", -ret); 00142 return NETWORK_X509_DEVICE_CRT_PARSE_ERROR; 00143 } 00144 00145 ret = mbedtls_pk_parse_key(&(tlsDataParams->pkey), (const unsigned char *)AWS_IOT_PRIVATE_KEY, strlen(AWS_IOT_PRIVATE_KEY), (const unsigned char *)(PASSWORD),strlen(PASSWORD)); 00146 if(ret != 0) { 00147 IOT_ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x while parsing private key\n\n", -ret); 00148 IOT_DEBUG(" path : %s ", pNetwork->tlsConnectParams.pDevicePrivateKeyLocation); 00149 return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR; 00150 } 00151 IOT_DEBUG(" ok\n"); 00152 snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort); 00153 IOT_DEBUG(" . Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer); 00154 if((ret = mbedtls_net_connect(&(tlsDataParams->server_fd), pNetwork->tlsConnectParams.pDestinationURL, 00155 portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { 00156 IOT_ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret); 00157 switch(ret) { 00158 case MBEDTLS_ERR_NET_SOCKET_FAILED: 00159 return NETWORK_ERR_NET_SOCKET_FAILED; 00160 case MBEDTLS_ERR_NET_UNKNOWN_HOST: 00161 return NETWORK_ERR_NET_UNKNOWN_HOST; 00162 case MBEDTLS_ERR_NET_CONNECT_FAILED: 00163 default: 00164 return NETWORK_ERR_NET_CONNECT_FAILED; 00165 }; 00166 } 00167 00168 ret = mbedtls_net_set_block(&(tlsDataParams->server_fd)); 00169 if(ret != 0) { 00170 IOT_ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret); 00171 return SSL_CONNECTION_ERROR; 00172 } IOT_DEBUG(" ok\n"); 00173 00174 IOT_DEBUG(" . Setting up the SSL/TLS structure..."); 00175 if((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, 00176 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { 00177 IOT_ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret); 00178 return SSL_CONNECTION_ERROR; 00179 } 00180 00181 mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); 00182 if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { 00183 mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED); 00184 } else { 00185 mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL); 00186 } 00187 mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg)); 00188 00189 mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL); 00190 if((ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey))) != 00191 0) { 00192 IOT_ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); 00193 return SSL_CONNECTION_ERROR; 00194 } 00195 00196 mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms); 00197 00198 if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) { 00199 IOT_ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret); 00200 return SSL_CONNECTION_ERROR; 00201 } 00202 if((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), pNetwork->tlsConnectParams.pDestinationURL)) != 0) { 00203 IOT_ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); 00204 return SSL_CONNECTION_ERROR; 00205 } 00206 IOT_DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); 00207 mbedtls_ssl_set_bio(&(tlsDataParams->ssl), &(tlsDataParams->server_fd), mbedtls_net_send, NULL, 00208 mbedtls_net_recv_timeout); 00209 IOT_DEBUG(" ok\n"); 00210 00211 IOT_DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); 00212 IOT_DEBUG(" . Performing the SSL/TLS handshake..."); 00213 while((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0) { 00214 if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 00215 IOT_ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret); 00216 if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { 00217 IOT_ERROR(" Unable to verify the server's certificate. " 00218 "Either it is invalid,\n" 00219 " or you didn't set ca_file or ca_path " 00220 "to an appropriate value.\n" 00221 " Alternatively, you may want to use " 00222 "auth_mode=optional for testing purposes.\n"); 00223 } 00224 return SSL_CONNECTION_ERROR; 00225 } 00226 } 00227 00228 IOT_DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&(tlsDataParams->ssl)), 00229 mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl))); 00230 if((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0) { 00231 IOT_DEBUG(" [ Record expansion is %d ]\n", ret); 00232 } else { 00233 IOT_DEBUG(" [ Record expansion is unknown (compression) ]\n"); 00234 } 00235 00236 IOT_DEBUG(" . Verifying peer X.509 certificate..."); 00237 00238 if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { 00239 if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0) { 00240 IOT_ERROR(" failed\n"); 00241 mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", tlsDataParams->flags); 00242 IOT_ERROR("%s\n", vrfy_buf); 00243 ret = SSL_CONNECTION_ERROR; 00244 } else { 00245 IOT_DEBUG(" ok\n"); 00246 ret = IOT_SUCCESS; 00247 } 00248 } else { 00249 IOT_DEBUG(" Server Verification skipped\n"); 00250 ret = IOT_SUCCESS; 00251 } 00252 00253 #ifdef IOT_DEBUG 00254 if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL) { 00255 IOT_DEBUG(" . Peer certificate information ...\n"); 00256 mbedtls_x509_crt_info((char *) buf, sizeof(buf) - 1, " ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl))); 00257 IOT_DEBUG("%s\n", buf); 00258 } 00259 #endif 00260 00261 mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), IOT_SSL_READ_TIMEOUT); 00262 00263 return (IoT_Error_t) ret; 00264 } 00265 00266 IoT_Error_t iot_tls_write(Network *pNetwork, unsigned char *pMsg, size_t len, TimerAWS *timer, size_t *written_len) { 00267 size_t written_so_far; 00268 bool isErrorFlag = false; 00269 int frags, ret; 00270 TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams); 00271 00272 for(written_so_far = 0, frags = 0; 00273 written_so_far < len && !has_timer_expired(timer); written_so_far += ret, frags++) { 00274 while(!has_timer_expired(timer) && 00275 (ret = mbedtls_ssl_write(&(tlsDataParams->ssl), pMsg + written_so_far, len - written_so_far)) <= 0) { 00276 if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 00277 IOT_ERROR(" failed\n ! mbedtls_ssl_write returned -0x%x\n\n", -ret); 00278 /* All other negative return values indicate connection needs to be reset. 00279 * Will be caught in ping request so ignored here */ 00280 isErrorFlag = true; 00281 break; 00282 } 00283 } 00284 if(isErrorFlag) { 00285 break; 00286 } 00287 } 00288 00289 *written_len = written_so_far; 00290 00291 if(isErrorFlag) { 00292 return NETWORK_SSL_WRITE_ERROR; 00293 } else if(has_timer_expired(timer) && written_so_far != len) { 00294 return NETWORK_SSL_WRITE_TIMEOUT_ERROR; 00295 } 00296 00297 return IOT_SUCCESS; 00298 } 00299 00300 IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, TimerAWS *timer, size_t *read_len) { 00301 mbedtls_ssl_context *ssl = &(pNetwork->tlsDataParams.ssl); 00302 size_t rxLen = 0; 00303 int ret; 00304 00305 while (len > 0) { 00306 // This read will timeout after IOT_SSL_READ_TIMEOUT if there's no data to be read 00307 ret = mbedtls_ssl_read(ssl, pMsg, len); 00308 if (ret > 0) { 00309 rxLen += ret; 00310 pMsg += ret; 00311 len -= ret; 00312 } else if (ret == 0 || (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_TIMEOUT)) { 00313 return NETWORK_SSL_READ_ERROR; 00314 } 00315 00316 // Evaluate timeout after the read to make sure read is done at least once 00317 if (has_timer_expired(timer)) { 00318 break; 00319 } 00320 } 00321 00322 if (len == 0) { 00323 *read_len = rxLen; 00324 return IOT_SUCCESS; 00325 } 00326 00327 if (rxLen == 0) { 00328 return NETWORK_SSL_NOTHING_TO_READ; 00329 } else { 00330 return NETWORK_SSL_READ_TIMEOUT_ERROR; 00331 } 00332 } 00333 00334 IoT_Error_t iot_tls_disconnect(Network *pNetwork) { 00335 mbedtls_ssl_context *ssl = &(pNetwork->tlsDataParams.ssl); 00336 int ret = 0; 00337 do { 00338 ret = mbedtls_ssl_close_notify(ssl); 00339 } while(ret == MBEDTLS_ERR_SSL_WANT_WRITE); 00340 00341 /* All other negative return values indicate connection needs to be reset. 00342 * No further action required since this is disconnect call */ 00343 00344 return IOT_SUCCESS; 00345 } 00346 00347 IoT_Error_t iot_tls_destroy(Network *pNetwork) { 00348 TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams); 00349 00350 mbedtls_net_free(&(tlsDataParams->server_fd)); 00351 00352 mbedtls_x509_crt_free(&(tlsDataParams->clicert)); 00353 mbedtls_x509_crt_free(&(tlsDataParams->cacert)); 00354 mbedtls_pk_free(&(tlsDataParams->pkey)); 00355 mbedtls_ssl_free(&(tlsDataParams->ssl)); 00356 mbedtls_ssl_config_free(&(tlsDataParams->conf)); 00357 mbedtls_ctr_drbg_free(&(tlsDataParams->ctr_drbg)); 00358 mbedtls_entropy_free(&(tlsDataParams->entropy)); 00359 00360 return IOT_SUCCESS; 00361 } 00362 00363 #ifdef __cplusplus 00364 } 00365 #endif
Generated on Tue Jul 12 2022 11:16:38 by 1.7.2