/*
 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>
#include "ts_local.h"
#include "crypto/ess.h"

DEFINE_STACK_OF(PKCS7_SIGNER_INFO)
DEFINE_STACK_OF(X509)
DEFINE_STACK_OF(ESS_CERT_ID)
DEFINE_STACK_OF(ESS_CERT_ID_V2)
DEFINE_STACK_OF(ASN1_UTF8STRING)
DEFINE_STACK_OF(GENERAL_NAME)

static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
                          X509 *signer, STACK_OF(X509) **chain);
static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
                                  STACK_OF(X509) *chain);

static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
                                    PKCS7 *token, TS_TST_INFO *tst_info);
static int ts_check_status_info(TS_RESP *response);
static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
static int ts_check_policy(const ASN1_OBJECT *req_oid,
                           const TS_TST_INFO *tst_info);
static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
                              X509_ALGOR **md_alg,
                              unsigned char **imprint, unsigned *imprint_len);
static int ts_check_imprints(X509_ALGOR *algor_a,
                             const unsigned char *imprint_a, unsigned len_a,
                             TS_TST_INFO *tst_info);
static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names,
                        GENERAL_NAME *name);

/*
 * This must be large enough to hold all values in ts_status_text (with
 * comma separator) or all text fields in ts_failure_info (also with comma).
 */
#define TS_STATUS_BUF_SIZE      256

/*
 * Local mapping between response codes and descriptions.
 */
static const char *ts_status_text[] = {
    "granted",
    "grantedWithMods",
    "rejection",
    "waiting",
    "revocationWarning",
    "revocationNotification"
};

#define TS_STATUS_TEXT_SIZE     OSSL_NELEM(ts_status_text)

static struct {
    int code;
    const char *text;
} ts_failure_info[] = {
    {TS_INFO_BAD_ALG, "badAlg"},
    {TS_INFO_BAD_REQUEST, "badRequest"},
    {TS_INFO_BAD_DATA_FORMAT, "badDataFormat"},
    {TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable"},
    {TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy"},
    {TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension"},
    {TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable"},
    {TS_INFO_SYSTEM_FAILURE, "systemFailure"}
};


/*-
 * This function carries out the following tasks:
 *      - Checks if there is one and only one signer.
 *      - Search for the signing certificate in 'certs' and in the response.
 *      - Check the extended key usage and key usage fields of the signer
 *      certificate (done by the path validation).
 *      - Build and validate the certificate path.
 *      - Check if the certificate path meets the requirements of the
 *      SigningCertificate ESS signed attribute.
 *      - Verify the signature value.
 *      - Returns the signer certificate in 'signer', if 'signer' is not NULL.
 */
int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
                             X509_STORE *store, X509 **signer_out)
{
    STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
    PKCS7_SIGNER_INFO *si;
    STACK_OF(X509) *signers = NULL;
    X509 *signer;
    STACK_OF(X509) *chain = NULL;
    char buf[4096];
    int i, j = 0, ret = 0;
    BIO *p7bio = NULL;

    /* Some sanity checks first. */
    if (!token) {
        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
        goto err;
    }
    if (!PKCS7_type_is_signed(token)) {
        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
        goto err;
    }
    sinfos = PKCS7_get_signer_info(token);
    if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) {
        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER);
        goto err;
    }
    si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
    if (PKCS7_get_detached(token)) {
        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
        goto err;
    }

    /*
     * Get hold of the signer certificate, search only internal certificates
     * if it was requested.
     */
    signers = PKCS7_get0_signers(token, certs, 0);
    if (!signers || sk_X509_num(signers) != 1)
        goto err;
    signer = sk_X509_value(signers, 0);

    if (!ts_verify_cert(store, certs, signer, &chain))
        goto err;
    if (!ts_check_signing_certs(si, chain))
        goto err;
    p7bio = PKCS7_dataInit(token, NULL);

    /* We now have to 'read' from p7bio to calculate digests etc. */
    while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0)
        continue;

    j = PKCS7_signatureVerify(p7bio, token, si, signer);
    if (j <= 0) {
        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
        goto err;
    }

    if (signer_out) {
        *signer_out = signer;
        X509_up_ref(signer);
    }
    ret = 1;

 err:
    BIO_free_all(p7bio);
    sk_X509_pop_free(chain, X509_free);
    sk_X509_free(signers);

    return ret;
}

