/**
 * @file session_server_tls.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @author Roman Janota <janota@cesnet.cz>
 * @brief libnetconf2 TLS server session manipulation functions
 *
 * @copyright
 * Copyright (c) 2015 - 2023 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE

#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <curl/curl.h>

#include "compat.h"
#include "config.h"
#include "log_p.h"
#include "session.h"
#include "session_p.h"
#include "session_wrapper.h"

struct nc_server_tls_opts tls_ch_opts;
extern struct nc_server_opts server_opts;

static int
nc_server_tls_ks_ref_get_cert_key(const char *referenced_key_name, const char *referenced_cert_name,
        char **privkey_data, NC_PRIVKEY_FORMAT *privkey_type, char **cert_data)
{
    uint16_t i, j;
    struct nc_keystore *ks = &server_opts.keystore;

    *privkey_data = NULL;
    *cert_data = NULL;

    /* lookup name */
    for (i = 0; i < ks->asym_key_count; i++) {
        if (!strcmp(referenced_key_name, ks->asym_keys[i].name)) {
            break;
        }
    }
    if (i == ks->asym_key_count) {
        ERR(NULL, "Keystore entry \"%s\" not found.", referenced_key_name);
        return -1;
    }

    for (j = 0; j < ks->asym_keys[i].cert_count; j++) {
        if (!strcmp(referenced_cert_name, ks->asym_keys[i].certs[j].name)) {
            break;
        }
    }
    if (j == ks->asym_keys[i].cert_count) {
        ERR(NULL, "Keystore certificate entry \"%s\" associated with the key \"%s\" not found.",
                referenced_cert_name, referenced_key_name);
        return -1;
    }

    *privkey_data = ks->asym_keys[i].privkey_data;
    *privkey_type = ks->asym_keys[i].privkey_type;
    *cert_data = ks->asym_keys[i].certs[j].data;
    return 0;
}

static int
nc_server_tls_ts_ref_get_certs(const char *referenced_name, struct nc_certificate **certs, uint16_t *cert_count)
{
    uint16_t i;
    struct nc_truststore *ts = &server_opts.truststore;

    *certs = NULL;
    *cert_count = 0;

    /* lookup name */
    for (i = 0; i < ts->cert_bag_count; i++) {
        if (!strcmp(referenced_name, ts->cert_bags[i].name)) {
            break;
        }
    }

    if (i == ts->cert_bag_count) {
        ERR(NULL, "Truststore entry \"%s\" not found.", referenced_name);
        return -1;
    }

    *certs = ts->cert_bags[i].certs;
    *cert_count = ts->cert_bags[i].cert_count;
    return 0;
}

static void *
nc_base64der_to_cert(const char *in)
{
    char *buf = NULL;
    void *cert;

    NC_CHECK_ARG_RET(NULL, in, NULL);

    if (asprintf(&buf, "%s%s%s", "-----BEGIN CERTIFICATE-----\n", in, "\n-----END CERTIFICATE-----") == -1) {
        ERRMEM;
        return NULL;
    }

    cert = nc_tls_pem_to_cert_wrap(buf);
    free(buf);
    return cert;
}

static void *
nc_base64der_to_privkey(const char *in, const char *key_str)
{
    char *buf = NULL;
    void *pkey;

    NC_CHECK_ARG_RET(NULL, in, NULL);

    if (asprintf(&buf, "%s%s%s%s%s%s%s", "-----BEGIN", key_str, "PRIVATE KEY-----\n", in, "\n-----END",
            key_str, "PRIVATE KEY-----") == -1) {
        ERRMEM;
        return NULL;
    }

    pkey = nc_tls_pem_to_privkey_wrap(buf);
    free(buf);
    return pkey;
}

static char *
nc_server_tls_digest_to_hex(const unsigned char *digest, unsigned int digest_len)
{
    unsigned int i;
    char *hex;

    hex = malloc(digest_len * 3);
    NC_CHECK_ERRMEM_RET(!hex, NULL);

    for (i = 0; i < digest_len - 1; ++i) {
        sprintf(hex + (i * 3), "%02x:", digest[i]);
    }
    sprintf(hex + (i * 3), "%02x", digest[i]);

    return hex;
}

