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