int ssl_socket_receive_all_blocking(void *state_data, void *data_, size_t size) { struct ssl_state *state = (struct ssl_state*)state_data; const uint8_t *data = (const uint8_t*)data_; mbedtls_net_set_block(&state->net_ctx); while (1) { /* mbedtls_ssl_read wants non-const data but it only reads it, so this cast is safe */ int ret = mbedtls_ssl_read(&state->ctx, (unsigned char*)data, size); if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) continue; if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) break; if (ret == 0) break; /* normal EOF */ if (ret < 0) return -1; } return 1; }
int ssl_socket_send_all_blocking(void *state_data, const void *data_, size_t size, bool no_signal) { struct ssl_state *state = (struct ssl_state*)state_data; const uint8_t *data = (const uint8_t*)data_; int ret; mbedtls_net_set_block(&state->net_ctx); while ((ret = mbedtls_ssl_write(&state->ctx, data, size)) <= 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) return false; } return true; }
int websocket_tls_handshake(websocket_t *data, char *hostname, int auth_mode) { int r; /* set socket file descriptor */ data->tls_net.fd = data->fd; /* set authentication mode */ mbedtls_ssl_conf_authmode(data->tls_conf, auth_mode); /* default setting block mode */ if ((r = mbedtls_net_set_block(&(data->tls_net))) != 0) { WEBSOCKET_DEBUG("Error: mbedtls_net_set_block returned -%4x\n", -r); return -1; } if ((r = mbedtls_ssl_setup(data->tls_ssl, data->tls_conf)) != 0) { WEBSOCKET_DEBUG("Error: mbedtls_ssl_setup returned -%4x\n", -r); return -1; } #if WEBSOCKET_CONF_CHECK_TLS_HOSTNAME if (hostname != NULL) { if ((r = mbedtls_ssl_set_hostname(data->tls_ssl, hostname)) != 0) { WEBSOCKET_DEBUG("Error: mbedtls_hostname returned -%4x\n", -r); return -1; } } #endif mbedtls_ssl_set_bio(data->tls_ssl, &(data->tls_net), mbedtls_net_send, mbedtls_net_recv, NULL); /* Handshake */ WEBSOCKET_DEBUG(" . Performing the SSL/TLS handshake..."); while ((r = mbedtls_ssl_handshake(data->tls_ssl)) != 0) { if (r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE) { WEBSOCKET_DEBUG("Error: mbedtls_ssl_handshake returned -%4x\n", -r); return r; } } WEBSOCKET_DEBUG("OK\n"); return WEBSOCKET_SUCCESS; }
IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { int ret = SUCCESS; TLSDataParams *tlsDataParams = NULL; char portBuffer[6]; char info_buf[256]; if(NULL == pNetwork) { return NULL_VALUE_ERROR; } if(NULL != params) { _iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation, params->pDevicePrivateKeyLocation, params->pDestinationURL, params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag); } tlsDataParams = &(pNetwork->tlsDataParams); mbedtls_net_init(&(tlsDataParams->server_fd)); mbedtls_ssl_init(&(tlsDataParams->ssl)); mbedtls_ssl_config_init(&(tlsDataParams->conf)); #ifdef CONFIG_MBEDTLS_DEBUG mbedtls_esp_enable_debug_log(&(tlsDataParams->conf), 4); #endif mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg)); mbedtls_x509_crt_init(&(tlsDataParams->cacert)); mbedtls_x509_crt_init(&(tlsDataParams->clicert)); mbedtls_pk_init(&(tlsDataParams->pkey)); ESP_LOGD(TAG, "Seeding the random number generator..."); mbedtls_entropy_init(&(tlsDataParams->entropy)); if((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy), (const unsigned char *) TAG, strlen(TAG))) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ctr_drbg_seed returned -0x%x", -ret); return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; } /* Load root CA... Certs/keys can be paths or they can be raw data. These use a very basic heuristic: if the cert starts with '/' then it's a path, if it's longer than this then it's raw cert data (PEM or DER, neither of which can start with a slash. */ if (pNetwork->tlsConnectParams.pRootCALocation[0] == '/') { ESP_LOGD(TAG, "Loading CA root certificate from file ..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->cacert), pNetwork->tlsConnectParams.pRootCALocation); } else { ESP_LOGD(TAG, "Loading embedded CA root certificate ..."); ret = mbedtls_x509_crt_parse(&(tlsDataParams->cacert), (const unsigned char *)pNetwork->tlsConnectParams.pRootCALocation, strlen(pNetwork->tlsConnectParams.pRootCALocation)+1); } if(ret < 0) { ESP_LOGE(TAG, "failed! mbedtls_x509_crt_parse returned -0x%x while parsing root cert", -ret); return NETWORK_X509_ROOT_CRT_PARSE_ERROR; } ESP_LOGD(TAG, "ok (%d skipped)", ret); /* Load client certificate... */ if (pNetwork->tlsConnectParams.pDeviceCertLocation[0] == '/') { ESP_LOGD(TAG, "Loading client cert from file..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->clicert), pNetwork->tlsConnectParams.pDeviceCertLocation); } else { ESP_LOGD(TAG, "Loading embedded client certificate..."); ret = mbedtls_x509_crt_parse(&(tlsDataParams->clicert), (const unsigned char *)pNetwork->tlsConnectParams.pDeviceCertLocation, strlen(pNetwork->tlsConnectParams.pDeviceCertLocation)+1); } if(ret != 0) { ESP_LOGE(TAG, "failed! mbedtls_x509_crt_parse returned -0x%x while parsing device cert", -ret); return NETWORK_X509_DEVICE_CRT_PARSE_ERROR; } /* Parse client private key... */ if (pNetwork->tlsConnectParams.pDevicePrivateKeyLocation[0] == '/') { ESP_LOGD(TAG, "Loading client private key from file..."); ret = mbedtls_pk_parse_keyfile(&(tlsDataParams->pkey), pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, ""); } else { ESP_LOGD(TAG, "Loading embedded client private key..."); ret = mbedtls_pk_parse_key(&(tlsDataParams->pkey), (const unsigned char *)pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, strlen(pNetwork->tlsConnectParams.pDevicePrivateKeyLocation)+1, (const unsigned char *)"", 0); } if(ret != 0) { ESP_LOGE(TAG, "failed! mbedtls_pk_parse_key returned -0x%x while parsing private key", -ret); return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR; } /* Done parsing certs */ ESP_LOGD(TAG, "ok"); snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort); ESP_LOGD(TAG, "Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer); if((ret = mbedtls_net_connect(&(tlsDataParams->server_fd), pNetwork->tlsConnectParams.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_net_connect returned -0x%x", -ret); switch(ret) { case MBEDTLS_ERR_NET_SOCKET_FAILED: return NETWORK_ERR_NET_SOCKET_FAILED; case MBEDTLS_ERR_NET_UNKNOWN_HOST: return NETWORK_ERR_NET_UNKNOWN_HOST; case MBEDTLS_ERR_NET_CONNECT_FAILED: default: return NETWORK_ERR_NET_CONNECT_FAILED; }; } ret = mbedtls_net_set_block(&(tlsDataParams->server_fd)); if(ret != 0) { ESP_LOGE(TAG, "failed! net_set_(non)block() returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } ESP_LOGD(TAG, "ok"); ESP_LOGD(TAG, "Setting up the SSL/TLS structure..."); if((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_config_defaults returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL); } mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg)); mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL); ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey)); if(ret != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_conf_own_cert returned %d", ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms); #ifdef CONFIG_MBEDTLS_SSL_ALPN /* Use the AWS IoT ALPN extension for MQTT, if port 443 is requested */ if (pNetwork->tlsConnectParams.DestinationPort == 443) { const char *alpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; if ((ret = mbedtls_ssl_conf_alpn_protocols(&(tlsDataParams->conf), alpnProtocols)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_conf_alpn_protocols returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } } #endif if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_setup returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } if((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), pNetwork->tlsConnectParams.pDestinationURL)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_set_hostname returned %d", ret); return SSL_CONNECTION_ERROR; } ESP_LOGD(TAG, "SSL state connect : %d ", tlsDataParams->ssl.state); mbedtls_ssl_set_bio(&(tlsDataParams->ssl), &(tlsDataParams->server_fd), mbedtls_net_send, NULL, mbedtls_net_recv_timeout); ESP_LOGD(TAG, "ok"); ESP_LOGD(TAG, "SSL state connect : %d ", tlsDataParams->ssl.state); ESP_LOGD(TAG, "Performing the SSL/TLS handshake..."); while((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0) { if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ESP_LOGE(TAG, "failed! mbedtls_ssl_handshake returned -0x%x", -ret); if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { ESP_LOGE(TAG, " Unable to verify the server's certificate. "); } return SSL_CONNECTION_ERROR; } } ESP_LOGD(TAG, "ok [ Protocol is %s ] [ Ciphersuite is %s ]", mbedtls_ssl_get_version(&(tlsDataParams->ssl)), mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl))); if((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0) { ESP_LOGD(TAG, " [ Record expansion is %d ]", ret); } else { ESP_LOGD(TAG, " [ Record expansion is unknown (compression) ]"); } ESP_LOGD(TAG, "Verifying peer X.509 certificate..."); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0) { ESP_LOGE(TAG, "failed"); mbedtls_x509_crt_verify_info(info_buf, sizeof(info_buf), " ! ", tlsDataParams->flags); ESP_LOGE(TAG, "%s", info_buf); ret = SSL_CONNECTION_ERROR; } else { ESP_LOGD(TAG, "ok"); ret = SUCCESS; } } else { ESP_LOGW(TAG, " Server Verification skipped"); ret = SUCCESS; } if(LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL) { ESP_LOGD(TAG, "Peer certificate information:"); mbedtls_x509_crt_info((char *) info_buf, sizeof(info_buf) - 1, " ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl))); ESP_LOGD(TAG, "%s", info_buf); } } return (IoT_Error_t) ret; }
int iot_tls_connect(Network *pNetwork, TLSConnectParams params) { const char *pers = "aws_iot_tls_wrapper"; unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; DEBUG(" . Loading the CA root certificate ..."); ret = mbedtls_x509_crt_parse_file(&cacert, params.pRootCALocation); if (ret < 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); return ret; } DEBUG(" ok (%d skipped)\n", ret); DEBUG(" . Loading the client cert. and key..."); ret = mbedtls_x509_crt_parse_file(&clicert, params.pDeviceCertLocation); if (ret != 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); return ret; } ret = mbedtls_pk_parse_keyfile(&pkey, params.pDevicePrivateKeyLocation, ""); if (ret != 0) { ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x\n\n", -ret); return ret; } DEBUG(" ok\n"); char portBuffer[6]; sprintf(portBuffer, "%d", params.DestinationPort); DEBUG(" . Connecting to %s/%s...", params.pDestinationURL, portBuffer); if ((ret = mbedtls_net_connect(&server_fd, params.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret); return ret; } ret = mbedtls_net_set_block(&server_fd); if (ret != 0) { ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret); return ret; } DEBUG(" ok\n"); DEBUG(" . Setting up the SSL/TLS structure..."); if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret); return ret; } mbedtls_ssl_conf_verify(&conf, myCertVerify, NULL); if (params.ServerVerificationFlag == true) { mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); } mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); if ((ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey)) != 0) { ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); return ret; } mbedtls_ssl_conf_read_timeout(&conf, params.timeout_ms); if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret); return ret; } if ((ret = mbedtls_ssl_set_hostname(&ssl, params.pDestinationURL)) != 0) { ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); return ret; } mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, NULL, mbedtls_net_recv_timeout); DEBUG(" ok\n"); DEBUG(" . Performing the SSL/TLS handshake..."); while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret); if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { ERROR(" Unable to verify the server's certificate. " "Either it is invalid,\n" " or you didn't set ca_file or ca_path " "to an appropriate value.\n" " Alternatively, you may want to use " "auth_mode=optional for testing purposes.\n"); } return ret; } } DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&ssl), mbedtls_ssl_get_ciphersuite(&ssl)); if ((ret = mbedtls_ssl_get_record_expansion(&ssl)) >= 0) { DEBUG(" [ Record expansion is %d ]\n", ret); } else { DEBUG(" [ Record expansion is unknown (compression) ]\n"); } DEBUG(" . Verifying peer X.509 certificate..."); if (params.ServerVerificationFlag == true) { if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) { char vrfy_buf[512]; ERROR(" failed\n"); mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags); ERROR("%s\n", vrfy_buf); } else { DEBUG(" ok\n"); ret = NONE_ERROR; } } else { DEBUG(" Server Verification skipped\n"); ret = NONE_ERROR; } if (mbedtls_ssl_get_peer_cert(&ssl) != NULL) { DEBUG(" . Peer certificate information ...\n"); mbedtls_x509_crt_info((char *) buf, sizeof(buf) - 1, " ", mbedtls_ssl_get_peer_cert(&ssl)); DEBUG("%s\n", buf); } mbedtls_ssl_conf_read_timeout(&conf, 10); return ret; }
IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { if(NULL == pNetwork) { return NULL_VALUE_ERROR; } if(NULL != params) { _iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation, params->pDevicePrivateKeyLocation, params->pDestinationURL, params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag); } int ret = 0; const char *pers = "aws_iot_tls_wrapper"; #ifdef IOT_DEBUG unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; #endif TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams); mbedtls_net_init(&(tlsDataParams->server_fd)); mbedtls_ssl_init(&(tlsDataParams->ssl)); mbedtls_ssl_config_init(&(tlsDataParams->conf)); mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg)); mbedtls_x509_crt_init(&(tlsDataParams->cacert)); mbedtls_x509_crt_init(&(tlsDataParams->clicert)); mbedtls_pk_init(&(tlsDataParams->pkey)); DEBUG("\n . Seeding the random number generator..."); mbedtls_entropy_init(&(tlsDataParams->entropy)); if ((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy), (const unsigned char *) pers, strlen(pers))) != 0) { ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret); return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; } DEBUG(" . Loading the CA root certificate ..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->cacert), pNetwork->tlsConnectParams.pRootCALocation); if (ret < 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing root cert\n\n", -ret); return NETWORK_X509_ROOT_CRT_PARSE_ERROR; } DEBUG(" ok (%d skipped)\n", ret); DEBUG(" . Loading the client cert. and key..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->clicert), pNetwork->tlsConnectParams.pDeviceCertLocation); if (ret != 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing device cert\n\n", -ret); return NETWORK_X509_DEVICE_CRT_PARSE_ERROR; } ret = mbedtls_pk_parse_keyfile(&(tlsDataParams->pkey), pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, ""); if (ret != 0) { ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x while parsing private key\n\n", -ret); DEBUG(" path : %s ", pNetwork->tlsConnectParams.pDevicePrivateKeyLocation); return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR; } DEBUG(" ok\n"); char portBuffer[6]; snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort); DEBUG(" . Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer); if ((ret = mbedtls_net_connect(&(tlsDataParams->server_fd), pNetwork->tlsConnectParams.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret); switch(ret) { case MBEDTLS_ERR_NET_SOCKET_FAILED: return NETWORK_ERR_NET_SOCKET_FAILED; case MBEDTLS_ERR_NET_UNKNOWN_HOST: return NETWORK_ERR_NET_UNKNOWN_HOST; case MBEDTLS_ERR_NET_CONNECT_FAILED: default: return NETWORK_ERR_NET_CONNECT_FAILED; }; } ret = mbedtls_net_set_block(&(tlsDataParams->server_fd)); if (ret != 0) { ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } DEBUG(" ok\n"); DEBUG(" . Setting up the SSL/TLS structure..."); if ((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); if (pNetwork->tlsConnectParams.ServerVerificationFlag == true) { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL); } mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg)); mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL); if ((ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey))) != 0) { ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms); if ((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) { ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } if ((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), pNetwork->tlsConnectParams.pDestinationURL)) != 0) { ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); return SSL_CONNECTION_ERROR; } DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); mbedtls_ssl_set_bio(&(tlsDataParams->ssl), &(tlsDataParams->server_fd), mbedtls_net_send, NULL, mbedtls_net_recv_timeout); DEBUG(" ok\n"); DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); DEBUG(" . Performing the SSL/TLS handshake..."); while ((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret); if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { ERROR(" Unable to verify the server's certificate. " "Either it is invalid,\n" " or you didn't set ca_file or ca_path " "to an appropriate value.\n" " Alternatively, you may want to use " "auth_mode=optional for testing purposes.\n"); } return SSL_CONNECTION_ERROR; } } DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&(tlsDataParams->ssl)), mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl))); if ((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0) { DEBUG(" [ Record expansion is %d ]\n", ret); } else { DEBUG(" [ Record expansion is unknown (compression) ]\n"); } DEBUG(" . Verifying peer X.509 certificate..."); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0) { char vrfy_buf[512]; ERROR(" failed\n"); mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", tlsDataParams->flags); ERROR("%s\n", vrfy_buf); ret = SSL_CONNECTION_ERROR; } else { DEBUG(" ok\n"); ret = SUCCESS; } } else { DEBUG(" Server Verification skipped\n"); ret = SUCCESS; } #ifdef IOT_DEBUG if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL) { DEBUG(" . Peer certificate information ...\n"); mbedtls_x509_crt_info((char *) buf, sizeof(buf) - 1, " ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl))); DEBUG("%s\n", buf); } #endif mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), IOT_SSL_READ_TIMEOUT); return ret; }