static char *
nc_server_tls_md5(void *cert)
{
    int rc;
    unsigned int buf_len = 16;
    unsigned char buf[buf_len];

    /* compute MD-5 hash of cert and store it in buf */
    rc = nc_server_tls_md5_wrap(cert, buf);
    if (rc) {
        return NULL;
    }

    /* convert the hash to hex */
    return nc_server_tls_digest_to_hex(buf, buf_len);
}

static char *
nc_server_tls_sha1(void *cert)
{
    int rc;
    unsigned int buf_len = 20;
    unsigned char buf[buf_len];

    /* compute SHA-1 hash of cert and store it in buf */
    rc = nc_server_tls_sha1_wrap(cert, buf);
    if (rc) {
        return NULL;
    }

    /* convert the hash to hex */
    return nc_server_tls_digest_to_hex(buf, buf_len);
}

static char *
nc_server_tls_sha224(void *cert)
{
    int rc;
    unsigned int buf_len = 28;
    unsigned char buf[buf_len];

    /* compute SHA-224 hash of cert and store it in buf */
    rc = nc_server_tls_sha224_wrap(cert, buf);
    if (rc) {
        return NULL;
    }

    /* convert the hash to hex */
    return nc_server_tls_digest_to_hex(buf, buf_len);
}

static char *
nc_server_tls_sha256(void *cert)
{
    int rc;
    unsigned int buf_len = 32;
    unsigned char buf[buf_len];

    /* compute SHA-256 hash of cert and store it in buf */
    rc = nc_server_tls_sha256_wrap(cert, buf);
    if (rc) {
        return NULL;
    }

    /* convert the hash to hex */
    return nc_server_tls_digest_to_hex(buf, buf_len);
}

static char *
nc_server_tls_sha384(void *cert)
{
    int rc;
    unsigned int buf_len = 48;
    unsigned char buf[buf_len];

    /* compute SHA-384 hash of cert and store it in buf */
    rc = nc_server_tls_sha384_wrap(cert, buf);
    if (rc) {
        return NULL;
    }

    /* convert the hash to hex */
    return nc_server_tls_digest_to_hex(buf, buf_len);
}

static char *
nc_server_tls_sha512(void *cert)
{
    int rc;
    unsigned int buf_len = 64;
    unsigned char buf[buf_len];

    /* compute SHA-512 hash of cert and store it in buf */
    rc = nc_server_tls_sha512_wrap(cert, buf);
    if (rc) {
        return NULL;
    }

    /* convert the hash to hex */
    return nc_server_tls_digest_to_hex(buf, buf_len);
}

