blob: 7a9cf4474d473dfffc284e895564c364f6cc2373 [file] [log] [blame]
romanfaecc582023-06-15 16:13:31 +02001/**
2 * @file test_crl.c
3 * @author Roman Janota <janota@cesnet.cz>
4 * @brief libnetconf2 TLS CRL test
5 *
6 * @copyright
7 * Copyright (c) 2023 CESNET, z.s.p.o.
8 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
15
16#define _GNU_SOURCE
17
18#include <pthread.h>
19#include <setjmp.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#include <cmocka.h>
25
26#include "tests/config.h"
27
28#define NC_ACCEPT_TIMEOUT 2000
29#define NC_PS_POLL_TIMEOUT 2000
30
31struct ly_ctx *ctx;
32
33struct test_state {
34 pthread_barrier_t barrier;
35};
36
37char buffer[512];
38char expected[512];
39
40static void
41test_msg_callback(const struct nc_session *session, NC_VERB_LEVEL level, const char *msg)
42{
43 (void) level;
44 (void) session;
45
46 if (strstr(msg, expected)) {
47 strcpy(buffer, msg);
48 }
49
50 printf("%s\n", msg);
51}
52
53static void *
54server_thread(void *arg)
55{
56 NC_MSG_TYPE msgtype;
57 struct nc_session *session;
58 struct test_state *state = arg;
59
60 /* set print clb so we get access to messages */
61 nc_set_print_clb_session(test_msg_callback);
62 buffer[0] = '\0';
63 strcpy(expected, "revoked per CRL");
64
65 /* accept a session and add it to the poll session structure */
66 pthread_barrier_wait(&state->barrier);
67 msgtype = nc_accept(NC_ACCEPT_TIMEOUT, ctx, &session);
68 assert_int_equal(msgtype, NC_MSG_ERROR);
69
70 assert_int_not_equal(strlen(buffer), 0);
71
72 nc_session_free(session, NULL);
73 return NULL;
74}
75
76static void *
77client_thread(void *arg)
78{
79 int ret;
80 struct nc_session *session = NULL;
81 struct test_state *state = arg;
82
83 ret = nc_client_set_schema_searchpath(MODULES_DIR);
84 assert_int_equal(ret, 0);
85
86 /* set client cert */
87 ret = nc_client_tls_set_cert_key_paths(TESTS_DIR "/data/client.crt", TESTS_DIR "/data/client.key");
88 assert_int_equal(ret, 0);
89
90 /* set client ca */
91 ret = nc_client_tls_set_trusted_ca_paths(NULL, TESTS_DIR "/data");
92 assert_int_equal(ret, 0);
93
94 pthread_barrier_wait(&state->barrier);
95 session = nc_connect_tls("127.0.0.1", 10005, NULL);
96
97 nc_session_free(session, NULL);
98 return NULL;
99}
100
101static void
102test_nc_tls(void **state)
103{
104 int ret, i;
105 pthread_t tids[2];
106
107 assert_non_null(state);
108
109 ret = pthread_create(&tids[0], NULL, client_thread, *state);
110 assert_int_equal(ret, 0);
111 ret = pthread_create(&tids[1], NULL, server_thread, *state);
112 assert_int_equal(ret, 0);
113
114 for (i = 0; i < 2; i++) {
115 pthread_join(tids[i], NULL);
116 }
117}
118
119static int
120setup_f(void **state)
121{
122 int ret;
123 struct lyd_node *tree = NULL;
124 struct test_state *test_state;
125
126 nc_verbosity(NC_VERB_VERBOSE);
127
128 /* init barrier */
129 test_state = malloc(sizeof *test_state);
130 assert_non_null(test_state);
131
132 ret = pthread_barrier_init(&test_state->barrier, NULL, 2);
133 assert_int_equal(ret, 0);
134
135 *state = test_state;
136
137 ret = ly_ctx_new(MODULES_DIR, 0, &ctx);
138 assert_int_equal(ret, 0);
139
140 ret = nc_server_init_ctx(&ctx);
141 assert_int_equal(ret, 0);
142
143 ret = nc_server_config_load_modules(&ctx);
144 assert_int_equal(ret, 0);
145
146 /* create new address and port data */
roman142718b2023-06-29 09:15:29 +0200147 ret = nc_server_config_new_address_port(ctx, "endpt", NC_TI_OPENSSL, "127.0.0.1", 10005, &tree);
romanfaecc582023-06-15 16:13:31 +0200148 assert_int_equal(ret, 0);
149
150 /* create new server certificate data */
roman6c4efcd2023-08-08 10:18:44 +0200151 ret = nc_server_config_new_tls_server_certificate(ctx, "endpt", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree);
romanfaecc582023-06-15 16:13:31 +0200152 assert_int_equal(ret, 0);
153
154 /* create new end entity client cert data */
155 ret = nc_server_config_new_tls_client_certificate(ctx, "endpt", "client_cert", TESTS_DIR "/data/client.crt", &tree);
156 assert_int_equal(ret, 0);
157
158 /* create new client ca data */
159 ret = nc_server_config_new_tls_client_ca(ctx, "endpt", "client_ca", TESTS_DIR "/data/serverca.pem", &tree);
160 assert_int_equal(ret, 0);
161
162 /* create new cert-to-name */
163 ret = nc_server_config_new_tls_ctn(ctx, "endpt", 1,
164 "04:85:6B:75:D1:1A:86:E0:D8:FE:5B:BD:72:F5:73:1D:07:EA:32:BF:09:11:21:6A:6E:23:78:8E:B6:D5:73:C3:2D",
165 NC_TLS_CTN_SPECIFIED, "client", &tree);
166 assert_int_equal(ret, 0);
167
168 /* limit TLS version to 1.3 */
169 ret = nc_server_config_new_tls_version(ctx, "endpt", NC_TLS_VERSION_13, &tree);
170 assert_int_equal(ret, 0);
171
172 /* set the TLS cipher */
173 ret = nc_server_config_new_tls_ciphers(ctx, "endpt", &tree, 3, "tls-aes-128-ccm-sha256", "tls-aes-128-gcm-sha256", "tls-chacha20-poly1305-sha256");
174 assert_int_equal(ret, 0);
175
romand30af552023-06-16 15:18:27 +0200176 /* set this node, but it should be deleted by the next call, bcs only one choice node can be present */
romanfaecc582023-06-15 16:13:31 +0200177 ret = nc_server_config_new_tls_crl_url(ctx, "endpt", "abc", &tree);
178 assert_int_equal(ret, 0);
179
romand30af552023-06-16 15:18:27 +0200180 /* set path to a CRL file */
romanfaecc582023-06-15 16:13:31 +0200181 ret = nc_server_config_new_tls_crl_path(ctx, "endpt", TESTS_DIR "/data/crl.pem", &tree);
182 assert_int_equal(ret, 0);
183
184 /* configure the server based on the data */
roman142718b2023-06-29 09:15:29 +0200185 ret = nc_server_config_setup_data(tree);
romanfaecc582023-06-15 16:13:31 +0200186 assert_int_equal(ret, 0);
187
188 ret = nc_server_init();
189 assert_int_equal(ret, 0);
190
191 lyd_free_all(tree);
192
193 return 0;
194}
195
196static int
197teardown_f(void **state)
198{
199 int ret = 0;
200 struct test_state *test_state;
201
202 assert_non_null(state);
203 test_state = *state;
204
205 ret = pthread_barrier_destroy(&test_state->barrier);
206 assert_int_equal(ret, 0);
207
208 free(*state);
209 nc_client_destroy();
210 nc_server_destroy();
211 ly_ctx_destroy(ctx);
212
213 return 0;
214}
215
216int
217main(void)
218{
219 const struct CMUnitTest tests[] = {
220 cmocka_unit_test_setup_teardown(test_nc_tls, setup_f, teardown_f),
221 };
222
223 setenv("CMOCKA_TEST_ABORT", "1", 1);
224 return cmocka_run_group_tests(tests, NULL, NULL);
225}