Skip to content

Commit 6785edb

Browse files
MarkusLassilacvinayak
authored andcommitted
applications: serial_lte_modem: allow to skip cert verify
Allow #XTCPCLI, #XUDPCLI and #XHTTPCCON to set PEER_VERIFY socket option, and to disable the hostname verification via TLS_HOSTNAME socket option. By default PEER_VERIFY is TLS_PEER_VERIFY_REQUIRED and hostname verification is done. Signed-off-by: Markus Lassila <markus.lassila@nordicsemi.no>
1 parent 1e7c5a3 commit 6785edb

File tree

6 files changed

+209
-58
lines changed

6 files changed

+209
-58
lines changed

applications/serial_lte_modem/doc/HTTPC_AT_commands.rst

+17-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Syntax
2424

2525
::
2626

27-
AT#XHTTPCCON=<op>[,<host>,<port>[,<sec_tag>]]
27+
AT#XHTTPCCON=<op>[,<host>,<port>[,<sec_tag>[,peer_verify[,hostname_verify]]]]
2828

2929
* The ``<op>`` parameter can accept one of the following values:
3030

@@ -38,6 +38,21 @@ Syntax
3838
It represents the HTTP server port.
3939
* The ``<sec_tag>`` parameter is an integer.
4040
It indicates to the modem the credential of the security tag used for establishing a secure connection.
41+
* The ``<peer_verify>`` parameter accepts the following values:
42+
43+
* ``0`` - None.
44+
Do not authenticate the peer.
45+
* ``1`` - Optional.
46+
Optionally authenticate the peer.
47+
* ``2`` - Required (default).
48+
Authenticate the peer.
49+
50+
* The ``<hostname_verify>`` parameter accepts the following values:
51+
52+
* ``0`` - Do not verify the hostname against the received certificate.
53+
* ``1`` - Verify the hostname against the received certificate (default).
54+
55+
See `nRF socket options`_ ``peer_verify`` and ``tls_hostname`` for more information on ``<peer_verify>`` and ``<hostname_verify>``.
4156

4257

4358
Response syntax
@@ -100,7 +115,7 @@ Example
100115
::
101116

102117
AT#XHTTPCCON=?
103-
#XHTTPCCON: (0,1),<host>,<port>,<sec_tag>
118+
#XHTTPCCON: (0,1),<host>,<port>,<sec_tag>,<peer_verify>,<hostname_verify>
104119
OK
105120

106121
HTTP request #XHTTPCREQ

applications/serial_lte_modem/doc/TCPUDP_AT_commands.rst

+36-6
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ Syntax
174174

175175
::
176176

177-
#XTCPCLI=<op>[,<url>,<port>[,[sec_tag]]
177+
#XTCPCLI=<op>[,<url>,<port>[,sec_tag[,peer_verify[,hostname_verify]]]]
178178

179179
* The ``<op>`` parameter can accept one of the following values:
180180

@@ -191,6 +191,21 @@ Syntax
191191
* The ``<sec_tag>`` parameter is an integer.
192192
If it is given, a TLS client will be started.
193193
It indicates to the modem the credential of the security tag used for establishing a secure connection.
194+
* The ``<peer_verify>`` parameter accepts the following values:
195+
196+
* ``0`` - None.
197+
Do not authenticate the peer.
198+
* ``1`` - Optional.
199+
Optionally authenticate the peer.
200+
* ``2`` - Required (default).
201+
Authenticate the peer.
202+
203+
* The ``<hostname_verify>`` parameter accepts the following values:
204+
205+
* ``0`` - Do not verify the hostname against the received certificate.
206+
* ``1`` - Verify the hostname against the received certificate (default).
207+
208+
See `nRF socket options`_ ``peer_verify`` and ``tls_hostname`` for more information on ``<peer_verify>`` and ``<hostname_verify>``.
194209