static int
nc_server_tls_cert_to_name(struct nc_ctn *ctn_first, void *cert, struct nc_ctn_data *data)
{
    int ret = 0;
    char *digest_md5 = NULL, *digest_sha1 = NULL, *digest_sha224 = NULL;
    char *digest_sha256 = NULL, *digest_sha384 = NULL, *digest_sha512 = NULL;
    struct nc_ctn *ctn;
    NC_TLS_CTN_MAPTYPE map_type;

    for (ctn = ctn_first; ctn; ctn = ctn->next) {
        /* reset map_type */
        map_type = NC_TLS_CTN_UNKNOWN;

        /* first make sure the entry is valid */
        if (!ctn->map_type || ((ctn->map_type == NC_TLS_CTN_SPECIFIED) && !ctn->name)) {
            VRB(NULL, "Cert verify CTN: entry with id %u not valid, skipping.", ctn->id);
            continue;
        }

        /* if ctn has no fingerprint, it will match any certificate */
        if (!ctn->fingerprint) {
            map_type = ctn->map_type;

            /* MD5 */
        } else if (!strncmp(ctn->fingerprint, "01", 2)) {
            if (!digest_md5) {
                digest_md5 = nc_server_tls_md5(cert);
                if (!digest_md5) {
                    ret = -1;
                    goto cleanup;
                }
            }

            if (!strcasecmp(ctn->fingerprint + 3, digest_md5)) {
                /* we got ourselves a potential winner! */
                VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }

            /* SHA-1 */
        } else if (!strncmp(ctn->fingerprint, "02", 2)) {
            if (!digest_sha1) {
                digest_sha1 = nc_server_tls_sha1(cert);
                if (!digest_sha1) {
                    ret = -1;
                    goto cleanup;
                }
            }

            if (!strcasecmp(ctn->fingerprint + 3, digest_sha1)) {
                /* we got ourselves a potential winner! */
                VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }

            /* SHA-224 */
        } else if (!strncmp(ctn->fingerprint, "03", 2)) {
            if (!digest_sha224) {
                digest_sha224 = nc_server_tls_sha224(cert);
                if (!digest_sha224) {
                    ret = -1;
                    goto cleanup;
                }
            }

            if (!strcasecmp(ctn->fingerprint + 3, digest_sha224)) {
                /* we got ourselves a potential winner! */
                VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }

            /* SHA-256 */
        } else if (!strncmp(ctn->fingerprint, "04", 2)) {
            if (!digest_sha256) {
                digest_sha256 = nc_server_tls_sha256(cert);
                if (!digest_sha256) {
                    ret = -1;
                    goto cleanup;
                }
            }

            if (!strcasecmp(ctn->fingerprint + 3, digest_sha256)) {
                /* we got ourselves a potential winner! */
                VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }

            /* SHA-384 */
        } else if (!strncmp(ctn->fingerprint, "05", 2)) {
            if (!digest_sha384) {
                digest_sha384 = nc_server_tls_sha384(cert);
                if (!digest_sha384) {
                    ret = -1;
                    goto cleanup;
                }
            }

            if (!strcasecmp(ctn->fingerprint + 3, digest_sha384)) {
                /* we got ourselves a potential winner! */
                VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }

            /* SHA-512 */
        } else if (!strncmp(ctn->fingerprint, "06", 2)) {
            if (!digest_sha512) {
                digest_sha512 = nc_server_tls_sha512(cert);
                if (!digest_sha512) {
                    ret = -1;
                    goto cleanup;
                }
            }

            if (!strcasecmp(ctn->fingerprint + 3, digest_sha512)) {
                /* we got ourselves a potential winner! */
                VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }

            /* unknown */
        } else {
            WRN(NULL, "Unknown fingerprint algorithm used (%s), skipping.", ctn->fingerprint);
            continue;
        }

        if (map_type != NC_TLS_CTN_UNKNOWN) {
            /* found a fingerprint match */
            if (!(map_type & data->matched_ctns)) {
                data->matched_ctns |= map_type;
                data->matched_ctn_type[data->matched_ctn_count++] = map_type;
                if (!data->username && (map_type == NC_TLS_CTN_SPECIFIED)) {
                    data->username = ctn->name;
                }
            }
        }
    }

cleanup:
    free(digest_md5);
    free(digest_sha1);
    free(digest_sha224);
    free(digest_sha256);
    free(digest_sha384);
    free(digest_sha512);
    return ret;
}

