/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
#include "common.h"

#include "mbedtls/build_info.h"
#if defined(MBEDTLS_PKCS7_C)
#include "mbedtls/pkcs7.h"
#include "mbedtls/x509.h"
#include "mbedtls/asn1.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509_crl.h"
#include "mbedtls/oid.h"
#include "mbedtls/error.h"

#if defined(MBEDTLS_FS_IO)
#include <sys/types.h>
#include <sys/stat.h>
#endif

#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"

#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE)
#include <time.h>
#endif

/**
 * Initializes the mbedtls_pkcs7 structure.
 */
void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7)
{
    memset(pkcs7, 0, sizeof(*pkcs7));
}

static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
                                      size_t *len)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
    if (ret != 0) {
        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
    } else if ((size_t) (end - *p) != *len) {
        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
                                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    }

    return ret;
}

/**
 * version Version
 * Version ::= INTEGER
 **/
static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    ret = mbedtls_asn1_get_int(p, end, ver);
    if (ret != 0) {
        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret);
    }

    /* If version != 1, return invalid version */
    if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) {
        ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
    }

    return ret;
}

/**
 * ContentInfo ::= SEQUENCE {
 *      contentType ContentType,
 *      content
 *              [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
 **/
static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
                                       unsigned char **seq_end,
                                       mbedtls_pkcs7_buf *pkcs7)
{
    size_t len = 0;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char *start = *p;

    ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_SEQUENCE);
    if (ret != 0) {
        *p = start;
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
    }
    *seq_end = *p + len;
    ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
    if (ret != 0) {
        *p = start;
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
    }

    pkcs7->tag = MBEDTLS_ASN1_OID;
    pkcs7->len = len;
    pkcs7->p = *p;
    *p += len;

    return ret;
}

/**
 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
 *
 * This is from x509.h
 **/
static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end,
                                      mbedtls_x509_buf *alg)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
    }

    return ret;
}

/**
 * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
 **/
static int pkcs7_get_digest_algorithm_set(unsigned char **p,
                                          unsigned char *end,
                                          mbedtls_x509_buf *alg)
{
    size_t len = 0;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_SET);
    if (ret != 0) {
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
    }

    end = *p + len;

    ret = mbedtls_asn1_get_alg_null(p, end, alg);
    if (ret != 0) {
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
    }

    /** For now, it assumes there is only one digest algorithm specified **/
    if (*p != end) {
        return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
    }

    return 0;
}

/**
 * certificates :: SET OF ExtendedCertificateOrCertificate,
 * ExtendedCertificateOrCertificate ::= CHOICE {
 *      certificate Certificate -- x509,
 *      extendedCertificate[0] IMPLICIT ExtendedCertificate }
 * Return number of certificates added to the signed data,
 * 0 or higher is valid.
 * Return negative error code for failure.
 **/
static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
                                  mbedtls_x509_crt *certs)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    size_t len1 = 0;
    size_t len2 = 0;
    unsigned char *end_set, *end_cert, *start;

    ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
    if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
        return 0;
    }
    if (ret != 0) {
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
    }
    start = *p;
    end_set = *p + len1;

    ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_SEQUENCE);
    if (ret != 0) {
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret);
    }

    end_cert = *p + len2;

    /*
     * This is to verify that there is only one signer certificate. It seems it is
     * not easy to differentiate between the chain vs different signer's certificate.
     * So, we support only the root certificate and the single signer.
     * The behaviour would be improved with addition of multiple signer support.
     */
    if (end_cert != end_set) {
        return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
    }

    if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) {
        return MBEDTLS_ERR_PKCS7_INVALID_CERT;
    }

    *p = end_cert;

    /*
     * Since in this version we strictly support single certificate, and reaching
     * here implies we have parsed successfully, we return 1.
     */
    return 1;
}

/**
 * EncryptedDigest ::= OCTET STRING
 **/
