diff options
Diffstat (limited to 'crypto/cmp/cmp_protect.c')
-rw-r--r-- | crypto/cmp/cmp_protect.c | 115 |
1 files changed, 47 insertions, 68 deletions
diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c index 539f6534cd01..e4f3bffed720 100644 --- a/crypto/cmp/cmp_protect.c +++ b/crypto/cmp/cmp_protect.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -10,6 +10,7 @@ */ #include "cmp_local.h" +#include "crypto/asn1.h" /* explicit #includes not strictly needed since implied by the above: */ #include <openssl/asn1t.h> @@ -21,9 +22,11 @@ /* * This function is also used by the internal verify_PBMAC() in cmp_vfy.c. * - * Calculate protection for given PKImessage according to - * the algorithm and parameters in the message header's protectionAlg + * Calculate protection for |msg| according to |msg->header->protectionAlg| * using the credentials, library context, and property criteria in the ctx. + * Unless |msg->header->protectionAlg| is PasswordBasedMAC, + * its value is completed according to |ctx->pkey| and |ctx->digest|, + * where the latter irrelevant in the case of Edwards curves. * * returns ASN1_BIT_STRING representing the protection on success, else NULL */ @@ -91,9 +94,8 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, if ((prot = ASN1_BIT_STRING_new()) == NULL) goto end; - /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */ - prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - prot->flags |= ASN1_STRING_FLAG_BITS_LEFT; + /* OpenSSL by default encodes all bit strings as ASN.1 NamedBitList */ + ossl_asn1_string_set_bits_left(prot, 0); if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) { ASN1_BIT_STRING_free(prot); prot = NULL; @@ -104,23 +106,22 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, OPENSSL_free(prot_part_der); return prot; } else { - int md_nid; - const EVP_MD *md = NULL; + const EVP_MD *md = ctx->digest; + char name[80] = ""; if (ctx->pkey == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION); return NULL; } - if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_nid, NULL) - || (md = EVP_get_digestbynid(md_nid)) == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID); - return NULL; - } + if (EVP_PKEY_get_default_digest_name(ctx->pkey, name, sizeof(name)) > 0 + && strcmp(name, "UNDEF") == 0) /* at least for Ed25519, Ed448 */ + md = NULL; if ((prot = ASN1_BIT_STRING_new()) == NULL) return NULL; - if (ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), NULL, + if (ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), + msg->header->protectionAlg, /* sets X509_ALGOR */ NULL, prot, &prot_part, NULL, ctx->pkey, md, ctx->libctx, ctx->propq)) return prot; @@ -129,6 +130,25 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, } } +void ossl_cmp_set_own_chain(OSSL_CMP_CTX *ctx) +{ + if (!ossl_assert(ctx != NULL)) + return; + /* if not yet done try to build chain using available untrusted certs */ + if (ctx->chain == NULL) { + ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert"); + ctx->chain = X509_build_chain(ctx->cert, ctx->untrusted, NULL, 0, + ctx->libctx, ctx->propq); + if (ctx->chain != NULL) { + ossl_cmp_debug(ctx, "success building chain for own CMP signer cert"); + } else { + /* dump errors to avoid confusion when printing further ones */ + OSSL_CMP_CTX_print_errors(ctx); + ossl_cmp_warn(ctx, "could not build chain for own CMP signer cert"); + } + } +} + /* ctx is not const just because ctx->chain may get adapted */ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) { @@ -141,22 +161,7 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) int prepend = X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP | X509_ADD_FLAG_PREPEND | X509_ADD_FLAG_NO_SS; - /* if not yet done try to build chain using available untrusted certs */ - if (ctx->chain == NULL) { - ossl_cmp_debug(ctx, - "trying to build chain for own CMP signer cert"); - ctx->chain = X509_build_chain(ctx->cert, ctx->untrusted, NULL, 0, - ctx->libctx, ctx->propq); - if (ctx->chain != NULL) { - ossl_cmp_debug(ctx, - "success building chain for own CMP signer cert"); - } else { - /* dump errors to avoid confusion when printing further ones */ - OSSL_CMP_CTX_print_errors(ctx); - ossl_cmp_warn(ctx, - "could not build chain for own CMP signer cert"); - } - } + ossl_cmp_set_own_chain(ctx); if (ctx->chain != NULL) { if (!ossl_x509_add_certs_new(&msg->extraCerts, ctx->chain, prepend)) return 0; @@ -185,15 +190,16 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) * Create an X509_ALGOR structure for PasswordBasedMAC protection based on * the pbm settings in the context */ -static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) +static X509_ALGOR *pbmac_algor(const OSSL_CMP_CTX *ctx) { OSSL_CRMF_PBMPARAMETER *pbm = NULL; unsigned char *pbm_der = NULL; int pbm_der_len; ASN1_STRING *pbm_str = NULL; + X509_ALGOR *alg = NULL; if (!ossl_assert(ctx != NULL)) - return 0; + return NULL; pbm = OSSL_CRMF_pbmp_new(ctx->libctx, ctx->pbm_slen, EVP_MD_get_type(ctx->pbm_owf), ctx->pbm_itercnt, @@ -201,47 +207,18 @@ static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) pbm_str = ASN1_STRING_new(); if (pbm == NULL || pbm_str == NULL) goto err; - if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0) goto err; - if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len)) goto err; - if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) - goto err; - OPENSSL_free(pbm_der); - - X509_ALGOR_set0(*alg, OBJ_nid2obj(NID_id_PasswordBasedMAC), - V_ASN1_SEQUENCE, pbm_str); - OSSL_CRMF_PBMPARAMETER_free(pbm); - return 1; - + alg = ossl_X509_ALGOR_from_nid(NID_id_PasswordBasedMAC, + V_ASN1_SEQUENCE, pbm_str); err: - ASN1_STRING_free(pbm_str); + if (alg == NULL) + ASN1_STRING_free(pbm_str); OPENSSL_free(pbm_der); OSSL_CRMF_PBMPARAMETER_free(pbm); - return 0; -} - -static int set_sig_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) -{ - int nid = 0; - ASN1_OBJECT *algo = NULL; - - if (!OBJ_find_sigid_by_algs(&nid, EVP_MD_get_type(ctx->digest), - EVP_PKEY_get_id(ctx->pkey))) { - ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_KEY_TYPE); - return 0; - } - if ((algo = OBJ_nid2obj(nid)) == NULL) - return 0; - if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) - return 0; - - if (X509_ALGOR_set0(*alg, algo, V_ASN1_UNDEF, NULL)) - return 1; - ASN1_OBJECT_free(algo); - return 0; + return alg; } static int set_senderKID(const OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg, @@ -260,6 +237,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) /* * For the case of re-protection remove pre-existing protection. + * Does not remove any pre-existing extraCerts. */ X509_ALGOR_free(msg->header->protectionAlg); msg->header->protectionAlg = NULL; @@ -271,7 +249,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } else if (ctx->secretValue != NULL) { /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */ - if (!set_pbmac_algor(ctx, &msg->header->protectionAlg)) + if ((msg->header->protectionAlg = pbmac_algor(ctx)) == NULL) goto err; if (!set_senderKID(ctx, msg, NULL)) goto err; @@ -290,7 +268,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } - if (!set_sig_algor(ctx, &msg->header->protectionAlg)) + if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL) goto err; /* set senderKID to keyIdentifier of the cert according to 5.1.1 */ if (!set_senderKID(ctx, msg, X509_get0_subject_key_id(ctx->cert))) @@ -306,6 +284,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } if (!ctx->unprotectedSend + /* protect according to msg->header->protectionAlg partly set above */ && ((msg->protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)) goto err; |