/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
 *  Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/**
 * @file Control Channel Verification Module OpenSSL implementation
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL)

#include "ssl_verify_openssl.h"

#include "error.h"
#include "ssl_openssl.h"
#include "ssl_verify.h"
#include "ssl_verify_backend.h"
#include "openssl_compat.h"

#include <openssl/x509v3.h>
#include <openssl/err.h>

int
verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
{
    int ret = 0;
    struct tls_session *session;
    SSL *ssl;
    struct gc_arena gc = gc_new();

    /* get the tls_session pointer */
    ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
    ASSERT(ssl);
    session = (struct tls_session *) SSL_get_ex_data(ssl, mydata_index);
    ASSERT(session);

    X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
    struct buffer cert_hash = x509_get_sha256_fingerprint(current_cert, &gc);
    cert_hash_remember(session, X509_STORE_CTX_get_error_depth(ctx), &cert_hash);

    /* did peer present cert which was signed by our root cert? */
    if (!preverify_ok)
    {
        /* get the X509 name */
        char *subject = x509_get_subject(current_cert, &gc);

        if (!subject)
        {
            subject = "(Failed to retrieve certificate subject)";
        }

        /* Log and ignore missing CRL errors */
        if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL)
        {
            msg(D_TLS_DEBUG_LOW, "VERIFY WARNING: depth=%d, %s: %s",
                X509_STORE_CTX_get_error_depth(ctx),
                X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
                subject);
            ret = 1;
            goto cleanup;
        }

        /* Remote site specified a certificate, but it's not correct */
        msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s",
            X509_STORE_CTX_get_error_depth(ctx),
            X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
            subject);

        ERR_clear_error();

        session->verified = false;
        goto cleanup;
    }

    if (SUCCESS != verify_cert(session, current_cert, X509_STORE_CTX_get_error_depth(ctx)))
    {
        goto cleanup;
    }

    ret = 1;

cleanup:
    gc_free(&gc);

    return ret;
}

#ifdef ENABLE_X509ALTUSERNAME
bool x509_username_field_ext_supported(const char *fieldname)
{
    int nid = OBJ_txt2nid(fieldname);
    return nid == NID_subject_alt_name || nid == NID_issuer_alt_name;
}

static
bool
extract_x509_extension(X509 *cert, char *fieldname, char *out, int size)
{
    bool retval = false;
    char *buf = 0;

    if (!x509_username_field_ext_supported(fieldname))
    {
        msg(D_TLS_ERRORS,
            "ERROR: --x509-username-field 'ext:%s' not supported", fieldname);
        return false;
    }

    int nid = OBJ_txt2nid(fieldname);
    GENERAL_NAMES *extensions = X509_get_ext_d2i(cert, nid, NULL, NULL);
    if (extensions)
    {
        int numalts;
        int i;
        /* get amount of alternatives,
         * RFC2459 claims there MUST be at least
         * one, but we don't depend on it...
         */

        numalts = sk_GENERAL_NAME_num(extensions);

        /* loop through all alternatives */
        for (i = 0; i<numalts; i++)
        {
            /* get a handle to alternative name number i */
            const GENERAL_NAME *name = sk_GENERAL_NAME_value(extensions, i );

            switch (name->type)
            {
                case GEN_EMAIL:
                    if (ASN1_STRING_to_UTF8((unsigned char **)&buf, name->d.ia5) < 0)
                    {
                        continue;
                    }
                    if (strlen(buf) != name->d.ia5->length)
                    {
                        msg(D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero");
                        OPENSSL_free(buf);
                    }
                    else
                    {
                        strncpynt(out, buf, size);
                        OPENSSL_free(buf);
                        retval = true;
                    }
                    break;

                default:
                    msg(D_TLS_DEBUG, "%s: ignoring general name field type %i",
                        __func__, name->type);
                    break;
            }
        }
        GENERAL_NAMES_free(extensions);
    }
    return retval;
}
#endif /* ENABLE_X509ALTUSERNAME */

/*
 * Extract a field from an X509 subject name.
 *
 * Example:
 *
 * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net
 *
 * The common name is 'Test-CA'
 *
 * Return true on success, false on error (insufficient buffer size in 'out'
 * to contain result is grounds for error).
 */
static result_t
extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out,
                       int size)
{
    int lastpos = -1;
    int tmp = -1;
    X509_NAME_ENTRY *x509ne = NULL;
    ASN1_STRING *asn1 = NULL;
    unsigned char *buf = NULL;
    ASN1_OBJECT *field_name_obj = OBJ_txt2obj(field_name, 0);

    if (field_name_obj == NULL)
    {
        msg(D_TLS_ERRORS, "Invalid X509 attribute name '%s'", field_name);
        return FAILURE;
    }

    ASSERT(size > 0);
    *out = '\0';
    do
    {
        lastpos = tmp;
        tmp = X509_NAME_get_index_by_OBJ(x509, field_name_obj, lastpos);
    } while (tmp > -1);

    ASN1_OBJECT_free(field_name_obj);

    /* Nothing found */
    if (lastpos == -1)
    {
        return FAILURE;
    }

    x509ne = X509_NAME_get_entry(x509, lastpos);
    if (!x509ne)
    {
        return FAILURE;
    }

    asn1 = X509_NAME_ENTRY_get_data(x509ne);
    if (!asn1)
    {
        return FAILURE;
    }
    if (ASN1_STRING_to_UTF8(&buf, asn1) < 0)
    {
        return FAILURE;
    }

    strncpynt(out, (char *)buf, size);

    {
        const result_t ret = (strlen((char *)buf) < size) ? SUCCESS : FAILURE;
        OPENSSL_free(buf);
        return ret;
    }
}