static int pkcs7_get_signature(unsigned char **p, unsigned char *end,
                               mbedtls_pkcs7_buf *signature)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    size_t len = 0;

    ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
    if (ret != 0) {
        return ret;
    }

    signature->tag = MBEDTLS_ASN1_OCTET_STRING;
    signature->len = len;
    signature->p = *p;

    *p = *p + len;

    return 0;
}

static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
{
    mbedtls_x509_name *name_cur;
    mbedtls_x509_name *name_prv;

    if (signer == NULL) {
        return;
    }

    name_cur = signer->issuer.next;
    while (name_cur != NULL) {
        name_prv = name_cur;
        name_cur = name_cur->next;
        mbedtls_free(name_prv);
    }
    signer->issuer.next = NULL;
}

/**
 * SignerInfo ::= SEQUENCE {
 *      version Version;
 *      issuerAndSerialNumber   IssuerAndSerialNumber,
 *      digestAlgorithm DigestAlgorithmIdentifier,
 *      authenticatedAttributes
 *              [0] IMPLICIT Attributes OPTIONAL,
 *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
 *      encryptedDigest EncryptedDigest,
 *      unauthenticatedAttributes
 *              [1] IMPLICIT Attributes OPTIONAL,
 * Returns 0 if the signerInfo is valid.
 * Return negative error code for failure.
 * Structure must not contain vales for authenticatedAttributes
 * and unauthenticatedAttributes.
 **/
static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
                                 mbedtls_pkcs7_signer_info *signer,
                                 mbedtls_x509_buf *alg)
{
    unsigned char *end_signer, *end_issuer_and_sn;
    int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    size_t len = 0;

    asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
                                    | MBEDTLS_ASN1_SEQUENCE);
    if (asn1_ret != 0) {
        goto out;
    }

    end_signer = *p + len;

    ret = pkcs7_get_version(p, end_signer, &signer->version);
    if (ret != 0) {
        goto out;
    }

    asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
    if (asn1_ret != 0) {
        goto out;
    }

    end_issuer_and_sn = *p + len;
    /* Parsing IssuerAndSerialNumber */
    signer->issuer_raw.p = *p;

    asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
    if (asn1_ret != 0) {
        goto out;
    }

    ret  = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
    if (ret != 0) {
        goto out;
    }

    signer->issuer_raw.len =  *p - signer->issuer_raw.p;

    ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
    if (ret != 0) {
        goto out;
    }

    /* ensure no extra or missing bytes */
    if (*p != end_issuer_and_sn) {
        ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
        goto out;
    }

    ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
    if (ret != 0) {
        goto out;
    }

    /* Check that the digest algorithm used matches the one provided earlier */
    if (signer->alg_identifier.tag != alg->tag ||
        signer->alg_identifier.len != alg->len ||
        memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) {
        ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
        goto out;
    }

    /* Assume authenticatedAttributes is nonexistent */
    ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
    if (ret != 0) {
        goto out;
    }

    ret = pkcs7_get_signature(p, end_signer, &signer->sig);
    if (ret != 0) {
        goto out;
    }

    /* Do not permit any unauthenticated attributes */
    if (*p != end_signer) {
        ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
    }

out:
    if (asn1_ret != 0 || ret != 0) {
        pkcs7_free_signer_info(signer);
        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
                                asn1_ret);
    }

    return ret;
}

/**
 * SignerInfos ::= SET of SignerInfo
 * Return number of signers added to the signed data,
 * 0 or higher is valid.
 * Return negative error code for failure.
 **/
static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
                                      mbedtls_pkcs7_signer_info *signers_set,
                                      mbedtls_x509_buf *digest_alg)
{
    unsigned char *end_set;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    int count = 0;
    size_t len = 0;

    ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_SET);
    if (ret != 0) {
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret);
    }

    /* Detect zero signers */
    if (len == 0) {
        return 0;
    }

    end_set = *p + len;

    ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg);
    if (ret != 0) {
        return ret;
    }
    count++;

    mbedtls_pkcs7_signer_info *prev = signers_set;
    while (*p != end_set) {
        mbedtls_pkcs7_signer_info *signer =
            mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info));
        if (!signer) {
            ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
            goto cleanup;
        }

        ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg);
        if (ret != 0) {
            mbedtls_free(signer);
            goto cleanup;
        }
        prev->next = signer;
        prev = signer;
        count++;
    }

    return count;

