blob: 14f684c36d51eb3cfbe838702ebf187699e1f35f [file] [log] [blame]
romanf02273a2023-05-25 09:44:11 +02001/**
2 * @file server_config_ts.c
3 * @author Roman Janota <janota@cesnet.cz>
4 * @brief libnetconf2 truststore configuration functions
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 <assert.h>
roman3f9b65c2023-06-05 14:26:58 +020019#include <stdint.h>
romanf02273a2023-05-25 09:44:11 +020020#include <stdlib.h>
21#include <string.h>
22
roman3f9b65c2023-06-05 14:26:58 +020023#include <libyang/libyang.h>
24
romanf02273a2023-05-25 09:44:11 +020025#include "compat.h"
roman3f9b65c2023-06-05 14:26:58 +020026#include "log_p.h"
romanf02273a2023-05-25 09:44:11 +020027#include "server_config_p.h"
roman3f9b65c2023-06-05 14:26:58 +020028#include "session_p.h"
romanf02273a2023-05-25 09:44:11 +020029
30extern struct nc_server_opts server_opts;
31
32/**
33 * @brief Get the pointer to a certificate bag structure based on node's location in the YANG data.
34 *
35 * @param[in] node Node from which the certificate bag containing this node is derived.
36 * @param[out] cbag Certificate bag containing the node.
37 * @return 0 on success, 1 on error.
38 */
39static int
40nc_server_config_get_certificate_bag(const struct lyd_node *node, struct nc_certificate_bag **cbag)
41{
42 uint16_t i;
43 const char *cbag_name;
44 struct nc_truststore *ts;
roman2b2dc2b2023-10-12 11:58:09 +020045 const char *node_name = LYD_NAME(node);
romanf02273a2023-05-25 09:44:11 +020046
roman4cb8bb12023-06-29 09:16:46 +020047 assert(node && cbag);
romanf02273a2023-05-25 09:44:11 +020048
49 while (node) {
50 if (!strcmp(LYD_NAME(node), "certificate-bag")) {
51 break;
52 }
53 node = lyd_parent(node);
54 }
55
56 if (!node) {
roman2b2dc2b2023-10-12 11:58:09 +020057 ERR(NULL, "Node \"%s\" is not contained in a certificate-bag subtree.", node_name);
romanf02273a2023-05-25 09:44:11 +020058 return 1;
59 }
60
61 node = lyd_child(node);
62 assert(!strcmp(LYD_NAME(node), "name"));
63 cbag_name = lyd_get_value(node);
64
65 ts = &server_opts.truststore;
66 for (i = 0; i < ts->cert_bag_count; i++) {
67 if (!strcmp(ts->cert_bags[i].name, cbag_name)) {
68 *cbag = &ts->cert_bags[i];
69 return 0;
70 }
71 }
72
73 ERR(NULL, "Certificate bag \"%s\" was not found.", cbag_name);
74 return 1;
75}
76
77/**
78 * @brief Get the pointer to a certificate structure based on node's location in the YANG data.
79 *
80 * @param[in] node Node from which the certificate containing this node is derived.
romanf02273a2023-05-25 09:44:11 +020081 * @param[out] cert Certificate containing the node.
82 * @return 0 on success, 1 on error.
83 */
84static int
roman4cb8bb12023-06-29 09:16:46 +020085nc_server_config_get_certificate(const struct lyd_node *node, struct nc_certificate **cert)
romanf02273a2023-05-25 09:44:11 +020086{
87 uint16_t i;
88 const char *cert_name;
roman4cb8bb12023-06-29 09:16:46 +020089 struct nc_certificate_bag *cbag;
roman2b2dc2b2023-10-12 11:58:09 +020090 const char *node_name = LYD_NAME(node);
romanf02273a2023-05-25 09:44:11 +020091
roman4cb8bb12023-06-29 09:16:46 +020092 assert(node && cert);
93
94 if (nc_server_config_get_certificate_bag(node, &cbag)) {
95 return 1;
96 }
romanf02273a2023-05-25 09:44:11 +020097
98 while (node) {
99 if (!strcmp(LYD_NAME(node), "certificate")) {
100 break;
101 }
102 node = lyd_parent(node);
103 }
104
105 if (!node) {
roman2b2dc2b2023-10-12 11:58:09 +0200106 ERR(NULL, "Node \"%s\" is not contained in a certificate subtree.", node_name);
romanf02273a2023-05-25 09:44:11 +0200107 return 1;
108 }
109
110 node = lyd_child(node);
111 assert(!strcmp(LYD_NAME(node), "name"));
112 cert_name = lyd_get_value(node);
113
114 for (i = 0; i < cbag->cert_count; i++) {
115 if (!strcmp(cbag->certs[i].name, cert_name)) {
116 *cert = &cbag->certs[i];
117 return 0;
118 }
119 }
120
121 ERR(NULL, "Certificate \"%s\" was not found.", cert_name);
122 return 1;
123}
124
125/**
126 * @brief Get the pointer to a public key bag structure based on node's location in the YANG data.
127 *
128 * @param[in] node Node from which the public key bag containing this node is derived.
129 * @param[out] pbag Public key bag containing the node.
130 * @return 0 on success, 1 on error.
131 */
132static int
133nc_server_config_get_public_key_bag(const struct lyd_node *node, struct nc_public_key_bag **pbag)
134{
135 uint16_t i;
136 const char *pbag_name;
137 struct nc_truststore *ts;
roman2b2dc2b2023-10-12 11:58:09 +0200138 const char *node_name = LYD_NAME(node);
romanf02273a2023-05-25 09:44:11 +0200139
roman4cb8bb12023-06-29 09:16:46 +0200140 assert(node && pbag);
romanf02273a2023-05-25 09:44:11 +0200141
142 while (node) {
143 if (!strcmp(LYD_NAME(node), "public-key-bag")) {
144 break;
145 }
146 node = lyd_parent(node);
147 }
148
149 if (!node) {
roman2b2dc2b2023-10-12 11:58:09 +0200150 ERR(NULL, "Node \"%s\" is not contained in a public-key-bag subtree.", node_name);
romanf02273a2023-05-25 09:44:11 +0200151 return 1;
152 }
153
154 node = lyd_child(node);
155 assert(!strcmp(LYD_NAME(node), "name"));
156 pbag_name = lyd_get_value(node);
157
158 ts = &server_opts.truststore;
159 for (i = 0; i < ts->pub_bag_count; i++) {
160 if (!strcmp(ts->pub_bags[i].name, pbag_name)) {
161 *pbag = &ts->pub_bags[i];
162 return 0;
163 }
164 }
165
166 ERR(NULL, "Public key bag \"%s\" was not found.", pbag_name);
167 return 1;
168}
169
170/**
171 * @brief Get the pointer to a public key structure based on node's location in the YANG data.
172 *
173 * @param[in] node Node from which the public key containing this node is derived.
romanf02273a2023-05-25 09:44:11 +0200174 * @param[out] pkey Public key containing the node.
175 * @return 0 on success, 1 on error.
176 */
177static int
roman4cb8bb12023-06-29 09:16:46 +0200178nc_server_config_get_public_key(const struct lyd_node *node, struct nc_public_key **pkey)
romanf02273a2023-05-25 09:44:11 +0200179{
180 uint16_t i;
181 const char *pkey_name;
roman4cb8bb12023-06-29 09:16:46 +0200182 struct nc_public_key_bag *pbag;
roman2b2dc2b2023-10-12 11:58:09 +0200183 const char *node_name = LYD_NAME(node);
romanf02273a2023-05-25 09:44:11 +0200184
roman4cb8bb12023-06-29 09:16:46 +0200185 assert(node && pkey);
186
187 if (nc_server_config_get_public_key_bag(node, &pbag)) {
188 return 1;
189 }
romanf02273a2023-05-25 09:44:11 +0200190
191 while (node) {
192 if (!strcmp(LYD_NAME(node), "public-key")) {
193 if (lyd_child(node)) {
194 /* check if it's not the leaf public-key, only case about the list */
195 break;
196 }
197 }
198
199 node = lyd_parent(node);
200 }
201
202 if (!node) {
roman2b2dc2b2023-10-12 11:58:09 +0200203 ERR(NULL, "Node \"%s\" is not contained in a public-key subtree.", node_name);
romanf02273a2023-05-25 09:44:11 +0200204 return 1;
205 }
206
207 node = lyd_child(node);
208 assert(!strcmp(LYD_NAME(node), "name"));
209 pkey_name = lyd_get_value(node);
210
211 for (i = 0; i < pbag->pubkey_count; i++) {
212 if (!strcmp(pbag->pubkeys[i].name, pkey_name)) {
213 *pkey = &pbag->pubkeys[i];
214 return 0;
215 }
216 }
217
218 ERR(NULL, "Public key \"%s\" was not found.", pkey_name);
219 return 1;
220}
221
222static void
romanf02273a2023-05-25 09:44:11 +0200223nc_server_config_ts_del_certificate(struct nc_certificate_bag *cbag, struct nc_certificate *cert)
224{
225 free(cert->name);
roman2b2dc2b2023-10-12 11:58:09 +0200226 free(cert->data);
romanf02273a2023-05-25 09:44:11 +0200227
228 cbag->cert_count--;
roman2b2dc2b2023-10-12 11:58:09 +0200229 if (!cbag->cert_count) {
romanf02273a2023-05-25 09:44:11 +0200230 free(cbag->certs);
231 cbag->certs = NULL;
roman2b2dc2b2023-10-12 11:58:09 +0200232 } else if (cert != &cbag->certs[cbag->cert_count]) {
233 memcpy(cert, &cbag->certs[cbag->cert_count], sizeof *cbag->certs);
romanf02273a2023-05-25 09:44:11 +0200234 }
235}
236
237static void
238nc_server_config_ts_del_public_key(struct nc_public_key_bag *pbag, struct nc_public_key *pkey)
239{
240 free(pkey->name);
roman2b2dc2b2023-10-12 11:58:09 +0200241 free(pkey->data);
romanf02273a2023-05-25 09:44:11 +0200242
243 pbag->pubkey_count--;
roman2b2dc2b2023-10-12 11:58:09 +0200244 if (!pbag->pubkey_count) {
romanf02273a2023-05-25 09:44:11 +0200245 free(pbag->pubkeys);
246 pbag->pubkeys = NULL;
roman2b2dc2b2023-10-12 11:58:09 +0200247 } else if (pkey != &pbag->pubkeys[pbag->pubkey_count]) {
248 memcpy(pkey, &pbag->pubkeys[pbag->pubkey_count], sizeof *pbag->pubkeys);
romanf02273a2023-05-25 09:44:11 +0200249 }
250}
251
252static void
253nc_server_config_ts_del_certificate_bag(struct nc_certificate_bag *cbag)
254{
255 uint16_t i, cert_count;
256 struct nc_truststore *ts = &server_opts.truststore;
257
258 free(cbag->name);
romanf02273a2023-05-25 09:44:11 +0200259
260 cert_count = cbag->cert_count;
261 for (i = 0; i < cert_count; i++) {
262 nc_server_config_ts_del_certificate(cbag, &cbag->certs[i]);
263 }
264
265 ts->cert_bag_count--;
roman2b2dc2b2023-10-12 11:58:09 +0200266 if (!ts->cert_bag_count) {
romanf02273a2023-05-25 09:44:11 +0200267 free(ts->cert_bags);
268 ts->cert_bags = NULL;
roman2b2dc2b2023-10-12 11:58:09 +0200269 } else if (cbag != &ts->cert_bags[ts->cert_bag_count]) {
270 memcpy(cbag, &ts->cert_bags[ts->cert_bag_count], sizeof *ts->cert_bags);
romanf02273a2023-05-25 09:44:11 +0200271 }
272}
273
274static void
275nc_server_config_ts_del_public_key_bag(struct nc_public_key_bag *pbag)
276{
277 uint16_t i, pubkey_count;
278 struct nc_truststore *ts = &server_opts.truststore;
279
280 free(pbag->name);
romanf02273a2023-05-25 09:44:11 +0200281
282 pubkey_count = pbag->pubkey_count;
283 for (i = 0; i < pubkey_count; i++) {
284 nc_server_config_ts_del_public_key(pbag, &pbag->pubkeys[i]);
285 }
286
287 ts->pub_bag_count--;
roman2b2dc2b2023-10-12 11:58:09 +0200288 if (!ts->pub_bag_count) {
romanf02273a2023-05-25 09:44:11 +0200289 free(ts->pub_bags);
290 ts->pub_bags = NULL;
roman2b2dc2b2023-10-12 11:58:09 +0200291 } else if (pbag != &ts->pub_bags[ts->pub_bag_count]) {
292 memcpy(pbag, &ts->pub_bags[ts->pub_bag_count], sizeof *ts->pub_bags);
romanf02273a2023-05-25 09:44:11 +0200293 }
294}
295
296static int
297nc_server_config_ts_certificate_bags(const struct lyd_node *node, NC_OPERATION op)
298{
299 uint16_t i, cert_bag_count;
300 struct nc_truststore *ts = &server_opts.truststore;
301
302 (void) node;
303
304 if (op == NC_OP_DELETE) {
305 cert_bag_count = ts->cert_bag_count;
306 for (i = 0; i < cert_bag_count; i++) {
307 nc_server_config_ts_del_certificate_bag(&ts->cert_bags[i]);
308 }
309 }
310
311 return 0;
312}
313
314static int
315nc_server_config_ts_public_key_bags(const struct lyd_node *node, NC_OPERATION op)
316{
317 uint16_t i, pub_bag_count;
318 struct nc_truststore *ts = &server_opts.truststore;
319
320 (void) node;
321
322 if (op == NC_OP_DELETE) {
323 pub_bag_count = ts->pub_bag_count;
324 for (i = 0; i < pub_bag_count; i++) {
325 nc_server_config_ts_del_public_key_bag(&ts->pub_bags[i]);
326 }
327 }
328
329 return 0;
330}
331
332int
333nc_server_config_ts_truststore(const struct lyd_node *node, NC_OPERATION op)
334{
335 (void) node;
336
337 if (op == NC_OP_DELETE) {
338 nc_server_config_ts_certificate_bags(NULL, NC_OP_DELETE);
339 nc_server_config_ts_public_key_bags(NULL, NC_OP_DELETE);
340 }
341
342 return 0;
343}
344
345static int
346nc_server_config_ts_create_certificate_bag(const struct lyd_node *node)
347{
348 struct nc_truststore *ts = &server_opts.truststore;
349
350 node = lyd_child(node);
351 assert(!strcmp(LYD_NAME(node), "name"));
352
353 return nc_server_config_realloc(lyd_get_value(node), (void **)&ts->cert_bags, sizeof *ts->cert_bags, &ts->cert_bag_count);
354}
355
356static int
357nc_server_config_ts_certificate_bag(const struct lyd_node *node, NC_OPERATION op)
358{
359 struct nc_certificate_bag *bag;
360
361 assert(!strcmp(LYD_NAME(node), "certificate-bag"));
362
363 if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
364 if (nc_server_config_ts_create_certificate_bag(node)) {
365 return 1;
366 }
367 } else {
368 if (nc_server_config_get_certificate_bag(node, &bag)) {
369 return 1;
370 }
371
372 nc_server_config_ts_del_certificate_bag(bag);
373 }
374
375 return 0;
376}
377
378static int
379nc_server_config_ts_create_certificate(const struct lyd_node *node, struct nc_certificate_bag *bag)
380{
381 node = lyd_child(node);
382 assert(!strcmp(LYD_NAME(node), "name"));
383
384 return nc_server_config_realloc(lyd_get_value(node), (void **)&bag->certs, sizeof *bag->certs, &bag->cert_count);
385}
386
387static int
388nc_server_config_ts_certificate(const struct lyd_node *node, NC_OPERATION op)
389{
390 struct nc_certificate_bag *bag;
391 struct nc_certificate *cert;
392
393 assert(!strcmp(LYD_NAME(node), "certificate"));
394
395 if (nc_server_config_get_certificate_bag(node, &bag)) {
396 return 1;
397 }
398
399 if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
400 if (nc_server_config_ts_create_certificate(node, bag)) {
401 return 1;
402 }
403 } else {
roman4cb8bb12023-06-29 09:16:46 +0200404 if (nc_server_config_get_certificate(node, &cert)) {
romanf02273a2023-05-25 09:44:11 +0200405 return 1;
406 }
407
408 nc_server_config_ts_del_certificate(bag, cert);
409 }
410
411 return 0;
412}
413
414static int
415nc_server_config_ts_cert_data(const struct lyd_node *node, NC_OPERATION op)
416{
romanf02273a2023-05-25 09:44:11 +0200417 struct nc_certificate *cert;
418
419 if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
roman4cb8bb12023-06-29 09:16:46 +0200420 if (nc_server_config_get_certificate(node, &cert)) {
romanf02273a2023-05-25 09:44:11 +0200421 return 1;
422 }
423
roman2b2dc2b2023-10-12 11:58:09 +0200424 free(cert->data);
roman3f9b65c2023-06-05 14:26:58 +0200425 cert->data = strdup(lyd_get_value(node));
roman3a95bb22023-10-26 11:07:17 +0200426 NC_CHECK_ERRMEM_RET(!cert->data, 1);
romanf02273a2023-05-25 09:44:11 +0200427 }
428
429 return 0;
430}
431
432static int
433nc_server_config_ts_create_public_key_bag(const struct lyd_node *node)
434{
435 struct nc_truststore *ts = &server_opts.truststore;
436
437 node = lyd_child(node);
438 assert(!strcmp(LYD_NAME(node), "name"));
439
440 return nc_server_config_realloc(lyd_get_value(node), (void **)&ts->pub_bags, sizeof *ts->pub_bags, &ts->pub_bag_count);
441}
442
443static int
444nc_server_config_ts_public_key_bag(const struct lyd_node *node, NC_OPERATION op)
445{
446 struct nc_public_key_bag *pbag;
447
448 assert(!strcmp(LYD_NAME(node), "public-key-bag"));
449
450 if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
451 if (nc_server_config_ts_create_public_key_bag(node)) {
452 return 1;
453 }
454 } else {
455 if (nc_server_config_get_public_key_bag(node, &pbag)) {
456 return 1;
457 }
458
459 nc_server_config_ts_del_public_key_bag(pbag);
460 }
461
462 return 0;
463}
464
465static int
466nc_server_config_ts_create_public_key(const struct lyd_node *node, struct nc_public_key_bag *bag)
467{
468 node = lyd_child(node);
469 assert(!strcmp(LYD_NAME(node), "name"));
470
471 return nc_server_config_realloc(lyd_get_value(node), (void **)&bag->pubkeys, sizeof *bag->pubkeys, &bag->pubkey_count);
472}
473
474static int
475nc_server_config_ts_public_key(const struct lyd_node *node, NC_OPERATION op)
476{
477 int ret = 0;
478 struct nc_public_key_bag *bag;
479 struct nc_public_key *pkey;
480
481 if (nc_server_config_get_public_key_bag(node, &bag)) {
482 ret = 1;
483 goto cleanup;
484 }
485
486 if (equal_parent_name(node, 1, "public-key-bag")) {
487 /* public-key list */
488 if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
489 ret = nc_server_config_ts_create_public_key(node, bag);
490 if (ret) {
491 goto cleanup;
492 }
493 } else {
roman4cb8bb12023-06-29 09:16:46 +0200494 if (nc_server_config_get_public_key(node, &pkey)) {
romanf02273a2023-05-25 09:44:11 +0200495 ret = 1;
496 goto cleanup;
497 }
498
499 nc_server_config_ts_del_public_key(bag, pkey);
500 }
501 } else {
502 /* public-key leaf */
roman4cb8bb12023-06-29 09:16:46 +0200503 if (nc_server_config_get_public_key(node, &pkey)) {
romanf02273a2023-05-25 09:44:11 +0200504 ret = 1;
505 goto cleanup;
506 }
507
508 /* replace the public key */
roman2b2dc2b2023-10-12 11:58:09 +0200509 free(pkey->data);
roman3f9b65c2023-06-05 14:26:58 +0200510 pkey->data = strdup(lyd_get_value(node));
roman3a95bb22023-10-26 11:07:17 +0200511 NC_CHECK_ERRMEM_GOTO(!pkey->data, ret = 1, cleanup);
romanf02273a2023-05-25 09:44:11 +0200512 }
513
514cleanup:
515 return ret;
516}
517
518static int
519nc_server_config_ts_public_key_format(const struct lyd_node *node, NC_OPERATION op)
520{
521 const char *format;
romanf02273a2023-05-25 09:44:11 +0200522 struct nc_public_key *pkey;
523
524 (void) op;
525
roman4cb8bb12023-06-29 09:16:46 +0200526 if (nc_server_config_get_public_key(node, &pkey)) {
romanf02273a2023-05-25 09:44:11 +0200527 return 1;
528 }
529
530 format = ((struct lyd_node_term *)node)->value.ident->name;
531 if (!strcmp(format, "ssh-public-key-format")) {
roman13145912023-08-17 15:36:54 +0200532 pkey->type = NC_PUBKEY_FORMAT_SSH;
romanf02273a2023-05-25 09:44:11 +0200533 } else if (!strcmp(format, "subject-public-key-info-format")) {
roman3f9b65c2023-06-05 14:26:58 +0200534 pkey->type = NC_PUBKEY_FORMAT_X509;
romanf02273a2023-05-25 09:44:11 +0200535 } else {
536 ERR(NULL, "Public key format (%s) not supported.", format);
537 }
538
539 return 0;
540}
541
542int
543nc_server_config_parse_truststore(const struct lyd_node *node, NC_OPERATION op)
544{
545 const char *name = LYD_NAME(node);
roman2b2dc2b2023-10-12 11:58:09 +0200546 int ret = 0;
romanf02273a2023-05-25 09:44:11 +0200547
548 if (!strcmp(name, "truststore")) {
roman2b2dc2b2023-10-12 11:58:09 +0200549 ret = nc_server_config_ts_truststore(node, op);
romanf02273a2023-05-25 09:44:11 +0200550 } else if (!strcmp(name, "certificate-bags")) {
roman2b2dc2b2023-10-12 11:58:09 +0200551 ret = nc_server_config_ts_certificate_bags(node, op);
romanf02273a2023-05-25 09:44:11 +0200552 } else if (!strcmp(name, "certificate-bag")) {
roman2b2dc2b2023-10-12 11:58:09 +0200553 ret = nc_server_config_ts_certificate_bag(node, op);
romanf02273a2023-05-25 09:44:11 +0200554 } else if (!strcmp(name, "certificate")) {
roman2b2dc2b2023-10-12 11:58:09 +0200555 ret = nc_server_config_ts_certificate(node, op);
romanf02273a2023-05-25 09:44:11 +0200556 } else if (!strcmp(name, "cert-data")) {
roman2b2dc2b2023-10-12 11:58:09 +0200557 ret = nc_server_config_ts_cert_data(node, op);
romanf02273a2023-05-25 09:44:11 +0200558 } else if (!strcmp(name, "public-key-bags")) {
roman2b2dc2b2023-10-12 11:58:09 +0200559 ret = nc_server_config_ts_public_key_bags(node, op);
romanf02273a2023-05-25 09:44:11 +0200560 } else if (!strcmp(name, "public-key-bag")) {
roman2b2dc2b2023-10-12 11:58:09 +0200561 ret = nc_server_config_ts_public_key_bag(node, op);
romanf02273a2023-05-25 09:44:11 +0200562 } else if (!strcmp(name, "public-key")) {
roman2b2dc2b2023-10-12 11:58:09 +0200563 ret = nc_server_config_ts_public_key(node, op);
romanf02273a2023-05-25 09:44:11 +0200564 } else if (!strcmp(name, "public-key-format")) {
roman2b2dc2b2023-10-12 11:58:09 +0200565 ret = nc_server_config_ts_public_key_format(node, op);
566 }
567
568 if (ret) {
569 ERR(NULL, "Configuring (%s) failed.", name);
570 return 1;
romanf02273a2023-05-25 09:44:11 +0200571 }
572
573 return 0;
romanf02273a2023-05-25 09:44:11 +0200574}
575
576int
577nc_server_config_fill_truststore(const struct lyd_node *data, NC_OPERATION op)
578{
579 int ret = 0;
580 uint32_t prev_lo;
581 struct lyd_node *tree;
582
583 /* silently search for nodes, some of them may not be present */
584 prev_lo = ly_log_options(0);
585
586 ret = lyd_find_path(data, "/ietf-truststore:truststore", 0, &tree);
587 if (ret || (tree->flags & LYD_DEFAULT)) {
roman5cbb6532023-06-22 12:53:17 +0200588 /* not found */
romanf02273a2023-05-25 09:44:11 +0200589 ret = 0;
590 goto cleanup;
591 }
592
roman0bbc19c2023-05-26 09:59:09 +0200593 if (nc_server_config_parse_tree(tree, op, NC_MODULE_TRUSTSTORE)) {
romanf02273a2023-05-25 09:44:11 +0200594 ret = 1;
595 goto cleanup;
596 }
597
598cleanup:
599 /* reset the logging options back to what they were */
600 ly_log_options(prev_lo);
601 return ret;
602}