int
nc_server_tls_get_username_from_cert(void *cert, NC_TLS_CTN_MAPTYPE map_type, char **username)
{
    char *subject, *cn, *san_value = NULL, rdn_separator;
    void *sans;
    int i, nsans = 0, rc;
    NC_TLS_CTN_MAPTYPE san_type = 0;

#ifdef HAVE_LIBMEDTLS
    rdn_separator = ',';
#else
    rdn_separator = '/';
#endif

    if (map_type == NC_TLS_CTN_COMMON_NAME) {
        subject = nc_server_tls_get_subject_wrap(cert);
        if (!subject) {
            return -1;
        }

        cn = strstr(subject, "CN=");
        if (!cn) {
            WRN(NULL, "Certificate does not include the commonName field.");
            free(subject);
            return 1;
        }

        /* skip "CN=" */
        cn += 3;
        if (strchr(cn, rdn_separator)) {
            *strchr(cn, rdn_separator) = '\0';
        }
        *username = strdup(cn);
        free(subject);
        NC_CHECK_ERRMEM_RET(!*username, -1);
    } else {
        sans = nc_tls_get_sans_wrap(cert);
        if (!sans) {
            WRN(NULL, "Certificate has no SANs or failed to retrieve them.");
            return 1;
        }
        nsans = nc_tls_get_num_sans_wrap(sans);

        for (i = 0; i < nsans; i++) {
            if ((rc = nc_tls_get_san_value_type_wrap(sans, i, &san_value, &san_type))) {
                if (rc == -1) {
                    /* fatal error */
                    nc_tls_sans_destroy_wrap(sans);
                    return -1;
                }

                /* got a type that we dont care about */
                continue;
            }

            if ((map_type == NC_TLS_CTN_SAN_ANY) || (map_type == san_type)) {
                /* found a match */
                *username = san_value;
                break;
            }
            free(san_value);
        }

        nc_tls_sans_destroy_wrap(sans);

        if (i == nsans) {
            switch (map_type) {
            case NC_TLS_CTN_SAN_RFC822_NAME:
                WRN(NULL, "Certificate does not include the SAN rfc822Name field.");
                break;
            case NC_TLS_CTN_SAN_DNS_NAME:
                WRN(NULL, "Certificate does not include the SAN dNSName field.");
                break;
            case NC_TLS_CTN_SAN_IP_ADDRESS:
                WRN(NULL, "Certificate does not include the SAN iPAddress field.");
                break;
            case NC_TLS_CTN_SAN_ANY:
                WRN(NULL, "Certificate does not include any relevant SAN fields.");
                break;
            default:
                break;
            }
            return 1;
        }
    }

    return 0;
}

static int
_nc_server_tls_verify_peer_cert(void *peer_cert, struct nc_cert_grouping *ee_certs)
{
    int i, ret;
    void *cert;
    struct nc_certificate *certs;
    uint16_t cert_count;

    if (ee_certs->store == NC_STORE_LOCAL) {
        /* local definition */
        certs = ee_certs->certs;
        cert_count = ee_certs->cert_count;
    } else {
        /* truststore reference */
        if (nc_server_tls_ts_ref_get_certs(ee_certs->ts_ref, &certs, &cert_count)) {
            ERR(NULL, "Error getting end-entity certificates from the truststore reference \"%s\".", ee_certs->ts_ref);
            return -1;
        }
    }

    for (i = 0; i < cert_count; i++) {
        /* import stored cert */
        cert = nc_base64der_to_cert(certs[i].data);

        /* compare stored with received */
        ret = nc_server_tls_certs_match_wrap(peer_cert, cert);
        nc_tls_cert_destroy_wrap(cert);
        if (ret) {
            /* found a match */
            VRB(NULL, "Cert verify: fail, but the end-entity certificate is trusted, continuing.");
            return 0;
        }
    }

    return 1;
}

int
nc_server_tls_verify_peer_cert(void *peer_cert, struct nc_server_tls_opts *opts)
{
    int rc;
    struct nc_endpt *referenced_endpt;

    rc = _nc_server_tls_verify_peer_cert(peer_cert, &opts->ee_certs);
    if (!rc) {
        return 0;
    }

    if (opts->referenced_endpt_name) {
        if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
            ERRINT;
            return -1;
        }

        rc = _nc_server_tls_verify_peer_cert(peer_cert, &referenced_endpt->opts.tls->ee_certs);
        if (!rc) {
            return 0;
        }
    }

    return 1;
}