195210
Response syntax
196211
~~~~~~~~~~~~~~~
@@ -260,15 +275,15 @@ Response syntax
260275

261276
::
262277

263-
#XTCPCLI: <list of ops>,<url>,<port>,<sec_tag>
278+
#XTCPCLI: <list of ops>,<url>,<port>,<sec_tag>,<peer_verify>,<hostname_verify>
264279

265280
Examples
266281
~~~~~~~~
267282

268283
::
269284

270285
AT#XTCPCLI=?
271-
#XTCPCLI: (0,1,2),<url>,<port>,<sec_tag>
286+
#XTCPCLI: (0,1,2),<url>,<port>,<sec_tag>,<peer_verify>,<hostname_verify>
272287
OK
273288

274289
TCP send data #XTCPSEND
@@ -532,7 +547,7 @@ Syntax
532547

533548
::
534549

535-
#XUDPCLI=<op>[,<url>,<port>[,<sec_tag>[,<use_dtls_cid>]]]
550+
#XUDPCLI=<op>[,<url>,<port>[,<sec_tag>[,<use_dtls_cid>[,peer_verify[,hostname_verify]]]]]
536551

537552
* The ``<op>`` parameter can accept one of the following values:
538553

@@ -554,6 +569,21 @@ Syntax
554569
This parameter is only supported with modem firmware 1.3.5 and newer.
555570
See :ref:`SLM_AT_SSOCKETOPT` for more details regarding the allowed values.
556571
The command will fail (with ``<error>`` equal to ``-134`` (``-ENOTSUP``) if the requested connection identifier is not accepted by the server.
572+
* The ``<peer_verify>`` parameter accepts the following values:
573+
574+
* ``0`` - None.
575+
Do not authenticate the peer.
576+
* ``1`` - Optional.
577+
Optionally authenticate the peer.
578+
* ``2`` - Required (default).
579+
Authenticate the peer.
580+
581+
* The ``<hostname_verify>`` parameter accepts the following values:
582+
583+
* ``0`` - Do not verify the hostname against the received certificate.
584+
* ``1`` - Verify the hostname against the received certificate (default).
585+
586+
See `nRF socket options`_ ``peer_verify`` and ``tls_hostname`` for more information on ``<peer_verify>`` and ``<hostname_verify>``.
557587

558588
Response syntax
559589
~~~~~~~~~~~~~~~
@@ -616,15 +646,15 @@ Syntax
616646

617647
::
618648

619-
#XUDPCLI: <list of ops>,<url>,<port>,<sec_tag>,<use_dtls_cid>
649+
#XUDPCLI: <list of ops>,<url>,<port>,<sec_tag>,<use_dtls_cid>,<peer_verify>,<hostname_verify>
620650

621651
Examples
622652
~~~~~~~~
623653

624654
::
625655

626656
AT#XUDPCLI=?
627-
#XUDPCLI: (0,1,2),<url>,<port>,<sec_tag>,<use_dtls_cid>
657+
#XUDPCLI: (0,1,2),<url>,<port>,<sec_tag>,<use_dtls_cid>,<peer_verify>,<tls_hostname_verify>
628658
OK
629659

630660
UDP send data #XUDPSEND

applications/serial_lte_modem/src/http_c/slm_at_httpc.c

+59-27
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ static struct slm_httpc_ctx {
4848
int fd; /* HTTPC socket */
4949
int family; /* Socket address family */
5050
uint32_t sec_tag; /* security tag to be used */
51+
int peer_verify; /* Peer verification level for TLS connection. */
52+
bool hostname_verify; /* Verify hostname against the certificate. */
5153
char host[SLM_MAX_URL]; /* HTTP server address */
5254
uint16_t port; /* HTTP server port */
5355
char *method_str; /* request method */
@@ -253,7 +255,6 @@ static int do_http_connect(void)
253255
}
254256
if (httpc.sec_tag != INVALID_SEC_TAG) {
255257
sec_tag_t sec_tag_list[] = { httpc.sec_tag };
256-
int peer_verify = TLS_PEER_VERIFY_REQUIRED;
257258

258259
ret = setsockopt(httpc.fd, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list,
259260
sizeof(sec_tag_t));
@@ -262,15 +263,19 @@ static int do_http_connect(void)
262263
ret = -errno;
263264
goto exit_cli;
264265
}
265-
ret = setsockopt(httpc.fd, SOL_TLS, TLS_PEER_VERIFY, &peer_verify,
266-
sizeof(peer_verify));
266+
ret = setsockopt(httpc.fd, SOL_TLS, TLS_PEER_VERIFY, &httpc.peer_verify,
267+
sizeof(httpc.peer_verify));
267268
if (ret) {
268269
LOG_ERR("setsockopt(TLS_PEER_VERIFY) error: %d", -errno);
269270
ret = -errno;
270271
goto exit_cli;
271272
}
272-
ret = setsockopt(httpc.fd, SOL_TLS, TLS_HOSTNAME, httpc.host,
273-
strlen(httpc.host));
273+
if (httpc.hostname_verify) {
274+
ret = setsockopt(httpc.fd, SOL_TLS, TLS_HOSTNAME, httpc.host,
275+
strlen(httpc.host));
276+
} else {
277+
ret = setsockopt(httpc.fd, SOL_TLS, TLS_HOSTNAME, NULL, 0);
278+
}
274279
if (ret) {
275280
LOG_ERR("setsockopt(TLS_HOSTNAME) error: %d", -errno);
276281
ret = -errno;
@@ -327,21 +332,25 @@ static int do_http_connect(void)
327332
static int do_http_disconnect(void)
328333
{
329334
/* Close socket if it is connected. */
330-
if (httpc.fd != INVALID_SOCKET) {
335+
if (httpc.fd == INVALID_SOCKET) {
336+
return 0;
337+
}
331338
#if defined(CONFIG_SLM_NATIVE_TLS)
332-
if (httpc.sec_tag != INVALID_SEC_TAG) {
333-
(void)slm_tls_unloadcrdl(httpc.sec_tag);
334-
httpc.sec_tag = INVALID_SEC_TAG;
335-
}
339+
if (httpc.sec_tag != INVALID_SEC_TAG) {
340+
(void)slm_tls_unloadcrdl(httpc.sec_tag);
341+
httpc.sec_tag = INVALID_SEC_TAG;
342+
}
336343
#endif
337-
close(httpc.fd);
338-
httpc.fd = INVALID_SOCKET;
339-
} else {
340-
return -ENOTCONN;
344+
int ret = close(httpc.fd);
345+
346+
if (ret) {
347+
LOG_WRN("close() failed: %d", -errno);
348+
ret = -errno;
341349
}
342-
rsp_send("\r\n#XHTTPCCON: 0\r\n");
350+
httpc.fd = INVALID_SOCKET;
351+
rsp_send("\r\n#XHTTPCCON: %d\r\n", ret);
343352

344-
return 0;
353+
return ret;
345354
}
346355

347356
static int http_method_str_enum(uint8_t *method_str)
@@ -430,26 +439,48 @@ int handle_at_httpc_connect(enum at_cmd_type cmd_type)
430439
if (err) {
431440
return err;
432441
}
433-
err = at_params_unsigned_short_get(&slm_at_param_list, 3, &httpc.port);
434-
if (err) {
435-
return err;
442+
if (at_params_unsigned_short_get(&slm_at_param_list, 3, &httpc.port)) {
443+
return -EINVAL;
436444
}
445+
const int param_count = at_params_valid_count_get(&slm_at_param_list);
446+
437447
httpc.sec_tag = INVALID_SEC_TAG;
438-
if (at_params_valid_count_get(&slm_at_param_list) > 4) {
439-
err = at_params_unsigned_int_get(&slm_at_param_list, 4,
440-
&httpc.sec_tag);
441-
if (err) {
442-
return err;
448+
if (param_count > 4) {
449+
if (at_params_unsigned_int_get(&slm_at_param_list, 4,
450+
&httpc.sec_tag)) {
451+
return -EINVAL;
452+
}
453+
}
454+
httpc.peer_verify = TLS_PEER_VERIFY_REQUIRED;
455+
if (param_count > 5) {
456+
if (at_params_unsigned_int_get(&slm_at_param_list, 5,
457+
&httpc.peer_verify) ||
458+
(httpc.peer_verify != TLS_PEER_VERIFY_NONE &&
459+
httpc.peer_verify != TLS_PEER_VERIFY_OPTIONAL &&
460+
httpc.peer_verify != TLS_PEER_VERIFY_REQUIRED)) {
461+
return -EINVAL;
443462
}
444463
}
464+
httpc.hostname_verify = true;
465+
if (param_count > 6) {
466+
uint16_t hostname_verify;
467+
468+
if (at_params_unsigned_short_get(&slm_at_param_list, 6,
469+
&hostname_verify) ||
470+
(hostname_verify != 0 && hostname_verify != 1)) {
471+
return -EINVAL;
472+
}
473+
httpc.hostname_verify = (bool)hostname_verify;
474+
}
445475
httpc.family = (op == HTTPC_CONNECT) ? AF_INET : AF_INET6;
446476
err = do_http_connect();
447477
break;
448478
} else if (op == HTTPC_DISCONNECT) {
449479
err = do_http_disconnect();
450480
} else {
451481
err = -EINVAL;
452-
} break;
482+
}
483+
break;
453484

454485
case AT_CMD_TYPE_READ_COMMAND:
455486
if (httpc.sec_tag != INVALID_SEC_TAG) {
@@ -465,8 +496,9 @@ int handle_at_httpc_connect(enum at_cmd_type cmd_type)
465496
break;
466497

467498
case AT_CMD_TYPE_TEST_COMMAND:
468-
rsp_send("\r\n#XHTTPCCON: (%d,%d,%d),<host>,<port>,<sec_tag>\r\n",
469-
HTTPC_DISCONNECT, HTTPC_CONNECT, HTTPC_CONNECT6);
499+
rsp_send("\r\n#XHTTPCCON: (%d,%d,%d),<host>,<port>,"
500+
"<sec_tag>,<peer_verify>,<hostname_verify>\r\n",
501+
HTTPC_DISCONNECT, HTTPC_CONNECT, HTTPC_CONNECT6);
470502
err = 0;
471503
break;
472504

applications/serial_lte_modem/src/slm_at_tcp_proxy.c

+42-12
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ static struct tcp_proxy {
4747
sec_tag_t sec_tag; /* Security tag of the credential */
4848
int sock_peer; /* Socket descriptor for peer. */
4949
enum slm_tcp_role role; /* Client or Server proxy */
50+
int peer_verify; /* Peer verification level for TLS connection. */
51+
bool hostname_verify; /* Verify hostname against the certificate. */
5052
} proxy;
5153

5254
/** forward declaration of thread function **/
@@ -271,8 +273,6 @@ static int do_tcp_client_connect(const char *url, uint16_t port)
271273

272274
if (proxy.sec_tag != INVALID_SEC_TAG) {
273275
sec_tag_t sec_tag_list[1] = { proxy.sec_tag };
274-
int peer_verify = TLS_PEER_VERIFY_REQUIRED;
275-
276276
#if defined(CONFIG_SLM_NATIVE_TLS)
277277
ret = slm_tls_loadcrdl(proxy.sec_tag);
278278
if (ret < 0) {
@@ -287,13 +287,23 @@ static int do_tcp_client_connect(const char *url, uint16_t port)
287287
ret = -errno;
288288
goto exit_cli;
289289
}
290-
ret = setsockopt(proxy.sock, SOL_TLS, TLS_PEER_VERIFY, &peer_verify,
291-
sizeof(peer_verify));
290+
ret = setsockopt(proxy.sock, SOL_TLS, TLS_PEER_VERIFY, &proxy.peer_verify,
291+
sizeof(proxy.peer_verify));
292292
if (ret) {
293293
LOG_ERR("setsockopt(TLS_PEER_VERIFY) error: %d", errno);
294294
ret = -errno;
295295
goto exit_cli;
296296
}
297+
if (proxy.hostname_verify) {
298+
ret = setsockopt(proxy.sock, SOL_TLS, TLS_HOSTNAME, url, strlen(url));
299+
} else {
300+
ret = setsockopt(proxy.sock, SOL_TLS, TLS_HOSTNAME, NULL, 0);
301+
}
302+
if (ret) {
303+
LOG_ERR("setsockopt(TLS_HOSTNAME) error: %d", errno);
304+
ret = -errno;
305+
goto exit_cli;
306+
}
297307
}
298308

299309
/* Connect to remote host */
@@ -749,17 +759,36 @@ int handle_at_tcp_client(enum at_cmd_type cmd_type)
749759
if (err) {
750760
return err;
751761
}
752-
err = at_params_unsigned_short_get(&slm_at_param_list, 3, &port);
753-
if (err) {
754-
return err;
762+
if (at_params_unsigned_short_get(&slm_at_param_list, 3, &port)) {
763+
return -EINVAL;
755764
}
756765
proxy.sec_tag = INVALID_SEC_TAG;
757766
if (param_count > 4) {
758-
err = at_params_int_get(&slm_at_param_list, 4, &proxy.sec_tag);
759-
if (err) {
760-
return err;
767+
if (at_params_int_get(&slm_at_param_list, 4, &proxy.sec_tag)) {
768+
return -EINVAL;
761769
}
762770
}
771+
proxy.peer_verify = TLS_PEER_VERIFY_REQUIRED;
772+
if (param_count > 5) {
773+
if (at_params_int_get(&slm_at_param_list, 5, &proxy.peer_verify) ||
774+
(proxy.peer_verify != TLS_PEER_VERIFY_NONE &&
775+
proxy.peer_verify != TLS_PEER_VERIFY_OPTIONAL &&
776+
proxy.peer_verify != TLS_PEER_VERIFY_REQUIRED)) {
777+
return -EINVAL;
778+
}
779+
}
780+
proxy.hostname_verify = true;
781+
if (param_count > 6) {
782+
uint16_t hostname_verify;
783+
784+
if (at_params_unsigned_short_get(&slm_at_param_list, 6,
785+
&hostname_verify) ||
786+
(hostname_verify != 0 && hostname_verify != 1)) {
787+
return -EINVAL;
788+
}
789+
proxy.hostname_verify = (bool)hostname_verify;
790+
}
791+
763792
proxy.family = (op == CLIENT_CONNECT) ? AF_INET : AF_INET6;
764793
err = do_tcp_client_connect(url, port);
765794
} else if (op == CLIENT_DISCONNECT) {
@@ -772,8 +801,9 @@ int handle_at_tcp_client(enum at_cmd_type cmd_type)
772801
break;
773802

774803
case AT_CMD_TYPE_TEST_COMMAND:
775-
rsp_send("\r\n#XTCPCLI: (%d,%d,%d),<url>,<port>,<sec_tag>\r\n",
776-
CLIENT_DISCONNECT, CLIENT_CONNECT, CLIENT_CONNECT6);
804+
rsp_send("\r\n#XTCPCLI: (%d,%d,%d),<url>,<port>,"
805+
"<sec_tag>,<peer_verify>,<hostname_verify>\r\n",
806+
CLIENT_DISCONNECT, CLIENT_CONNECT, CLIENT_CONNECT6);
777807
err = 0;
778808
break;
779809

0 commit comments

Comments
 (0)