blob: a0ce5295b798f2d3a2fd7b211c05816b01044980 [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)) {
Michal Vaskof0313632023-11-21 11:21:12 +010047 strncpy(buffer, msg, 511);
romanfaecc582023-06-15 16:13:31 +020048 }
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';
romanf0cf81b2024-04-23 15:13:41 +020063 strcpy(expected, "revoked");
romanfaecc582023-06-15 16:13:31 +020064
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);
Jan Kundrátf8d9e8d2024-04-08 12:13:02 +020095 session = nc_connect_tls("127.0.0.1", TEST_PORT, NULL);
romanfaecc582023-06-15 16:13:31 +020096
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 */
romand8973d12024-04-25 14:57:18 +0200147 ret = nc_server_config_add_address_port(ctx, "endpt", NC_TI_TLS, "127.0.0.1", TEST_PORT, &tree);
romanfaecc582023-06-15 16:13:31 +0200148 assert_int_equal(ret, 0);
149
150 /* create new server certificate data */
romane6ec60e2023-10-19 15:21:52 +0200151 ret = nc_server_config_add_tls_server_cert(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 */
romane6ec60e2023-10-19 15:21:52 +0200155 ret = nc_server_config_add_tls_client_cert(ctx, "endpt", "client_cert", TESTS_DIR "/data/client.crt", &tree);
romanfaecc582023-06-15 16:13:31 +0200156 assert_int_equal(ret, 0);
157
158 /* create new client ca data */
romane6ec60e2023-10-19 15:21:52 +0200159 ret = nc_server_config_add_tls_ca_cert(ctx, "endpt", "client_ca", TESTS_DIR "/data/serverca.pem", &tree);
romanfaecc582023-06-15 16:13:31 +0200160 assert_int_equal(ret, 0);
161
162 /* create new cert-to-name */
Roytakb2794852023-10-18 14:30:22 +0200163 ret = nc_server_config_add_tls_ctn(ctx, "endpt", 1,
romanfaecc582023-06-15 16:13:31 +0200164 "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
romand348b942023-10-13 14:32:19 +0200168 /* set path to a CRL file */
Michal Vaskocf898172024-01-15 15:04:28 +0100169 ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/endpoints/endpoint[name='endpt']/tls/"
170 "tls-server-parameters/client-authentication/libnetconf2-netconf-server:crl-path", TESTS_DIR "/data/crl.pem", 0, NULL);
romand348b942023-10-13 14:32:19 +0200171 assert_int_equal(ret, 0);
172
romanfaecc582023-06-15 16:13:31 +0200173 /* configure the server based on the data */
roman142718b2023-06-29 09:15:29 +0200174 ret = nc_server_config_setup_data(tree);
romanfaecc582023-06-15 16:13:31 +0200175 assert_int_equal(ret, 0);
176
177 ret = nc_server_init();
178 assert_int_equal(ret, 0);
179
romaneadc4782023-09-14 10:10:08 +0200180 /* initialize client */
181 ret = nc_client_init();
182 assert_int_equal(ret, 0);
183
romanfaecc582023-06-15 16:13:31 +0200184 lyd_free_all(tree);
185
186 return 0;
187}
188
189static int
190teardown_f(void **state)
191{
192 int ret = 0;
193 struct test_state *test_state;
194
195 assert_non_null(state);
196 test_state = *state;
197
198 ret = pthread_barrier_destroy(&test_state->barrier);
199 assert_int_equal(ret, 0);
200
201 free(*state);
202 nc_client_destroy();
203 nc_server_destroy();
204 ly_ctx_destroy(ctx);
205
206 return 0;
207}
208
209int
210main(void)
211{
212 const struct CMUnitTest tests[] = {
213 cmocka_unit_test_setup_teardown(test_nc_tls, setup_f, teardown_f),
214 };
215
216 setenv("CMOCKA_TEST_ABORT", "1", 1);
217 return cmocka_run_group_tests(tests, NULL, NULL);
218}