1 /*
2 * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 #include <zephyr/net/net_core.h>
9 #include <zephyr/net/net_ip.h>
10 #include <zephyr/net/socket.h>
11 #include <zephyr/net/tls_credentials.h>
12 #include <zephyr/posix/unistd.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/ztest.h>
15
16 LOG_MODULE_REGISTER(tls_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
17
18 /**
19 * @brief An encrypted message to pass between server and client.
20 *
21 * The answer to life, the universe, and everything.
22 *
23 * See also <a href="https://en.wikipedia.org/wiki/42_(number)#The_Hitchhiker's_Guide_to_the_Galaxy">42</a>.
24 */
25 #define SECRET "forty-two"
26
27 /**
28 * @brief Size of the encrypted message passed between server and client.
29 */
30 #define SECRET_SIZE (sizeof(SECRET) - 1)
31
32 /** @brief Stack size for the server thread */
33 #define STACK_SIZE 8192
34
35 #define MY_IPV4_ADDR "127.0.0.1"
36
37 /** @brief TCP port for the server thread */
38 #define PORT 4242
39
40 /** @brief arbitrary timeout value in ms */
41 #define TIMEOUT 1000
42
43 /**
44 * @brief Application-dependent TLS credential identifiers
45 *
46 * Since both the server and client exist in the same test
47 * application in this case, both the server and client credentials
48 * are loaded together.
49 *
50 * The server would normally need
51 * - SERVER_CERTIFICATE_TAG (for both public and private keys)
52 * - CA_CERTIFICATE_TAG (only when client authentication is required)
53 *
54 * The client would normally load
55 * - CA_CERTIFICATE_TAG (always required, to verify the server)
56 * - CLIENT_CERTIFICATE_TAG (for both public and private keys, only when
57 * client authentication is required)
58 */
59 enum tls_tag {
60 /** The Certificate Authority public key */
61 CA_CERTIFICATE_TAG,
62 /** Used for both the public and private server keys */
63 SERVER_CERTIFICATE_TAG,
64 /** Used for both the public and private client keys */
65 CLIENT_CERTIFICATE_TAG,
66 };
67
68 /** @brief synchronization object for server & client threads */
69 static struct k_sem server_sem;
70
71 /** @brief The server thread stack */
72 static K_THREAD_STACK_DEFINE(server_stack, STACK_SIZE);
73 /** @brief the server thread object */
74 static struct k_thread server_thread;
75
76 #ifdef CONFIG_TLS_CREDENTIALS
77 /**
78 * @brief The Certificate Authority (CA) Certificate
79 *
80 * The client needs the CA cert to verify the server public key. TLS client
81 * sockets are always required to verify the server public key.
82 *
83 * Additionally, when the peer verification mode is
84 * @ref TLS_PEER_VERIFY_OPTIONAL or @ref TLS_PEER_VERIFY_REQUIRED, then
85 * the server also needs the CA cert in order to verify the client. This
86 * type of configuration is often referred to as *mutual authentication*.
87 */
88 static const unsigned char ca[] = {
89 #include "ca.inc"
90 };
91
92 /**
93 * @brief The Server Certificate
94 *
95 * This is the public key of the server.
96 */
97 static const unsigned char server[] = {
98 #include "server.inc"
99 };
100
101 /**
102 * @brief The Server Private Key
103 *
104 * This is the private key of the server.
105 */
106 static const unsigned char server_privkey[] = {
107 #include "server_privkey.inc"
108 };
109
110 /**
111 * @brief The Client Certificate
112 *
113 * This is the public key of the client.
114 */
115 static const unsigned char client[] = {
116 #include "client.inc"
117 };
118
119 /**
120 * @brief The Client Private Key
121 *
122 * This is the private key of the client.
123 */
124 static const unsigned char client_privkey[] = {
125 #include "client_privkey.inc"
126 };
127 #else /* CONFIG_TLS_CREDENTIALS */
128 #define ca NULL
129 #define server NULL
130 #define server_privkey NULL
131 #define client NULL
132 #define client_privkey NULL
133 #endif /* CONFIG_TLS_CREDENTIALS */
134
135 /**
136 * @brief The server thread function
137 *
138 * This function simply accepts a client connection and
139 * echoes the first @ref SECRET_SIZE bytes of the first
140 * packet. After that, the server is closed and connections
141 * are no longer accepted.
142 *
143 * @param arg0 a pointer to the int representing the server file descriptor
144 * @param arg1 ignored
145 * @param arg2 ignored
146 */
server_thread_fn(void * arg0,void * arg1,void * arg2)147 static void server_thread_fn(void *arg0, void *arg1, void *arg2)
148 {
149 const int server_fd = POINTER_TO_INT(arg0);
150
151 int r;
152 int client_fd;
153 socklen_t addrlen;
154 char addrstr[INET_ADDRSTRLEN];
155 struct sockaddr_in sa;
156 char *addrstrp;
157
158 k_thread_name_set(k_current_get(), "server");
159
160 NET_DBG("Server thread running");
161
162 memset(&sa, 0, sizeof(sa));
163 addrlen = sizeof(sa);
164
165 NET_DBG("Accepting client connection..");
166 k_sem_give(&server_sem);
167 r = accept(server_fd, (struct sockaddr *)&sa, &addrlen);
168 zassert_not_equal(r, -1, "accept() failed (%d)", r);
169 client_fd = r;
170
171 memset(addrstr, '\0', sizeof(addrstr));
172 addrstrp = (char *)inet_ntop(AF_INET, &sa.sin_addr,
173 addrstr, sizeof(addrstr));
174 zassert_not_equal(addrstrp, NULL, "inet_ntop() failed (%d)", errno);
175
176 NET_DBG("accepted connection from [%s]:%d as fd %d",
177 addrstr, ntohs(sa.sin_port), client_fd);
178
179 NET_DBG("calling recv()");
180 r = recv(client_fd, addrstr, sizeof(addrstr), 0);
181 zassert_not_equal(r, -1, "recv() failed (%d)", errno);
182 zassert_equal(r, SECRET_SIZE, "expected: %zu actual: %d", SECRET_SIZE, r);
183
184 NET_DBG("calling send()");
185 r = send(client_fd, SECRET, SECRET_SIZE, 0);
186 zassert_not_equal(r, -1, "send() failed (%d)", errno);
187 zassert_equal(r, SECRET_SIZE, "expected: %zu actual: %d", SECRET_SIZE, r);
188
189 NET_DBG("closing client fd");
190 r = close(client_fd);
191 zassert_not_equal(r, -1, "close() failed on the server fd (%d)", errno);
192 }
193
test_common(int peer_verify)194 static void test_common(int peer_verify)
195 {
196 const int yes = true;
197
198 int r;
199 int server_fd;
200 int client_fd;
201 int proto = IPPROTO_TCP;
202 char *addrstrp;
203 k_tid_t server_thread_id;
204 struct sockaddr_in sa;
205 char addrstr[INET_ADDRSTRLEN];
206
207 k_sem_init(&server_sem, 0, 1);
208
209 /* set the common protocol for both client and server */
210 if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS)) {
211 proto = IPPROTO_TLS_1_2;
212 }
213 /*
214 * Server socket setup
215 */
216
217 NET_DBG("Creating server socket");
218 r = socket(AF_INET, SOCK_STREAM, proto);
219 zassert_not_equal(r, -1, "failed to create server socket (%d)", errno);
220 server_fd = r;
221
222 r = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
223 zassert_not_equal(r, -1, "failed to set SO_REUSEADDR (%d)", errno);
224
225 if (IS_ENABLED(CONFIG_TLS_CREDENTIALS)
226 && IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS)) {
227
228 static const sec_tag_t server_tag_list_verify_none[] = {
229 SERVER_CERTIFICATE_TAG,
230 };
231
232 static const sec_tag_t server_tag_list_verify[] = {
233 CA_CERTIFICATE_TAG,
234 SERVER_CERTIFICATE_TAG,
235 };
236
237 const sec_tag_t *sec_tag_list;
238 size_t sec_tag_list_size;
239
240 switch (peer_verify) {
241 case TLS_PEER_VERIFY_NONE:
242 sec_tag_list = server_tag_list_verify_none;
243 sec_tag_list_size = sizeof(server_tag_list_verify_none);
244 break;
245 case TLS_PEER_VERIFY_OPTIONAL:
246 case TLS_PEER_VERIFY_REQUIRED:
247 sec_tag_list = server_tag_list_verify;
248 sec_tag_list_size = sizeof(server_tag_list_verify);
249
250 r = setsockopt(server_fd, SOL_TLS, TLS_PEER_VERIFY,
251 &peer_verify, sizeof(peer_verify));
252 zassert_not_equal(r, -1,
253 "failed to set TLS_PEER_VERIFY (%d)", errno);
254 break;
255 default:
256 zassert_true(false,
257 "unrecognized TLS peer verify type %d",
258 peer_verify);
259 return;
260 }
261
262 r = setsockopt(server_fd, SOL_TLS, TLS_SEC_TAG_LIST,
263 sec_tag_list, sec_tag_list_size);
264 zassert_not_equal(r, -1, "failed to set TLS_SEC_TAG_LIST (%d)",
265 errno);
266
267 r = setsockopt(server_fd, SOL_TLS, TLS_HOSTNAME, "localhost",
268 sizeof("localhost"));
269 zassert_not_equal(r, -1, "failed to set TLS_HOSTNAME (%d)",
270 errno);
271 }
272
273 memset(&sa, 0, sizeof(sa));
274 /* The server listens on all network interfaces */
275 sa.sin_addr.s_addr = INADDR_ANY;
276 sa.sin_family = AF_INET;
277 sa.sin_port = htons(PORT);
278
279 r = bind(server_fd, (struct sockaddr *)&sa, sizeof(sa));
280 zassert_not_equal(r, -1, "failed to bind (%d)", errno);
281
282 r = listen(server_fd, 1);
283 zassert_not_equal(r, -1, "failed to listen (%d)", errno);
284
285 memset(addrstr, '\0', sizeof(addrstr));
286 addrstrp = (char *)inet_ntop(AF_INET, &sa.sin_addr,
287 addrstr, sizeof(addrstr));
288 zassert_not_equal(addrstrp, NULL, "inet_ntop() failed (%d)", errno);
289
290 NET_DBG("listening on [%s]:%d as fd %d",
291 addrstr, ntohs(sa.sin_port), server_fd);
292
293 NET_DBG("Creating server thread");
294 server_thread_id = k_thread_create(&server_thread, server_stack,
295 STACK_SIZE, server_thread_fn,
296 INT_TO_POINTER(server_fd), NULL, NULL,
297 K_PRIO_PREEMPT(8), 0, K_NO_WAIT);
298
299 r = k_sem_take(&server_sem, K_MSEC(TIMEOUT));
300 zassert_equal(0, r, "failed to synchronize with server thread (%d)", r);
301
302 /*
303 * Client socket setup
304 */
305
306 k_thread_name_set(k_current_get(), "client");
307
308 NET_DBG("Creating client socket");
309 r = socket(AF_INET, SOCK_STREAM, proto);
310 zassert_not_equal(r, -1, "failed to create client socket (%d)", errno);
311 client_fd = r;
312
313 if (IS_ENABLED(CONFIG_TLS_CREDENTIALS)
314 && IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS)) {
315
316 static const sec_tag_t client_tag_list_verify_none[] = {
317 CA_CERTIFICATE_TAG,
318 };
319
320 static const sec_tag_t client_tag_list_verify[] = {
321 CA_CERTIFICATE_TAG,
322 CLIENT_CERTIFICATE_TAG,
323 };
324
325 const sec_tag_t *sec_tag_list;
326 size_t sec_tag_list_size;
327
328 switch (peer_verify) {
329 case TLS_PEER_VERIFY_NONE:
330 sec_tag_list = client_tag_list_verify_none;
331 sec_tag_list_size = sizeof(client_tag_list_verify_none);
332 break;
333 case TLS_PEER_VERIFY_OPTIONAL:
334 case TLS_PEER_VERIFY_REQUIRED:
335 sec_tag_list = client_tag_list_verify;
336 sec_tag_list_size = sizeof(client_tag_list_verify);
337 break;
338 default:
339 zassert_true(false, "unrecognized TLS peer verify type %d",
340 peer_verify);
341 return;
342 }
343
344 r = setsockopt(client_fd, SOL_TLS, TLS_SEC_TAG_LIST,
345 sec_tag_list, sec_tag_list_size);
346 zassert_not_equal(r, -1, "failed to set TLS_SEC_TAG_LIST (%d)",
347 errno);
348
349 r = setsockopt(client_fd, SOL_TLS, TLS_HOSTNAME, "localhost",
350 sizeof("localhost"));
351 zassert_not_equal(r, -1, "failed to set TLS_HOSTNAME (%d)", errno);
352 }
353
354 r = inet_pton(AF_INET, MY_IPV4_ADDR, &sa.sin_addr.s_addr);
355 zassert_not_equal(-1, r, "inet_pton() failed (%d)", errno);
356 zassert_not_equal(0, r, "%s is not a valid IPv4 address", MY_IPV4_ADDR);
357 zassert_equal(1, r, "inet_pton() failed to convert %s", MY_IPV4_ADDR);
358
359 memset(addrstr, '\0', sizeof(addrstr));
360 addrstrp = (char *)inet_ntop(AF_INET, &sa.sin_addr,
361 addrstr, sizeof(addrstr));
362 zassert_not_equal(addrstrp, NULL, "inet_ntop() failed (%d)", errno);
363
364 NET_DBG("connecting to [%s]:%d with fd %d",
365 addrstr, ntohs(sa.sin_port), client_fd);
366
367 r = connect(client_fd, (struct sockaddr *)&sa, sizeof(sa));
368 zassert_not_equal(r, -1, "failed to connect (%d)", errno);
369
370 /*
371 * The main part of the test
372 */
373
374 NET_DBG("Calling send()");
375 r = send(client_fd, SECRET, SECRET_SIZE, 0);
376 zassert_not_equal(r, -1, "send() failed (%d)", errno);
377 zassert_equal(SECRET_SIZE, r, "expected: %zu actual: %d", SECRET_SIZE, r);
378
379 NET_DBG("Calling recv()");
380 memset(addrstr, 0, sizeof(addrstr));
381 r = recv(client_fd, addrstr, sizeof(addrstr), 0);
382 zassert_not_equal(r, -1, "recv() failed (%d)", errno);
383 zassert_equal(SECRET_SIZE, r, "expected: %zu actual: %d", SECRET_SIZE, r);
384
385 zassert_mem_equal(SECRET, addrstr, SECRET_SIZE,
386 "expected: %s actual: %s", SECRET, addrstr);
387
388 /*
389 * Cleanup resources
390 */
391
392 NET_DBG("closing client fd");
393 r = close(client_fd);
394 zassert_not_equal(-1, r, "close() failed on the client fd (%d)", errno);
395
396 NET_DBG("closing server fd");
397 r = close(server_fd);
398 zassert_not_equal(-1, r, "close() failed on the server fd (%d)", errno);
399
400 r = k_thread_join(&server_thread, K_FOREVER);
401 zassert_equal(0, r, "k_thread_join() failed (%d)", r);
402 }
403
ZTEST(net_socket_tls_api_extension,test_tls_peer_verify_none)404 ZTEST(net_socket_tls_api_extension, test_tls_peer_verify_none)
405 {
406 test_common(TLS_PEER_VERIFY_NONE);
407 }
408
ZTEST(net_socket_tls_api_extension,test_tls_peer_verify_optional)409 ZTEST(net_socket_tls_api_extension, test_tls_peer_verify_optional)
410 {
411 test_common(TLS_PEER_VERIFY_OPTIONAL);
412 }
413
ZTEST(net_socket_tls_api_extension,test_tls_peer_verify_required)414 ZTEST(net_socket_tls_api_extension, test_tls_peer_verify_required)
415 {
416 test_common(TLS_PEER_VERIFY_REQUIRED);
417 }
418
setup(void)419 static void *setup(void)
420 {
421 int r;
422
423 /*
424 * Load both client & server credentials
425 *
426 * Normally, this would be split into separate applications but
427 * for testing purposes, we just use separate threads.
428 *
429 * Also, it has to be done before tests are run, otherwise
430 * there are errors due to attempts to load too many certificates.
431 *
432 * The server would normally load
433 * - server public key
434 * - server private key
435 * - ca cert (only when client authentication is required)
436 *
437 * The client would normally load
438 * - ca cert (to verify the server)
439 * - client public key (only when client authentication is required)
440 * - client private key (only when client authentication is required)
441 */
442 if (IS_ENABLED(CONFIG_TLS_CREDENTIALS)) {
443 NET_DBG("Loading credentials");
444 r = tls_credential_add(CA_CERTIFICATE_TAG,
445 TLS_CREDENTIAL_CA_CERTIFICATE,
446 ca, sizeof(ca));
447 zassert_equal(r, 0, "failed to add CA Certificate (%d)", r);
448
449 r = tls_credential_add(SERVER_CERTIFICATE_TAG,
450 TLS_CREDENTIAL_SERVER_CERTIFICATE,
451 server, sizeof(server));
452 zassert_equal(r, 0, "failed to add Server Certificate (%d)", r);
453
454 r = tls_credential_add(SERVER_CERTIFICATE_TAG,
455 TLS_CREDENTIAL_PRIVATE_KEY,
456 server_privkey, sizeof(server_privkey));
457 zassert_equal(r, 0, "failed to add Server Private Key (%d)", r);
458
459 r = tls_credential_add(CLIENT_CERTIFICATE_TAG,
460 TLS_CREDENTIAL_SERVER_CERTIFICATE,
461 client, sizeof(client));
462 zassert_equal(r, 0, "failed to add Client Certificate (%d)", r);
463
464 r = tls_credential_add(CLIENT_CERTIFICATE_TAG,
465 TLS_CREDENTIAL_PRIVATE_KEY,
466 client_privkey, sizeof(client_privkey));
467 zassert_equal(r, 0, "failed to add Client Private Key (%d)", r);
468 }
469 return NULL;
470 }
471
472 ZTEST_SUITE(net_socket_tls_api_extension, NULL, setup, NULL, NULL, NULL);
473