/*
 * The certificate chain is returned in chain. Caller is responsible for
 * freeing the vector.
 */
static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
                          X509 *signer, STACK_OF(X509) **chain)
{
    X509_STORE_CTX *cert_ctx = NULL;
    int i;
    int ret = 0;

    *chain = NULL;
    cert_ctx = X509_STORE_CTX_new();
    if (cert_ctx == NULL) {
        TSerr(TS_F_TS_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (!X509_STORE_CTX_init(cert_ctx, store, signer, untrusted))
        goto end;
    X509_STORE_CTX_set_purpose(cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
    i = X509_verify_cert(cert_ctx);
    if (i <= 0) {
        int j = X509_STORE_CTX_get_error(cert_ctx);
        TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
        ERR_add_error_data(2, "Verify error:",
                           X509_verify_cert_error_string(j));
        goto err;
    }
    *chain = X509_STORE_CTX_get1_chain(cert_ctx);
    ret = 1;
    goto end;

err:
    ret = 0;

end:
    X509_STORE_CTX_free(cert_ctx);
    return ret;
}

static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
                                  STACK_OF(X509) *chain)
{
    ESS_SIGNING_CERT *ss = ESS_SIGNING_CERT_get(si);
    STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
    ESS_SIGNING_CERT_V2 *ssv2 = ESS_SIGNING_CERT_V2_get(si);
    STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = NULL;
    X509 *cert;
    int i = 0;
    int ret = 0;

    if (ss != NULL) {
        cert_ids = ss->cert_ids;
        cert = sk_X509_value(chain, 0);
        if (ess_find_cert(cert_ids, cert) != 0)
            goto err;

        /*
         * Check the other certificates of the chain if there are more than one
         * certificate ids in cert_ids.
         */
        if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
            for (i = 1; i < sk_X509_num(chain); ++i) {
                cert = sk_X509_value(chain, i);
                if (ess_find_cert(cert_ids, cert) < 0)
                    goto err;
            }
        }
    } else if (ssv2 != NULL) {
        cert_ids_v2 = ssv2->cert_ids;
        cert = sk_X509_value(chain, 0);
        if (ess_find_cert_v2(cert_ids_v2, cert) != 0)
            goto err;

        /*
         * Check the other certificates of the chain if there are more than one
         * certificate ids in cert_ids.
         */
        if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) {
            for (i = 1; i < sk_X509_num(chain); ++i) {
                cert = sk_X509_value(chain, i);
                if (ess_find_cert_v2(cert_ids_v2, cert) < 0)
                    goto err;
            }
        }
    } else {
        goto err;
    }

    ret = 1;
 err:
    if (!ret)
        TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
              TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
    ESS_SIGNING_CERT_free(ss);
    ESS_SIGNING_CERT_V2_free(ssv2);
    return ret;
}

/*-
 * Verifies whether 'response' contains a valid response with regards
 * to the settings of the context:
 *      - Gives an error message if the TS_TST_INFO is not present.
 *      - Calls _TS_RESP_verify_token to verify the token content.
 */
int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
{
    PKCS7 *token = response->token;
    TS_TST_INFO *tst_info = response->tst_info;
    int ret = 0;

    if (!ts_check_status_info(response))
        goto err;
    if (!int_ts_RESP_verify_token(ctx, token, tst_info))
        goto err;
    ret = 1;

 err:
    return ret;
}

/*
 * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
 * calls the internal int_TS_RESP_verify_token function for verifying it.
 */
int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
{
    TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
    int ret = 0;
    if (tst_info) {
        ret = int_ts_RESP_verify_token(ctx, token, tst_info);
        TS_TST_INFO_free(tst_info);
    }
    return ret;
}

