/**
 * @file session_server_tls.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief libnetconf2 TLS server session manipulation functions
 *
 * @copyright
 * Copyright (c) 2015 - 2021 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 <string.h>
#include <unistd.h>

#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#include "compat.h"
#include "libnetconf.h"
#include "session_server.h"
#include "session_server_ch.h"

#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define X509_STORE_CTX_get_by_subject X509_STORE_get_by_subject
#endif

struct nc_server_tls_opts tls_ch_opts;
pthread_mutex_t tls_ch_opts_lock = PTHREAD_MUTEX_INITIALIZER;
extern struct nc_server_opts server_opts;

static pthread_key_t verify_key;
static pthread_once_t verify_once = PTHREAD_ONCE_INIT;

static char *
asn1time_to_str(const ASN1_TIME *t)
{
    char *cp;
    BIO *bio;
    int n;

    if (!t) {
        return NULL;
    }
    bio = BIO_new(BIO_s_mem());
    if (!bio) {
        return NULL;
    }
    ASN1_TIME_print(bio, t);
    n = BIO_pending(bio);
    cp = malloc(n + 1);
    if (!cp) {
        ERRMEM;
        BIO_free(bio);
        return NULL;
    }
    n = BIO_read(bio, cp, n);
    if (n < 0) {
        BIO_free(bio);
        free(cp);
        return NULL;
    }
    cp[n] = '\0';
    BIO_free(bio);
    return cp;
}

static void
digest_to_str(const unsigned char *digest, unsigned int dig_len, char **str)
{
    unsigned int i;

    *str = malloc(dig_len * 3);
    if (!*str) {
        ERRMEM;
        return;
    }
    for (i = 0; i < dig_len - 1; ++i) {
        sprintf((*str) + (i * 3), "%02x:", digest[i]);
    }
    sprintf((*str) + (i * 3), "%02x", digest[i]);
}

/* return NULL - SSL error can be retrieved */
static X509 *
base64der_to_cert(const char *in)
{
    X509 *out;
    char *buf;
    BIO *bio;

    if (in == NULL) {
        return NULL;
    }

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

    out = PEM_read_bio_X509(bio, NULL, NULL, NULL);
    if (!out) {
        free(buf);
        BIO_free(bio);
        return NULL;
    }

    free(buf);
    BIO_free(bio);
    return out;
}

/* return NULL - either errno or SSL error */
static X509 *
pem_to_cert(const char *path)
{
    FILE *fp;
    X509 *out;

    fp = fopen(path, "r");
    if (!fp) {
        return NULL;
    }

    out = PEM_read_X509(fp, NULL, NULL, NULL);
    fclose(fp);
    return out;
}

static EVP_PKEY *
base64der_to_privatekey(const char *in, const char *key_str)
{
    EVP_PKEY *out;
    char *buf;
    BIO *bio;

    if (in == NULL) {
        return 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) {
        return NULL;
    }
    bio = BIO_new_mem_buf(buf, strlen(buf));
    if (!bio) {
        free(buf);
        return NULL;
    }

    out = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
    if (!out) {
        free(buf);
        BIO_free(bio);
        return NULL;
    }

    free(buf);
    BIO_free(bio);
    return out;
}

static int
cert_pubkey_match(X509 *cert1, X509 *cert2)
{
    ASN1_BIT_STRING *bitstr1, *bitstr2;

    bitstr1 = X509_get0_pubkey_bitstr(cert1);
    bitstr2 = X509_get0_pubkey_bitstr(cert2);

    if (!bitstr1 || !bitstr2 || (bitstr1->length != bitstr2->length) ||
            memcmp(bitstr1->data, bitstr2->data, bitstr1->length)) {
        return 0;
    }

    return 1;
}

static int
nc_tls_ctn_get_username_from_cert(X509 *client_cert, NC_TLS_CTN_MAPTYPE map_type, char **username)
{
    STACK_OF(GENERAL_NAME) * san_names;
    GENERAL_NAME *san_name;
    ASN1_OCTET_STRING *ip;
    int i, san_count;
    char *subject, *common_name;

    if (map_type == NC_TLS_CTN_COMMON_NAME) {
        subject = X509_NAME_oneline(X509_get_subject_name(client_cert), NULL, 0);
        common_name = strstr(subject, "CN=");
        if (!common_name) {
            WRN(NULL, "Certificate does not include the commonName field.");
            free(subject);
            return 1;
        }
        common_name += 3;
        if (strchr(common_name, '/')) {
            *strchr(common_name, '/') = '\0';
        }
        *username = strdup(common_name);
        if (!*username) {
            ERRMEM;
            return 1;
        }
        free(subject);
    } else {
        /* retrieve subjectAltName's rfc822Name (email), dNSName and iPAddress values */
        san_names = X509_get_ext_d2i(client_cert, NID_subject_alt_name, NULL, NULL);
        if (!san_names) {
            WRN(NULL, "Certificate has no SANs or failed to retrieve them.");
            return 1;
        }

        san_count = sk_GENERAL_NAME_num(san_names);
        for (i = 0; i < san_count; ++i) {
            san_name = sk_GENERAL_NAME_value(san_names, i);

            /* rfc822Name (email) */
            if (((map_type == NC_TLS_CTN_SAN_ANY) || (map_type == NC_TLS_CTN_SAN_RFC822_NAME)) &&
                    (san_name->type == GEN_EMAIL)) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0
                *username = strdup((char *)ASN1_STRING_data(san_name->d.rfc822Name));
#else
                *username = strdup((char *)ASN1_STRING_get0_data(san_name->d.rfc822Name));
#endif
                if (!*username) {
                    ERRMEM;
                    return 1;
                }
                break;
            }

            /* dNSName */
            if (((map_type == NC_TLS_CTN_SAN_ANY) || (map_type == NC_TLS_CTN_SAN_DNS_NAME)) &&
                    (san_name->type == GEN_DNS)) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0
                *username = strdup((char *)ASN1_STRING_data(san_name->d.dNSName));
#else
                *username = strdup((char *)ASN1_STRING_get0_data(san_name->d.dNSName));
#endif
                if (!*username) {
                    ERRMEM;
                    return 1;
                }
                break;
            }

            /* iPAddress */
            if (((map_type == NC_TLS_CTN_SAN_ANY) || (map_type == NC_TLS_CTN_SAN_IP_ADDRESS)) &&
                    (san_name->type == GEN_IPADD)) {
                ip = san_name->d.iPAddress;
                if (ip->length == 4) {
                    if (asprintf(username, "%d.%d.%d.%d", ip->data[0], ip->data[1], ip->data[2], ip->data[3]) == -1) {
                        ERRMEM;
                        sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
                        return -1;
                    }
                    break;
                } else if (ip->length == 16) {
                    if (asprintf(username, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                            ip->data[0], ip->data[1], ip->data[2], ip->data[3], ip->data[4], ip->data[5],
                            ip->data[6], ip->data[7], ip->data[8], ip->data[9], ip->data[10], ip->data[11],
                            ip->data[12], ip->data[13], ip->data[14], ip->data[15]) == -1) {
                        ERRMEM;
                        sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
                        return -1;
                    }
                    break;
                } else {
                    WRN(NULL, "SAN IP address in an unknown format (length is %d).", ip->length);
                }
            }
        }
        sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);

        if (i == san_count) {
            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;
}

