/**
 * @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 <openssl/bio.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 "config.h"
#include "log_p.h"
#include "session.h"
#include "session_p.h"

struct nc_server_tls_opts tls_ch_opts;
extern struct nc_server_opts server_opts;

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;
}

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 (!key_str) {
        /* avoid writing (null) for possibly unknown key formats */
        key_str = "";
    }
    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;

    *username = NULL;

    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);
        NC_CHECK_ERRMEM_RET(!*username, 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)) {
                *username = strdup((char *)ASN1_STRING_get0_data(san_name->d.rfc822Name));
                NC_CHECK_ERRMEM_RET(!*username, 1);
                break;
            }

            /* dNSName */
            if (((map_type == NC_TLS_CTN_SAN_ANY) || (map_type == NC_TLS_CTN_SAN_DNS_NAME)) &&
                    (san_name->type == GEN_DNS)) {
                *username = strdup((char *)ASN1_STRING_get0_data(san_name->d.dNSName));
                NC_CHECK_ERRMEM_RET(!*username, 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_session *session, struct nc_ctn *ctn_first, X509 *cert)
{
    char *digest_md5 = NULL, *digest_sha1 = NULL, *digest_sha224 = NULL;
    char *digest_sha256 = NULL, *digest_sha384 = NULL, *digest_sha512 = NULL;
    unsigned char *buf;
    unsigned int buf_len = 64;
    int ret = 0;
    struct nc_ctn *ctn;
    NC_TLS_CTN_MAPTYPE map_type;
    char *username = NULL;

    buf = malloc(buf_len);
    NC_CHECK_ERRMEM_RET(!buf, -1);

    if (!session || !cert) {
        free(buf);
        return -1;
    }

    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(session, "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) {
                if (X509_digest(cert, EVP_md5(), buf, &buf_len) != 1) {
                    ERR(session, "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 potential winner! */
                VRB(session, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }
            free(digest_md5);
            digest_md5 = NULL;

            /* SHA-1 */
        } else if (!strncmp(ctn->fingerprint, "02", 2)) {
            if (!digest_sha1) {
                if (X509_digest(cert, EVP_sha1(), buf, &buf_len) != 1) {
                    ERR(session, "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 potential winner! */
                VRB(session, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }
            free(digest_sha1);
            digest_sha1 = NULL;

            /* SHA-224 */
        } else if (!strncmp(ctn->fingerprint, "03", 2)) {
            if (!digest_sha224) {
                if (X509_digest(cert, EVP_sha224(), buf, &buf_len) != 1) {
                    ERR(session, "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 potential winner! */
                VRB(session, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }
            free(digest_sha224);
            digest_sha224 = NULL;

            /* SHA-256 */
        } else if (!strncmp(ctn->fingerprint, "04", 2)) {
            if (!digest_sha256) {
                if (X509_digest(cert, EVP_sha256(), buf, &buf_len) != 1) {
                    ERR(session, "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 potential winner! */
                VRB(session, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }
            free(digest_sha256);
            digest_sha256 = NULL;

            /* SHA-384 */
        } else if (!strncmp(ctn->fingerprint, "05", 2)) {
            if (!digest_sha384) {
                if (X509_digest(cert, EVP_sha384(), buf, &buf_len) != 1) {
                    ERR(session, "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 potential winner! */
                VRB(session, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }
            free(digest_sha384);
            digest_sha384 = NULL;

            /* SHA-512 */
        } else if (!strncmp(ctn->fingerprint, "06", 2)) {
            if (!digest_sha512) {
                if (X509_digest(cert, EVP_sha512(), buf, &buf_len) != 1) {
                    ERR(session, "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 potential winner! */
                VRB(session, "Cert verify CTN: entry with a matching fingerprint found.");
                map_type = ctn->map_type;
            }
            free(digest_sha512);
            digest_sha512 = NULL;

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

        if (map_type != NC_TLS_CTN_UNKNOWN) {
            /* found a fingerprint match */
            if (map_type == NC_TLS_CTN_SPECIFIED) {
                /* specified -> get username from the ctn entry */
                session->username = strdup(ctn->name);
                NC_CHECK_ERRMEM_GOTO(!session->username, ret = -1, cleanup);
            } else {
                /* try to get the username from the cert with this ctn's map type */
                ret = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &username);
                if (ret == -1) {
                    /* fatal error */
                    goto cleanup;
                } else if (ret) {
                    /* didn't get username, try next ctn entry */
                    continue;
                }

                /* success */
                session->username = username;
            }

            /* matching fingerprint found and username obtained, success */
            ret = 0;
            goto cleanup;
        }
    }

    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;
}

static int
nc_server_tls_check_crl(X509_STORE *crl_store, X509_STORE_CTX *x509_ctx, X509 *cert,
        const X509_NAME *subject, const X509_NAME *issuer)
{
    int n, i, ret = 0;
    X509_STORE_CTX *store_ctx = NULL;
    X509_OBJECT *obj = NULL;
    X509_CRL *crl;
    X509_REVOKED *revoked;
    EVP_PKEY *pubkey;
    const ASN1_INTEGER *serial;
    const ASN1_TIME *last_update = NULL, *next_update = NULL;
    char *cp;

    store_ctx = X509_STORE_CTX_new();
    NC_CHECK_ERRMEM_GOTO(!store_ctx, ret = -1, cleanup);

    /* init store context */
    ret = X509_STORE_CTX_init(store_ctx, crl_store, NULL, NULL);
    if (!ret) {
        ERR(NULL, "Initializing x509 store ctx failed (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }
    ret = 0;

    /* try to find a CRL entry that corresponds to the current certificate in question */
    obj = X509_STORE_CTX_get_obj_by_subject(store_ctx, X509_LU_CRL, subject);
    crl = X509_OBJECT_get0_X509_CRL(obj);
    X509_OBJECT_free(obj);
    if (crl) {
        /* found it */
        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_get0_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);
            ret = -1;
            goto cleanup;
        }

        /* 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);
            ret = -1;
            goto cleanup;
        }

        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);
            ret = -1;
            goto cleanup;
        }
    }

    /* try to retrieve a CRL corresponding to the _issuer_ of
     * the current certificate in order to check for revocation */
    obj = X509_STORE_CTX_get_obj_by_subject(store_ctx, X509_LU_CRL, issuer);
    crl = X509_OBJECT_get0_X509_CRL(obj);
    if (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);
                ret = -1;
                goto cleanup;
            }
        }
    }

cleanup:
    X509_STORE_CTX_free(store_ctx);
    X509_OBJECT_free(obj);
    return ret;
}

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;
}

/* In case a CA chain verification failed an end-entity certificate must match.
 * The meaning of local_or_referenced is that it states, which end-entity certificates to check
 * (1 = current endpoint's, 2 = referenced endpoint's).
 */
static int
nc_server_tls_do_preverify(struct nc_session *session, X509_STORE_CTX *x509_ctx, int local_or_referenced)
{
    X509_STORE *store;
    struct nc_cert_grouping *ee_certs;
    int i, ret;
    X509 *cert;
    struct nc_certificate *certs;
    uint16_t cert_count;

    store = X509_STORE_CTX_get0_store(x509_ctx);
    if (!store) {
        ERR(session, "Error getting store from context (%s).", ERR_reason_error_string(ERR_get_error()));
        return -1;
    }

    /* get the data from the store */
    ee_certs = X509_STORE_get_ex_data(store, local_or_referenced);
    if (!ee_certs) {
        ERR(session, "Error getting data from store (%s).", ERR_reason_error_string(ERR_get_error()));
        return -1;
    }

    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++) {
        cert = base64der_to_cert(certs[i].data);
        ret = cert_pubkey_match(session->opts.server.client_cert, cert);
        X509_free(cert);
        if (ret) {
            /* 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 end-entity 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);
            return 1;
        }
    }

    return 0;
}

static int
nc_tlsclb_verify(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    char *cp;
    X509_STORE *store;

    STACK_OF(X509) * cert_stack;
    struct nc_session *session;
    struct nc_server_tls_opts *opts;
    struct nc_endpt *referenced_endpt;
    int rc, depth;

    store = X509_STORE_CTX_get0_store(x509_ctx);
    if (!store) {
        ERR(NULL, "Error getting store from context (%s).", ERR_reason_error_string(ERR_get_error()));
        return 0;
    }

    /* get session from the store */
    session = X509_STORE_get_ex_data(store, 0);
    if (!session) {
        ERR(session, "Error getting session from store (%s).", ERR_reason_error_string(ERR_get_error()));
        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 an end-entity client cert must match to continue */
    if (!preverify_ok) {
        /* check current endpoint's end-entity certs */
        rc = nc_server_tls_do_preverify(session, x509_ctx, 1);
        if (rc == -1) {
            return 0;
        } else if (rc == 1) {
            return 1;
        }

        /* no match, continue */
        if (opts->referenced_endpt_name) {
            /* check referenced endpoint's end-entity certs */
            rc = nc_server_tls_do_preverify(session, x509_ctx, 2);
            if (rc == -1) {
                return 0;
            } else if (rc == 1) {
                return 1;
            }
        }

        /* no match, fail */
        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 if the current certificate is revoked if CRL is set */
    if (opts->crl_store) {
        rc = nc_server_tls_check_crl(opts->crl_store, x509_ctx, cert, subject, issuer);
        if (rc) {
            return 0;
        }
    }

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

    /* cert-to-name */
    rc = nc_tls_cert_to_name(session, opts->ctn, cert);
    if (rc == -1) {
        /* fatal error */
        depth = 0;
        goto fail;
    } else if ((rc == 1) && !opts->referenced_endpt_name) {
        /* no match found and no referenced endpoint */
        goto fail;
    } else if ((rc == 1) && opts->referenced_endpt_name) {
        /* no match found, but has a referenced endpoint so try it */
        if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
            /* fatal error */
            ERRINT;
            depth = 0;
            goto fail;
        }

        rc = nc_tls_cert_to_name(session, referenced_endpt->opts.tls->ctn, cert);
        if (rc) {
            if (rc == -1) {
                /* fatal error */
                depth = 0;
            }
            /* rc == 1 is a normal CTN fail (no match found) */
            goto fail;
        }
    }

    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;
}

API const X509 *
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;
}

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_tls_ctx_set_server_cert_key(SSL_CTX *tls_ctx, struct nc_server_tls_opts *opts)
{
    char *privkey_data = NULL, *cert_data = NULL;
    int ret = 0;
    NC_PRIVKEY_FORMAT privkey_type;
    X509 *cert = NULL;
    EVP_PKEY *pkey = NULL;

    NC_CHECK_ARG_RET(NULL, tls_ctx, opts, -1);

    /* 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 */
        ret = nc_server_tls_ks_ref_get_cert_key(opts->key_ref, opts->cert_ref, &privkey_data, &privkey_type, &cert_data);
        if (ret) {
            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.");
        ret = -1;
        goto cleanup;
    }

    /* load the cert */
    cert = base64der_to_cert(cert_data);
    if (!cert) {
        ERR(NULL, "Converting certificate data to certificate format failed.");
        ret = -1;
        goto cleanup;
    }

    /* set server cert */
    ret = SSL_CTX_use_certificate(tls_ctx, cert);
    if (ret != 1) {
        ERR(NULL, "Loading the server certificate failed (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }

    /* load the private key */
    pkey = base64der_to_privatekey(privkey_data, nc_privkey_format_to_str(privkey_type));
    if (!pkey) {
        ERR(NULL, "Converting private key data to private key format failed.");
        ret = -1;
        goto cleanup;
    }

    /* set server key */
    ret = SSL_CTX_use_PrivateKey(tls_ctx, pkey);
    if (ret != 1) {
        ERR(NULL, "Loading the server private key failed (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }

    ret = 0;

cleanup:
    X509_free(cert);
    EVP_PKEY_free(pkey);
    return ret;
}

static int
tls_store_add_trusted_cert(X509_STORE *cert_store, const char *cert_data)
{
    X509 *cert;

    cert = base64der_to_cert(cert_data);

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

    /* 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 -1;
    }
    X509_free(cert);

    return 0;
}

static int
nc_tls_store_set_trusted_certs(X509_STORE *cert_store, struct nc_cert_grouping *ca_certs)
{
    uint16_t i;
    struct nc_certificate *certs;
    uint16_t cert_count;

    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++) {
        if (tls_store_add_trusted_cert(cert_store, certs[i].data)) {
            return -1;
        }
    }

    return 0;
}

static int
nc_server_tls_crl_path(struct nc_session *session, const char *crl_path, X509_STORE *store)
{
    int ret = 0;
    X509_CRL *crl = NULL;
    FILE *f;

    f = fopen(crl_path, "r");
    if (!f) {
        ERR(session, "Unable to open CRL file \"%s\".", crl_path);
        return -1;
    }

    /* try DER first */
    crl = d2i_X509_CRL_fp(f, NULL);
    if (crl) {
        /* success */
        goto ok;
    }

    /* DER failed, try PEM */
    rewind(f);
    crl = PEM_read_X509_CRL(f, NULL, NULL, NULL);
    if (!crl) {
        ERR(session, "Reading CRL from file \"%s\" failed.", crl_path);
        ret = -1;
        goto cleanup;
    }

ok:
    ret = X509_STORE_add_crl(store, crl);
    if (!ret) {
        ERR(session, "Error adding CRL to store (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }
    /* ok */
    ret = 0;

cleanup:
    fclose(f);
    X509_CRL_free(crl);
    return ret;
}

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_init(struct nc_session *session, CURL **handle, struct nc_curl_data *data)
{
    NC_CHECK_ARG_RET(session, handle, data, -1);

    *handle = NULL;

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

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

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

    return 0;
}

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

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

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

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

    return 0;
}

static int
nc_server_tls_add_crl_to_store(struct nc_session *session, struct nc_curl_data *downloaded, X509_STORE *store)
{
    int ret = 0;
    X509_CRL *crl = NULL;
    BIO *bio = NULL;

    /* try DER first */
    crl = d2i_X509_CRL(NULL, (const unsigned char **) &downloaded->data, downloaded->size);
    if (crl) {
        /* it was DER */
        goto ok;
    }

    /* DER failed, try PEM next */
    bio = BIO_new_mem_buf(downloaded->data, downloaded->size);
    if (!bio) {
        ERR(session, "Creating new bio failed (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }

    /* try to parse PEM from the downloaded data */
    crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
    if (!crl) {
        ERR(session, "Reading downloaded CRL failed (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }

ok:
    /* we obtained the CRL, now add it to the CRL store */
    ret = X509_STORE_add_crl(store, crl);
    if (!ret) {
        ERR(session, "Error adding CRL to store (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }
    /* ok */
    ret = 0;

cleanup:
    X509_CRL_free(crl);
    BIO_free(bio);
    return ret;
}

static int
nc_server_tls_crl_url(struct nc_session *session, const char *url, X509_STORE *store)
{
    int ret = 0;
    CURL *handle = NULL;
    struct nc_curl_data downloaded = {0};

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

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

    /* download the CRL */
    ret = nc_server_tls_curl_fetch(session, 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(session, &downloaded, store);
    if (ret) {
        goto cleanup;
    }

cleanup:
    curl_easy_cleanup(handle);
    return ret;
}

static int
nc_server_tls_crl_cert_ext(struct nc_session *session, X509_STORE *cert_store, X509_STORE *crl_store)
{
    int ret = 0, i, j, k, gtype;
    CURL *handle = NULL;
    struct nc_curl_data downloaded = {0};

    STACK_OF(X509_OBJECT) * objs;
    X509_OBJECT *obj;
    X509 *cert;

    STACK_OF(DIST_POINT) * dist_points;
    DIST_POINT *dist_point;
    GENERAL_NAMES *general_names;
    GENERAL_NAME *general_name;
    ASN1_STRING *asn_string_uri;
    const char *crl_distpoint_uri;

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

    /* treat all entries in the cert_store as X509_OBJECTs */
    objs = X509_STORE_get0_objects(cert_store);
    if (!objs) {
        ERR(session, "Getting certificates from store failed (%s).", ERR_reason_error_string(ERR_get_error()));
        ret = -1;
        goto cleanup;
    }

    /* iterate over all the CAs */
    for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
        obj = sk_X509_OBJECT_value(objs, i);
        cert = X509_OBJECT_get0_X509(obj);
        if (!cert) {
            /* the object on this index was not a certificate */
            continue;
        }

        /* get all the distribution points for this CA */
        dist_points = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL);

        /* iterate over all the dist points (there can be multiple for a single cert) */
        for (j = 0; j < sk_DIST_POINT_num(dist_points); j++) {
            dist_point = sk_DIST_POINT_value(dist_points, j);
            if (!dist_point) {
                continue;
            }
            general_names = dist_point->distpoint->name.fullname;

            /* iterate over all the GeneralesNames in the distribution point */
            for (k = 0; k < sk_GENERAL_NAME_num(general_names); k++) {
                general_name = sk_GENERAL_NAME_value(general_names, k);
                asn_string_uri = GENERAL_NAME_get0_value(general_name, &gtype);

                /* check if the general name is a URI and has a valid length */
                if ((gtype != GEN_URI) || (ASN1_STRING_length(asn_string_uri) <= 6)) {
                    continue;
                }

                crl_distpoint_uri = (const char *) ASN1_STRING_get0_data(asn_string_uri);

                VRB(session, "Downloading CRL from \"%s\".", crl_distpoint_uri);

                /* download the CRL */
                ret = nc_server_tls_curl_fetch(session, handle, crl_distpoint_uri);
                if (ret) {
                    /* failed to download the CRL from this entry, try th next */
                    continue;
                }

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

                /* the CRL was downloaded, no need to download it again using different protocol */
                break;
            }
        }
    }

cleanup:
    curl_easy_cleanup(handle);
    return ret;
}

static int
nc_tls_store_set_crl(struct nc_session *session, struct nc_server_tls_opts *opts, X509_STORE *store)
{
    if (!opts->crl_store) {
        /* first call on this endpoint */
        opts->crl_store = X509_STORE_new();
        NC_CHECK_ERRMEM_GOTO(!opts->crl_store, , fail);
    }

    if (opts->crl_path) {
        if (nc_server_tls_crl_path(session, opts->crl_path, opts->crl_store)) {
            goto fail;
        }
    } else if (opts->crl_url) {
        if (nc_server_tls_crl_url(session, opts->crl_url, opts->crl_store)) {
            goto fail;
        }
    } else {
        if (nc_server_tls_crl_cert_ext(session, store, opts->crl_store)) {
            goto fail;
        }
    }

    return 0;

fail:
    return -1;
}

static int
nc_server_tls_accept_check(int accept_ret, struct nc_session *session)
{
    int verify;

    /* check certificate verification result */
    verify = SSL_get_verify_result(session->ti.tls);
    switch (verify) {
    case X509_V_OK:
        if (accept_ret == 1) {
            VRB(session, "Client certificate verified.");
        }
        break;
    default:
        ERR(session, "Client certificate error (%s).", X509_verify_cert_error_string(verify));
    }

    if (accept_ret != 1) {
        switch (SSL_get_error(session->ti.tls, accept_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 accept_ret;
}

int
nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opts, int sock, int timeout)
{
    X509_STORE *cert_store;
    SSL_CTX *tls_ctx;
    int ret;
    struct timespec ts_timeout;
    struct nc_endpt *referenced_endpt = NULL;

    /* SSL_CTX */
    tls_ctx = SSL_CTX_new(TLS_server_method());

    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)) {
        goto error;
    }

    /* X509_STORE, managed (freed) with the context */
    cert_store = X509_STORE_new();
    if (!cert_store) {
        ERR(session, "Creating certificate store failed (%s).", ERR_reason_error_string(ERR_get_error()));
        goto error;
    }

    /* store the session, retrieve it when needed */
    ret = X509_STORE_set_ex_data(cert_store, 0, session);
    if (!ret) {
        ERR(session, "Setting certificate store data failed (%s).", ERR_reason_error_string(ERR_get_error()));
        goto error;
    }

    /* set end-entity certs as cert store data, retrieve them if verification fails later */
    ret = X509_STORE_set_ex_data(cert_store, 1, &opts->ee_certs);
    if (!ret) {
        ERR(session, "Setting certificate store data failed (%s).", ERR_reason_error_string(ERR_get_error()));
        goto error;
    }

    /* do the same for referenced endpoint's end entity certs */
    if (opts->referenced_endpt_name) {
        if (nc_server_get_referenced_endpt(opts->referenced_endpt_name, &referenced_endpt)) {
            ERRINT;
            goto error;
        }

        ret = X509_STORE_set_ex_data(cert_store, 2, &referenced_endpt->opts.tls->ee_certs);
        if (!ret) {
            ERR(session, "Setting certificate store data failed (%s).", ERR_reason_error_string(ERR_get_error()));
            goto error;
        }
    }

    /* set store to the context */
    SSL_CTX_set_cert_store(tls_ctx, cert_store);

    /* set certificate authority certs */
    if (nc_tls_store_set_trusted_certs(cert_store, &opts->ca_certs)) {
        goto error;
    }

    /* set referenced endpoint's CA certs if set */
    if (opts->referenced_endpt_name) {
        if (nc_tls_store_set_trusted_certs(cert_store, &referenced_endpt->opts.tls->ca_certs)) {
            goto error;
        }
    }

    /* set Certificate Revocation List if configured */
    if (opts->crl_path || opts->crl_url || opts->crl_cert_ext) {
        if (nc_tls_store_set_crl(session, opts, cert_store)) {
            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;
    }

    /* set TLS versions for the current SSL session */
    if (opts->tls_versions) {
        if (!(opts->tls_versions & NC_TLS_VERSION_10)) {
            SSL_set_options(session->ti.tls, SSL_OP_NO_TLSv1);
        }
        if (!(opts->tls_versions & NC_TLS_VERSION_11)) {
            SSL_set_options(session->ti.tls, SSL_OP_NO_TLSv1_1);
        }
        if (!(opts->tls_versions & NC_TLS_VERSION_12)) {
            SSL_set_options(session->ti.tls, SSL_OP_NO_TLSv1_2);
        }
        if (!(opts->tls_versions & NC_TLS_VERSION_13)) {
            SSL_set_options(session->ti.tls, SSL_OP_NO_TLSv1_3);
        }
    }

    /* set TLS cipher suites */
    if (opts->ciphers) {
        /* set for TLS1.2 and lower */
        SSL_set_cipher_list(session->ti.tls, opts->ciphers);
        /* set for TLS1.3 */
        SSL_set_ciphersuites(session->ti.tls, opts->ciphers);
    }

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

    if (timeout > -1) {
        nc_timeouttime_get(&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_timeouttime_cur_diff(&ts_timeout) < 1)) {
            ERR(session, "SSL accept timeout.");
            return 0;
        }
    }
    if (nc_server_tls_accept_check(ret, session) != 1) {
        return -1;
    }

    return 1;

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