int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
{
    ASN1_OCTET_STRING *os = NULL;
    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
    EVP_PKEY_CTX *pkctx = NULL;
    int r = -1;
    unsigned char mval[EVP_MAX_MD_SIZE];
    unsigned int mlen;
    if (mctx == NULL) {
        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (CMS_signed_get_attr_count(si) >= 0) {
        os = CMS_signed_get0_data_by_OBJ(si,
                                         OBJ_nid2obj(NID_pkcs9_messageDigest),
                                         -3, V_ASN1_OCTET_STRING);
        if (!os) {
            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
            goto err;
        }
    }
    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
        goto err;
    if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
               CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
        goto err;
    }
    if (os) {
        if (mlen != (unsigned int)os->length) {
            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
                   CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
            goto err;
        }
        if (memcmp(mval, os->data, mlen)) {
            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
                   CMS_R_VERIFICATION_FAILURE);
            r = 0;
        } else
            r = 1;
    } else {
        const EVP_MD *md = EVP_MD_CTX_md(mctx);
        pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
        if (pkctx == NULL)
            goto err;
        if (EVP_PKEY_verify_init(pkctx) <= 0)
            goto err;
        if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
            goto err;
        si->pctx = pkctx;
        if (!cms_sd_asn1_ctrl(si, 1))
            goto err;
        r = EVP_PKEY_verify(pkctx, si->signature->data,
                            si->signature->length, mval, mlen);
        if (r <= 0) {
            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
                   CMS_R_VERIFICATION_FAILURE);
            r = 0;
        }
    }
 err:
    EVP_PKEY_CTX_free(pkctx);
    EVP_MD_CTX_free(mctx);
    return r;
}
['int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)\n{\n    ASN1_OCTET_STRING *os = NULL;\n    EVP_MD_CTX *mctx = EVP_MD_CTX_new();\n    EVP_PKEY_CTX *pkctx = NULL;\n    int r = -1;\n    unsigned char mval[EVP_MAX_MD_SIZE];\n    unsigned int mlen;\n    if (mctx == NULL) {\n        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    if (CMS_signed_get_attr_count(si) >= 0) {\n        os = CMS_signed_get0_data_by_OBJ(si,\n                                         OBJ_nid2obj(NID_pkcs9_messageDigest),\n                                         -3, V_ASN1_OCTET_STRING);\n        if (!os) {\n            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,\n                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);\n            goto err;\n        }\n    }\n    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))\n        goto err;\n    if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {\n        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,\n               CMS_R_UNABLE_TO_FINALIZE_CONTEXT);\n        goto err;\n    }\n    if (os) {\n        if (mlen != (unsigned int)os->length) {\n            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,\n                   CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);\n            goto err;\n        }\n        if (memcmp(mval, os->data, mlen)) {\n            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,\n                   CMS_R_VERIFICATION_FAILURE);\n            r = 0;\n        } else\n            r = 1;\n    } else {\n        const EVP_MD *md = EVP_MD_CTX_md(mctx);\n        pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);\n        if (pkctx == NULL)\n            goto err;\n        if (EVP_PKEY_verify_init(pkctx) <= 0)\n            goto err;\n        if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)\n            goto err;\n        si->pctx = pkctx;\n        if (!cms_sd_asn1_ctrl(si, 1))\n            goto err;\n        r = EVP_PKEY_verify(pkctx, si->signature->data,\n                            si->signature->length, mval, mlen);\n        if (r <= 0) {\n            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,\n                   CMS_R_VERIFICATION_FAILURE);\n            r = 0;\n        }\n    }\n err:\n    EVP_PKEY_CTX_free(pkctx);\n    EVP_MD_CTX_free(mctx);\n    return r;\n}', 'EVP_MD_CTX *EVP_MD_CTX_new(void)\n{\n    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));\n}', 'void *CRYPTO_zalloc(size_t num, const char *file, int line)\n{\n    void *ret = CRYPTO_malloc(num, file, line);\n    if (ret != NULL)\n        memset(ret, 0, num);\n    return ret;\n}', 'void *CRYPTO_malloc(size_t num, const char *file, int line)\n{\n    void *ret = NULL;\n    if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)\n        return malloc_impl(num, file, line);\n    if (num <= 0)\n        return NULL;\n    allow_customize = 0;\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);\n        ret = malloc(num);\n        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);\n    } else {\n        ret = malloc(num);\n    }\n#else\n    osslargused(file); osslargused(line);\n    ret = malloc(num);\n#endif\n    return ret;\n}', 'int CMS_signed_get_attr_count(const CMS_SignerInfo *si)\n{\n    return X509at_get_attr_count(si->signedAttrs);\n}', 'int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)\n{\n    return sk_X509_ATTRIBUTE_num(x);\n}', 'int OPENSSL_sk_num(const OPENSSL_STACK *st)\n{\n    if (st == NULL)\n        return -1;\n    return st->num;\n}', 'int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,\n                                 X509_ALGOR *mdalg)\n{\n    int nid;\n    const ASN1_OBJECT *mdoid;\n    X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);\n    nid = OBJ_obj2nid(mdoid);\n    for (;;) {\n        EVP_MD_CTX *mtmp;\n        chain = BIO_find_type(chain, BIO_TYPE_MD);\n        if (chain == NULL) {\n            CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,\n                   CMS_R_NO_MATCHING_DIGEST);\n            return 0;\n        }\n        BIO_get_md_ctx(chain, &mtmp);\n        if (EVP_MD_CTX_type(mtmp) == nid\n            || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)\n            return EVP_MD_CTX_copy_ex(mctx, mtmp);\n        chain = BIO_next(chain);\n    }\n}', 'void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,\n                     const void **ppval, const X509_ALGOR *algor)\n{\n    if (paobj)\n        *paobj = algor->algorithm;\n    if (pptype) {\n        if (algor->parameter == NULL) {\n            *pptype = V_ASN1_UNDEF;\n            return;\n        } else\n            *pptype = algor->parameter->type;\n        if (ppval)\n            *ppval = algor->parameter->value.ptr;\n    }\n}', 'int OBJ_obj2nid(const ASN1_OBJECT *a)\n{\n    const unsigned int *op;\n    ADDED_OBJ ad, *adp;\n    if (a == NULL)\n        return (NID_undef);\n    if (a->nid != 0)\n        return (a->nid);\n    if (a->length == 0)\n        return NID_undef;\n    if (added != NULL) {\n        ad.type = ADDED_DATA;\n        ad.obj = (ASN1_OBJECT *)a;\n        adp = lh_ADDED_OBJ_retrieve(added, &ad);\n        if (adp != NULL)\n            return (adp->obj->nid);\n    }\n    op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);\n    if (op == NULL)\n        return (NID_undef);\n    return (nid_objs[*op].nid);\n}', 'DEFINE_LHASH_OF(ADDED_OBJ)', 'void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)\n{\n    unsigned long hash;\n    OPENSSL_LH_NODE **rn;\n    void *ret;\n    lh->error = 0;\n    rn = getrn(lh, data, &hash);\n    if (*rn == NULL) {\n        lh->num_retrieve_miss++;\n        return (NULL);\n    } else {\n        ret = (*rn)->data;\n        lh->num_retrieve++;\n    }\n    return (ret);\n}', 'void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)\n{\n    if (ctx == NULL)\n        return;\n    if (ctx->pmeth && ctx->pmeth->cleanup)\n        ctx->pmeth->cleanup(ctx);\n    EVP_PKEY_free(ctx->pkey);\n    EVP_PKEY_free(ctx->peerkey);\n#ifndef OPENSSL_NO_ENGINE\n    ENGINE_finish(ctx->engine);\n#endif\n    OPENSSL_free(ctx);\n}', 'void EVP_MD_CTX_free(EVP_MD_CTX *ctx)\n{\n    EVP_MD_CTX_reset(ctx);\n    OPENSSL_free(ctx);\n}', 'void CRYPTO_free(void *str, const char *file, int line)\n{\n    if (free_impl != NULL && free_impl != &CRYPTO_free) {\n        free_impl(str, file, line);\n        return;\n    }\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_free(str, 0, file, line);\n        free(str);\n        CRYPTO_mem_debug_free(str, 1, file, line);\n    } else {\n        free(str);\n    }\n#else\n    free(str);\n#endif\n}']