/* return: 0 - OK, 1 - no match, -1 - error */
static int
nc_tls_cert_to_name(struct nc_ctn *ctn_first, X509 *cert, NC_TLS_CTN_MAPTYPE *map_type, const char **name)
{
    char *digest_md5 = NULL, *digest_sha1 = NULL, *digest_sha224 = NULL;
    char *digest_sha256 = NULL, *digest_sha384 = NULL, *digest_sha512 = NULL;
    unsigned char *buf = malloc(64);
    unsigned int buf_len = 64;
    int ret = 0;
    struct nc_ctn *ctn;

    if (!buf) {
        ERRMEM;
        return -1;
    }

    if (!ctn_first || !cert || !map_type || !name) {
        free(buf);
        return -1;
    }

    for (ctn = ctn_first; ctn; ctn = ctn->next) {
        /* first make sure the entry is valid */
        if (!ctn->fingerprint || !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;
        }

        /* MD5 */
        if (!strncmp(ctn->fingerprint, "01", 2)) {
            if (!digest_md5) {
                if (X509_digest(cert, EVP_md5(), buf, &buf_len) != 1) {
                    ERR(NULL, "Calculating MD5 digest failed (%s).", ERR_reason_error_string(ERR_get_error()));
                    ret = -1;
                    goto cleanup;
                }
                digest_to_str(buf, buf_len, &digest_md5);
            }

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

            /* SHA-1 */
        } else if (!strncmp(ctn->fingerprint, "02", 2)) {
            if (!digest_sha1) {
                if (X509_digest(cert, EVP_sha1(), buf, &buf_len) != 1) {
                    ERR(NULL, "Calculating SHA-1 digest failed (%s).", ERR_reason_error_string(ERR_get_error()));
                    ret = -1;
                    goto cleanup;
                }
                digest_to_str(buf, buf_len, &digest_sha1);
            }

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

            /* SHA-224 */
        } else if (!strncmp(ctn->fingerprint, "03", 2)) {
            if (!digest_sha224) {
                if (X509_digest(cert, EVP_sha224(), buf, &buf_len) != 1) {
                    ERR(NULL, "Calculating SHA-224 digest failed (%s).", ERR_reason_error_string(ERR_get_error()));
                    ret = -1;
                    goto cleanup;
                }
                digest_to_str(buf, buf_len, &digest_sha224);
            }

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

            /* SHA-256 */
        } else if (!strncmp(ctn->fingerprint, "04", 2)) {
            if (!digest_sha256) {
                if (X509_digest(cert, EVP_sha256(), buf, &buf_len) != 1) {
                    ERR(NULL, "Calculating SHA-256 digest failed (%s).", ERR_reason_error_string(ERR_get_error()));
                    ret = -1;
                    goto cleanup;
                }
                digest_to_str(buf, buf_len, &digest_sha256);
            }

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

            /* SHA-384 */
        } else if (!strncmp(ctn->fingerprint, "05", 2)) {
            if (!digest_sha384) {
                if (X509_digest(cert, EVP_sha384(), buf, &buf_len) != 1) {
                    ERR(NULL, "Calculating SHA-384 digest failed (%s).", ERR_reason_error_string(ERR_get_error()));
                    ret = -1;
                    goto cleanup;
                }
                digest_to_str(buf, buf_len, &digest_sha384);
            }

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

            /* SHA-512 */
        } else if (!strncmp(ctn->fingerprint, "06", 2)) {
            if (!digest_sha512) {
                if (X509_digest(cert, EVP_sha512(), buf, &buf_len) != 1) {
                    ERR(NULL, "Calculating SHA-512 digest failed (%s).", ERR_reason_error_string(ERR_get_error()));
                    ret = -1;
                    goto cleanup;
                }
                digest_to_str(buf, buf_len, &digest_sha512);
            }

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

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

    if (!ctn) {
        ret = 1;
    }

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

#if OPENSSL_VERSION_NUMBER >= 0x10100000L // >= 1.1.0

static int
nc_tlsclb_verify(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
    X509_STORE_CTX *store_ctx;
    X509_OBJECT *obj;
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    X509_CRL *crl;
    X509_REVOKED *revoked;

    STACK_OF(X509) * cert_stack;
    EVP_PKEY *pubkey;
    struct nc_session *session;
    struct nc_server_tls_opts *opts;
    const ASN1_INTEGER *serial;
    int i, n, rc, depth;
    char *cp;
    const char *username = NULL;
    NC_TLS_CTN_MAPTYPE map_type = 0;
    const ASN1_TIME *last_update = NULL, *next_update = NULL;

    /* get the thread session */
    session = pthread_getspecific(verify_key);
    if (!session) {
        ERRINT;
        return 0;
    }

    opts = session->data;

    /* get the last certificate, that is the peer (client) certificate */
    if (!session->opts.server.client_cert) {
        cert_stack = X509_STORE_CTX_get1_chain(x509_ctx);
        session->opts.server.client_cert = sk_X509_value(cert_stack, 0);
        X509_up_ref(session->opts.server.client_cert);
        sk_X509_pop_free(cert_stack, X509_free);
    }

    /* standard certificate verification failed, so a trusted client cert must match to continue */
    if (!preverify_ok) {
        subject = X509_get_subject_name(session->opts.server.client_cert);
        cert_stack = X509_STORE_CTX_get1_certs(x509_ctx, subject);
        if (cert_stack) {
            for (i = 0; i < sk_X509_num(cert_stack); ++i) {
                if (cert_pubkey_match(session->opts.server.client_cert, sk_X509_value(cert_stack, i))) {
                    /* we are just overriding the failed standard certificate verification (preverify_ok == 0),
                     * this callback will be called again with the same current certificate and preverify_ok == 1 */
                    VRB(NULL, "Cert verify: fail (%s), but the client certificate is trusted, continuing.",
                            X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_ctx)));
                    X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
                    sk_X509_pop_free(cert_stack, X509_free);
                    return 1;
                }
            }
            sk_X509_pop_free(cert_stack, X509_free);
        }

        ERR(NULL, "Cert verify: fail (%s).", X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_ctx)));
        return 0;
    }

    /* print cert verify info */
    depth = X509_STORE_CTX_get_error_depth(x509_ctx);
    VRB(NULL, "Cert verify: depth %d.", depth);

    cert = X509_STORE_CTX_get_current_cert(x509_ctx);
    subject = X509_get_subject_name(cert);
    issuer = X509_get_issuer_name(cert);

    cp = X509_NAME_oneline(subject, NULL, 0);
    VRB(NULL, "Cert verify: subject: %s.", cp);
    OPENSSL_free(cp);
    cp = X509_NAME_oneline(issuer, NULL, 0);
    VRB(NULL, "Cert verify: issuer:  %s.", cp);
    OPENSSL_free(cp);

    /* check for revocation if set */
    if (opts->crl_store) {
        /* try to retrieve a CRL corresponding to the _subject_ of
         * the current certificate in order to verify it's integrity */
        store_ctx = X509_STORE_CTX_new();
        obj = X509_OBJECT_new();
        X509_STORE_CTX_init(store_ctx, opts->crl_store, NULL, NULL);
        rc = X509_STORE_CTX_get_by_subject(store_ctx, X509_LU_CRL, subject, obj);
        X509_STORE_CTX_free(store_ctx);
        crl = X509_OBJECT_get0_X509_CRL(obj);
        if ((rc > 0) && crl) {
            cp = X509_NAME_oneline(subject, NULL, 0);
            VRB(NULL, "Cert verify CRL: issuer: %s.", cp);
            OPENSSL_free(cp);

            last_update = X509_CRL_get0_lastUpdate(crl);
            next_update = X509_CRL_get0_nextUpdate(crl);
            cp = asn1time_to_str(last_update);
            VRB(NULL, "Cert verify CRL: last update: %s.", cp);
            free(cp);
            cp = asn1time_to_str(next_update);
            VRB(NULL, "Cert verify CRL: next update: %s.", cp);
            free(cp);

            /* verify the signature on this CRL */
            pubkey = X509_get_pubkey(cert);
            if (X509_CRL_verify(crl, pubkey) <= 0) {
                ERR(NULL, "Cert verify CRL: invalid signature.");
                X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
                X509_OBJECT_free(obj);
                if (pubkey) {
                    EVP_PKEY_free(pubkey);
                }
                return 0;
            }
            if (pubkey) {
                EVP_PKEY_free(pubkey);
            }

            /* check date of CRL to make sure it's not expired */
            if (!next_update) {
                ERR(NULL, "Cert verify CRL: invalid nextUpdate field.");
                X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
                X509_OBJECT_free(obj);
                return 0;
            }
            if (X509_cmp_current_time(next_update) < 0) {
                ERR(NULL, "Cert verify CRL: expired - revoking all certificates.");
                X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
                X509_OBJECT_free(obj);
                return 0;
            }
            X509_OBJECT_free(obj);
        }

        /* try to retrieve a CRL corresponding to the _issuer_ of
         * the current certificate in order to check for revocation */
        store_ctx = X509_STORE_CTX_new();
        obj = X509_OBJECT_new();
        X509_STORE_CTX_init(store_ctx, opts->crl_store, NULL, NULL);
        rc = X509_STORE_CTX_get_by_subject(store_ctx, X509_LU_CRL, issuer, obj);
        X509_STORE_CTX_free(store_ctx);
        crl = X509_OBJECT_get0_X509_CRL(obj);
        if ((rc > 0) && crl) {
            /* check if the current certificate is revoked by this CRL */
            n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
            for (i = 0; i < n; i++) {
                revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
                serial = X509_REVOKED_get0_serialNumber(revoked);
                if (ASN1_INTEGER_cmp(serial, X509_get_serialNumber(cert)) == 0) {
                    cp = X509_NAME_oneline(issuer, NULL, 0);
                    ERR(NULL, "Cert verify CRL: certificate with serial %ld (0x%lX) revoked per CRL from issuer %s.",
                            serial, serial, cp);
                    OPENSSL_free(cp);
                    X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CERT_REVOKED);
                    X509_OBJECT_free(obj);
                    return 0;
                }
            }
            X509_OBJECT_free(obj);
        }
    }

    /* cert-to-name already successful */
    if (session->username) {
        return 1;
    }

    /* cert-to-name */
    rc = nc_tls_cert_to_name(opts->ctn, cert, &map_type, &username);

    if (rc) {
        if (rc == -1) {
            /* fatal error */
            depth = 0;
        }
        /* rc == 1 is a normal CTN fail (no match found) */
        goto fail;
    }

    /* cert-to-name match, now to extract the specific field from the peer cert */
    if (map_type == NC_TLS_CTN_SPECIFIED) {
        session->username = strdup(username);
    } else {
        rc = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &cp);
        if (rc) {
            if (rc == -1) {
                depth = 0;
            }
            goto fail;
        }
        session->username = cp;
    }

    VRB(NULL, "Cert verify CTN: new client username recognized as \"%s\".", session->username);

    if (server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {
        VRB(NULL, "Cert verify: user verify callback revoked authorization.");
        X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_APPLICATION_VERIFICATION);
        return 0;
    }

    return 1;