cleanup:
    pkcs7_free_signer_info(signers_set);
    mbedtls_pkcs7_signer_info *signer = signers_set->next;
    while (signer != NULL) {
        prev = signer;
        signer = signer->next;
        pkcs7_free_signer_info(prev);
        mbedtls_free(prev);
    }
    signers_set->next = NULL;
    return ret;
}

/**
 * SignedData ::= SEQUENCE {
 *      version Version,
 *      digestAlgorithms DigestAlgorithmIdentifiers,
 *      contentInfo ContentInfo,
 *      certificates
 *              [0] IMPLICIT ExtendedCertificatesAndCertificates
 *                  OPTIONAL,
 *      crls
 *              [0] IMPLICIT CertificateRevocationLists OPTIONAL,
 *      signerInfos SignerInfos }
 */
static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
                                 mbedtls_pkcs7_signed_data *signed_data)
{
    unsigned char *p = buf;
    unsigned char *end = buf + buflen;
    unsigned char *end_content_info = NULL;
    size_t len = 0;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_md_type_t md_alg;

    ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_SEQUENCE);
    if (ret != 0) {
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
    }

    if (p + len != end) {
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    }

    /* Get version of signed data */
    ret = pkcs7_get_version(&p, end, &signed_data->version);
    if (ret != 0) {
        return ret;
    }

    /* Get digest algorithm */
    ret = pkcs7_get_digest_algorithm_set(&p, end,
                                         &signed_data->digest_alg_identifiers);
    if (ret != 0) {
        return ret;
    }

    ret = mbedtls_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg);
    if (ret != 0) {
        return MBEDTLS_ERR_PKCS7_INVALID_ALG;
    }

    mbedtls_pkcs7_buf content_type;
    memset(&content_type, 0, sizeof(content_type));
    ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type);
    if (ret != 0) {
        return ret;
    }
    if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) {
        return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
    }

    if (p != end_content_info) {
        /* Determine if valid content is present */
        ret = mbedtls_asn1_get_tag(&p,
                                   end_content_info,
                                   &len,
                                   MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
        if (ret != 0) {
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
        }
        p += len;
        if (p != end_content_info) {
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
        }
        /* Valid content is present - this is not supported */
        return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
    }

    /* Look for certificates, there may or may not be any */
    mbedtls_x509_crt_init(&signed_data->certs);
    ret = pkcs7_get_certificates(&p, end, &signed_data->certs);
    if (ret < 0) {
        return ret;
    }

    signed_data->no_of_certs = ret;

    /*
     * Currently CRLs are not supported. If CRL exist, the parsing will fail
     * at next step of getting signers info and return error as invalid
     * signer info.
     */

    signed_data->no_of_crls = 0;

    /* Get signers info */
    ret = pkcs7_get_signers_info_set(&p,
                                     end,
                                     &signed_data->signers,
                                     &signed_data->digest_alg_identifiers);
    if (ret < 0) {
        return ret;
    }

    signed_data->no_of_signers = ret;

    /* Don't permit trailing data */
    if (p != end) {
        return MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
    }

    return 0;
}

int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
                            const size_t buflen)
{
    unsigned char *p;
    unsigned char *end;
    size_t len = 0;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (pkcs7 == NULL) {
        return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
    }

    /* make an internal copy of the buffer for parsing */
    pkcs7->raw.p = p = mbedtls_calloc(1, buflen);
    if (pkcs7->raw.p == NULL) {
        ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
        goto out;
    }
    memcpy(p, buf, buflen);
    pkcs7->raw.len = buflen;
    end = p + buflen;

    ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
                               | MBEDTLS_ASN1_SEQUENCE);
    if (ret != 0) {
        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
        goto out;
    }

    if ((size_t) (end - p) != len) {
        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
                                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
        goto out;
    }

    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
        if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
            goto out;
        }
        p = pkcs7->raw.p;
        len = buflen;
        goto try_data;
    }

    if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) {
        /* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */
        if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len)
            || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len)
            || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len)
            || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len)
            || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) {
            /* OID is valid according to the spec, but unsupported */
            ret =  MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
        } else {
            /* OID is invalid according to the spec */
            ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
        }
        goto out;
    }

    p += len;

    ret = pkcs7_get_next_content_len(&p, end, &len);
    if (ret != 0) {
        goto out;
    }

    /* ensure no extra/missing data */
    if (p + len != end) {
        ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
        goto out;
    }