int
nc_server_tls_verify_cert(void *cert, int depth, int trusted, struct nc_tls_verify_cb_data *cb_data)
{
    int ret = 0, i;
    char *subject = NULL, *issuer = NULL;
    struct nc_server_tls_opts *opts = cb_data->opts;
    struct nc_session *session = cb_data->session;
    struct nc_endpt *referenced_endpt;

    if (session->username) {
        /* already verified */
        return 0;
    }

    subject = nc_server_tls_get_subject_wrap(cert);
    issuer = nc_server_tls_get_issuer_wrap(cert);
    if (!subject || !issuer) {
        ERR(session, "Failed to get certificate's subject or issuer.");
        ret = -1;
        goto cleanup;
    }

    VRB(session, "Cert verify: depth %d.", depth);
    VRB(session, "Cert verify: subject: %s.", subject);
    VRB(session, "Cert verify: issuer: %s.", issuer);

    if (depth == 0) {
        if (!trusted) {
            /* peer cert is not trusted, so it must match any configured end-entity cert
             * on the given endpoint in order for the client to be authenticated */
            ret = nc_server_tls_verify_peer_cert(cert, opts);
            if (ret) {
                ERR(session, "Cert verify: fail (Client certificate not trusted and does not match any configured end-entity certificate).");
                goto cleanup;
            }
        }
    }

    /* get matching ctn entries */
    ret = nc_server_tls_cert_to_name(opts->ctn, cert, &cb_data->ctn_data);
    if (ret == -1) {
        /* fatal error */
        goto cleanup;
    }

    /* check the referenced endpoint's ctn entries */
    if (opts->referenced_endpt_name) {
        if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
            ERRINT;
            ret = -1;
            goto cleanup;
        }

        ret = nc_server_tls_cert_to_name(referenced_endpt->opts.tls->ctn, cert, &cb_data->ctn_data);
        if (ret == -1) {
            /* fatal error */
            goto cleanup;
        }
    }

    /* obtain username from matched ctn entries */
    if (depth == 0) {
        for (i = 0; i < cb_data->ctn_data.matched_ctn_count; i++) {
            if (cb_data->ctn_data.matched_ctn_type[i] == NC_TLS_CTN_SPECIFIED) {
                session->username = strdup(cb_data->ctn_data.username);
                NC_CHECK_ERRMEM_GOTO(!session->username, ret = -1, cleanup);
            } else {
                ret = nc_server_tls_get_username_from_cert(cert, cb_data->ctn_data.matched_ctn_type[i], &session->username);
                if (ret == -1) {
                    /* fatal error */
                    goto cleanup;
                } else if (!ret) {
                    /* username obtained */
                    break;
                }
            }
        }
        if (session->username) {
            VRB(NULL, "Cert verify CTN: new client username recognized as \"%s\".", session->username);
        } else {
            VRB(NULL, "Cert verify CTN: unsuccessful, dropping the new client.");
            ret = 1;
            goto cleanup;
        }
    }

    if (session->username && server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {
        VRB(session, "Cert verify: user verify callback revoked authorization.");
        ret = 1;
        goto cleanup;
    }

cleanup:
    free(subject);
    free(issuer);
    return ret;
}

API const void *
nc_session_get_client_cert(const struct nc_session *session)
{
    if (!session || (session->side != NC_SERVER)) {
        ERRARG(session, "session");
        return NULL;
    }

    return session->opts.server.client_cert;
}

API void
nc_server_tls_set_verify_clb(int (*verify_clb)(const struct nc_session *session))
{
    server_opts.user_verify_clb = verify_clb;
}

int
nc_server_tls_load_server_cert_key(struct nc_server_tls_opts *opts, void **srv_cert, void **srv_pkey)
{
    char *privkey_data = NULL, *cert_data = NULL;
    NC_PRIVKEY_FORMAT privkey_type;
    void *cert = NULL;
    void *pkey = NULL;

    *srv_cert = *srv_pkey = NULL;

    /* get data needed for setting the server cert */
    if (opts->store == NC_STORE_LOCAL) {
        /* local definition */
        cert_data = opts->cert_data;
        privkey_data = opts->privkey_data;
        privkey_type = opts->privkey_type;
    } else {
        /* keystore */
        if (nc_server_tls_ks_ref_get_cert_key(opts->key_ref, opts->cert_ref, &privkey_data, &privkey_type, &cert_data)) {
            ERR(NULL, "Getting server certificate from the keystore reference \"%s\" failed.", opts->key_ref);
            return 1;
        }
    }
    if (!cert_data || !privkey_data) {
        ERR(NULL, "Server certificate not configured.");
        return 1;
    }

    cert = nc_base64der_to_cert(cert_data);
    if (!cert) {
        return 1;
    }

    pkey = nc_base64der_to_privkey(privkey_data, nc_privkey_format_to_str(privkey_type));
    if (!pkey) {
        nc_tls_cert_destroy_wrap(cert);
        return 1;
    }

    *srv_cert = cert;
    *srv_pkey = pkey;
    return 0;
}