/*-
 * Verifies whether the 'token' contains a valid time stamp token
 * with regards to the settings of the context. Only those checks are
 * carried out that are specified in the context:
 *      - Verifies the signature of the TS_TST_INFO.
 *      - Checks the version number of the response.
 *      - Check if the requested and returned policies math.
 *      - Check if the message imprints are the same.
 *      - Check if the nonces are the same.
 *      - Check if the TSA name matches the signer.
 *      - Check if the TSA name is the expected TSA.
 */
static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
                                    PKCS7 *token, TS_TST_INFO *tst_info)
{
    X509 *signer = NULL;
    GENERAL_NAME *tsa_name = tst_info->tsa;
    X509_ALGOR *md_alg = NULL;
    unsigned char *imprint = NULL;
    unsigned imprint_len = 0;
    int ret = 0;
    int flags = ctx->flags;

    /* Some options require us to also check the signature */
    if (((flags & TS_VFY_SIGNER) && tsa_name != NULL)
            || (flags & TS_VFY_TSA_NAME)) {
        flags |= TS_VFY_SIGNATURE;
    }

    if ((flags & TS_VFY_SIGNATURE)
        && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))
        goto err;
    if ((flags & TS_VFY_VERSION)
        && TS_TST_INFO_get_version(tst_info) != 1) {
        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
        goto err;
    }
    if ((flags & TS_VFY_POLICY)
        && !ts_check_policy(ctx->policy, tst_info))
        goto err;
    if ((flags & TS_VFY_IMPRINT)
        && !ts_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
                              tst_info))
        goto err;
    if ((flags & TS_VFY_DATA)
        && (!ts_compute_imprint(ctx->data, tst_info,
                                &md_alg, &imprint, &imprint_len)
            || !ts_check_imprints(md_alg, imprint, imprint_len, tst_info)))
        goto err;
    if ((flags & TS_VFY_NONCE)
        && !ts_check_nonces(ctx->nonce, tst_info))
        goto err;
    if ((flags & TS_VFY_SIGNER)
        && tsa_name && !ts_check_signer_name(tsa_name, signer)) {
        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
        goto err;
    }
    if ((flags & TS_VFY_TSA_NAME)
        && !ts_check_signer_name(ctx->tsa_name, signer)) {
        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
        goto err;
    }
    ret = 1;

 err:
    X509_free(signer);
    X509_ALGOR_free(md_alg);
    OPENSSL_free(imprint);
    return ret;
}

static int ts_check_status_info(TS_RESP *response)
{
    TS_STATUS_INFO *info = response->status_info;
    long status = ASN1_INTEGER_get(info->status);
    const char *status_text = NULL;
    char *embedded_status_text = NULL;
    char failure_text[TS_STATUS_BUF_SIZE] = "";

    if (status == 0 || status == 1)
        return 1;

    /* There was an error, get the description in status_text. */
    if (0 <= status && status < (long) OSSL_NELEM(ts_status_text))
        status_text = ts_status_text[status];
    else
        status_text = "unknown code";

    if (sk_ASN1_UTF8STRING_num(info->text) > 0
        && (embedded_status_text = ts_get_status_text(info->text)) == NULL)
        return 0;

    /* Fill in failure_text with the failure information. */
    if (info->failure_info) {
        int i;
        int first = 1;
        for (i = 0; i < (int)OSSL_NELEM(ts_failure_info); ++i) {
            if (ASN1_BIT_STRING_get_bit(info->failure_info,
                                        ts_failure_info[i].code)) {
                if (!first)
                    strcat(failure_text, ",");
                else
                    first = 0;
                strcat(failure_text, ts_failure_info[i].text);
            }
        }
    }
    if (failure_text[0] == '\0')
        strcpy(failure_text, "unspecified");

    TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
    ERR_add_error_data(6,
                       "status code: ", status_text,
                       ", status text: ", embedded_status_text ?
                       embedded_status_text : "unspecified",
                       ", failure codes: ", failure_text);
    OPENSSL_free(embedded_status_text);

    return 0;
}