result_t
backend_x509_get_username(char *common_name, int cn_len,
                          char *x509_username_field, X509 *peer_cert)
{
#ifdef ENABLE_X509ALTUSERNAME
    if (strncmp("ext:",x509_username_field,4) == 0)
    {
        if (!extract_x509_extension(peer_cert, x509_username_field+4, common_name, cn_len))
        {
            return FAILURE;
        }
    }
    else
#endif
    if (FAILURE == extract_x509_field_ssl(X509_get_subject_name(peer_cert),
                                          x509_username_field, common_name, cn_len))
    {
        return FAILURE;
    }

    return SUCCESS;
}

char *
backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
{
    ASN1_INTEGER *asn1_i;
    BIGNUM *bignum;
    char *openssl_serial, *serial;

    asn1_i = X509_get_serialNumber(cert);
    bignum = ASN1_INTEGER_to_BN(asn1_i, NULL);
    openssl_serial = BN_bn2dec(bignum);

    serial = string_alloc(openssl_serial, gc);

    BN_free(bignum);
    OPENSSL_free(openssl_serial);

    return serial;
}

char *
backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
{
    const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert);

    return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc);
}

struct buffer
x509_get_sha1_fingerprint(X509 *cert, struct gc_arena *gc)
{
    const EVP_MD *sha1 = EVP_sha1();
    struct buffer hash = alloc_buf_gc(EVP_MD_size(sha1), gc);
    X509_digest(cert, EVP_sha1(), BPTR(&hash), NULL);
    ASSERT(buf_inc_len(&hash, EVP_MD_size(sha1)));
    return hash;
}

struct buffer
x509_get_sha256_fingerprint(X509 *cert, struct gc_arena *gc)
{
    const EVP_MD *sha256 = EVP_sha256();
    struct buffer hash = alloc_buf_gc(EVP_MD_size(sha256), gc);
    X509_digest(cert, EVP_sha256(), BPTR(&hash), NULL);
    ASSERT(buf_inc_len(&hash, EVP_MD_size(sha256)));
    return hash;
}

