Skip to content

Commit 5db5dd0

Browse files
authored
check x509 cert hostname to make sure we are connected to the correct host (#146)
* check x509 cert hostname to make sure we are connected to the correct host. * reduce memory usage by reusing tls buffers for cert validation.
1 parent 9a79312 commit 5db5dd0

File tree

4 files changed

+40
-32
lines changed

4 files changed

+40
-32
lines changed

cmake/arm-gcc-cortex-toolchain.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ set(CMAKE_COMMON_FLAGS "-ffunction-sections -fdata-sections -Wunused -Wuninitial
7272
set(CMAKE_C_FLAGS "${MCPU_FLAGS} ${VFP_FLAGS} ${SPECS_FLAGS} ${CMAKE_COMMON_FLAGS}")
7373
set(CMAKE_CXX_FLAGS "${MCPU_FLAGS} ${VFP_FLAGS} ${SPECS_FLAGS} ${CMAKE_COMMON_FLAGS}")
7474
set(CMAKE_ASM_FLAGS "${MCPU_FLAGS} ${VFP_FLAGS} ${SPECS_FLAGS}")
75-
set(CMAKE_EXE_LINKER_FLAGS "${LD_FLAGS} -Wl,--gc-sections,-print-memory-usage")
75+
set(CMAKE_EXE_LINKER_FLAGS "${LD_FLAGS} -fno-common -Wl,--gc-sections,-print-memory-usage")
7676

7777
set(CMAKE_C_FLAGS_DEBUG "-O0 -g")
7878
set(CMAKE_CXX_ASM_FLAGS_DEBUG "-O0 -g")

core/src/azure_iot_mqtt/azure_iot_dps_mqtt.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424

2525
#define EVENT_FLAGS_SUCCESS 1
2626

27-
static VOID processRetry(AZURE_IOT_MQTT* azure_iot_mqtt, CHAR* topic, CHAR* message)
27+
extern CHAR* azure_iot_x509_hostname;
28+
29+
static VOID process_retry(AZURE_IOT_MQTT* azure_iot_mqtt, CHAR* topic, CHAR* message)
2830
{
2931
UINT status;
3032

@@ -72,7 +74,7 @@ static VOID processRetry(AZURE_IOT_MQTT* azure_iot_mqtt, CHAR* topic, CHAR* mess
7274
}
7375
}
7476

75-
static VOID processSuccess(AZURE_IOT_MQTT* azure_iot_mqtt, CHAR* topic, CHAR* message)
77+
static VOID process_success(AZURE_IOT_MQTT* azure_iot_mqtt, CHAR* topic, CHAR* message)
7678
{
7779
jsmn_parser parser;
7880
jsmntok_t tokens[64];
@@ -146,13 +148,13 @@ static VOID mqtt_notify_cb(NXD_MQTT_CLIENT* client_ptr, UINT number_of_messages)
146148
switch (msg_status)
147149
{
148150
case 202:
149-
processRetry(azure_iot_mqtt,
151+
process_retry(azure_iot_mqtt,
150152
azure_iot_mqtt->mqtt_receive_topic_buffer,
151153
azure_iot_mqtt->mqtt_receive_message_buffer);
152154
break;
153155

154156
case 200:
155-
processSuccess(azure_iot_mqtt,
157+
process_success(azure_iot_mqtt,
156158
azure_iot_mqtt->mqtt_receive_topic_buffer,
157159
azure_iot_mqtt->mqtt_receive_message_buffer);
158160
tx_event_flags_set(&azure_iot_mqtt->mqtt_event_flags, EVENT_FLAGS_SUCCESS, TX_OR);
@@ -282,6 +284,9 @@ UINT azure_iot_dps_register(AZURE_IOT_MQTT* azure_iot_mqtt, UINT wait)
282284
return status;
283285
}
284286

287+
// Stash the hostname so we can verify the cert at connect
288+
azure_iot_x509_hostname = azure_iot_mqtt->mqtt_dps_endpoint;
289+
285290
status = nxd_mqtt_client_secure_connect(&azure_iot_mqtt->nxd_mqtt_client,
286291
&server_ip,
287292
NXD_MQTT_TLS_PORT,

core/src/azure_iot_mqtt/azure_iot_mqtt.c

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@
3636
#define MQTT_TIMEOUT (10 * TX_TIMER_TICKS_PER_SECOND)
3737
#define MQTT_KEEP_ALIVE 240
3838

39+
CHAR* azure_iot_x509_hostname;
40+
41+
static ULONG azure_iot_certificate_verify(NX_SECURE_TLS_SESSION* session, NX_SECURE_X509_CERT* certificate)
42+
{
43+
UINT status;
44+
45+
// Check certicate matches the correct address
46+
status = nx_secure_x509_common_name_dns_check(
47+
certificate, (UCHAR*)azure_iot_x509_hostname, strlen(azure_iot_x509_hostname));
48+
if (status)
49+
{
50+
printf("Error in certificate verification: DNS name did not match CN\r\n");
51+
}
52+
53+
return status;
54+
}
55+
3956
UINT azure_iot_mqtt_register_direct_method_callback(
4057
AZURE_IOT_MQTT* azure_iot_mqtt, func_ptr_direct_method mqtt_direct_method_callback)
4158
{
@@ -107,26 +124,6 @@ UINT tls_setup(NXD_MQTT_CLIENT* client,
107124
return status;
108125
}
109126

110-
status = nx_secure_tls_remote_certificate_allocate(tls_session,
111-
&azure_iot_mqtt->mqtt_remote_certificate,
112-
azure_iot_mqtt->mqtt_remote_cert_buffer,
113-
sizeof(azure_iot_mqtt->mqtt_remote_cert_buffer));
114-
if (status != NX_SUCCESS)
115-
{
116-
printf("Failed to create remote certificate buffer (0x%04x)\r\n", status);
117-
return status;
118-
}
119-
120-
status = nx_secure_tls_remote_certificate_allocate(tls_session,
121-
&azure_iot_mqtt->mqtt_remote_issuer,
122-
azure_iot_mqtt->mqtt_remote_issuer_buffer,
123-
sizeof(azure_iot_mqtt->mqtt_remote_issuer_buffer));
124-
if (status != NX_SUCCESS)
125-
{
126-
printf("Failed to create remote issuer buffer (0x%04x)\r\n", status);
127-
return status;
128-
}
129-
130127
// Add a CA Certificate to our trusted store for verifying incoming server certificates
131128
status = nx_secure_x509_certificate_initialize(trusted_cert,
132129
(UCHAR*)azure_iot_root_ca,
@@ -157,6 +154,15 @@ UINT tls_setup(NXD_MQTT_CLIENT* client,
157154
return status;
158155
}
159156

157+
// Setup the callback invoked when TLS has a certificate it wants to verify so we can
158+
// do additional checks not done automatically by TLS.
159+
status = nx_secure_tls_session_certificate_callback_set(tls_session, azure_iot_certificate_verify);
160+
if (status)
161+
{
162+
printf("Failed to set the session certificate callback: status: %d", status);
163+
return status;
164+
}
165+
160166
// Add a timestamp function for time checking and timestamps in the TLS handshake
161167
nx_secure_tls_session_time_function_set(tls_session, azure_iot_mqtt->unix_time_get);
162168

@@ -717,6 +723,9 @@ UINT azure_iot_mqtt_connect(AZURE_IOT_MQTT* azure_iot_mqtt)
717723
return status;
718724
}
719725

726+
// Stash the hostname in a global variable so we can verify the cert at connect
727+
azure_iot_x509_hostname = azure_iot_mqtt->mqtt_hub_hostname;
728+
720729
status = nxd_mqtt_client_secure_connect(&azure_iot_mqtt->nxd_mqtt_client,
721730
&server_ip,
722731
NXD_MQTT_TLS_PORT,

core/src/azure_iot_mqtt/azure_iot_mqtt.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
#define AZURE_IOT_MQTT_DIRECT_COMMAND_RID_SIZE 6
2424

2525
#define AZURE_IOT_MQTT_CLIENT_STACK_SIZE 4096
26-
#define AZURE_IOT_MQTT_CERT_BUFFER_SIZE 4096
2726

28-
#define TLS_PACKET_BUFFER 4096
27+
#define TLS_PACKET_BUFFER (7 * 1024)
2928

3029
#define MQTT_QOS_0 0 // QoS 0 - Deliver at most once
3130
#define MQTT_QOS_1 1 // QoS 1 - Deliver at least once
@@ -78,11 +77,6 @@ struct AZURE_IOT_MQTT_STRUCT
7877
ULONG tls_metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE / sizeof(ULONG)];
7978
UCHAR tls_packet_buffer[TLS_PACKET_BUFFER];
8079

81-
NX_SECURE_X509_CERT mqtt_remote_certificate;
82-
NX_SECURE_X509_CERT mqtt_remote_issuer;
83-
UCHAR mqtt_remote_cert_buffer[AZURE_IOT_MQTT_CERT_BUFFER_SIZE];
84-
UCHAR mqtt_remote_issuer_buffer[AZURE_IOT_MQTT_CERT_BUFFER_SIZE];
85-
8680
func_ptr_direct_method cb_ptr_mqtt_invoke_direct_method;
8781
func_ptr_c2d_message cb_ptr_mqtt_c2d_message;
8882
func_ptr_device_twin_desired_prop cb_ptr_mqtt_device_twin_desired_prop_callback;

0 commit comments

Comments
 (0)