X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpkcs7%2Fpk7_doit.c;h=b815a4a77b99c748a01f87554c41523112974267;hp=91864dceae9b70cc04579f47a12558a6820bdf49;hb=HEAD;hpb=bfb0641f932490c2e7fb5f9f7cb4a88017a5abfa diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 91864dceae..c753a0880b 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -1,74 +1,28 @@ -/* crypto/pkcs7/pk7_doit.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. +/* + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] + * 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 -#include "internal/cryptlib.h" #include #include #include #include #include +#include "internal/cryptlib.h" +#include "internal/sizes.h" +#include "crypto/evp.h" +#include "pk7_local.h" static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value); -static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); +static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid); -static int PKCS7_type_is_other(PKCS7 *p7) +int PKCS7_type_is_other(PKCS7 *p7) { int isOther = 1; @@ -91,7 +45,7 @@ static int PKCS7_type_is_other(PKCS7 *p7) } -static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) +ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) { if (PKCS7_type_is_data(p7)) return p7->d.data; @@ -101,26 +55,46 @@ static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) return NULL; } -static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) +static int pkcs7_bio_add_digest(BIO **pbio, X509_ALGOR *alg, + const PKCS7_CTX *ctx) { BIO *btmp; + char name[OSSL_MAX_NAME_SIZE]; + EVP_MD *fetched = NULL; const EVP_MD *md; + if ((btmp = BIO_new(BIO_f_md())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } - md = EVP_get_digestbyobj(alg->algorithm); + OBJ_obj2txt(name, sizeof(name), alg->algorithm, 0); + + (void)ERR_set_mark(); + fetched = EVP_MD_fetch(ossl_pkcs7_ctx_get0_libctx(ctx), name, + ossl_pkcs7_ctx_get0_propq(ctx)); + if (fetched != NULL) + md = fetched; + else + md = EVP_get_digestbyname(name); + if (md == NULL) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } + (void)ERR_pop_to_mark(); - BIO_set_md(btmp, md); + if (BIO_set_md(btmp, md) <= 0) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); + EVP_MD_free(fetched); + goto err; + } + EVP_MD_free(fetched); if (*pbio == NULL) *pbio = btmp; else if (!BIO_push(*pbio, btmp)) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } btmp = NULL; @@ -130,7 +104,6 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) err: BIO_free(btmp); return 0; - } static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, @@ -141,34 +114,26 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *ek = NULL; int ret = 0; size_t eklen; + const PKCS7_CTX *ctx = ri->ctx; - pkey = X509_get_pubkey(ri->cert); - - if (!pkey) + pkey = X509_get0_pubkey(ri->cert); + if (pkey == NULL) return 0; - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pctx) + pctx = EVP_PKEY_CTX_new_from_pkey(ossl_pkcs7_ctx_get0_libctx(ctx), pkey, + ossl_pkcs7_ctx_get0_propq(ctx)); + if (pctx == NULL) return 0; if (EVP_PKEY_encrypt_init(pctx) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { - PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); - goto err; - } - if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) goto err; ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); + if (ek == NULL) goto err; - } if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) goto err; @@ -179,7 +144,6 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, ret = 1; err: - EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(pctx); OPENSSL_free(ek); return ret; @@ -187,45 +151,35 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, } static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, - PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) + PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey, + size_t fixlen) { EVP_PKEY_CTX *pctx = NULL; unsigned char *ek = NULL; size_t eklen; - int ret = -1; + const PKCS7_CTX *ctx = ri->ctx; - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pctx) + pctx = EVP_PKEY_CTX_new_from_pkey(ossl_pkcs7_ctx_get0_libctx(ctx), pkey, + ossl_pkcs7_ctx_get0_propq(ctx)); + if (pctx == NULL) return -1; if (EVP_PKEY_decrypt_init(pctx) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, - EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); - goto err; - } + if (EVP_PKEY_is_a(pkey, "RSA")) + /* upper layer pkcs7 code incorrectly assumes that a successful RSA + * decryption means that the key matches ciphertext (which never + * was the case, implicit rejection or not), so to make it work + * disable implicit rejection for RSA keys */ + EVP_PKEY_CTX_ctrl_str(pctx, "rsa_pkcs1_implicit_rejection", "0"); - if (EVP_PKEY_decrypt(pctx, NULL, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0) + ret = evp_pkey_decrypt_alloc(pctx, &ek, &eklen, fixlen, + ri->enc_key->data, ri->enc_key->length); + if (ret <= 0) goto err; - ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_PKEY_decrypt(pctx, ek, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0) { - ret = 0; - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); - goto err; - } - ret = 1; OPENSSL_clear_free(*pek, *peklen); @@ -245,17 +199,26 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) int i; BIO *out = NULL, *btmp = NULL; X509_ALGOR *xa = NULL; + EVP_CIPHER *fetched_cipher = NULL; + const EVP_CIPHER *cipher; const EVP_CIPHER *evp_cipher = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; X509_ALGOR *xalg = NULL; PKCS7_RECIP_INFO *ri = NULL; ASN1_OCTET_STRING *os = NULL; + const PKCS7_CTX *p7_ctx; + OSSL_LIB_CTX *libctx; + const char *propq; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return NULL; } + p7_ctx = ossl_pkcs7_get0_ctx(p7); + libctx = ossl_pkcs7_ctx_get0_libctx(p7_ctx); + propq = ossl_pkcs7_ctx_get0_propq(p7_ctx); + /* * The content field in the PKCS7 ContentInfo is optional, but that really * only applies to inner content (precisely, detached signatures). @@ -267,7 +230,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) * calling this method, so a NULL p7->d is always an error. */ if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return NULL; } @@ -285,7 +248,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) xalg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; @@ -294,7 +257,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) xalg = p7->d.enveloped->enc_data->algorithm; evp_cipher = p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; @@ -305,15 +268,15 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) case NID_pkcs7_data: break; default: - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) - if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) + if (!pkcs7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i), p7_ctx)) goto err; - if (xa && !PKCS7_bio_add_digest(&out, xa)) + if (xa && !pkcs7_bio_add_digest(&out, xa, p7_ctx)) goto err; if (evp_cipher != NULL) { @@ -323,18 +286,33 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) EVP_CIPHER_CTX *ctx; if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); - keylen = EVP_CIPHER_key_length(evp_cipher); - ivlen = EVP_CIPHER_iv_length(evp_cipher); - xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); + keylen = EVP_CIPHER_get_key_length(evp_cipher); + ivlen = EVP_CIPHER_get_iv_length(evp_cipher); + xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_get_type(evp_cipher)); if (ivlen > 0) - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(libctx, iv, ivlen, 0) <= 0) goto err; - if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) + + (void)ERR_set_mark(); + fetched_cipher = EVP_CIPHER_fetch(libctx, + EVP_CIPHER_get0_name(evp_cipher), + propq); + (void)ERR_pop_to_mark(); + if (fetched_cipher != NULL) + cipher = fetched_cipher; + else + cipher = evp_cipher; + + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) <= 0) goto err; + + EVP_CIPHER_free(fetched_cipher); + fetched_cipher = NULL; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) @@ -346,7 +324,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) if (xalg->parameter == NULL) goto err; } - if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) + if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) <= 0) goto err; } @@ -366,16 +344,18 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) } if (bio == NULL) { - if (PKCS7_is_detached(p7)) + if (PKCS7_is_detached(p7)) { bio = BIO_new(BIO_s_null()); - else if (os && os->length > 0) + } else if (os && os->length > 0) { bio = BIO_new_mem_buf(os->data, os->length); - if (bio == NULL) { + } else { bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto err; BIO_set_mem_eof_return(bio, 0); } + if (bio == NULL) + goto err; } if (out) BIO_push(out, bio); @@ -384,6 +364,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) return out; err: + EVP_CIPHER_free(fetched_cipher); BIO_free_all(out); BIO_free_all(btmp); return NULL; @@ -396,19 +377,21 @@ static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) X509_get_issuer_name(pcert)); if (ret) return ret; - return ASN1_INTEGER_cmp(X509_get_serialNumber(pcert), + return ASN1_INTEGER_cmp(X509_get0_serialNumber(pcert), ri->issuer_and_serial->serial); } /* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { - int i, j; + int i, len; BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body = NULL; - const EVP_MD *evp_md; - const EVP_CIPHER *evp_cipher = NULL; + EVP_MD *evp_md = NULL; + const EVP_MD *md; + EVP_CIPHER *evp_cipher = NULL; + const EVP_CIPHER *cipher = NULL; EVP_CIPHER_CTX *evp_ctx = NULL; X509_ALGOR *enc_alg = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; @@ -416,14 +399,22 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) PKCS7_RECIP_INFO *ri = NULL; unsigned char *ek = NULL, *tkey = NULL; int eklen = 0, tkeylen = 0; + char name[OSSL_MAX_NAME_SIZE]; + const PKCS7_CTX *p7_ctx; + OSSL_LIB_CTX *libctx; + const char *propq; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return NULL; } + p7_ctx = ossl_pkcs7_get0_ctx(p7); + libctx = ossl_pkcs7_ctx_get0_libctx(p7_ctx); + propq = ossl_pkcs7_ctx_get0_propq(p7_ctx); + if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return NULL; } @@ -440,8 +431,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) */ data_body = PKCS7_get_octet_string(p7->d.sign->contents); if (!PKCS7_is_detached(p7) && data_body == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_INVALID_SIGNED_DATA_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_SIGNED_DATA_TYPE); goto err; } md_sk = p7->d.sign->md_algs; @@ -452,33 +442,52 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + + OBJ_obj2txt(name, sizeof(name), enc_alg->algorithm, 0); + + (void)ERR_set_mark(); + evp_cipher = EVP_CIPHER_fetch(libctx, name, propq); + if (evp_cipher != NULL) + cipher = evp_cipher; + else + cipher = EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } + (void)ERR_pop_to_mark(); break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; enc_alg = p7->d.enveloped->enc_data->algorithm; /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.enveloped->enc_data->enc_data; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + OBJ_obj2txt(name, sizeof(name), enc_alg->algorithm, 0); + + (void)ERR_set_mark(); + evp_cipher = EVP_CIPHER_fetch(libctx, name, propq); + if (evp_cipher != NULL) + cipher = evp_cipher; + else + cipher = EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } + (void)ERR_pop_to_mark(); break; default: - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* Detached content must be supplied via in_bio instead. */ if (data_body == NULL && in_bio == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); goto err; } @@ -487,19 +496,32 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { xa = sk_X509_ALGOR_value(md_sk, i); if ((btmp = BIO_new(BIO_f_md())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } - j = OBJ_obj2nid(xa->algorithm); - evp_md = EVP_get_digestbynid(j); - if (evp_md == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNKNOWN_DIGEST_TYPE); + OBJ_obj2txt(name, sizeof(name), xa->algorithm, 0); + + (void)ERR_set_mark(); + evp_md = EVP_MD_fetch(libctx, name, propq); + if (evp_md != NULL) + md = evp_md; + else + md = EVP_get_digestbyname(name); + + if (md == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } + (void)ERR_pop_to_mark(); - BIO_set_md(btmp, evp_md); + if (BIO_set_md(btmp, md) <= 0) { + EVP_MD_free(evp_md); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); + goto err; + } + EVP_MD_free(evp_md); if (out == NULL) out = btmp; else @@ -508,9 +530,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } } - if (evp_cipher != NULL) { + if (cipher != NULL) { if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } @@ -532,8 +554,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) ri = NULL; } if (ri == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } @@ -546,26 +568,31 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); - - if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + ri->ctx = p7_ctx; + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, + EVP_CIPHER_get_key_length(cipher)) < 0) goto err; ERR_clear_error(); } } else { + ri->ctx = p7_ctx; /* Only exit on fatal errors, not decrypt failure */ - if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0) goto err; ERR_clear_error(); } evp_ctx = NULL; BIO_get_cipher_ctx(etmp, &evp_ctx); - if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) + if (EVP_CipherInit_ex(evp_ctx, cipher, NULL, NULL, NULL, 0) <= 0) goto err; - if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) + if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) <= 0) goto err; /* Generate random key as MMA defence */ - tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); + len = EVP_CIPHER_CTX_get_key_length(evp_ctx); + if (len <= 0) + goto err; + tkeylen = (size_t)len; tkey = OPENSSL_malloc(tkeylen); if (tkey == NULL) goto err; @@ -577,13 +604,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) tkey = NULL; } - if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { + if (eklen != EVP_CIPHER_CTX_get_key_length(evp_ctx)) { /* * Some S/MIME clients don't use the same key and effective key * length. The key length is determined by the size of the * decrypted RSA key. */ - if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { + if (EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen) <= 0) { /* Use random key as MMA defence */ OPENSSL_clear_free(ek, eklen); ek = tkey; @@ -623,16 +650,18 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } BIO_push(out, bio); bio = NULL; + EVP_CIPHER_free(evp_cipher); return out; err: + EVP_CIPHER_free(evp_cipher); OPENSSL_clear_free(ek, eklen); OPENSSL_clear_free(tkey, tkeylen); BIO_free_all(out); BIO_free_all(btmp); BIO_free_all(etmp); BIO_free_all(bio); - return NULL; + return NULL; } static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) @@ -640,16 +669,15 @@ static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) for (;;) { bio = BIO_find_type(bio, BIO_TYPE_MD); if (bio == NULL) { - PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); return NULL; } BIO_get_md_ctx(bio, pmd); if (*pmd == NULL) { - PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_PKCS7, ERR_R_INTERNAL_ERROR); return NULL; } - if (EVP_MD_CTX_type(*pmd) == nid) + if (EVP_MD_CTX_get_type(*pmd) == nid) return bio; bio = BIO_next(bio); } @@ -664,18 +692,18 @@ static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) /* Add signing time if not already present */ if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { if (!PKCS7_add0_attrib_signing_time(si, NULL)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB); return 0; } } /* Add digest */ if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); return 0; } if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB); return 0; } @@ -696,20 +724,23 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; ASN1_OCTET_STRING *os = NULL; + const PKCS7_CTX *p7_ctx; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return 0; } + p7_ctx = ossl_pkcs7_get0_ctx(p7); + if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return 0; } ctx_tmp = EVP_MD_CTX_new(); if (ctx_tmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); return 0; } @@ -727,7 +758,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) if (os == NULL) { os = ASN1_OCTET_STRING_new(); if (os == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); goto err; } p7->d.signed_and_enveloped->enc_data->enc_data = os; @@ -739,7 +770,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) if (os == NULL) { os = ASN1_OCTET_STRING_new(); if (os == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); goto err; } p7->d.enveloped->enc_data->enc_data = os; @@ -767,7 +798,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) break; default: - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } @@ -803,14 +834,16 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) goto err; } else { unsigned char *abuf = NULL; - unsigned int abuflen; - abuflen = EVP_PKEY_size(si->pkey); - abuf = OPENSSL_malloc(abuflen); - if (abuf == NULL) + unsigned int abuflen = EVP_PKEY_get_size(si->pkey); + + if (abuflen == 0 || (abuf = OPENSSL_malloc(abuflen)) == NULL) goto err; - if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); + if (!EVP_SignFinal_ex(ctx_tmp, abuf, &abuflen, si->pkey, + ossl_pkcs7_ctx_get0_libctx(p7_ctx), + ossl_pkcs7_ctx_get0_propq(p7_ctx))) { + OPENSSL_free(abuf); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); goto err; } ASN1_STRING_set0(si->enc_digest, abuf, abuflen); @@ -824,7 +857,8 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) goto err; if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) goto err; - ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); + if (!ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len)) + goto err; } if (!PKCS7_is_detached(p7)) { @@ -839,7 +873,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) long contlen; btmp = BIO_find_type(bio, BIO_TYPE_MEM); if (btmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); goto err; } contlen = BIO_get_mem_data(btmp, &cont); @@ -855,17 +889,18 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) ret = 1; err: EVP_MD_CTX_free(ctx_tmp); - return (ret); + return ret; } int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) { EVP_MD_CTX *mctx; - EVP_PKEY_CTX *pctx; + EVP_PKEY_CTX *pctx = NULL; unsigned char *abuf = NULL; int alen; size_t siglen; const EVP_MD *md = NULL; + const PKCS7_CTX *ctx = si->ctx; md = EVP_get_digestbyobj(si->digest_alg->algorithm); if (md == NULL) @@ -873,19 +908,16 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) mctx = EVP_MD_CTX_new(); if (mctx == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); goto err; } - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + if (EVP_DigestSignInit_ex(mctx, &pctx, EVP_MD_get0_name(md), + ossl_pkcs7_ctx_get0_libctx(ctx), + ossl_pkcs7_ctx_get0_propq(ctx), si->pkey, + NULL) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); - goto err; - } - alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); if (!abuf) @@ -902,12 +934,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); - goto err; - } - EVP_MD_CTX_free(mctx); ASN1_STRING_set0(si->enc_digest, abuf, siglen); @@ -918,85 +944,92 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) OPENSSL_free(abuf); EVP_MD_CTX_free(mctx); return 0; - } +/* This partly overlaps with PKCS7_verify(). It does not support flags. */ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si) { PKCS7_ISSUER_AND_SERIAL *ias; int ret = 0, i; - STACK_OF(X509) *cert; - X509 *x509; + STACK_OF(X509) *untrusted; + STACK_OF(X509_CRL) *crls; + X509 *signer; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return 0; } if (PKCS7_type_is_signed(p7)) { - cert = p7->d.sign->cert; + untrusted = p7->d.sign->cert; + crls = p7->d.sign->crl; } else if (PKCS7_type_is_signedAndEnveloped(p7)) { - cert = p7->d.signed_and_enveloped->cert; + untrusted = p7->d.signed_and_enveloped->cert; + crls = p7->d.signed_and_enveloped->crl; } else { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } + X509_STORE_CTX_set0_crls(ctx, crls); + /* XXXXXXXXXXXXXXXXXXXXXXX */ ias = si->issuer_and_serial; - x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); + signer = X509_find_by_issuer_and_serial(untrusted, ias->issuer, ias->serial); - /* were we able to find the cert in passed to us */ - if (x509 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, - PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); + /* Were we able to find the signer certificate in passed to us? */ + if (signer == NULL) { + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); goto err; } /* Lets verify */ - if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); + if (!X509_STORE_CTX_init(ctx, cert_store, signer, untrusted)) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); goto err; } X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); i = X509_verify_cert(ctx); if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); - X509_STORE_CTX_cleanup(ctx); + ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); goto err; } - X509_STORE_CTX_cleanup(ctx); - return PKCS7_signatureVerify(bio, p7, si, x509); + return PKCS7_signatureVerify(bio, p7, si, signer); err: return ret; } int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - X509 *x509) + X509 *signer) { ASN1_OCTET_STRING *os; EVP_MD_CTX *mdc_tmp, *mdc; + const EVP_MD *md; + EVP_MD *fetched_md = NULL; int ret = 0, i; int md_type; STACK_OF(X509_ATTRIBUTE) *sk; BIO *btmp; EVP_PKEY *pkey; + const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7); + OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx); + const char *propq = ossl_pkcs7_ctx_get0_propq(ctx); mdc_tmp = EVP_MD_CTX_new(); if (mdc_tmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); goto err; } if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } @@ -1006,22 +1039,21 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, for (;;) { if ((btmp == NULL) || ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } BIO_get_md_ctx(btmp, &mdc); if (mdc == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_PKCS7, ERR_R_INTERNAL_ERROR); goto err; } - if (EVP_MD_CTX_type(mdc) == md_type) + if (EVP_MD_CTX_get_type(mdc) == md_type) break; /* * Workaround for some broken clients that put the signature OID * instead of the digest OID in digest_alg->algorithm */ - if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) + if (EVP_MD_get_pkey_type(EVP_MD_CTX_get0_md(mdc)) == md_type) break; btmp = BIO_next(btmp); } @@ -1044,24 +1076,34 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, goto err; message_digest = PKCS7_digest_from_attributes(sk); if (!message_digest) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } if ((message_digest->length != (int)md_len) || (memcmp(message_digest->data, md_dat, md_len))) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE); ret = -1; goto err; } - if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL)) + (void)ERR_set_mark(); + fetched_md = EVP_MD_fetch(libctx, OBJ_nid2sn(md_type), propq); + + if (fetched_md != NULL) + md = fetched_md; + else + md = EVP_get_digestbynid(md_type); + + if (md == NULL || !EVP_VerifyInit_ex(mdc_tmp, md, NULL)) { + (void)ERR_clear_last_mark(); goto err; + } + (void)ERR_pop_to_mark(); alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); if (alen <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); ret = -1; goto err; } @@ -1072,23 +1114,23 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, } os = si->enc_digest; - pkey = X509_get_pubkey(x509); - if (!pkey) { + pkey = X509_get0_pubkey(signer); + if (pkey == NULL) { ret = -1; goto err; } - i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey); - EVP_PKEY_free(pkey); + i = EVP_VerifyFinal_ex(mdc_tmp, os->data, os->length, pkey, libctx, propq); if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE); ret = -1; goto err; } ret = 1; err: EVP_MD_CTX_free(mdc_tmp); - return (ret); + EVP_MD_free(fetched_md); + return ret; } PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) @@ -1106,28 +1148,28 @@ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) if (rsk == NULL) return NULL; if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) - return (NULL); + return NULL; ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); - return (ri->issuer_and_serial); + return ri->issuer_and_serial; } -ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) +ASN1_TYPE *PKCS7_get_signed_attribute(const PKCS7_SIGNER_INFO *si, int nid) { - return (get_attribute(si->auth_attr, nid)); + return get_attribute(si->auth_attr, nid); } -ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) +ASN1_TYPE *PKCS7_get_attribute(const PKCS7_SIGNER_INFO *si, int nid) { - return (get_attribute(si->unauth_attr, nid)); + return get_attribute(si->unauth_attr, nid); } -static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) +static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid) { - int idx; - X509_ATTRIBUTE *xa; - idx = X509at_get_attr_by_NID(sk, nid, -1); - xa = X509at_get_attr(sk, idx); - return X509_ATTRIBUTE_get0_type(xa, 0); + int idx = X509at_get_attr_by_NID(sk, nid, -1); + + if (idx < 0) + return NULL; + return X509_ATTRIBUTE_get0_type(X509at_get_attr(sk, idx), 0); } ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) @@ -1152,9 +1194,9 @@ int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value (sk, i)))) == NULL) - return (0); + return 0; } - return (1); + return 1; } int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, @@ -1171,21 +1213,21 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value (sk, i)))) == NULL) - return (0); + return 0; } - return (1); + return 1; } int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, void *value) { - return (add_attribute(&(p7si->auth_attr), nid, atrtype, value)); + return add_attribute(&(p7si->auth_attr), nid, atrtype, value); } int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, void *value) { - return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value)); + return add_attribute(&(p7si->unauth_attr), nid, atrtype, value); } static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, @@ -1223,5 +1265,5 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, goto new_attrib; } end: - return (1); + return 1; }