char *
x509_get_subject(X509 *cert, struct gc_arena *gc)
{
    BIO *subject_bio = NULL;
    BUF_MEM *subject_mem;
    char *subject = NULL;

    /*
     * Generate the subject string in OpenSSL proprietary format,
     * when in --compat-names mode
     */
    if (compat_flag(COMPAT_FLAG_QUERY | COMPAT_NAMES))
    {
        subject = gc_malloc(256, false, gc);
        X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
        subject[255] = '\0';
        return subject;
    }

    subject_bio = BIO_new(BIO_s_mem());
    if (subject_bio == NULL)
    {
        goto err;
    }

    X509_NAME_print_ex(subject_bio, X509_get_subject_name(cert),
                       0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN
                       |ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL);

    if (BIO_eof(subject_bio))
    {
        goto err;
    }

    BIO_get_mem_ptr(subject_bio, &subject_mem);

    subject = gc_malloc(subject_mem->length + 1, false, gc);

    memcpy(subject, subject_mem->data, subject_mem->length);
    subject[subject_mem->length] = '\0';

err:
    if (subject_bio)
    {
        BIO_free(subject_bio);
    }

    return subject;
}


/*
 * x509-track implementation -- save X509 fields to environment,
 * using the naming convention:
 *
 *  X509_{cert_depth}_{name}={value}
 *
 * This function differs from x509_setenv below in the following ways:
 *
 * (1) Only explicitly named attributes in xt are saved, per usage
 *     of "x509-track" program options.
 * (2) Only the level 0 cert info is saved unless the XT_FULL_CHAIN
 *     flag is set in xt->flags (corresponds with prepending a '+'
 *     to the name when specified by "x509-track" program option).
 * (3) This function supports both X509 subject name fields as
 *     well as X509 V3 extensions.
 * (4) This function can return the SHA1 fingerprint of a cert, e.g.
 *       x509-track "+SHA1"
 *     will return the SHA1 fingerprint for each certificate in the
 *     peer chain.
 */