fail:
    if (depth > 0) {
        VRB(NULL, "Cert verify CTN: cert fail, cert-to-name will continue on the next cert in chain.");
        return 1;
    }

    VRB(NULL, "Cert-to-name unsuccessful, dropping the new client.");
    X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_APPLICATION_VERIFICATION);
    return 0;
}

#else

static int
nc_tlsclb_verify(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
    X509_STORE_CTX store_ctx;
    X509_OBJECT obj;
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    X509_CRL *crl;
    X509_REVOKED *revoked;

    STACK_OF(X509) * cert_stack;
    EVP_PKEY *pubkey;
    struct nc_session *session;
    struct nc_server_tls_opts *opts;
    long serial;
    int i, n, rc, depth;
    char *cp;
    const char *username = NULL;
    NC_TLS_CTN_MAPTYPE map_type = 0;
    ASN1_TIME *last_update = NULL, *next_update = NULL;

    /* get the thread session */
    session = pthread_getspecific(verify_key);
    if (!session) {
        ERRINT;
        return 0;
    }

    opts = session->data;

    /* get the last certificate, that is the peer (client) certificate */
    if (!session->opts.server.client_cert) {
        cert_stack = X509_STORE_CTX_get1_chain(x509_ctx);
        while ((cert = sk_X509_pop(cert_stack))) {
            X509_free(session->opts.server.client_cert);
            session->opts.server.client_cert = cert;
        }
        sk_X509_pop_free(cert_stack, X509_free);
    }

    /* standard certificate verification failed, so a trusted client cert must match to continue */
    if (!preverify_ok) {
        subject = X509_get_subject_name(session->opts.server.client_cert);
        cert_stack = X509_STORE_get1_certs(x509_ctx, subject);
        if (cert_stack) {
            for (i = 0; i < sk_X509_num(cert_stack); ++i) {
                if (cert_pubkey_match(session->opts.server.client_cert, sk_X509_value(cert_stack, i))) {
                    /* we are just overriding the failed standard certificate verification (preverify_ok == 0),
                     * this callback will be called again with the same current certificate and preverify_ok == 1 */
                    VRB(session, "Cert verify: fail (%s), but the client certificate is trusted, continuing.",
                            X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_ctx)));
                    X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
                    sk_X509_pop_free(cert_stack, X509_free);
                    return 1;
                }
            }
            sk_X509_pop_free(cert_stack, X509_free);
        }

        ERR(session, "Cert verify: fail (%s).", X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_ctx)));
        return 0;
    }

    /* print cert verify info */
    depth = X509_STORE_CTX_get_error_depth(x509_ctx);
    VRB(session, "Cert verify: depth %d.", depth);

    cert = X509_STORE_CTX_get_current_cert(x509_ctx);
    subject = X509_get_subject_name(cert);
    issuer = X509_get_issuer_name(cert);

    cp = X509_NAME_oneline(subject, NULL, 0);
    VRB(session, "Cert verify: subject: %s.", cp);
    OPENSSL_free(cp);
    cp = X509_NAME_oneline(issuer, NULL, 0);
    VRB(session, "Cert verify: issuer:  %s.", cp);
    OPENSSL_free(cp);

    /* check for revocation if set */
    if (opts->crl_store) {
        /* try to retrieve a CRL corresponding to the _subject_ of
         * the current certificate in order to verify it's integrity */
        memset((char *)&obj, 0, sizeof(obj));
        X509_STORE_CTX_init(&store_ctx, opts->crl_store, NULL, NULL);
        rc = X509_STORE_CTX_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
        X509_STORE_CTX_cleanup(&store_ctx);
        crl = obj.data.crl;
        if ((rc > 0) && crl) {
            cp = X509_NAME_oneline(subject, NULL, 0);
            VRB(session, "Cert verify CRL: issuer: %s.", cp);
            OPENSSL_free(cp);

            last_update = X509_CRL_get_lastUpdate(crl);
            next_update = X509_CRL_get_nextUpdate(crl);
            cp = asn1time_to_str(last_update);
            VRB(session, "Cert verify CRL: last update: %s.", cp);
            free(cp);
            cp = asn1time_to_str(next_update);
            VRB(session, "Cert verify CRL: next update: %s.", cp);
            free(cp);

            /* verify the signature on this CRL */
            pubkey = X509_get_pubkey(cert);
            if (X509_CRL_verify(crl, pubkey) <= 0) {
                ERR(session, "Cert verify CRL: invalid signature.");
                X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
                X509_OBJECT_free_contents(&obj);
                if (pubkey) {
                    EVP_PKEY_free(pubkey);
                }
                return 0;
            }
            if (pubkey) {
                EVP_PKEY_free(pubkey);
            }

            /* check date of CRL to make sure it's not expired */
            if (!next_update) {
                ERR(session, "Cert verify CRL: invalid nextUpdate field.");
                X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
                X509_OBJECT_free_contents(&obj);
                return 0;
            }
            if (X509_cmp_current_time(next_update) < 0) {
                ERR(session, "Cert verify CRL: expired - revoking all certificates.");
                X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
                X509_OBJECT_free_contents(&obj);
                return 0;
            }
            X509_OBJECT_free_contents(&obj);
        }

        /* try to retrieve a CRL corresponding to the _issuer_ of
         * the current certificate in order to check for revocation */
        memset((char *)&obj, 0, sizeof(obj));
        X509_STORE_CTX_init(&store_ctx, opts->crl_store, NULL, NULL);
        rc = X509_STORE_CTX_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
        X509_STORE_CTX_cleanup(&store_ctx);
        crl = obj.data.crl;
        if ((rc > 0) && crl) {
            /* check if the current certificate is revoked by this CRL */
            n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
            for (i = 0; i < n; i++) {
                revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
                if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) {
                    serial = ASN1_INTEGER_get(revoked->serialNumber);
                    cp = X509_NAME_oneline(issuer, NULL, 0);
                    ERR(session, "Cert verify CRL: certificate with serial %ld (0x%lX) revoked per CRL from issuer %s.",
                            serial, serial, cp);
                    OPENSSL_free(cp);
                    X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CERT_REVOKED);
                    X509_OBJECT_free_contents(&obj);
                    return 0;
                }
            }
            X509_OBJECT_free_contents(&obj);
        }
    }

    /* cert-to-name already successful */
    if (session->username) {
        return 1;
    }

    /* cert-to-name */
    rc = nc_tls_cert_to_name(opts->ctn, cert, &map_type, &username);

    if (rc) {
        if (rc == -1) {
            /* fatal error */
            depth = 0;
        }
        /* rc == 1 is a normal CTN fail (no match found) */
        goto fail;
    }

    /* cert-to-name match, now to extract the specific field from the peer cert */
    if (map_type == NC_TLS_CTN_SPECIFIED) {
        lydict_insert(server_opts.ctx, username, 0, &session->username);
    } else {
        rc = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &cp);
        if (rc) {
            if (rc == -1) {
                depth = 0;
            }
            goto fail;
        }
        lydict_insert_zc(server_opts.ctx, cp, &session->username);
    }

    VRB(session, "Cert verify CTN: new client username recognized as \"%s\".", session->username);

    if (server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {
        VRB(session, "Cert verify: user verify callback revoked authorization.");
        X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_APPLICATION_VERIFICATION);
        return 0;
    }

    return 1;

