blob: 4ac373611b346d60b187b46b6ba7ed2dec90b273 [file] [log] [blame]
Radek Krejci5da708a2015-09-01 17:33:23 +02001/**
Michal Vasko95ea9ff2021-11-09 12:29:14 +01002 * @file session_server_tls.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
roman3f9b65c2023-06-05 14:26:58 +02004 * @author Roman Janota <janota@cesnet.cz>
Michal Vasko95ea9ff2021-11-09 12:29:14 +01005 * @brief libnetconf2 TLS server session manipulation functions
Radek Krejci5da708a2015-09-01 17:33:23 +02006 *
Michal Vasko95ea9ff2021-11-09 12:29:14 +01007 * @copyright
roman3f9b65c2023-06-05 14:26:58 +02008 * Copyright (c) 2015 - 2023 CESNET, z.s.p.o.
Radek Krejci5da708a2015-09-01 17:33:23 +02009 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +010010 * This source code is licensed under BSD 3-Clause License (the "License").
11 * You may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
Michal Vaskoafd416b2016-02-25 14:51:46 +010013 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +010014 * https://opensource.org/licenses/BSD-3-Clause
Radek Krejci5da708a2015-09-01 17:33:23 +020015 */
16
Michal Vaskoc14e3c82016-01-11 16:14:30 +010017#define _GNU_SOURCE
18
Michal Vaskoc14e3c82016-01-11 16:14:30 +010019#include <poll.h>
roman3f9b65c2023-06-05 14:26:58 +020020#include <stdint.h>
21#include <stdio.h>
22#include <stdlib.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020023#include <string.h>
Michal Vaskof0537d82016-01-29 14:42:38 +010024#include <unistd.h>
Michal Vaskoc14e3c82016-01-11 16:14:30 +010025
roman3f9b65c2023-06-05 14:26:58 +020026#include <curl/curl.h>
Michal Vaskoc14e3c82016-01-11 16:14:30 +010027
Michal Vasko316c9632020-04-15 11:06:57 +020028#include "compat.h"
roman3f9b65c2023-06-05 14:26:58 +020029#include "config.h"
30#include "log_p.h"
31#include "session.h"
32#include "session_p.h"
roman69962562024-04-05 12:33:39 +020033#include "session_wrapper.h"
Rosen Penev4f552d62019-06-26 16:10:43 -070034
Michal Vasko3031aae2016-01-27 16:07:18 +010035struct nc_server_tls_opts tls_ch_opts;
Michal Vaskoc14e3c82016-01-11 16:14:30 +010036extern struct nc_server_opts server_opts;
Michal Vaskoc61c4492016-01-25 11:13:34 +010037
roman3f9b65c2023-06-05 14:26:58 +020038static int
39nc_server_tls_ks_ref_get_cert_key(const char *referenced_key_name, const char *referenced_cert_name,
40 char **privkey_data, NC_PRIVKEY_FORMAT *privkey_type, char **cert_data)
Andrew Langefeld440b6c72018-08-27 16:26:20 -050041{
roman3f9b65c2023-06-05 14:26:58 +020042 uint16_t i, j;
43 struct nc_keystore *ks = &server_opts.keystore;
Andrew Langefeld440b6c72018-08-27 16:26:20 -050044
roman3f9b65c2023-06-05 14:26:58 +020045 *privkey_data = NULL;
46 *cert_data = NULL;
Andrew Langefeld440b6c72018-08-27 16:26:20 -050047
roman3f9b65c2023-06-05 14:26:58 +020048 /* lookup name */
49 for (i = 0; i < ks->asym_key_count; i++) {
50 if (!strcmp(referenced_key_name, ks->asym_keys[i].name)) {
51 break;
Andrew Langefeld440b6c72018-08-27 16:26:20 -050052 }
53 }
roman3f9b65c2023-06-05 14:26:58 +020054 if (i == ks->asym_key_count) {
55 ERR(NULL, "Keystore entry \"%s\" not found.", referenced_key_name);
Andrew Langefeld440b6c72018-08-27 16:26:20 -050056 return -1;
57 }
58
roman3f9b65c2023-06-05 14:26:58 +020059 for (j = 0; j < ks->asym_keys[i].cert_count; j++) {
roman78df0fa2023-11-02 10:33:57 +010060 if (!strcmp(referenced_cert_name, ks->asym_keys[i].certs[j].name)) {
roman3f9b65c2023-06-05 14:26:58 +020061 break;
Andrew Langefeld440b6c72018-08-27 16:26:20 -050062 }
63 }
roman3f9b65c2023-06-05 14:26:58 +020064 if (j == ks->asym_keys[i].cert_count) {
65 ERR(NULL, "Keystore certificate entry \"%s\" associated with the key \"%s\" not found.",
66 referenced_cert_name, referenced_key_name);
67 return -1;
68 }
Andrew Langefeld440b6c72018-08-27 16:26:20 -050069
roman3f9b65c2023-06-05 14:26:58 +020070 *privkey_data = ks->asym_keys[i].privkey_data;
71 *privkey_type = ks->asym_keys[i].privkey_type;
72 *cert_data = ks->asym_keys[i].certs[j].data;
73 return 0;
Andrew Langefeld440b6c72018-08-27 16:26:20 -050074}
75
Michal Vasko4c1fb492017-01-30 14:31:07 +010076static int
roman69962562024-04-05 12:33:39 +020077nc_server_tls_ts_ref_get_certs(const char *referenced_name, struct nc_certificate **certs, uint16_t *cert_count)
78{
79 uint16_t i;
80 struct nc_truststore *ts = &server_opts.truststore;
81
82 *certs = NULL;
83 *cert_count = 0;
84
85 /* lookup name */
86 for (i = 0; i < ts->cert_bag_count; i++) {
87 if (!strcmp(referenced_name, ts->cert_bags[i].name)) {
88 break;
89 }
90 }
91
92 if (i == ts->cert_bag_count) {
93 ERR(NULL, "Truststore entry \"%s\" not found.", referenced_name);
94 return -1;
95 }
96
97 *certs = ts->cert_bags[i].certs;
98 *cert_count = ts->cert_bags[i].cert_count;
99 return 0;
100}
101
102static void *
103nc_base64der_to_cert(const char *in)
104{
romanebc7bba2024-04-15 14:58:39 +0200105 char *buf = NULL;
106 void *cert;
roman69962562024-04-05 12:33:39 +0200107
108 NC_CHECK_ARG_RET(NULL, in, NULL);
109
110 if (asprintf(&buf, "%s%s%s", "-----BEGIN CERTIFICATE-----\n", in, "\n-----END CERTIFICATE-----") == -1) {
111 ERRMEM;
112 return NULL;
113 }
114
115 cert = nc_tls_pem_to_cert_wrap(buf);
116 free(buf);
117 return cert;
118}
119
roman69962562024-04-05 12:33:39 +0200120static void *
romanebc7bba2024-04-15 14:58:39 +0200121nc_base64der_to_privkey(const char *in, const char *key_str)
roman69962562024-04-05 12:33:39 +0200122{
romanebc7bba2024-04-15 14:58:39 +0200123 char *buf = NULL;
roman69962562024-04-05 12:33:39 +0200124 void *pkey;
125
126 NC_CHECK_ARG_RET(NULL, in, NULL);
127
roman04a65d02024-04-25 15:07:00 +0200128 if (asprintf(&buf, "%s%s%s%s%s%s%s", "-----BEGIN", key_str, "PRIVATE KEY-----\n", in, "\n-----END",
129 key_str, "PRIVATE KEY-----") == -1) {
roman69962562024-04-05 12:33:39 +0200130 ERRMEM;
131 return NULL;
132 }
133
134 pkey = nc_tls_pem_to_privkey_wrap(buf);
135 free(buf);
136 return pkey;
137}
138
romanebc7bba2024-04-15 14:58:39 +0200139static char *
roman69962562024-04-05 12:33:39 +0200140nc_server_tls_digest_to_hex(const unsigned char *digest, unsigned int digest_len)
141{
142 unsigned int i;
143 char *hex;
144
145 hex = malloc(digest_len * 3);
146 NC_CHECK_ERRMEM_RET(!hex, NULL);
147
148 for (i = 0; i < digest_len - 1; ++i) {
149 sprintf(hex + (i * 3), "%02x:", digest[i]);
150 }
151 sprintf(hex + (i * 3), "%02x", digest[i]);
152
153 return hex;
154}
155
romanebc7bba2024-04-15 14:58:39 +0200156static char *
roman69962562024-04-05 12:33:39 +0200157nc_server_tls_md5(void *cert)
158{
159 int rc;
160 unsigned int buf_len = 16;
161 unsigned char buf[buf_len];
162
163 /* compute MD-5 hash of cert and store it in buf */
164 rc = nc_server_tls_md5_wrap(cert, buf);
165 if (rc) {
166 return NULL;
167 }
168
169 /* convert the hash to hex */
170 return nc_server_tls_digest_to_hex(buf, buf_len);
171}
172
romanebc7bba2024-04-15 14:58:39 +0200173static char *
roman69962562024-04-05 12:33:39 +0200174nc_server_tls_sha1(void *cert)
175{
176 int rc;
177 unsigned int buf_len = 20;
178 unsigned char buf[buf_len];
179
180 /* compute SHA-1 hash of cert and store it in buf */
181 rc = nc_server_tls_sha1_wrap(cert, buf);
182 if (rc) {
183 return NULL;
184 }
185
186 /* convert the hash to hex */
187 return nc_server_tls_digest_to_hex(buf, buf_len);
188}
189
romanebc7bba2024-04-15 14:58:39 +0200190static char *
roman69962562024-04-05 12:33:39 +0200191nc_server_tls_sha224(void *cert)
192{
193 int rc;
194 unsigned int buf_len = 28;
195 unsigned char buf[buf_len];
196
197 /* compute SHA-224 hash of cert and store it in buf */
198 rc = nc_server_tls_sha224_wrap(cert, buf);
199 if (rc) {
200 return NULL;
201 }
202
203 /* convert the hash to hex */
204 return nc_server_tls_digest_to_hex(buf, buf_len);
205}
206
romanebc7bba2024-04-15 14:58:39 +0200207static char *
roman69962562024-04-05 12:33:39 +0200208nc_server_tls_sha256(void *cert)
209{
210 int rc;
211 unsigned int buf_len = 32;
212 unsigned char buf[buf_len];
213
214 /* compute SHA-256 hash of cert and store it in buf */
215 rc = nc_server_tls_sha256_wrap(cert, buf);
216 if (rc) {
217 return NULL;
218 }
219
220 /* convert the hash to hex */
221 return nc_server_tls_digest_to_hex(buf, buf_len);
222}
223
romanebc7bba2024-04-15 14:58:39 +0200224static char *
roman69962562024-04-05 12:33:39 +0200225nc_server_tls_sha384(void *cert)
226{
227 int rc;
228 unsigned int buf_len = 48;
229 unsigned char buf[buf_len];
230
231 /* compute SHA-384 hash of cert and store it in buf */
232 rc = nc_server_tls_sha384_wrap(cert, buf);
233 if (rc) {
234 return NULL;
235 }
236
237 /* convert the hash to hex */
238 return nc_server_tls_digest_to_hex(buf, buf_len);
239}
240
romanebc7bba2024-04-15 14:58:39 +0200241static char *
roman69962562024-04-05 12:33:39 +0200242nc_server_tls_sha512(void *cert)
243{
244 int rc;
245 unsigned int buf_len = 64;
246 unsigned char buf[buf_len];
247
248 /* compute SHA-512 hash of cert and store it in buf */
249 rc = nc_server_tls_sha512_wrap(cert, buf);
250 if (rc) {
251 return NULL;
252 }
253
254 /* convert the hash to hex */
255 return nc_server_tls_digest_to_hex(buf, buf_len);
256}
257
258static int
259nc_server_tls_cert_to_name(struct nc_ctn *ctn_first, void *cert, struct nc_ctn_data *data)
260{
261 int ret = 0;
262 char *digest_md5 = NULL, *digest_sha1 = NULL, *digest_sha224 = NULL;
263 char *digest_sha256 = NULL, *digest_sha384 = NULL, *digest_sha512 = NULL;
264 struct nc_ctn *ctn;
265 NC_TLS_CTN_MAPTYPE map_type;
266
267 for (ctn = ctn_first; ctn; ctn = ctn->next) {
268 /* reset map_type */
269 map_type = NC_TLS_CTN_UNKNOWN;
270
271 /* first make sure the entry is valid */
272 if (!ctn->map_type || ((ctn->map_type == NC_TLS_CTN_SPECIFIED) && !ctn->name)) {
273 VRB(NULL, "Cert verify CTN: entry with id %u not valid, skipping.", ctn->id);
274 continue;
275 }
276
277 /* if ctn has no fingerprint, it will match any certificate */
278 if (!ctn->fingerprint) {
279 map_type = ctn->map_type;
280
281 /* MD5 */
282 } else if (!strncmp(ctn->fingerprint, "01", 2)) {
283 if (!digest_md5) {
284 digest_md5 = nc_server_tls_md5(cert);
285 if (!digest_md5) {
286 ret = -1;
287 goto cleanup;
288 }
289 }
290
291 if (!strcasecmp(ctn->fingerprint + 3, digest_md5)) {
292 /* we got ourselves a potential winner! */
293 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
294 map_type = ctn->map_type;
295 }
296
297 /* SHA-1 */
298 } else if (!strncmp(ctn->fingerprint, "02", 2)) {
299 if (!digest_sha1) {
300 digest_sha1 = nc_server_tls_sha1(cert);
301 if (!digest_sha1) {
302 ret = -1;
303 goto cleanup;
304 }
305 }
306
307 if (!strcasecmp(ctn->fingerprint + 3, digest_sha1)) {
308 /* we got ourselves a potential winner! */
309 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
310 map_type = ctn->map_type;
311 }
312
313 /* SHA-224 */
314 } else if (!strncmp(ctn->fingerprint, "03", 2)) {
315 if (!digest_sha224) {
316 digest_sha224 = nc_server_tls_sha224(cert);
317 if (!digest_sha224) {
318 ret = -1;
319 goto cleanup;
320 }
321 }
322
323 if (!strcasecmp(ctn->fingerprint + 3, digest_sha224)) {
324 /* we got ourselves a potential winner! */
325 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
326 map_type = ctn->map_type;
327 }
328
329 /* SHA-256 */
330 } else if (!strncmp(ctn->fingerprint, "04", 2)) {
331 if (!digest_sha256) {
332 digest_sha256 = nc_server_tls_sha256(cert);
333 if (!digest_sha256) {
334 ret = -1;
335 goto cleanup;
336 }
337 }
338
339 if (!strcasecmp(ctn->fingerprint + 3, digest_sha256)) {
340 /* we got ourselves a potential winner! */
341 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
342 map_type = ctn->map_type;
343 }
344
345 /* SHA-384 */
346 } else if (!strncmp(ctn->fingerprint, "05", 2)) {
347 if (!digest_sha384) {
348 digest_sha384 = nc_server_tls_sha384(cert);
349 if (!digest_sha384) {
350 ret = -1;
351 goto cleanup;
352 }
353 }
354
355 if (!strcasecmp(ctn->fingerprint + 3, digest_sha384)) {
356 /* we got ourselves a potential winner! */
357 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
358 map_type = ctn->map_type;
359 }
360
361 /* SHA-512 */
362 } else if (!strncmp(ctn->fingerprint, "06", 2)) {
363 if (!digest_sha512) {
364 digest_sha512 = nc_server_tls_sha512(cert);
365 if (!digest_sha512) {
366 ret = -1;
367 goto cleanup;
368 }
369 }
370
371 if (!strcasecmp(ctn->fingerprint + 3, digest_sha512)) {
372 /* we got ourselves a potential winner! */
373 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
374 map_type = ctn->map_type;
375 }
376
377 /* unknown */
378 } else {
379 WRN(NULL, "Unknown fingerprint algorithm used (%s), skipping.", ctn->fingerprint);
380 continue;
381 }
382
383 if (map_type != NC_TLS_CTN_UNKNOWN) {
384 /* found a fingerprint match */
385 if (!(map_type & data->matched_ctns)) {
386 data->matched_ctns |= map_type;
387 data->matched_ctn_type[data->matched_ctn_count++] = map_type;
roman008cfe72024-04-05 12:36:18 +0200388 if (!data->username && (map_type == NC_TLS_CTN_SPECIFIED)) {
roman7ffd2fc2024-05-13 13:48:34 +0200389 data->username = ctn->name;
roman69962562024-04-05 12:33:39 +0200390 }
391 }
392 }
393 }
394
395cleanup:
396 free(digest_md5);
397 free(digest_sha1);
398 free(digest_sha224);
399 free(digest_sha256);
400 free(digest_sha384);
401 free(digest_sha512);
402 return ret;
403}
404
roman69962562024-04-05 12:33:39 +0200405int
romanebc7bba2024-04-15 14:58:39 +0200406nc_server_tls_get_username_from_cert(void *cert, NC_TLS_CTN_MAPTYPE map_type, char **username)
407{
romance435112024-04-23 15:12:09 +0200408 char *subject, *cn, *san_value = NULL, rdn_separator;
romanebc7bba2024-04-15 14:58:39 +0200409 void *sans;
410 int i, nsans = 0, rc;
411 NC_TLS_CTN_MAPTYPE san_type = 0;
412
413#ifdef HAVE_LIBMEDTLS
romance435112024-04-23 15:12:09 +0200414 rdn_separator = ',';
romanebc7bba2024-04-15 14:58:39 +0200415#else
romance435112024-04-23 15:12:09 +0200416 rdn_separator = '/';
romanebc7bba2024-04-15 14:58:39 +0200417#endif
418
419 if (map_type == NC_TLS_CTN_COMMON_NAME) {
420 subject = nc_server_tls_get_subject_wrap(cert);
421 if (!subject) {
422 return -1;
423 }
424
425 cn = strstr(subject, "CN=");
426 if (!cn) {
427 WRN(NULL, "Certificate does not include the commonName field.");
428 free(subject);
429 return 1;
430 }
431
432 /* skip "CN=" */
433 cn += 3;
434 if (strchr(cn, rdn_separator)) {
435 *strchr(cn, rdn_separator) = '\0';
436 }
437 *username = strdup(cn);
438 free(subject);
439 NC_CHECK_ERRMEM_RET(!*username, -1);
440 } else {
441 sans = nc_tls_get_sans_wrap(cert);
442 if (!sans) {
443 WRN(NULL, "Certificate has no SANs or failed to retrieve them.");
444 return 1;
445 }
446 nsans = nc_tls_get_num_sans_wrap(sans);
447
448 for (i = 0; i < nsans; i++) {
449 if ((rc = nc_tls_get_san_value_type_wrap(sans, i, &san_value, &san_type))) {
450 if (rc == -1) {
451 /* fatal error */
452 nc_tls_sans_destroy_wrap(sans);
453 return -1;
454 }
455
456 /* got a type that we dont care about */
457 continue;
458 }
459
460 if ((map_type == NC_TLS_CTN_SAN_ANY) || (map_type == san_type)) {
461 /* found a match */
462 *username = san_value;
463 break;
464 }
465 free(san_value);
466 }
467
468 nc_tls_sans_destroy_wrap(sans);
469
470 if (i == nsans) {
471 switch (map_type) {
472 case NC_TLS_CTN_SAN_RFC822_NAME:
473 WRN(NULL, "Certificate does not include the SAN rfc822Name field.");
474 break;
475 case NC_TLS_CTN_SAN_DNS_NAME:
476 WRN(NULL, "Certificate does not include the SAN dNSName field.");
477 break;
478 case NC_TLS_CTN_SAN_IP_ADDRESS:
479 WRN(NULL, "Certificate does not include the SAN iPAddress field.");
480 break;
481 case NC_TLS_CTN_SAN_ANY:
482 WRN(NULL, "Certificate does not include any relevant SAN fields.");
483 break;
484 default:
485 break;
486 }
487 return 1;
488 }
489 }
490
491 return 0;
492}
493
romance435112024-04-23 15:12:09 +0200494static int
495_nc_server_tls_verify_peer_cert(void *peer_cert, struct nc_cert_grouping *ee_certs)
496{
497 int i, ret;
498 void *cert;
499 struct nc_certificate *certs;
500 uint16_t cert_count;
501
502 if (ee_certs->store == NC_STORE_LOCAL) {
503 /* local definition */
504 certs = ee_certs->certs;
505 cert_count = ee_certs->cert_count;
506 } else {
507 /* truststore reference */
508 if (nc_server_tls_ts_ref_get_certs(ee_certs->ts_ref, &certs, &cert_count)) {
509 ERR(NULL, "Error getting end-entity certificates from the truststore reference \"%s\".", ee_certs->ts_ref);
510 return -1;
511 }
512 }
513
514 for (i = 0; i < cert_count; i++) {
515 /* import stored cert */
516 cert = nc_base64der_to_cert(certs[i].data);
517
518 /* compare stored with received */
519 ret = nc_server_tls_certs_match_wrap(peer_cert, cert);
520 nc_tls_cert_destroy_wrap(cert);
521 if (ret) {
522 /* found a match */
523 VRB(NULL, "Cert verify: fail, but the end-entity certificate is trusted, continuing.");
524 return 0;
525 }
526 }
527
528 return 1;
529}
530
531int
532nc_server_tls_verify_peer_cert(void *peer_cert, struct nc_server_tls_opts *opts)
533{
534 int rc;
535 struct nc_endpt *referenced_endpt;
536
537 rc = _nc_server_tls_verify_peer_cert(peer_cert, &opts->ee_certs);
538 if (!rc) {
539 return 0;
540 }
541
542 if (opts->referenced_endpt_name) {
543 if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
544 ERRINT;
545 return -1;
546 }
547
548 rc = _nc_server_tls_verify_peer_cert(peer_cert, &referenced_endpt->opts.tls->ee_certs);
549 if (!rc) {
550 return 0;
551 }
552 }
553
554 return 1;
555}
556
romanebc7bba2024-04-15 14:58:39 +0200557int
roman7ffd2fc2024-05-13 13:48:34 +0200558nc_server_tls_verify_cert(void *cert, int depth, int trusted, struct nc_tls_verify_cb_data *cb_data)
roman69962562024-04-05 12:33:39 +0200559{
560 int ret = 0, i;
561 char *subject = NULL, *issuer = NULL;
562 struct nc_server_tls_opts *opts = cb_data->opts;
563 struct nc_session *session = cb_data->session;
564 struct nc_endpt *referenced_endpt;
565
roman7ffd2fc2024-05-13 13:48:34 +0200566 if (session->username) {
567 /* already verified */
568 return 0;
569 }
570
roman69962562024-04-05 12:33:39 +0200571 subject = nc_server_tls_get_subject_wrap(cert);
572 issuer = nc_server_tls_get_issuer_wrap(cert);
573 if (!subject || !issuer) {
574 ERR(session, "Failed to get certificate's subject or issuer.");
575 ret = -1;
576 goto cleanup;
577 }
578
579 VRB(session, "Cert verify: depth %d.", depth);
580 VRB(session, "Cert verify: subject: %s.", subject);
581 VRB(session, "Cert verify: issuer: %s.", issuer);
582
583 if (depth == 0) {
roman7ffd2fc2024-05-13 13:48:34 +0200584 if (!trusted) {
roman69962562024-04-05 12:33:39 +0200585 /* peer cert is not trusted, so it must match any configured end-entity cert
romanebc7bba2024-04-15 14:58:39 +0200586 * on the given endpoint in order for the client to be authenticated */
romance435112024-04-23 15:12:09 +0200587 ret = nc_server_tls_verify_peer_cert(cert, opts);
roman69962562024-04-05 12:33:39 +0200588 if (ret) {
romance435112024-04-23 15:12:09 +0200589 ERR(session, "Cert verify: fail (Client certificate not trusted and does not match any configured end-entity certificate).");
590 goto cleanup;
roman69962562024-04-05 12:33:39 +0200591 }
592 }
593 }
594
romanebc7bba2024-04-15 14:58:39 +0200595 /* get matching ctn entries */
roman69962562024-04-05 12:33:39 +0200596 ret = nc_server_tls_cert_to_name(opts->ctn, cert, &cb_data->ctn_data);
597 if (ret == -1) {
598 /* fatal error */
599 goto cleanup;
600 }
601
602 /* check the referenced endpoint's ctn entries */
603 if (opts->referenced_endpt_name) {
604 if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
605 ERRINT;
606 ret = -1;
607 goto cleanup;
608 }
609
610 ret = nc_server_tls_cert_to_name(referenced_endpt->opts.tls->ctn, cert, &cb_data->ctn_data);
611 if (ret == -1) {
612 /* fatal error */
613 goto cleanup;
614 }
615 }
616
romanebc7bba2024-04-15 14:58:39 +0200617 /* obtain username from matched ctn entries */
roman69962562024-04-05 12:33:39 +0200618 if (depth == 0) {
619 for (i = 0; i < cb_data->ctn_data.matched_ctn_count; i++) {
620 if (cb_data->ctn_data.matched_ctn_type[i] == NC_TLS_CTN_SPECIFIED) {
621 session->username = strdup(cb_data->ctn_data.username);
romanebc7bba2024-04-15 14:58:39 +0200622 NC_CHECK_ERRMEM_GOTO(!session->username, ret = -1, cleanup);
roman69962562024-04-05 12:33:39 +0200623 } else {
romanebc7bba2024-04-15 14:58:39 +0200624 ret = nc_server_tls_get_username_from_cert(cert, cb_data->ctn_data.matched_ctn_type[i], &session->username);
roman69962562024-04-05 12:33:39 +0200625 if (ret == -1) {
romanebc7bba2024-04-15 14:58:39 +0200626 /* fatal error */
roman69962562024-04-05 12:33:39 +0200627 goto cleanup;
romanebc7bba2024-04-15 14:58:39 +0200628 } else if (!ret) {
629 /* username obtained */
630 break;
roman69962562024-04-05 12:33:39 +0200631 }
632 }
633 }
romanebc7bba2024-04-15 14:58:39 +0200634 if (session->username) {
635 VRB(NULL, "Cert verify CTN: new client username recognized as \"%s\".", session->username);
636 } else {
637 VRB(NULL, "Cert verify CTN: unsuccessful, dropping the new client.");
638 ret = 1;
639 goto cleanup;
640 }
roman69962562024-04-05 12:33:39 +0200641 }
642
romanebc7bba2024-04-15 14:58:39 +0200643 if (session->username && server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {
roman69962562024-04-05 12:33:39 +0200644 VRB(session, "Cert verify: user verify callback revoked authorization.");
romanebc7bba2024-04-15 14:58:39 +0200645 ret = 1;
roman69962562024-04-05 12:33:39 +0200646 goto cleanup;
647 }
648
649cleanup:
650 free(subject);
651 free(issuer);
652 return ret;
653}
654
655API const void *
656nc_session_get_client_cert(const struct nc_session *session)
657{
658 if (!session || (session->side != NC_SERVER)) {
659 ERRARG(session, "session");
660 return NULL;
661 }
662
663 return session->opts.server.client_cert;
664}
665
666API void
667nc_server_tls_set_verify_clb(int (*verify_clb)(const struct nc_session *session))
668{
669 server_opts.user_verify_clb = verify_clb;
670}
671
672int
673nc_server_tls_load_server_cert_key(struct nc_server_tls_opts *opts, void **srv_cert, void **srv_pkey)
Michal Vasko4c1fb492017-01-30 14:31:07 +0100674{
roman3f9b65c2023-06-05 14:26:58 +0200675 char *privkey_data = NULL, *cert_data = NULL;
roman3f9b65c2023-06-05 14:26:58 +0200676 NC_PRIVKEY_FORMAT privkey_type;
roman69962562024-04-05 12:33:39 +0200677 void *cert = NULL;
678 void *pkey = NULL;
Michal Vasko4c1fb492017-01-30 14:31:07 +0100679
romanebc7bba2024-04-15 14:58:39 +0200680 *srv_cert = *srv_pkey = NULL;
681
roman3f9b65c2023-06-05 14:26:58 +0200682 /* get data needed for setting the server cert */
683 if (opts->store == NC_STORE_LOCAL) {
684 /* local definition */
685 cert_data = opts->cert_data;
686 privkey_data = opts->privkey_data;
687 privkey_type = opts->privkey_type;
Michal Vasko4c1fb492017-01-30 14:31:07 +0100688 } else {
roman3f9b65c2023-06-05 14:26:58 +0200689 /* keystore */
roman69962562024-04-05 12:33:39 +0200690 if (nc_server_tls_ks_ref_get_cert_key(opts->key_ref, opts->cert_ref, &privkey_data, &privkey_type, &cert_data)) {
roman3f9b65c2023-06-05 14:26:58 +0200691 ERR(NULL, "Getting server certificate from the keystore reference \"%s\" failed.", opts->key_ref);
roman69962562024-04-05 12:33:39 +0200692 return 1;
Michal Vasko4c1fb492017-01-30 14:31:07 +0100693 }
694 }
romana55fee02024-03-21 16:00:48 +0100695 if (!cert_data || !privkey_data) {
696 ERR(NULL, "Server certificate not configured.");
romanbc541a82024-04-25 14:56:35 +0200697 return 1;
romana55fee02024-03-21 16:00:48 +0100698 }
Michal Vasko4c1fb492017-01-30 14:31:07 +0100699
roman69962562024-04-05 12:33:39 +0200700 cert = nc_base64der_to_cert(cert_data);
roman3f9b65c2023-06-05 14:26:58 +0200701 if (!cert) {
roman69962562024-04-05 12:33:39 +0200702 return 1;
roman3f9b65c2023-06-05 14:26:58 +0200703 }
704
romanebc7bba2024-04-15 14:58:39 +0200705 pkey = nc_base64der_to_privkey(privkey_data, nc_privkey_format_to_str(privkey_type));
roman3f9b65c2023-06-05 14:26:58 +0200706 if (!pkey) {
roman69962562024-04-05 12:33:39 +0200707 nc_tls_cert_destroy_wrap(cert);
708 return 1;
Michal Vasko4c1fb492017-01-30 14:31:07 +0100709 }
710
roman69962562024-04-05 12:33:39 +0200711 *srv_cert = cert;
712 *srv_pkey = pkey;
roman3f9b65c2023-06-05 14:26:58 +0200713 return 0;
Michal Vasko4c1fb492017-01-30 14:31:07 +0100714}
715
roman3f9b65c2023-06-05 14:26:58 +0200716static size_t
717nc_server_tls_curl_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
718{
719 struct nc_curl_data *data;
720
721 size = nmemb;
722
723 data = (struct nc_curl_data *)userdata;
724
725 data->data = nc_realloc(data->data, data->size + size);
roman3a95bb22023-10-26 11:07:17 +0200726 NC_CHECK_ERRMEM_RET(!data->data, 0);
roman3f9b65c2023-06-05 14:26:58 +0200727
728 memcpy(&data->data[data->size], ptr, size);
729 data->size += size;
730
731 return size;
732}
733
734static int
roman69962562024-04-05 12:33:39 +0200735nc_server_tls_curl_fetch(CURL *handle, const char *url)
roman3f9b65c2023-06-05 14:26:58 +0200736{
737 char err_buf[CURL_ERROR_SIZE];
738
739 /* set uri */
740 if (curl_easy_setopt(handle, CURLOPT_URL, url)) {
roman69962562024-04-05 12:33:39 +0200741 ERR(NULL, "Setting URI \"%s\" to download CRL from failed.", url);
romanebc7bba2024-04-15 14:58:39 +0200742 return 1;
roman3f9b65c2023-06-05 14:26:58 +0200743 }
744
745 /* set err buf */
roman134783b2023-11-09 12:41:45 +0100746 if (curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, err_buf)) {
roman69962562024-04-05 12:33:39 +0200747 ERR(NULL, "Setting CURL error buffer option failed.");
romanebc7bba2024-04-15 14:58:39 +0200748 return 1;
roman134783b2023-11-09 12:41:45 +0100749 }
roman3f9b65c2023-06-05 14:26:58 +0200750
751 /* download */
752 if (curl_easy_perform(handle)) {
roman69962562024-04-05 12:33:39 +0200753 ERR(NULL, "Downloading CRL from \"%s\" failed (%s).", url, err_buf);
romanebc7bba2024-04-15 14:58:39 +0200754 return 1;
roman3f9b65c2023-06-05 14:26:58 +0200755 }
756
757 return 0;
758}
759
760static int
roman69962562024-04-05 12:33:39 +0200761nc_server_tls_curl_init(CURL **handle, struct nc_curl_data *data)
762{
763 NC_CHECK_ARG_RET(NULL, handle, data, -1);
764
765 *handle = NULL;
766
767 *handle = curl_easy_init();
768 if (!*handle) {
769 ERR(NULL, "Initializing CURL failed.");
romanebc7bba2024-04-15 14:58:39 +0200770 return 1;
roman69962562024-04-05 12:33:39 +0200771 }
772
773 if (curl_easy_setopt(*handle, CURLOPT_WRITEFUNCTION, nc_server_tls_curl_cb)) {
774 ERR(NULL, "Setting curl callback failed.");
romanebc7bba2024-04-15 14:58:39 +0200775 return 1;
roman69962562024-04-05 12:33:39 +0200776 }
777
778 if (curl_easy_setopt(*handle, CURLOPT_WRITEDATA, data)) {
779 ERR(NULL, "Setting curl callback data failed.");
romanebc7bba2024-04-15 14:58:39 +0200780 return 1;
roman69962562024-04-05 12:33:39 +0200781 }
782
783 return 0;
784}
785
786static int
romance435112024-04-23 15:12:09 +0200787nc_server_tls_crl_path(const char *path, void *crl_store)
roman3f9b65c2023-06-05 14:26:58 +0200788{
romance435112024-04-23 15:12:09 +0200789 return nc_tls_import_crl_path_wrap(path, crl_store);
roman3f9b65c2023-06-05 14:26:58 +0200790}
791
792static int
romance435112024-04-23 15:12:09 +0200793nc_server_tls_crl_url(const char *url, void *crl_store)
roman3f9b65c2023-06-05 14:26:58 +0200794{
795 int ret = 0;
796 CURL *handle = NULL;
797 struct nc_curl_data downloaded = {0};
798
799 /* init curl */
roman69962562024-04-05 12:33:39 +0200800 ret = nc_server_tls_curl_init(&handle, &downloaded);
roman3f9b65c2023-06-05 14:26:58 +0200801 if (ret) {
802 goto cleanup;
803 }
804
roman69962562024-04-05 12:33:39 +0200805 VRB(NULL, "Downloading CRL from \"%s\".", url);
roman3f9b65c2023-06-05 14:26:58 +0200806
807 /* download the CRL */
roman69962562024-04-05 12:33:39 +0200808 ret = nc_server_tls_curl_fetch(handle, url);
roman3f9b65c2023-06-05 14:26:58 +0200809 if (ret) {
810 goto cleanup;
811 }
812
813 /* convert the downloaded data to CRL and add it to the store */
romance435112024-04-23 15:12:09 +0200814 ret = nc_server_tls_add_crl_to_store_wrap(downloaded.data, downloaded.size, crl_store);
roman3f9b65c2023-06-05 14:26:58 +0200815 if (ret) {
816 goto cleanup;
817 }
818
819cleanup:
820 curl_easy_cleanup(handle);
821 return ret;
822}
823
romanebc7bba2024-04-15 14:58:39 +0200824static int
825nc_server_tls_crl_cert_ext(void *cert_store, void *crl_store)
826{
827 int ret = 0;
828 CURL *handle = NULL;
829 struct nc_curl_data downloaded = {0};
830 char **uris = NULL;
831 int uri_count = 0, i;
832
833 /* init curl */
834 ret = nc_server_tls_curl_init(&handle, &downloaded);
835 if (ret) {
836 goto cleanup;
837 }
838
839 /* get all the uris we can, even though some may point to the same CRL */
840 ret = nc_server_tls_get_crl_distpoint_uris_wrap(cert_store, &uris, &uri_count);
841 if (ret) {
842 goto cleanup;
843 }
844
845 for (i = 0; i < uri_count; i++) {
846 VRB(NULL, "Downloading CRL from \"%s\".", uris[i]);
847 ret = nc_server_tls_curl_fetch(handle, uris[i]);
848 if (ret) {
849 /* failed to download the CRL from this entry, try the next entry */
850 WRN(NULL, "Failed to fetch CRL from \"%s\".", uris[i]);
851 continue;
852 }
853
854 /* convert the downloaded data to CRL and add it to the store */
romance435112024-04-23 15:12:09 +0200855 ret = nc_server_tls_add_crl_to_store_wrap(downloaded.data, downloaded.size, crl_store);
romanebc7bba2024-04-15 14:58:39 +0200856 if (ret) {
857 goto cleanup;
858 }
859 }
860
861cleanup:
862 for (i = 0; i < uri_count; i++) {
863 free(uris[i]);
864 }
865 free(uris);
866 curl_easy_cleanup(handle);
867 return ret;
868}
869
roman69962562024-04-05 12:33:39 +0200870int
871nc_server_tls_load_crl(struct nc_server_tls_opts *opts, void *cert_store, void *crl_store)
roman3f9b65c2023-06-05 14:26:58 +0200872{
roman3f9b65c2023-06-05 14:26:58 +0200873 if (opts->crl_path) {
romance435112024-04-23 15:12:09 +0200874 if (nc_server_tls_crl_path(opts->crl_path, crl_store)) {
roman69962562024-04-05 12:33:39 +0200875 return 1;
roman3f9b65c2023-06-05 14:26:58 +0200876 }
877 } else if (opts->crl_url) {
romance435112024-04-23 15:12:09 +0200878 if (nc_server_tls_crl_url(opts->crl_url, crl_store)) {
roman69962562024-04-05 12:33:39 +0200879 return 1;
roman3f9b65c2023-06-05 14:26:58 +0200880 }
881 } else {
roman69962562024-04-05 12:33:39 +0200882 if (nc_server_tls_crl_cert_ext(cert_store, crl_store)) {
883 return 1;
roman3f9b65c2023-06-05 14:26:58 +0200884 }
885 }
886
887 return 0;
roman69962562024-04-05 12:33:39 +0200888}
roman3f9b65c2023-06-05 14:26:58 +0200889
roman69962562024-04-05 12:33:39 +0200890int
891nc_server_tls_load_trusted_certs(struct nc_cert_grouping *ca_certs, void *cert_store)
892{
893 struct nc_certificate *certs;
894 uint16_t i, cert_count;
romance435112024-04-23 15:12:09 +0200895 void *cert;
roman69962562024-04-05 12:33:39 +0200896
897 if (ca_certs->store == NC_STORE_LOCAL) {
898 /* local definition */
899 certs = ca_certs->certs;
900 cert_count = ca_certs->cert_count;
901 } else {
902 /* truststore */
903 if (nc_server_tls_ts_ref_get_certs(ca_certs->ts_ref, &certs, &cert_count)) {
904 ERR(NULL, "Error getting certificate-authority certificates from the truststore reference \"%s\".", ca_certs->ts_ref);
905 return 1;
906 }
907 }
908
909 for (i = 0; i < cert_count; i++) {
romance435112024-04-23 15:12:09 +0200910 /* parse data into cert */
911 cert = nc_base64der_to_cert(certs[i].data);
912 if (!cert) {
913 return 1;
914 }
915
916 /* store cert in cert store */
917 if (nc_tls_add_cert_to_store_wrap(cert, cert_store)) {
918 nc_tls_cert_destroy_wrap(cert);
roman69962562024-04-05 12:33:39 +0200919 return 1;
920 }
921 }
922
923 return 0;
roman3f9b65c2023-06-05 14:26:58 +0200924}
925
926static int
roman69962562024-04-05 12:33:39 +0200927nc_server_tls_accept_check(int accept_ret, void *tls_session)
Michal Vasko9af52322022-07-25 14:39:30 +0200928{
roman69962562024-04-05 12:33:39 +0200929 uint32_t verify;
romanebc7bba2024-04-15 14:58:39 +0200930 char *err;
Michal Vasko9af52322022-07-25 14:39:30 +0200931
932 /* check certificate verification result */
roman69962562024-04-05 12:33:39 +0200933 verify = nc_tls_get_verify_result_wrap(tls_session);
roman008cfe72024-04-05 12:36:18 +0200934 if (!verify && (accept_ret == 1)) {
roman69962562024-04-05 12:33:39 +0200935 VRB(NULL, "Client certificate verified.");
romanebc7bba2024-04-15 14:58:39 +0200936 } else if (verify) {
937 err = nc_tls_verify_error_string_wrap(verify);
938 ERR(NULL, "Client certificate error (%s).", err);
939 free(err);
Michal Vasko9af52322022-07-25 14:39:30 +0200940 }
941
942 if (accept_ret != 1) {
romance435112024-04-23 15:12:09 +0200943 nc_server_tls_print_accept_err_wrap(accept_ret, tls_session);
Michal Vasko9af52322022-07-25 14:39:30 +0200944 }
945
946 return accept_ret;
947}
948
Michal Vasko3031aae2016-01-27 16:07:18 +0100949int
roman3f9b65c2023-06-05 14:26:58 +0200950nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opts, int sock, int timeout)
Michal Vasko3031aae2016-01-27 16:07:18 +0100951{
roman69962562024-04-05 12:33:39 +0200952 int rc, timeouted = 0;
roman6ece9c52022-06-22 09:29:17 +0200953 struct timespec ts_timeout;
roman69962562024-04-05 12:33:39 +0200954 struct nc_tls_verify_cb_data cb_data = {0};
955 struct nc_endpt *referenced_endpt;
956 void *tls_cfg, *srv_cert, *srv_pkey, *cert_store, *crl_store;
Michal Vaskoc61c4492016-01-25 11:13:34 +0100957
roman69962562024-04-05 12:33:39 +0200958 tls_cfg = srv_cert = srv_pkey = cert_store = crl_store = NULL;
roman3f9b65c2023-06-05 14:26:58 +0200959
roman69962562024-04-05 12:33:39 +0200960 /* set verify cb data */
961 cb_data.session = session;
962 cb_data.opts = opts;
Michal Vaskoe2713da2016-08-22 16:06:40 +0200963
roman69962562024-04-05 12:33:39 +0200964 /* prepare TLS context from which a session will be created */
romance435112024-04-23 15:12:09 +0200965 tls_cfg = nc_tls_config_new_wrap(NC_SERVER);
roman69962562024-04-05 12:33:39 +0200966 if (!tls_cfg) {
967 goto fail;
roman3f9b65c2023-06-05 14:26:58 +0200968 }
969
roman69962562024-04-05 12:33:39 +0200970 /* opaque CA/CRL certificate store */
971 cert_store = nc_tls_cert_store_new_wrap();
972 if (!cert_store) {
973 goto fail;
974 }
975
976 /* load server's key and certificate */
977 if (nc_server_tls_load_server_cert_key(opts, &srv_cert, &srv_pkey)) {
978 ERR(session, "Loading server certificate and/or private key failed.");
979 goto fail;
980 }
981
982 /* load trusted CA certificates */
983 if (nc_server_tls_load_trusted_certs(&opts->ca_certs, cert_store)) {
984 ERR(session, "Loading server CA certs failed.");
985 goto fail;
986 }
987
988 /* load referenced endpoint's trusted CA certs if set */
roman78df0fa2023-11-02 10:33:57 +0100989 if (opts->referenced_endpt_name) {
romanebc7bba2024-04-15 14:58:39 +0200990 if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
991 ERR(session, "Referenced endpoint \"%s\" not found.", opts->referenced_endpt_name);
992 goto fail;
993 }
994
roman69962562024-04-05 12:33:39 +0200995 if (nc_server_tls_load_trusted_certs(&referenced_endpt->opts.tls->ca_certs, cert_store)) {
996 ERR(session, "Loading server CA certs from referenced endpoint failed.");
997 goto fail;
Michal Vaskoe2713da2016-08-22 16:06:40 +0200998 }
roman3f9b65c2023-06-05 14:26:58 +0200999 }
Michal Vaskoe2713da2016-08-22 16:06:40 +02001000
roman3f9b65c2023-06-05 14:26:58 +02001001 if (opts->crl_path || opts->crl_url || opts->crl_cert_ext) {
roman69962562024-04-05 12:33:39 +02001002 /* opaque CRL store */
1003 crl_store = nc_tls_crl_store_new_wrap();
1004 if (!crl_store) {
1005 goto fail;
1006 }
1007
1008 /* load CRLs into one of the stores */
1009 if (nc_server_tls_load_crl(opts, cert_store, crl_store)) {
1010 ERR(session, "Loading server CRL failed.");
1011 goto fail;
Michal Vaskoe2713da2016-08-22 16:06:40 +02001012 }
1013 }
1014
roman69962562024-04-05 12:33:39 +02001015 /* set supported TLS versions */
roman3f9b65c2023-06-05 14:26:58 +02001016 if (opts->tls_versions) {
roman69962562024-04-05 12:33:39 +02001017 if (nc_server_tls_set_tls_versions_wrap(tls_cfg, opts->tls_versions)) {
1018 ERR(session, "Setting supported server TLS versions failed.");
1019 goto fail;
roman3f9b65c2023-06-05 14:26:58 +02001020 }
1021 }
1022
romanebc7bba2024-04-15 14:58:39 +02001023 /* set supported cipher suites */
1024 if (opts->ciphers) {
1025 nc_server_tls_set_cipher_suites_wrap(tls_cfg, opts->ciphers);
1026 }
1027
romance435112024-04-23 15:12:09 +02001028 /* set verify flags, callback and its data */
1029 nc_server_tls_set_verify_wrap(tls_cfg, &cb_data);
1030
roman69962562024-04-05 12:33:39 +02001031 /* init TLS context and store data which may be needed later in it */
romance435112024-04-23 15:12:09 +02001032 if (nc_tls_init_ctx_wrap(sock, srv_cert, srv_pkey, cert_store, crl_store, &session->ti.tls.ctx)) {
roman69962562024-04-05 12:33:39 +02001033 goto fail;
roman3f9b65c2023-06-05 14:26:58 +02001034 }
1035
roman69962562024-04-05 12:33:39 +02001036 /* memory is managed by context now */
1037 srv_cert = srv_pkey = cert_store = crl_store = NULL;
1038
1039 /* setup config from ctx */
romance435112024-04-23 15:12:09 +02001040 if (nc_tls_setup_config_from_ctx_wrap(&session->ti.tls.ctx, NC_SERVER, tls_cfg)) {
roman69962562024-04-05 12:33:39 +02001041 goto fail;
romance435112024-04-23 15:12:09 +02001042 }
romanebc7bba2024-04-15 14:58:39 +02001043 session->ti.tls.config = tls_cfg;
1044 tls_cfg = NULL;
roman69962562024-04-05 12:33:39 +02001045
1046 /* fill session data and create TLS session from config */
romanebc7bba2024-04-15 14:58:39 +02001047 session->ti_type = NC_TI_TLS;
1048 if (!(session->ti.tls.session = nc_tls_session_new_wrap(session->ti.tls.config))) {
roman69962562024-04-05 12:33:39 +02001049 goto fail;
1050 }
roman69962562024-04-05 12:33:39 +02001051
roman69962562024-04-05 12:33:39 +02001052 /* set session fd */
1053 nc_server_tls_set_fd_wrap(session->ti.tls.session, sock, &session->ti.tls.ctx);
1054
Michal Vaskoe2713da2016-08-22 16:06:40 +02001055 sock = -1;
Michal Vaskoc14e3c82016-01-11 16:14:30 +01001056
roman69962562024-04-05 12:33:39 +02001057 /* do the handshake */
Michal Vasko36c7be82017-02-22 13:37:59 +01001058 if (timeout > -1) {
Michal Vaskod8a74192023-02-06 15:51:50 +01001059 nc_timeouttime_get(&ts_timeout, timeout);
Michal Vasko36c7be82017-02-22 13:37:59 +01001060 }
roman69962562024-04-05 12:33:39 +02001061 while ((rc = nc_server_tls_handshake_step_wrap(session->ti.tls.session)) == 0) {
Michal Vasko0190bc32016-03-02 15:47:49 +01001062 usleep(NC_TIMEOUT_STEP);
Michal Vaskod8a74192023-02-06 15:51:50 +01001063 if ((timeout > -1) && (nc_timeouttime_cur_diff(&ts_timeout) < 1)) {
roman69962562024-04-05 12:33:39 +02001064 ERR(session, "TLS accept timeout.");
1065 timeouted = 1;
1066 goto fail;
Michal Vasko0190bc32016-03-02 15:47:49 +01001067 }
1068 }
roman69962562024-04-05 12:33:39 +02001069
1070 /* check if handshake was ok */
1071 if (nc_server_tls_accept_check(rc, session->ti.tls.session) != 1) {
1072 goto fail;
Michal Vaskoc14e3c82016-01-11 16:14:30 +01001073 }
1074
Michal Vasko1a38c862016-01-15 15:50:07 +01001075 return 1;
Michal Vaskoe2713da2016-08-22 16:06:40 +02001076
roman69962562024-04-05 12:33:39 +02001077fail:
Michal Vaskoe2713da2016-08-22 16:06:40 +02001078 if (sock > -1) {
1079 close(sock);
1080 }
roman69962562024-04-05 12:33:39 +02001081
romanebc7bba2024-04-15 14:58:39 +02001082 nc_tls_config_destroy_wrap(tls_cfg);
1083 nc_tls_cert_destroy_wrap(srv_cert);
1084 nc_tls_privkey_destroy_wrap(srv_pkey);
1085 nc_tls_cert_store_destroy_wrap(cert_store);
1086 nc_tls_crl_store_destroy_wrap(crl_store);
roman69962562024-04-05 12:33:39 +02001087
1088 if (timeouted) {
1089 return 0;
1090 } else {
1091 return -1;
1092 }
Michal Vasko9e036d52016-01-08 10:49:26 +01001093}