void
x509_track_add(const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
{
    struct x509_track *xt;
    ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
    if (*name == '+')
    {
        xt->flags |= XT_FULL_CHAIN;
        ++name;
    }
    xt->name = name;
    xt->nid = OBJ_txt2nid(name);
    if (xt->nid != NID_undef)
    {
        xt->next = *ll_head;
        *ll_head = xt;
    }
    else
    {
        msg(msglevel, "x509_track: no such attribute '%s'", name);
    }
}

/* worker method for setenv_x509_track */
static void
do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
{
    char *name_expand;
    size_t name_expand_size;

    string_mod(value, CC_ANY, CC_CRLF, '?');
    msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
    name_expand_size = 64 + strlen(name);
    name_expand = (char *) malloc(name_expand_size);
    check_malloc_return(name_expand);
    openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
    setenv_str(es, name_expand, value);
    free(name_expand);
}

void
x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
{
    struct gc_arena gc = gc_new();
    X509_NAME *x509_name = X509_get_subject_name(x509);
    const char nullc = '\0';

    while (xt)
    {
        if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
        {
            switch (xt->nid)
            {
                case NID_sha1:
                case NID_sha256:
                {
                    struct buffer fp_buf;
                    char *fp_str = NULL;

                    if (xt->nid == NID_sha1)
                    {
                        fp_buf = x509_get_sha1_fingerprint(x509, &gc);
                    }
                    else
                    {
                        fp_buf = x509_get_sha256_fingerprint(x509, &gc);
                    }

                    fp_str = format_hex_ex(BPTR(&fp_buf), BLEN(&fp_buf), 0,
                                           1 | FHE_CAPS, ":", &gc);
                    do_setenv_x509(es, xt->name, fp_str, depth);
                }
                break;

                default:
                {
                    int i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
                    if (i >= 0)
                    {
                        X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
                        if (ent)
                        {
                            ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
                            unsigned char *buf;
                            buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
                            if (ASN1_STRING_to_UTF8(&buf, val) >= 0)
                            {
                                do_setenv_x509(es, xt->name, (char *)buf, depth);
                                OPENSSL_free(buf);
                            }
                        }
                    }
                    else
                    {
                        i = X509_get_ext_by_NID(x509, xt->nid, -1);
                        if (i >= 0)
                        {
                            X509_EXTENSION *ext = X509_get_ext(x509, i);
                            if (ext)
                            {
                                BIO *bio = BIO_new(BIO_s_mem());
                                if (bio)
                                {
                                    if (X509V3_EXT_print(bio, ext, 0, 0))
                                    {
                                        if (BIO_write(bio, &nullc, 1) == 1)
                                        {
                                            char *str;
                                            BIO_get_mem_data(bio, &str);
                                            do_setenv_x509(es, xt->name, str, depth);
                                        }
                                    }
                                    BIO_free(bio);
                                }
                            }
                        }
                    }
                }
            }
        }
        xt = xt->next;
    }
    gc_free(&gc);
}

/*
 * Save X509 fields to environment, using the naming convention:
 *
 *  X509_{cert_depth}_{name}={value}
 */
void
x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
{
    int i, n;
    int fn_nid;
    ASN1_OBJECT *fn;
    ASN1_STRING *val;
    X509_NAME_ENTRY *ent;
    const char *objbuf;
    unsigned char *buf;
    char *name_expand;
    size_t name_expand_size;
    X509_NAME *x509 = X509_get_subject_name(peer_cert);

    n = X509_NAME_entry_count(x509);
    for (i = 0; i < n; ++i)
    {
        ent = X509_NAME_get_entry(x509, i);
        if (!ent)
        {
            continue;
        }
        fn = X509_NAME_ENTRY_get_object(ent);
        if (!fn)
        {
            continue;
        }
        val = X509_NAME_ENTRY_get_data(ent);
        if (!val)
        {
            continue;
        }
        fn_nid = OBJ_obj2nid(fn);
        if (fn_nid == NID_undef)
        {
            continue;
        }
        objbuf = OBJ_nid2sn(fn_nid);
        if (!objbuf)
        {
            continue;
        }
        buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
        if (ASN1_STRING_to_UTF8(&buf, val) < 0)
        {
            continue;
        }
        name_expand_size = 64 + strlen(objbuf);
        name_expand = (char *) malloc(name_expand_size);
        check_malloc_return(name_expand);
        openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", cert_depth,
                         objbuf);
        string_mod(name_expand, CC_PRINT, CC_CRLF, '_');
        string_mod((char *)buf, CC_PRINT, CC_CRLF, '_');
        setenv_str_incr(es, name_expand, (char *)buf);
        free(name_expand);
        OPENSSL_free(buf);
    }
}

result_t
x509_verify_ns_cert_type(openvpn_x509_cert_t *peer_cert, const int usage)
{
    if (usage == NS_CERT_CHECK_NONE)
    {
        return SUCCESS;
    }
    if (usage == NS_CERT_CHECK_CLIENT)
    {
        /*
         * Unfortunately, X509_check_purpose() does some weird thing that
         * prevent it to take a const argument
         */
        result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ?
	       SUCCESS : FAILURE;

        /*
         * old versions of OpenSSL allow us to make the less strict check we used to
         * do. If this less strict check pass, warn user that this might not be the
         * case when its distribution will update to OpenSSL 1.1
         */
        if (result == FAILURE)
        {
            ASN1_BIT_STRING *ns;
            ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
            result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_CLIENT)) ? SUCCESS : FAILURE;
            if (result == SUCCESS)
            {
                msg(M_WARN, "X509: Certificate is a client certificate yet it's purpose "
                    "cannot be verified (check may fail in the future)");
            }
            ASN1_BIT_STRING_free(ns);
        }
        return result;
    }
    if (usage == NS_CERT_CHECK_SERVER)
    {
        /*
         * Unfortunately, X509_check_purpose() does some weird thing that
         * prevent it to take a const argument
         */
        result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_SERVER, 0) ?
	       SUCCESS : FAILURE;

        /*
         * old versions of OpenSSL allow us to make the less strict check we used to
         * do. If this less strict check pass, warn user that this might not be the
         * case when its distribution will update to OpenSSL 1.1
         */
        if (result == FAILURE)
        {
            ASN1_BIT_STRING *ns;
            ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
            result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_SERVER)) ? SUCCESS : FAILURE;
            if (result == SUCCESS)
            {
                msg(M_WARN, "X509: Certificate is a server certificate yet it's purpose "
                    "cannot be verified (check may fail in the future)");
            }
            ASN1_BIT_STRING_free(ns);
        }
        return result;
    }

    return FAILURE;
}