static size_t
nc_server_tls_curl_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    struct nc_curl_data *data;

    size = nmemb;

    data = (struct nc_curl_data *)userdata;

    data->data = nc_realloc(data->data, data->size + size);
    NC_CHECK_ERRMEM_RET(!data->data, 0);

    memcpy(&data->data[data->size], ptr, size);
    data->size += size;

    return size;
}

static int
nc_server_tls_curl_fetch(CURL *handle, const char *url)
{
    char err_buf[CURL_ERROR_SIZE];

    /* set uri */
    if (curl_easy_setopt(handle, CURLOPT_URL, url)) {
        ERR(NULL, "Setting URI \"%s\" to download CRL from failed.", url);
        return 1;
    }

    /* set err buf */
    if (curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, err_buf)) {
        ERR(NULL, "Setting CURL error buffer option failed.");
        return 1;
    }

    /* download */
    if (curl_easy_perform(handle)) {
        ERR(NULL, "Downloading CRL from \"%s\" failed (%s).", url, err_buf);
        return 1;
    }

    return 0;
}

static int
nc_server_tls_curl_init(CURL **handle, struct nc_curl_data *data)
{
    NC_CHECK_ARG_RET(NULL, handle, data, -1);

    *handle = NULL;

    *handle = curl_easy_init();
    if (!*handle) {
        ERR(NULL, "Initializing CURL failed.");
        return 1;
    }

    if (curl_easy_setopt(*handle, CURLOPT_WRITEFUNCTION, nc_server_tls_curl_cb)) {
        ERR(NULL, "Setting curl callback failed.");
        return 1;
    }

    if (curl_easy_setopt(*handle, CURLOPT_WRITEDATA, data)) {
        ERR(NULL, "Setting curl callback data failed.");
        return 1;
    }

    return 0;
}

static int
nc_server_tls_crl_path(const char *path, void *crl_store)
{
    return nc_tls_import_crl_path_wrap(path, crl_store);
}

static int
nc_server_tls_crl_url(const char *url, void *crl_store)
{
    int ret = 0;
    CURL *handle = NULL;
    struct nc_curl_data downloaded = {0};

    /* init curl */
    ret = nc_server_tls_curl_init(&handle, &downloaded);
    if (ret) {
        goto cleanup;
    }

    VRB(NULL, "Downloading CRL from \"%s\".", url);

    /* download the CRL */
    ret = nc_server_tls_curl_fetch(handle, url);
    if (ret) {
        goto cleanup;
    }

    /* convert the downloaded data to CRL and add it to the store */
    ret = nc_server_tls_add_crl_to_store_wrap(downloaded.data, downloaded.size, crl_store);
    if (ret) {
        goto cleanup;
    }

cleanup:
    curl_easy_cleanup(handle);
    return ret;
}

