보안 IoT 장치 통신을 시도했다 (MbedTLS 이식편-MQTTS)
소개
2019년 5월에 IoTLT에서 LT를 했습니다.
그 내용의 팔로우를 기입하면서 나름대로 정리해 가고 싶습니다.
발표 내용:
스타트업 IoT 디바이스 보안 고려
마지막까지의 개요
보안 IoT 장치 통신을 시도했습니다 (MbedTLS 이식편 - https 테스트 - 연결) 에서 https에서 기본 GET 요청을 보내고 응답을 받았습니다.
이번 기사와 관련된 소스 코드는 아래에서 공개 중.
kmwebnet/ECC608-mqtts-client
MQTT 연결을 위한 포팅
디바이스 측에서 MQTTS를 통해 브로커에 연결하여 게시 및 구독을 테스트합니다.
이번 대상 MQTT 브로커는 CentOS7에 OpenSSL1.1.1 및 Mosquitto1.6 설치
환경을 사용합니다.
이번에도 코드에서 포팅 포인트를 정리합니다.
MQTT 클라이언트 내장
ESP-IDF 용 MQTT 코드를 src/mqtt에 배치합니다.
그 중, transport_ssl.c의 ssl_connect 함수에, 디바이스의 증명서를 ATECC608A로부터 추출해 포함하는 루틴을 넣는다.
/* Convert to an mbedtls key */
if (0 != atca_mbedtls_pk_init(&pkey, 0))
{
printf("Failed to parse key from device\n");
goto exit;
}
/* Extract the device certificate and convert to mbedtls cert */
if (0 != atca_mbedtls_cert_add(&ssl->cert, &g_cert_def_2_device))
{
printf("Failed to parse cert from device\n");
goto exit;
}
status = atcab_release();
if (ATCA_SUCCESS != (status = atcab_init(&cfg)))
{
printf("Failed to init: %d\r\n", status);
}
/* Extract the signer certificate, convert, then attach to the chain */
if (0 != atca_mbedtls_cert_add(&ssl->cert, &g_cert_def_1_signer))
{
printf("Failed to parse cert from device\n");
goto exit;
}
/* Attach the certificate chain and private key to the SSL/TLS context */
printf(" . Set up the client credentials.");
fflush(stdout);
if(0 != (ret = mbedtls_ssl_conf_own_cert(
&ssl->conf, &ssl->cert, &pkey)))
{
printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\r\n", ret);
goto exit;
}
printf(" ok\n");
메인 처리에 대해서
main.c 내의 분석.
실제의 MQTT의 처리는, 우선 mqtt_app_start 내의 하기, 접속처 URL의 설정과 클라이언트의 기동이 행해진다.
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "mqtts://testcorp.com:8883",
// .host = "",
// .port = ,
.event_handle = mqtt_event_handler,
.cert_pem = (const char *)rootcacert,
};
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_start(client);
esp_mqtt_client_start (client);는 내부적으로 구독 FreeRTOS 작업을 시작합니다.
MQTT 메시지를 기다리는 상태가 됩니다.
그 후, BME280의 초기화가 행해진 후, 다음의 루프에 들어간다.
while(1) {
…
com_rslt = bme280_read_uncomp_pressure_temperature_humidity(
&v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32);
…
sprintf(pubMessage,
"{\"Temparature\": \"%f\" , "
"\"Pressure\": \"%f\" , "
"\"Humidity\": \"%f\"}",
bme280_compensate_temperature_double(v_uncomp_temperature_s32),
bme280_compensate_pressure_double(v_uncomp_pressure_s32)/100,
bme280_compensate_humidity_double(v_uncomp_humidity_s32)) ;
esp_mqtt_client_publish(client, "/topic/qos0", pubMessage, 0, 0, 0);
const portTickType yDelay = 10000 / portTICK_RATE_MS; // 1000ms
vTaskDelay(yDelay);
}
처리의 흐름으로서는,
1, BME280의 측정 결과 취득
2, JSON의 형태로 데이터를 성형
3, esp_mqtt_client_publish로 데이터 게시
4, 10초 웨이트
이 반복이 된다.
/topic/qos0이 주제 이름이 되고 다른 노드에서 이 주제로 게시하면
mqtt_event_handler의 MQTT_EVENT_DATA가 잡히고 콘솔에 표시하는 동작을 수행한다.
I (24175) ECC608: Stack remaining for task 'main' is 1904 bytes
I (24185) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (24185) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.485141" , "Pressure": "1004.483107" , "Humidity": "53.987691"}
I (25325) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (25325) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.947010" , "Pressure": "1005.009985" , "Humidity": "59.377412"}
그리고는 Node-RED로 데이터를 추출하여 시각화할 수 있다.
Reference
이 문제에 관하여(보안 IoT 장치 통신을 시도했다 (MbedTLS 이식편-MQTTS)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kmitsu76/items/8573ee925ffd72b027e0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
보안 IoT 장치 통신을 시도했습니다 (MbedTLS 이식편 - https 테스트 - 연결) 에서 https에서 기본 GET 요청을 보내고 응답을 받았습니다.
이번 기사와 관련된 소스 코드는 아래에서 공개 중.
kmwebnet/ECC608-mqtts-client
MQTT 연결을 위한 포팅
디바이스 측에서 MQTTS를 통해 브로커에 연결하여 게시 및 구독을 테스트합니다.
이번 대상 MQTT 브로커는 CentOS7에 OpenSSL1.1.1 및 Mosquitto1.6 설치
환경을 사용합니다.
이번에도 코드에서 포팅 포인트를 정리합니다.
MQTT 클라이언트 내장
ESP-IDF 용 MQTT 코드를 src/mqtt에 배치합니다.
그 중, transport_ssl.c의 ssl_connect 함수에, 디바이스의 증명서를 ATECC608A로부터 추출해 포함하는 루틴을 넣는다.
/* Convert to an mbedtls key */
if (0 != atca_mbedtls_pk_init(&pkey, 0))
{
printf("Failed to parse key from device\n");
goto exit;
}
/* Extract the device certificate and convert to mbedtls cert */
if (0 != atca_mbedtls_cert_add(&ssl->cert, &g_cert_def_2_device))
{
printf("Failed to parse cert from device\n");
goto exit;
}
status = atcab_release();
if (ATCA_SUCCESS != (status = atcab_init(&cfg)))
{
printf("Failed to init: %d\r\n", status);
}
/* Extract the signer certificate, convert, then attach to the chain */
if (0 != atca_mbedtls_cert_add(&ssl->cert, &g_cert_def_1_signer))
{
printf("Failed to parse cert from device\n");
goto exit;
}
/* Attach the certificate chain and private key to the SSL/TLS context */
printf(" . Set up the client credentials.");
fflush(stdout);
if(0 != (ret = mbedtls_ssl_conf_own_cert(
&ssl->conf, &ssl->cert, &pkey)))
{
printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\r\n", ret);
goto exit;
}
printf(" ok\n");
메인 처리에 대해서
main.c 내의 분석.
실제의 MQTT의 처리는, 우선 mqtt_app_start 내의 하기, 접속처 URL의 설정과 클라이언트의 기동이 행해진다.
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "mqtts://testcorp.com:8883",
// .host = "",
// .port = ,
.event_handle = mqtt_event_handler,
.cert_pem = (const char *)rootcacert,
};
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_start(client);
esp_mqtt_client_start (client);는 내부적으로 구독 FreeRTOS 작업을 시작합니다.
MQTT 메시지를 기다리는 상태가 됩니다.
그 후, BME280의 초기화가 행해진 후, 다음의 루프에 들어간다.
while(1) {
…
com_rslt = bme280_read_uncomp_pressure_temperature_humidity(
&v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32);
…
sprintf(pubMessage,
"{\"Temparature\": \"%f\" , "
"\"Pressure\": \"%f\" , "
"\"Humidity\": \"%f\"}",
bme280_compensate_temperature_double(v_uncomp_temperature_s32),
bme280_compensate_pressure_double(v_uncomp_pressure_s32)/100,
bme280_compensate_humidity_double(v_uncomp_humidity_s32)) ;
esp_mqtt_client_publish(client, "/topic/qos0", pubMessage, 0, 0, 0);
const portTickType yDelay = 10000 / portTICK_RATE_MS; // 1000ms
vTaskDelay(yDelay);
}
처리의 흐름으로서는,
1, BME280의 측정 결과 취득
2, JSON의 형태로 데이터를 성형
3, esp_mqtt_client_publish로 데이터 게시
4, 10초 웨이트
이 반복이 된다.
/topic/qos0이 주제 이름이 되고 다른 노드에서 이 주제로 게시하면
mqtt_event_handler의 MQTT_EVENT_DATA가 잡히고 콘솔에 표시하는 동작을 수행한다.
I (24175) ECC608: Stack remaining for task 'main' is 1904 bytes
I (24185) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (24185) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.485141" , "Pressure": "1004.483107" , "Humidity": "53.987691"}
I (25325) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (25325) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.947010" , "Pressure": "1005.009985" , "Humidity": "59.377412"}
그리고는 Node-RED로 데이터를 추출하여 시각화할 수 있다.
Reference
이 문제에 관하여(보안 IoT 장치 통신을 시도했다 (MbedTLS 이식편-MQTTS)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kmitsu76/items/8573ee925ffd72b027e0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
ESP-IDF 용 MQTT 코드를 src/mqtt에 배치합니다.
그 중, transport_ssl.c의 ssl_connect 함수에, 디바이스의 증명서를 ATECC608A로부터 추출해 포함하는 루틴을 넣는다.
/* Convert to an mbedtls key */
if (0 != atca_mbedtls_pk_init(&pkey, 0))
{
printf("Failed to parse key from device\n");
goto exit;
}
/* Extract the device certificate and convert to mbedtls cert */
if (0 != atca_mbedtls_cert_add(&ssl->cert, &g_cert_def_2_device))
{
printf("Failed to parse cert from device\n");
goto exit;
}
status = atcab_release();
if (ATCA_SUCCESS != (status = atcab_init(&cfg)))
{
printf("Failed to init: %d\r\n", status);
}
/* Extract the signer certificate, convert, then attach to the chain */
if (0 != atca_mbedtls_cert_add(&ssl->cert, &g_cert_def_1_signer))
{
printf("Failed to parse cert from device\n");
goto exit;
}
/* Attach the certificate chain and private key to the SSL/TLS context */
printf(" . Set up the client credentials.");
fflush(stdout);
if(0 != (ret = mbedtls_ssl_conf_own_cert(
&ssl->conf, &ssl->cert, &pkey)))
{
printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\r\n", ret);
goto exit;
}
printf(" ok\n");
메인 처리에 대해서
main.c 내의 분석.
실제의 MQTT의 처리는, 우선 mqtt_app_start 내의 하기, 접속처 URL의 설정과 클라이언트의 기동이 행해진다.
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "mqtts://testcorp.com:8883",
// .host = "",
// .port = ,
.event_handle = mqtt_event_handler,
.cert_pem = (const char *)rootcacert,
};
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_start(client);
esp_mqtt_client_start (client);는 내부적으로 구독 FreeRTOS 작업을 시작합니다.
MQTT 메시지를 기다리는 상태가 됩니다.
그 후, BME280의 초기화가 행해진 후, 다음의 루프에 들어간다.
while(1) {
…
com_rslt = bme280_read_uncomp_pressure_temperature_humidity(
&v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32);
…
sprintf(pubMessage,
"{\"Temparature\": \"%f\" , "
"\"Pressure\": \"%f\" , "
"\"Humidity\": \"%f\"}",
bme280_compensate_temperature_double(v_uncomp_temperature_s32),
bme280_compensate_pressure_double(v_uncomp_pressure_s32)/100,
bme280_compensate_humidity_double(v_uncomp_humidity_s32)) ;
esp_mqtt_client_publish(client, "/topic/qos0", pubMessage, 0, 0, 0);
const portTickType yDelay = 10000 / portTICK_RATE_MS; // 1000ms
vTaskDelay(yDelay);
}
처리의 흐름으로서는,
1, BME280의 측정 결과 취득
2, JSON의 형태로 데이터를 성형
3, esp_mqtt_client_publish로 데이터 게시
4, 10초 웨이트
이 반복이 된다.
/topic/qos0이 주제 이름이 되고 다른 노드에서 이 주제로 게시하면
mqtt_event_handler의 MQTT_EVENT_DATA가 잡히고 콘솔에 표시하는 동작을 수행한다.
I (24175) ECC608: Stack remaining for task 'main' is 1904 bytes
I (24185) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (24185) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.485141" , "Pressure": "1004.483107" , "Humidity": "53.987691"}
I (25325) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (25325) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.947010" , "Pressure": "1005.009985" , "Humidity": "59.377412"}
그리고는 Node-RED로 데이터를 추출하여 시각화할 수 있다.
Reference
이 문제에 관하여(보안 IoT 장치 통신을 시도했다 (MbedTLS 이식편-MQTTS)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kmitsu76/items/8573ee925ffd72b027e0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "mqtts://testcorp.com:8883",
// .host = "",
// .port = ,
.event_handle = mqtt_event_handler,
.cert_pem = (const char *)rootcacert,
};
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_start(client);
while(1) {
…
com_rslt = bme280_read_uncomp_pressure_temperature_humidity(
&v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32);
…
sprintf(pubMessage,
"{\"Temparature\": \"%f\" , "
"\"Pressure\": \"%f\" , "
"\"Humidity\": \"%f\"}",
bme280_compensate_temperature_double(v_uncomp_temperature_s32),
bme280_compensate_pressure_double(v_uncomp_pressure_s32)/100,
bme280_compensate_humidity_double(v_uncomp_humidity_s32)) ;
esp_mqtt_client_publish(client, "/topic/qos0", pubMessage, 0, 0, 0);
const portTickType yDelay = 10000 / portTICK_RATE_MS; // 1000ms
vTaskDelay(yDelay);
}
I (24175) ECC608: Stack remaining for task 'main' is 1904 bytes
I (24185) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (24185) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.485141" , "Pressure": "1004.483107" , "Humidity": "53.987691"}
I (25325) MQTT_CLIENT: deliver_publish, message_length_read=97, message_length=97
I (25325) ECC608: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA={"Temparature": "26.947010" , "Pressure": "1005.009985" , "Humidity": "59.377412"}
Reference
이 문제에 관하여(보안 IoT 장치 통신을 시도했다 (MbedTLS 이식편-MQTTS)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kmitsu76/items/8573ee925ffd72b027e0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)