static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
{
    return sk_ASN1_UTF8STRING2text(text, "/", TS_MAX_STATUS_LENGTH);
}

static int ts_check_policy(const ASN1_OBJECT *req_oid,
                           const TS_TST_INFO *tst_info)
{
    const ASN1_OBJECT *resp_oid = tst_info->policy_id;

    if (OBJ_cmp(req_oid, resp_oid) != 0) {
        TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
        return 0;
    }

    return 1;
}

static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
                              X509_ALGOR **md_alg,
                              unsigned char **imprint, unsigned *imprint_len)
{
    TS_MSG_IMPRINT *msg_imprint = tst_info->msg_imprint;
    X509_ALGOR *md_alg_resp = msg_imprint->hash_algo;
    const EVP_MD *md;
    EVP_MD_CTX *md_ctx = NULL;
    unsigned char buffer[4096];
    int length;

    *md_alg = NULL;
    *imprint = NULL;

    if ((*md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL)
        goto err;
    if ((md = EVP_get_digestbyobj((*md_alg)->algorithm)) == NULL) {
        TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
        goto err;
    }
    length = EVP_MD_size(md);
    if (length < 0)
        goto err;
    *imprint_len = length;
    if ((*imprint = OPENSSL_malloc(*imprint_len)) == NULL) {
        TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    md_ctx = EVP_MD_CTX_new();
    if (md_ctx == NULL) {
        TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (!EVP_DigestInit(md_ctx, md))
        goto err;
    while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {
        if (!EVP_DigestUpdate(md_ctx, buffer, length))
            goto err;
    }
    if (!EVP_DigestFinal(md_ctx, *imprint, NULL))
        goto err;
    EVP_MD_CTX_free(md_ctx);

    return 1;
 err:
    EVP_MD_CTX_free(md_ctx);
    X509_ALGOR_free(*md_alg);
    OPENSSL_free(*imprint);
    *imprint_len = 0;
    *imprint = 0;
    return 0;
}

static int ts_check_imprints(X509_ALGOR *algor_a,
                             const unsigned char *imprint_a, unsigned len_a,
                             TS_TST_INFO *tst_info)
{
    TS_MSG_IMPRINT *b = tst_info->msg_imprint;
    X509_ALGOR *algor_b = b->hash_algo;
    int ret = 0;

    if (algor_a) {
        if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm))
            goto err;

        /* The parameter must be NULL in both. */
        if ((algor_a->parameter
             && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
            || (algor_b->parameter
                && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
            goto err;
    }

    ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) &&
        memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len_a) == 0;
 err:
    if (!ret)
        TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
    return ret;
}

static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
{
    const ASN1_INTEGER *b = tst_info->nonce;

    if (!b) {
        TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
        return 0;
    }

    /* No error if a nonce is returned without being requested. */
    if (ASN1_INTEGER_cmp(a, b) != 0) {
        TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
        return 0;
    }

    return 1;
}

/*
 * Check if the specified TSA name matches either the subject or one of the
 * subject alternative names of the TSA certificate.
 */
static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
{
    STACK_OF(GENERAL_NAME) *gen_names = NULL;
    int idx = -1;
    int found = 0;

    if (tsa_name->type == GEN_DIRNAME
        && X509_name_cmp(tsa_name->d.dirn, X509_get_subject_name(signer)) == 0)
        return 1;
    gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx);
    while (gen_names != NULL) {
        found = ts_find_name(gen_names, tsa_name) >= 0;
        if (found)
            break;
        /*
         * Get the next subject alternative name, although there should be no
         * more than one.
         */
        GENERAL_NAMES_free(gen_names);
        gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx);
    }
    GENERAL_NAMES_free(gen_names);

    return found;
}

/* Returns 1 if name is in gen_names, 0 otherwise. */
static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
{
    int i, found;
    for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); ++i) {
        GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
        found = GENERAL_NAME_cmp(current, name) == 0;
    }
    return found ? i - 1 : -1;
}