static int
nc_server_tls_crl_cert_ext(void *cert_store, void *crl_store)
{
    int ret = 0;
    CURL *handle = NULL;
    struct nc_curl_data downloaded = {0};
    char **uris = NULL;
    int uri_count = 0, i;

    /* init curl */
    ret = nc_server_tls_curl_init(&handle, &downloaded);
    if (ret) {
        goto cleanup;
    }

    /* get all the uris we can, even though some may point to the same CRL */
    ret = nc_server_tls_get_crl_distpoint_uris_wrap(cert_store, &uris, &uri_count);
    if (ret) {
        goto cleanup;
    }

    for (i = 0; i < uri_count; i++) {
        VRB(NULL, "Downloading CRL from \"%s\".", uris[i]);
        ret = nc_server_tls_curl_fetch(handle, uris[i]);
        if (ret) {
            /* failed to download the CRL from this entry, try the next entry */
            WRN(NULL, "Failed to fetch CRL from \"%s\".", uris[i]);
            continue;
        }

        /* convert the downloaded data to CRL and add it to the store */
        ret = nc_server_tls_add_crl_to_store_wrap(downloaded.data, downloaded.size, crl_store);
        if (ret) {
            goto cleanup;
        }
    }

cleanup:
    for (i = 0; i < uri_count; i++) {
        free(uris[i]);
    }
    free(uris);
    curl_easy_cleanup(handle);
    return ret;
}

int
nc_server_tls_load_crl(struct nc_server_tls_opts *opts, void *cert_store, void *crl_store)
{
    if (opts->crl_path) {
        if (nc_server_tls_crl_path(opts->crl_path, crl_store)) {
            return 1;
        }
    } else if (opts->crl_url) {
        if (nc_server_tls_crl_url(opts->crl_url, crl_store)) {
            return 1;
        }
    } else {
        if (nc_server_tls_crl_cert_ext(cert_store, crl_store)) {
            return 1;
        }
    }

    return 0;
}

int
nc_server_tls_load_trusted_certs(struct nc_cert_grouping *ca_certs, void *cert_store)
{
    struct nc_certificate *certs;
    uint16_t i, cert_count;
    void *cert;

    if (ca_certs->store == NC_STORE_LOCAL) {
        /* local definition */
        certs = ca_certs->certs;
        cert_count = ca_certs->cert_count;
    } else {
        /* truststore */
        if (nc_server_tls_ts_ref_get_certs(ca_certs->ts_ref, &certs, &cert_count)) {
            ERR(NULL, "Error getting certificate-authority certificates from the truststore reference \"%s\".", ca_certs->ts_ref);
            return 1;
        }
    }

    for (i = 0; i < cert_count; i++) {
        /* parse data into cert */
        cert = nc_base64der_to_cert(certs[i].data);
        if (!cert) {
            return 1;
        }

        /* store cert in cert store */
        if (nc_tls_add_cert_to_store_wrap(cert, cert_store)) {
            nc_tls_cert_destroy_wrap(cert);
            return 1;
        }
    }

    return 0;
}

static int
nc_server_tls_accept_check(int accept_ret, void *tls_session)
{
    uint32_t verify;
    char *err;

    /* check certificate verification result */
    verify = nc_tls_get_verify_result_wrap(tls_session);
    if (!verify && (accept_ret == 1)) {
        VRB(NULL, "Client certificate verified.");
    } else if (verify) {
        err = nc_tls_verify_error_string_wrap(verify);
        ERR(NULL, "Client certificate error (%s).", err);
        free(err);
    }

    if (accept_ret != 1) {
        nc_server_tls_print_accept_err_wrap(accept_ret, tls_session);
    }

    return accept_ret;
}