try_data:
    ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
    if (ret != 0) {
        goto out;
    }

    ret = MBEDTLS_PKCS7_SIGNED_DATA;

out:
    if (ret < 0) {
        mbedtls_pkcs7_free(pkcs7);
    }

    return ret;
}

static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
                                             const mbedtls_x509_crt *cert,
                                             const unsigned char *data,
                                             size_t datalen,
                                             const int is_data_hash)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char *hash;
    mbedtls_pk_context pk_cxt = cert->pk;
    const mbedtls_md_info_t *md_info;
    mbedtls_md_type_t md_alg;
    mbedtls_pkcs7_signer_info *signer;

    if (pkcs7->signed_data.no_of_signers == 0) {
        return MBEDTLS_ERR_PKCS7_INVALID_CERT;
    }

    if (mbedtls_x509_time_is_past(&cert->valid_to) ||
        mbedtls_x509_time_is_future(&cert->valid_from)) {
        return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
    }

    ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
    if (ret != 0) {
        return ret;
    }

    md_info = mbedtls_md_info_from_type(md_alg);
    if (md_info == NULL) {
        return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
    }

    hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
    if (hash == NULL) {
        return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
    }

    /* BEGIN must free hash before jumping out */
    if (is_data_hash) {
        if (datalen != mbedtls_md_get_size(md_info)) {
            ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
        } else {
            memcpy(hash, data, datalen);
        }
    } else {
        ret = mbedtls_md(md_info, data, datalen, hash);
    }
    if (ret != 0) {
        mbedtls_free(hash);
        return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
    }

    /* assume failure */
    ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;

    /*
     * Potential TODOs
     * Currently we iterate over all signers and return success if any of them
     * verify.
     *
     * However, we could make this better by checking against the certificate's
     * identification and SignerIdentifier fields first. That would also allow
     * us to distinguish between 'no signature for key' and 'signature for key
     * failed to validate'.
     */
    for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
        ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
                                mbedtls_md_get_size(md_info),
                                signer->sig.p, signer->sig.len);

        if (ret == 0) {
            break;
        }
    }

    mbedtls_free(hash);
    /* END must free hash before jumping out */
    return ret;
}

int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
                                     const mbedtls_x509_crt *cert,
                                     const unsigned char *data,
                                     size_t datalen)
{
    if (data == NULL) {
        return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
    }
    return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
}

int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
                                     const mbedtls_x509_crt *cert,
                                     const unsigned char *hash,
                                     size_t hashlen)
{
    if (hash == NULL) {
        return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
    }
    return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
}

/*
 * Unallocate all pkcs7 data
 */
void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7)
{
    mbedtls_pkcs7_signer_info *signer_cur;
    mbedtls_pkcs7_signer_info *signer_prev;

    if (pkcs7 == NULL || pkcs7->raw.p == NULL) {
        return;
    }

    mbedtls_free(pkcs7->raw.p);

    mbedtls_x509_crt_free(&pkcs7->signed_data.certs);
    mbedtls_x509_crl_free(&pkcs7->signed_data.crl);

    signer_cur = pkcs7->signed_data.signers.next;
    pkcs7_free_signer_info(&pkcs7->signed_data.signers);
    while (signer_cur != NULL) {
        signer_prev = signer_cur;
        signer_cur = signer_prev->next;
        pkcs7_free_signer_info(signer_prev);
        mbedtls_free(signer_prev);
    }

    pkcs7->raw.p = NULL;
}

#endif