fail:
    if (depth > 0) {
        VRB(session, "Cert verify CTN: cert fail, cert-to-name will continue on the next cert in chain.");
        return 1;
    }

    VRB(session, "Cert-to-name unsuccessful, dropping the new client.");
    X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_APPLICATION_VERIFICATION);
    return 0;
}

#endif

static int
nc_server_tls_set_server_cert(const char *name, struct nc_server_tls_opts *opts)
{
    if (!name) {
        if (opts->server_cert) {
            free(opts->server_cert);
        }
        opts->server_cert = NULL;
        return 0;
    }

    if (opts->server_cert) {
        free(opts->server_cert);
    }
    opts->server_cert = strdup(name);

    return 0;
}

API int
nc_server_tls_endpt_set_server_cert(const char *endpt_name, const char *name)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_set_server_cert(name, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_endpt_set_server_cert(const char *client_name, const char *endpt_name, const char *name)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_set_server_cert(name, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

API void
nc_server_tls_set_server_cert_clb(int (*cert_clb)(const char *name, void *user_data, char **cert_path, char **cert_data,
        char **privkey_path, char **privkey_data, NC_SSH_KEY_TYPE *privkey_type), void *user_data,
        void (*free_user_data)(void *user_data))
{
    if (!cert_clb) {
        ERRARG("cert_clb");
        return;
    }

    server_opts.server_cert_clb = cert_clb;
    server_opts.server_cert_data = user_data;
    server_opts.server_cert_data_free = free_user_data;
}

API void
nc_server_tls_set_server_cert_chain_clb(int (*cert_chain_clb)(const char *name, void *user_data, char ***cert_paths,
        int *cert_path_count, char ***cert_data, int *cert_data_count), void *user_data, void (*free_user_data)(void *user_data))
{
    if (!cert_chain_clb) {
        ERRARG("cert_chain_clb");
        return;
    }

    server_opts.server_cert_chain_clb = cert_chain_clb;
    server_opts.server_cert_chain_data = user_data;
    server_opts.server_cert_chain_data_free = free_user_data;
}

static int
nc_server_tls_add_trusted_cert_list(const char *name, struct nc_server_tls_opts *opts)
{
    if (!name) {
        ERRARG("name");
        return -1;
    }

    ++opts->trusted_cert_list_count;
    opts->trusted_cert_lists = nc_realloc(opts->trusted_cert_lists,
            opts->trusted_cert_list_count * sizeof *opts->trusted_cert_lists);
    if (!opts->trusted_cert_lists) {
        ERRMEM;
        return -1;
    }
    opts->trusted_cert_lists[opts->trusted_cert_list_count - 1] = strdup(name);

    return 0;
}

API int
nc_server_tls_endpt_add_trusted_cert_list(const char *endpt_name, const char *name)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_add_trusted_cert_list(name, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_endpt_add_trusted_cert_list(const char *client_name, const char *endpt_name, const char *name)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_add_trusted_cert_list(name, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

API void
nc_server_tls_set_trusted_cert_list_clb(int (*cert_list_clb)(const char *name, void *user_data, char ***cert_paths,
        int *cert_path_count, char ***cert_data, int *cert_data_count),
        void *user_data, void (*free_user_data)(void *user_data))
{
    if (!cert_list_clb) {
        ERRARG("cert_list_clb");
        return;
    }

    server_opts.trusted_cert_list_clb = cert_list_clb;
    server_opts.trusted_cert_list_data = user_data;
    server_opts.trusted_cert_list_data_free = free_user_data;
}

static int
nc_server_tls_del_trusted_cert_list(const char *name, struct nc_server_tls_opts *opts)
{
    uint16_t i;

    if (!name) {
        for (i = 0; i < opts->trusted_cert_list_count; ++i) {
            free(opts->trusted_cert_lists[i]);
        }
        free(opts->trusted_cert_lists);
        opts->trusted_cert_lists = NULL;
        opts->trusted_cert_list_count = 0;
        return 0;
    } else {
        for (i = 0; i < opts->trusted_cert_list_count; ++i) {
            if (!strcmp(opts->trusted_cert_lists[i], name)) {
                free(opts->trusted_cert_lists[i]);

                --opts->trusted_cert_list_count;
                if (i < opts->trusted_cert_list_count - 1) {
                    memmove(opts->trusted_cert_lists + i, opts->trusted_cert_lists + i + 1,
                            (opts->trusted_cert_list_count - i) * sizeof *opts->trusted_cert_lists);
                }
                return 0;
            }
        }
    }

    ERR(NULL, "Certificate list \"%s\" not found.", name);
    return -1;
}

API int
nc_server_tls_endpt_del_trusted_cert_list(const char *endpt_name, const char *name)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_del_trusted_cert_list(name, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_endpt_del_trusted_cert_list(const char *client_name, const char *endpt_name, const char *name)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_del_trusted_cert_list(name, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

static int
nc_server_tls_set_trusted_ca_paths(const char *ca_file, const char *ca_dir, struct nc_server_tls_opts *opts)
{
    if (!ca_file && !ca_dir) {
        ERRARG("ca_file and ca_dir");
        return -1;
    }

    if (ca_file) {
        free(opts->trusted_ca_file);
        opts->trusted_ca_file = strdup(ca_file);
    }

    if (ca_dir) {
        free(opts->trusted_ca_dir);
        opts->trusted_ca_dir = strdup(ca_dir);
    }

    return 0;
}

API int
nc_server_tls_endpt_set_trusted_ca_paths(const char *endpt_name, const char *ca_file, const char *ca_dir)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_set_trusted_ca_paths(ca_file, ca_dir, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_endpt_set_trusted_ca_paths(const char *client_name, const char *endpt_name, const char *ca_file,
        const char *ca_dir)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_set_trusted_ca_paths(ca_file, ca_dir, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

static int
nc_server_tls_set_crl_paths(const char *crl_file, const char *crl_dir, struct nc_server_tls_opts *opts)
{
    X509_LOOKUP *lookup;

    if (!crl_file && !crl_dir) {
        ERRARG("crl_file and crl_dir");
        return -1;
    }

    if (!opts->crl_store) {
        opts->crl_store = X509_STORE_new();
    }

    if (crl_file) {
        lookup = X509_STORE_add_lookup(opts->crl_store, X509_LOOKUP_file());
        if (!lookup) {
            ERR(NULL, "Failed to add a lookup method.");
            goto fail;
        }

        if (X509_LOOKUP_load_file(lookup, crl_file, X509_FILETYPE_PEM) != 1) {
            ERR(NULL, "Failed to add a revocation lookup file (%s).", ERR_reason_error_string(ERR_get_error()));
            goto fail;
        }
    }

    if (crl_dir) {
        lookup = X509_STORE_add_lookup(opts->crl_store, X509_LOOKUP_hash_dir());
        if (!lookup) {
            ERR(NULL, "Failed to add a lookup method.");
            goto fail;
        }

        if (X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM) != 1) {
            ERR(NULL, "Failed to add a revocation lookup directory (%s).", ERR_reason_error_string(ERR_get_error()));
            goto fail;
        }
    }

    return 0;

fail:
    return -1;
}

API int
nc_server_tls_endpt_set_crl_paths(const char *endpt_name, const char *crl_file, const char *crl_dir)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_set_crl_paths(crl_file, crl_dir, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_set_crl_paths(const char *client_name, const char *endpt_name, const char *crl_file,
        const char *crl_dir)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_set_crl_paths(crl_file, crl_dir, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

static void
nc_server_tls_clear_crls(struct nc_server_tls_opts *opts)
{
    if (!opts->crl_store) {
        return;
    }

    X509_STORE_free(opts->crl_store);
    opts->crl_store = NULL;
}

API void
nc_server_tls_endpt_clear_crls(const char *endpt_name)
{
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return;
    }
    nc_server_tls_clear_crls(endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);
}

API void
nc_server_tls_ch_client_endpt_clear_crls(const char *client_name, const char *endpt_name)
{
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return;
    }

    nc_server_tls_clear_crls(endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);
}

static int
nc_server_tls_add_ctn(uint32_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name,
        struct nc_server_tls_opts *opts)
{
    struct nc_ctn *ctn, *new;

    if (!opts->ctn) {
        /* the first item */
        opts->ctn = new = calloc(1, sizeof *new);
        if (!new) {
            ERRMEM;
            return -1;
        }
    } else if (opts->ctn->id > id) {
        /* insert at the beginning */
        new = calloc(1, sizeof *new);
        if (!new) {
            ERRMEM;
            return -1;
        }
        new->next = opts->ctn;
        opts->ctn = new;
    } else {
        for (ctn = opts->ctn; ctn->next && ctn->next->id <= id; ctn = ctn->next) {}
        if (ctn->id == id) {
            /* it exists already */
            new = ctn;
        } else {
            /* insert after ctn */
            new = calloc(1, sizeof *new);
            if (!new) {
                ERRMEM;
                return -1;
            }
            new->next = ctn->next;
            ctn->next = new;
        }
    }

    new->id = id;
    if (fingerprint) {
        free(new->fingerprint);
        new->fingerprint = strdup(fingerprint);
    }
    if (map_type) {
        new->map_type = map_type;
    }
    if (name) {
        free(new->name);
        new->name = strdup(name);
    }

    return 0;
}

API int
nc_server_tls_endpt_add_ctn(const char *endpt_name, uint32_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type,
        const char *name)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_add_ctn(id, fingerprint, map_type, name, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_endpt_add_ctn(const char *client_name, const char *endpt_name, uint32_t id,
        const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_add_ctn(id, fingerprint, map_type, name, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

static int
nc_server_tls_del_ctn(int64_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name,
        struct nc_server_tls_opts *opts)
{
    struct nc_ctn *ctn, *next, *prev;
    int ret = -1;

    if ((id < 0) && !fingerprint && !map_type && !name) {
        ctn = opts->ctn;
        while (ctn) {
            free(ctn->fingerprint);
            free(ctn->name);

            next = ctn->next;
            free(ctn);
            ctn = next;

            ret = 0;
        }
        opts->ctn = NULL;
    } else {
        prev = NULL;
        ctn = opts->ctn;
        while (ctn) {
            if (((id < 0) || (ctn->id == id)) &&
                    (!fingerprint || !strcmp(ctn->fingerprint, fingerprint)) &&
                    (!map_type || (ctn->map_type == map_type)) &&
                    (!name || (ctn->name && !strcmp(ctn->name, name)))) {
                free(ctn->fingerprint);
                free(ctn->name);

                if (prev) {
                    prev->next = ctn->next;
                    next = ctn->next;
                } else {
                    opts->ctn = ctn->next;
                    next = ctn->next;
                }
                free(ctn);
                ctn = next;

                ret = 0;
            } else {
                prev = ctn;
                ctn = ctn->next;
            }
        }
    }

    return ret;
}

API int
nc_server_tls_endpt_del_ctn(const char *endpt_name, int64_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type,
        const char *name)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_del_ctn(id, fingerprint, map_type, name, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_endpt_del_ctn(const char *client_name, const char *endpt_name, int64_t id,
        const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_del_ctn(id, fingerprint, map_type, name, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

static int
nc_server_tls_get_ctn(uint32_t *id, char **fingerprint, NC_TLS_CTN_MAPTYPE *map_type, char **name,
        struct nc_server_tls_opts *opts)
{
    struct nc_ctn *ctn;
    int ret = -1;

    for (ctn = opts->ctn; ctn; ctn = ctn->next) {
        if (id && *id && (*id != ctn->id)) {
            continue;
        }
        if (fingerprint && *fingerprint && (!ctn->fingerprint || strcmp(*fingerprint, ctn->fingerprint))) {
            continue;
        }
        if (map_type && *map_type && (!ctn->map_type || (*map_type != ctn->map_type))) {
            continue;
        }
        if (name && *name && (!ctn->name || strcmp(*name, ctn->name))) {
            continue;
        }

        /* first match, good enough */
        if (id && !(*id)) {
            *id = ctn->id;
        }
        if (fingerprint && !(*fingerprint) && ctn->fingerprint) {
            *fingerprint = strdup(ctn->fingerprint);
        }
        if (map_type && !(*map_type) && ctn->map_type) {
            *map_type = ctn->map_type;
        }
        if (name && !(*name) && ctn->name) {
            *name = strdup(ctn->name);
        }

        ret = 0;
        break;
    }

    return ret;
}

API int
nc_server_tls_endpt_get_ctn(const char *endpt_name, uint32_t *id, char **fingerprint, NC_TLS_CTN_MAPTYPE *map_type,
        char **name)
{
    int ret;
    struct nc_endpt *endpt;

    if (!endpt_name) {
        ERRARG("endpt_name");
        return -1;
    }

    /* LOCK */
    endpt = nc_server_endpt_lock_get(endpt_name, NC_TI_OPENSSL, NULL);
    if (!endpt) {
        return -1;
    }
    ret = nc_server_tls_get_ctn(id, fingerprint, map_type, name, endpt->opts.tls);
    /* UNLOCK */
    pthread_rwlock_unlock(&server_opts.endpt_lock);

    return ret;
}

API int
nc_server_tls_ch_client_endpt_get_ctn(const char *client_name, const char *endpt_name, uint32_t *id, char **fingerprint,
        NC_TLS_CTN_MAPTYPE *map_type, char **name)
{
    int ret;
    struct nc_ch_client *client;
    struct nc_ch_endpt *endpt;

    /* LOCK */
    endpt = nc_server_ch_client_lock(client_name, endpt_name, NC_TI_OPENSSL, &client);
    if (!endpt) {
        return -1;
    }

    ret = nc_server_tls_get_ctn(id, fingerprint, map_type, name, endpt->opts.tls);

    /* UNLOCK */
    nc_server_ch_client_unlock(client);

    return ret;
}

API const X509 *
nc_session_get_client_cert(const struct nc_session *session)
{
    if (!session || (session->side != NC_SERVER)) {
        ERRARG("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;
}

void
nc_server_tls_clear_opts(struct nc_server_tls_opts *opts)
{
    free(opts->server_cert);
    nc_server_tls_del_trusted_cert_list(NULL, opts);
    free(opts->trusted_ca_file);
    free(opts->trusted_ca_dir);
    nc_server_tls_clear_crls(opts);
    nc_server_tls_del_ctn(-1, NULL, 0, NULL, opts);
}

static void
nc_tls_make_verify_key(void)
{
    pthread_key_create(&verify_key, NULL);
}

static X509 *
tls_load_cert(const char *cert_path, const char *cert_data)
{
    X509 *cert;

    if (cert_path) {
        cert = pem_to_cert(cert_path);
    } else {
        cert = base64der_to_cert(cert_data);
    }

    if (!cert) {
        if (cert_path) {
            ERR(NULL, "Loading a trusted certificate (path \"%s\") failed (%s).", cert_path,
                    ERR_reason_error_string(ERR_get_error()));
        } else {
            ERR(NULL, "Loading a trusted certificate (data \"%s\") failed (%s).", cert_data,
                    ERR_reason_error_string(ERR_get_error()));
        }
    }
    return cert;
}

static int
nc_tls_ctx_set_server_cert_chain(SSL_CTX *tls_ctx, const char *cert_name)
{
    char **cert_paths = NULL, **cert_data = NULL;
    int cert_path_count = 0, cert_data_count = 0, ret = 0, i = 0;
    X509 *cert = NULL;

    if (!server_opts.server_cert_chain_clb) {
        /* This is optional, so return OK */
        return 0;
    }

    if (server_opts.server_cert_chain_clb(cert_name, server_opts.server_cert_chain_data, &cert_paths,
            &cert_path_count, &cert_data, &cert_data_count)) {
        ERR(NULL, "Server certificate chain callback failed.");
        return -1;
    }

    for (i = 0; i < cert_path_count; ++i) {
        cert = tls_load_cert(cert_paths[i], NULL);
        if (!cert || (SSL_CTX_add_extra_chain_cert(tls_ctx, cert) != 1)) {
            ERR(NULL, "Loading the server certificate chain failed (%s).", ERR_reason_error_string(ERR_get_error()));
            ret = -1;
            goto cleanup;
        }
    }

    for (i = 0; i < cert_data_count; ++i) {
        cert = tls_load_cert(NULL, cert_data[i]);
        if (!cert || (SSL_CTX_add_extra_chain_cert(tls_ctx, cert) != 1)) {
            ERR(NULL, "Loading the server certificate chain failed (%s).", ERR_reason_error_string(ERR_get_error()));
            ret = -1;
            goto cleanup;
        }
    }
cleanup:
    for (i = 0; i < cert_path_count; ++i) {
        free(cert_paths[i]);
    }
    free(cert_paths);
    for (i = 0; i < cert_data_count; ++i) {
        free(cert_data[i]);
    }
    free(cert_data);
    /* cert is owned by the SSL_CTX */

    return ret;
}

static int
nc_tls_ctx_set_server_cert_key(SSL_CTX *tls_ctx, const char *cert_name)
{
    char *cert_path = NULL, *cert_data = NULL, *privkey_path = NULL, *privkey_data = NULL;
    int ret = 0;
    NC_SSH_KEY_TYPE privkey_type;
    X509 *cert = NULL;
    EVP_PKEY *pkey = NULL;

    if (!cert_name) {
        ERR(NULL, "Server certificate not set.");
        return -1;
    } else if (!server_opts.server_cert_clb) {
        ERR(NULL, "Callback for retrieving the server certificate is not set.");
        return -1;
    }

    if (server_opts.server_cert_clb(cert_name, server_opts.server_cert_data, &cert_path, &cert_data, &privkey_path,
            &privkey_data, &privkey_type)) {
        ERR(NULL, "Server certificate callback failed.");
        return -1;
    }

    /* load the certificate */
    if (cert_path) {
        if (SSL_CTX_use_certificate_file(tls_ctx, cert_path, SSL_FILETYPE_PEM) != 1) {
            ERR(NULL, "Loading the server certificate failed (%s).", ERR_reason_error_string(ERR_get_error()));
            ret = -1;
            goto cleanup;
        }
    } else {
        cert = base64der_to_cert(cert_data);
        if (!cert || (SSL_CTX_use_certificate(tls_ctx, cert) != 1)) {
            ERR(NULL, "Loading the server certificate failed (%s).", ERR_reason_error_string(ERR_get_error()));
            ret = -1;
            goto cleanup;
        }
    }

    /* load the private key */
    if (privkey_path) {
        if (SSL_CTX_use_PrivateKey_file(tls_ctx, privkey_path, SSL_FILETYPE_PEM) != 1) {
            ERR(NULL, "Loading the server private key failed (%s).", ERR_reason_error_string(ERR_get_error()));
            ret = -1;
            goto cleanup;
        }
    } else {
        pkey = base64der_to_privatekey(privkey_data, nc_keytype2str(privkey_type));
        if (!pkey || (SSL_CTX_use_PrivateKey(tls_ctx, pkey) != 1)) {
            ERR(NULL, "Loading the server private key failed (%s).", ERR_reason_error_string(ERR_get_error()));
            ret = -1;
            goto cleanup;
        }
    }

    ret = nc_tls_ctx_set_server_cert_chain(tls_ctx, cert_name);

cleanup:
    X509_free(cert);
    EVP_PKEY_free(pkey);
    free(cert_path);
    free(cert_data);
    free(privkey_path);
    free(privkey_data);
    return ret;
}

static void
tls_store_add_trusted_cert(X509_STORE *cert_store, const char *cert_path, const char *cert_data)
{
    X509 *cert = tls_load_cert(cert_path, cert_data);

    if (!cert) {
        return;
    }

    /* add the trusted certificate */
    if (X509_STORE_add_cert(cert_store, cert) != 1) {
        ERR(NULL, "Adding a trusted certificate failed (%s).", ERR_reason_error_string(ERR_get_error()));
        X509_free(cert);
        return;
    }
    X509_free(cert);
}

static int
nc_tls_store_set_trusted_certs(X509_STORE *cert_store, char **trusted_cert_lists, uint16_t trusted_cert_list_count)
{
    uint16_t i;
    int j;
    char **cert_paths, **cert_data;
    int cert_path_count, cert_data_count;

    if (!server_opts.trusted_cert_list_clb) {
        ERR(NULL, "Callback for retrieving trusted certificate lists is not set.");
        return -1;
    }

    for (i = 0; i < trusted_cert_list_count; ++i) {
        cert_paths = cert_data = NULL;
        cert_path_count = cert_data_count = 0;
        if (server_opts.trusted_cert_list_clb(trusted_cert_lists[i], server_opts.trusted_cert_list_data,
                &cert_paths, &cert_path_count, &cert_data, &cert_data_count)) {
            ERR(NULL, "Trusted certificate list callback for \"%s\" failed.", trusted_cert_lists[i]);
            return -1;
        }

        for (j = 0; j < cert_path_count; ++j) {
            tls_store_add_trusted_cert(cert_store, cert_paths[j], NULL);
            free(cert_paths[j]);
        }
        free(cert_paths);

        for (j = 0; j < cert_data_count; ++j) {
            tls_store_add_trusted_cert(cert_store, NULL, cert_data[j]);
            free(cert_data[j]);
        }
        free(cert_data);
    }

    return 0;
}

int
nc_accept_tls_session(struct nc_session *session, int sock, int timeout)
{
    X509_STORE *cert_store;
    SSL_CTX *tls_ctx;
    X509_LOOKUP *lookup;
    struct nc_server_tls_opts *opts;
    int ret;
    struct timespec ts_timeout, ts_cur;

    opts = session->data;

    /* SSL_CTX */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L // >= 1.1.0
    tls_ctx = SSL_CTX_new(TLS_server_method());
#else
    tls_ctx = SSL_CTX_new(TLSv1_2_server_method());
#endif
    if (!tls_ctx) {
        ERR(session, "Failed to create TLS context.");
        goto error;
    }
    SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nc_tlsclb_verify);
    if (nc_tls_ctx_set_server_cert_key(tls_ctx, opts->server_cert)) {
        goto error;
    }

    /* X509_STORE, managed (freed) with the context */
    cert_store = X509_STORE_new();
    SSL_CTX_set_cert_store(tls_ctx, cert_store);

    if (nc_tls_store_set_trusted_certs(cert_store, opts->trusted_cert_lists, opts->trusted_cert_list_count)) {
        goto error;
    }

    if (opts->trusted_ca_file) {
        lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_file());
        if (!lookup) {
            ERR(session, "Failed to add a lookup method.");
            goto error;
        }

        if (X509_LOOKUP_load_file(lookup, opts->trusted_ca_file, X509_FILETYPE_PEM) != 1) {
            ERR(session, "Failed to add a trusted cert file (%s).", ERR_reason_error_string(ERR_get_error()));
            goto error;
        }
    }

    if (opts->trusted_ca_dir) {
        lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_hash_dir());
        if (!lookup) {
            ERR(session, "Failed to add a lookup method.");
            goto error;
        }

        if (X509_LOOKUP_add_dir(lookup, opts->trusted_ca_dir, X509_FILETYPE_PEM) != 1) {
            ERR(session, "Failed to add a trusted cert directory (%s).", ERR_reason_error_string(ERR_get_error()));
            goto error;
        }
    }

    session->ti_type = NC_TI_OPENSSL;
    session->ti.tls = SSL_new(tls_ctx);

    /* context can be freed already, trusted certs must be freed manually */
    SSL_CTX_free(tls_ctx);
    tls_ctx = NULL;

    if (!session->ti.tls) {
        ERR(session, "Failed to create TLS structure from context.");
        goto error;
    }

    SSL_set_fd(session->ti.tls, sock);
    sock = -1;
    SSL_set_mode(session->ti.tls, SSL_MODE_AUTO_RETRY);

    /* store session on per-thread basis */
    pthread_once(&verify_once, nc_tls_make_verify_key);
    pthread_setspecific(verify_key, session);

    if (timeout > -1) {
        nc_gettimespec_mono(&ts_timeout);
        nc_addtimespec(&ts_timeout, timeout);
    }
    while (((ret = SSL_accept(session->ti.tls)) == -1) && (SSL_get_error(session->ti.tls, ret) == SSL_ERROR_WANT_READ)) {
        usleep(NC_TIMEOUT_STEP);
        if (timeout > -1) {
            nc_gettimespec_mono(&ts_cur);
            if (nc_difftimespec(&ts_cur, &ts_timeout) < 1) {
                ERR(session, "SSL_accept timeout.");
                return 0;
            }
        }
    }

    if (ret != 1) {
        switch (SSL_get_error(session->ti.tls, ret)) {
        case SSL_ERROR_SYSCALL:
            ERR(session, "SSL_accept failed (%s).", strerror(errno));
            break;
        case SSL_ERROR_SSL:
            ERR(session, "SSL_accept failed (%s).", ERR_reason_error_string(ERR_get_error()));
            break;
        default:
            ERR(session, "SSL_accept failed.");
            break;
        }
        return -1;
    }

    return 1;

error:
    if (sock > -1) {
        close(sock);
    }
    SSL_CTX_free(tls_ctx);
    return -1;
}