result_t
x509_verify_cert_ku(X509 *x509, const unsigned *const expected_ku,
                    int expected_len)
{
    ASN1_BIT_STRING *ku = X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);

    if (ku == NULL)
    {
        msg(D_TLS_ERRORS, "Certificate does not have key usage extension");
        return FAILURE;
    }

    if (expected_ku[0] == OPENVPN_KU_REQUIRED)
    {
        /* Extension required, value checked by TLS library */
        ASN1_BIT_STRING_free(ku);
        return SUCCESS;
    }

    unsigned nku = 0;
    for (size_t i = 0; i < 8; i++)
    {
        if (ASN1_BIT_STRING_get_bit(ku, i))
        {
            nku |= 1 << (7 - i);
        }
    }

    /*
     * Fixup if no LSB bits
     */
    if ((nku & 0xff) == 0)
    {
        nku >>= 8;
    }

    msg(D_HANDSHAKE, "Validating certificate key usage");
    result_t fFound = FAILURE;
    for (size_t i = 0; fFound != SUCCESS && i < expected_len; i++)
    {
        if (expected_ku[i] != 0 && (nku & expected_ku[i]) == expected_ku[i])
        {
            fFound = SUCCESS;
        }
    }

    if (fFound != SUCCESS)
    {
        msg(D_TLS_ERRORS,
            "ERROR: Certificate has key usage %04x, expected one of:", nku);
        for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
        {
            msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
        }
    }

    ASN1_BIT_STRING_free(ku);

    return fFound;
}

result_t
x509_verify_cert_eku(X509 *x509, const char *const expected_oid)
{
    EXTENDED_KEY_USAGE *eku = NULL;
    result_t fFound = FAILURE;

    if ((eku = (EXTENDED_KEY_USAGE *) X509_get_ext_d2i(x509, NID_ext_key_usage,
                                                       NULL, NULL)) == NULL)
    {
        msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
    }
    else
    {
        int i;

        msg(D_HANDSHAKE, "Validating certificate extended key usage");
        for (i = 0; SUCCESS != fFound && i < sk_ASN1_OBJECT_num(eku); i++)
        {
            ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(eku, i);
            char szOid[1024];

            if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 0) != -1)
            {
                msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
                    szOid, expected_oid);
                if (!strcmp(expected_oid, szOid))
                {
                    fFound = SUCCESS;
                }
            }
            if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 1) != -1)
            {
                msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
                    szOid, expected_oid);
                if (!strcmp(expected_oid, szOid))
                {
                    fFound = SUCCESS;
                }
            }
        }
    }

    if (eku != NULL)
    {
        sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
    }

    return fFound;
}

result_t
x509_write_pem(FILE *peercert_file, X509 *peercert)
{
    if (PEM_write_X509(peercert_file, peercert) < 0)
    {
        msg(M_ERR, "Failed to write peer certificate in PEM format");
        return FAILURE;
    }
    return SUCCESS;
}

bool
tls_verify_crl_missing(const struct tls_options *opt)
{
    if (!opt->crl_file || (opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
    {
        return false;
    }

    X509_STORE *store = SSL_CTX_get_cert_store(opt->ssl_ctx.ctx);
    if (!store)
    {
        crypto_msg(M_FATAL, "Cannot get certificate store");
    }

    STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store);
    for (int i = 0; i < sk_X509_OBJECT_num(objs); i++)
    {
        X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i);
        ASSERT(obj);
        if (X509_OBJECT_get_type(obj) == X509_LU_CRL)
        {
            return false;
        }
    }
    return true;
}

#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) */
