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