int
nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opts, int sock, int timeout)
{
    int rc, timeouted = 0;
    struct timespec ts_timeout;
    struct nc_tls_verify_cb_data cb_data = {0};
    struct nc_endpt *referenced_endpt;
    void *tls_cfg, *srv_cert, *srv_pkey, *cert_store, *crl_store;

    tls_cfg = srv_cert = srv_pkey = cert_store = crl_store = NULL;

    /* set verify cb data */
    cb_data.session = session;
    cb_data.opts = opts;

    /* prepare TLS context from which a session will be created */
    tls_cfg = nc_tls_config_new_wrap(NC_SERVER);
    if (!tls_cfg) {
        goto fail;
    }

    /* opaque CA/CRL certificate store */
    cert_store = nc_tls_cert_store_new_wrap();
    if (!cert_store) {
        goto fail;
    }

    /* load server's key and certificate */
    if (nc_server_tls_load_server_cert_key(opts, &srv_cert, &srv_pkey)) {
        ERR(session, "Loading server certificate and/or private key failed.");
        goto fail;
    }

    /* load trusted CA certificates */
    if (nc_server_tls_load_trusted_certs(&opts->ca_certs, cert_store)) {
        ERR(session, "Loading server CA certs failed.");
        goto fail;
    }

    /* load referenced endpoint's trusted CA certs if set */
    if (opts->referenced_endpt_name) {
        if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
            ERR(session, "Referenced endpoint \"%s\" not found.", opts->referenced_endpt_name);
            goto fail;
        }

        if (nc_server_tls_load_trusted_certs(&referenced_endpt->opts.tls->ca_certs, cert_store)) {
            ERR(session, "Loading server CA certs from referenced endpoint failed.");
            goto fail;
        }
    }

    if (opts->crl_path || opts->crl_url || opts->crl_cert_ext) {
        /* opaque CRL store */
        crl_store = nc_tls_crl_store_new_wrap();
        if (!crl_store) {
            goto fail;
        }

        /* load CRLs into one of the stores */
        if (nc_server_tls_load_crl(opts, cert_store, crl_store)) {
            ERR(session, "Loading server CRL failed.");
            goto fail;
        }
    }

    /* set supported TLS versions */
    if (opts->tls_versions) {
        if (nc_server_tls_set_tls_versions_wrap(tls_cfg, opts->tls_versions)) {
            ERR(session, "Setting supported server TLS versions failed.");
            goto fail;
        }
    }

    /* set supported cipher suites */
    if (opts->ciphers) {
        nc_server_tls_set_cipher_suites_wrap(tls_cfg, opts->ciphers);
    }

    /* set verify flags, callback and its data */
    nc_server_tls_set_verify_wrap(tls_cfg, &cb_data);

    /* init TLS context and store data which may be needed later in it */
    if (nc_tls_init_ctx_wrap(sock, srv_cert, srv_pkey, cert_store, crl_store, &session->ti.tls.ctx)) {
        goto fail;
    }

    /* memory is managed by context now */
    srv_cert = srv_pkey = cert_store = crl_store = NULL;

    /* setup config from ctx */
    if (nc_tls_setup_config_from_ctx_wrap(&session->ti.tls.ctx, NC_SERVER, tls_cfg)) {
        goto fail;
    }
    session->ti.tls.config = tls_cfg;
    tls_cfg = NULL;

    /* fill session data and create TLS session from config */
    session->ti_type = NC_TI_TLS;
    if (!(session->ti.tls.session = nc_tls_session_new_wrap(session->ti.tls.config))) {
        goto fail;
    }

    /* set session fd */
    nc_server_tls_set_fd_wrap(session->ti.tls.session, sock, &session->ti.tls.ctx);

    sock = -1;

    /* do the handshake */
    if (timeout > -1) {
        nc_timeouttime_get(&ts_timeout, timeout);
    }
    while ((rc = nc_server_tls_handshake_step_wrap(session->ti.tls.session)) == 0) {
        usleep(NC_TIMEOUT_STEP);
        if ((timeout > -1) && (nc_timeouttime_cur_diff(&ts_timeout) < 1)) {
            ERR(session, "TLS accept timeout.");
            timeouted = 1;
            goto fail;
        }
    }

    /* check if handshake was ok */
    if (nc_server_tls_accept_check(rc, session->ti.tls.session) != 1) {
        goto fail;
    }

    return 1;

fail:
    if (sock > -1) {
        close(sock);
    }

    nc_tls_config_destroy_wrap(tls_cfg);
    nc_tls_cert_destroy_wrap(srv_cert);
    nc_tls_privkey_destroy_wrap(srv_pkey);
    nc_tls_cert_store_destroy_wrap(cert_store);
    nc_tls_crl_store_destroy_wrap(crl_store);

    if (timeouted) {
        return 0;
    } else {
        return -1;
    }
}
