diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-04-26 12:08:27 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-04-28 09:38:31 +0200 |
commit | eaf8a40d97d642ccd2c55fbf8bb8ee3242aec04a (patch) | |
tree | 23ef2d3756c42a91841270eb74330a8840dbf5d0 /crypto | |
parent | c0a79e9836a9aa30912978f69fab3b3bb3a8ddc5 (diff) | |
download | openssl-eaf8a40d97d642ccd2c55fbf8bb8ee3242aec04a.zip openssl-eaf8a40d97d642ccd2c55fbf8bb8ee3242aec04a.tar.gz openssl-eaf8a40d97d642ccd2c55fbf8bb8ee3242aec04a.tar.bz2 |
Prefer fetch over legacy get_digestby/get_cipherby
Fixes #14198
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15028)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/crmf/crmf_lib.c | 19 | ||||
-rw-r--r-- | crypto/ess/ess_lib.c | 50 | ||||
-rw-r--r-- | crypto/ocsp/ocsp_vfy.c | 50 | ||||
-rw-r--r-- | crypto/ts/ts_rsp_verify.c | 26 |
4 files changed, 106 insertions, 39 deletions
diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index 6cea644..e26637d 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -30,6 +30,7 @@ #include "crmf_local.h" #include "internal/constant_time.h" +#include "internal/sizes.h" /* explicit #includes not strictly needed since implied by the above: */ #include <openssl/crmf.h> @@ -589,24 +590,37 @@ X509 EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */ unsigned char *ek = NULL; /* decrypted symmetric encryption key */ size_t eksize = 0; /* size of decrypted symmetric encryption key */ - const EVP_CIPHER *cipher = NULL; /* used cipher */ + EVP_CIPHER *cipher = NULL; /* used cipher */ int cikeysize = 0; /* key size from cipher */ unsigned char *iv = NULL; /* initial vector for symmetric encryption */ unsigned char *outbuf = NULL; /* decryption output buffer */ const unsigned char *p = NULL; /* needed for decoding ASN1 */ int n, outlen = 0; EVP_PKEY_CTX *pkctx = NULL; /* private key context */ + char name[OSSL_MAX_NAME_SIZE]; if (ecert == NULL || ecert->symmAlg == NULL || ecert->encSymmKey == NULL || ecert->encValue == NULL || pkey == NULL) { ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); return NULL; } + /* select symmetric cipher based on algorithm given in message */ - if ((cipher = EVP_get_cipherbyobj(ecert->symmAlg->algorithm)) == NULL) { + OBJ_obj2txt(name, sizeof(name), ecert->symmAlg->algorithm, 0); + + (void)ERR_set_mark(); + cipher = EVP_CIPHER_fetch(NULL, name, NULL); + + if (cipher == NULL) + cipher = (EVP_CIPHER *)EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_CIPHER); goto end; } + (void)ERR_pop_to_mark(); + cikeysize = EVP_CIPHER_key_length(cipher); /* first the symmetric key needs to be decrypted */ pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); @@ -670,6 +684,7 @@ X509 EVP_PKEY_CTX_free(pkctx); OPENSSL_free(outbuf); EVP_CIPHER_CTX_free(evp_ctx); + EVP_CIPHER_free(cipher); OPENSSL_clear_free(ek, eksize); OPENSSL_free(iv); return cert; diff --git a/crypto/ess/ess_lib.c b/crypto/ess/ess_lib.c index ebfe5b9..6ded9f6 100644 --- a/crypto/ess/ess_lib.c +++ b/crypto/ess/ess_lib.c @@ -11,6 +11,7 @@ #include <openssl/x509v3.h> #include <openssl/err.h> #include <openssl/ess.h> +#include "internal/sizes.h" #include "crypto/ess.h" #include "crypto/x509.h" @@ -302,36 +303,48 @@ static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2, int index, const STACK_OF(X509) *certs) { const X509 *cert; - const EVP_MD *md; + EVP_MD *md = NULL; + char name[OSSL_MAX_NAME_SIZE]; unsigned char cert_digest[EVP_MAX_MD_SIZE]; unsigned int len, cid_hash_len; const ESS_ISSUER_SERIAL *is; int i; + int ret = -1; if (cid == NULL && cid_v2 == NULL) { ERR_raise(ERR_LIB_ESS, ERR_R_PASSED_INVALID_ARGUMENT); return -1; } + if (cid != NULL) + strcpy(name, "SHA1"); + else if (cid_v2->hash_alg == NULL) + strcpy(name, "SHA256"); + else + OBJ_obj2txt(name, sizeof(name), cid_v2->hash_alg->algorithm, 0); + + (void)ERR_set_mark(); + md = EVP_MD_fetch(NULL, name, NULL); + + if (md == NULL) + md = (EVP_MD *)EVP_get_digestbyname(name); + + if (md == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN); + goto end; + } + (void)ERR_pop_to_mark(); + /* Look for cert with cid in the certs. */ for (i = 0; i < sk_X509_num(certs); ++i) { cert = sk_X509_value(certs, i); - if (cid != NULL) - md = EVP_sha1(); - else - md = cid_v2->hash_alg == NULL ? EVP_sha256() : - EVP_get_digestbyobj(cid_v2->hash_alg->algorithm); - if (md == NULL) { - ERR_raise(ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN); - return -1; - } - cid_hash_len = cid != NULL ? cid->hash->length : cid_v2->hash->length; if (!X509_digest(cert, md, cert_digest, &len) || cid_hash_len != len) { ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_DIGEST_ERROR); - return -1; + goto end; } if (memcmp(cid != NULL ? cid->hash->data : cid_v2->hash->data, @@ -339,16 +352,21 @@ static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2, is = cid != NULL ? cid->issuer_serial : cid_v2->issuer_serial; /* Well, it's not really required to match the serial numbers. */ if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0) { - if ((i == 0) == (index == 0)) - return i + 1; + if ((i == 0) == (index == 0)) { + ret = i + 1; + goto end; + } ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_WRONG_ORDER); - return -1; + goto end; } } } + ret = 0; ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_NOT_FOUND); - return 0; +end: + EVP_MD_free(md); + return ret; } /* diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c index 02af584..4231c3f 100644 --- a/crypto/ocsp/ocsp_vfy.c +++ b/crypto/ocsp/ocsp_vfy.c @@ -7,10 +7,11 @@ * https://www.openssl.org/source/license.html */ +#include <string.h> #include <openssl/ocsp.h> -#include "ocsp_local.h" #include <openssl/err.h> -#include <string.h> +#include "internal/sizes.h" +#include "ocsp_local.h" static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, unsigned long flags); @@ -302,42 +303,56 @@ static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp) { + int ret = -1; + EVP_MD *dgst = NULL; + /* If only one ID to match then do it */ if (cid != NULL) { - const EVP_MD *dgst = EVP_get_digestbyobj(cid->hashAlgorithm.algorithm); + char name[OSSL_MAX_NAME_SIZE]; const X509_NAME *iname; int mdlen; unsigned char md[EVP_MAX_MD_SIZE]; + OBJ_obj2txt(name, sizeof(name), cid->hashAlgorithm.algorithm, 0); + + (void)ERR_set_mark(); + dgst = EVP_MD_fetch(NULL, name, NULL); + if (dgst == NULL) + dgst = (EVP_MD *)EVP_get_digestbyname(name); + if (dgst == NULL) { + (void)ERR_clear_last_mark(); ERR_raise(ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST); - return -1; + goto end; } + (void)ERR_pop_to_mark(); mdlen = EVP_MD_size(dgst); if (mdlen < 0) { ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_SIZE_ERR); - return -1; + goto end; } if (cid->issuerNameHash.length != mdlen || - cid->issuerKeyHash.length != mdlen) - return 0; + cid->issuerKeyHash.length != mdlen) { + ret = 0; + goto end; + } iname = X509_get_subject_name(cert); - if (!X509_NAME_digest(iname, dgst, md, NULL)) { - ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_NAME_ERR); - return -1; + if (!X509_NAME_digest(iname, dgst, md, NULL)) + goto end; + if (memcmp(md, cid->issuerNameHash.data, mdlen) != 0) { + ret = 0; + goto end; } - if (memcmp(md, cid->issuerNameHash.data, mdlen) != 0) - return 0; if (!X509_pubkey_digest(cert, dgst, md, NULL)) { ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_ERR); - return -1; + goto end; } - if (memcmp(md, cid->issuerKeyHash.data, mdlen) != 0) - return 0; + ret = memcmp(md, cid->issuerKeyHash.data, mdlen) == 0; + goto end; } else { /* We have to match the whole lot */ - int i, ret; + int i; OCSP_CERTID *tmpid; for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { @@ -348,6 +363,9 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, } } return 1; +end: + EVP_MD_free(dgst); + return ret; } static int ocsp_check_delegated(X509 *x) diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c index f307e29..09daa2a 100644 --- a/crypto/ts/ts_rsp_verify.c +++ b/crypto/ts/ts_rsp_verify.c @@ -8,12 +8,13 @@ */ #include <stdio.h> -#include "internal/cryptlib.h" #include <openssl/objects.h> #include <openssl/ts.h> #include <openssl/pkcs7.h> -#include "ts_local.h" +#include "internal/cryptlib.h" +#include "internal/sizes.h" #include "crypto/ess.h" +#include "ts_local.h" static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer, STACK_OF(X509) **chain); @@ -395,9 +396,10 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info, { TS_MSG_IMPRINT *msg_imprint = tst_info->msg_imprint; X509_ALGOR *md_alg_resp = msg_imprint->hash_algo; - const EVP_MD *md; + EVP_MD *md = NULL; EVP_MD_CTX *md_ctx = NULL; unsigned char buffer[4096]; + char name[OSSL_MAX_NAME_SIZE]; int length; *md_alg = NULL; @@ -405,10 +407,21 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info, if ((*md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL) goto err; - if ((md = EVP_get_digestbyobj((*md_alg)->algorithm)) == NULL) { - ERR_raise(ERR_LIB_TS, TS_R_UNSUPPORTED_MD_ALGORITHM); + + OBJ_obj2txt(name, sizeof(name), md_alg_resp->algorithm, 0); + + (void)ERR_set_mark(); + md = EVP_MD_fetch(NULL, name, NULL); + + if (md == NULL) + md = (EVP_MD *)EVP_get_digestbyname(name); + + if (md == NULL) { + (void)ERR_clear_last_mark(); goto err; } + (void)ERR_pop_to_mark(); + length = EVP_MD_size(md); if (length < 0) goto err; @@ -425,6 +438,8 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info, } if (!EVP_DigestInit(md_ctx, md)) goto err; + EVP_MD_free(md); + md = NULL; while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) { if (!EVP_DigestUpdate(md_ctx, buffer, length)) goto err; @@ -436,6 +451,7 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info, return 1; err: EVP_MD_CTX_free(md_ctx); + EVP_MD_free(md); X509_ALGOR_free(*md_alg); *md_alg = NULL; OPENSSL_free(*imprint); |