/*
 * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright Nokia 2007-2020
 * Copyright Siemens AG 2015-2020
 *
 * 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
 */

/* CMP functions for PKIMessage checking */

#include "cmp_local.h"
#include <openssl/cmp_util.h>

/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/asn1t.h>
#include <openssl/cmp.h>
#include <openssl/crmf.h>
#include <openssl/err.h>
#include <openssl/x509.h>

/* Verify a message protected by signature according to RFC section 5.1.3.3 */
static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
                            const OSSL_CMP_MSG *msg, X509 *cert)
{
    OSSL_CMP_PROTECTEDPART prot_part;
    EVP_PKEY *pubkey = NULL;
    BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */
    int res = 0;

    if (!ossl_assert(cmp_ctx != NULL && msg != NULL && cert != NULL))
        return 0;

    /* verify that keyUsage, if present, contains digitalSignature */
    if (!cmp_ctx->ignore_keyusage
            && (X509_get_key_usage(cert) & X509v3_KU_DIGITAL_SIGNATURE) == 0) {
        ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE);
        goto sig_err;
    }

    pubkey = X509_get_pubkey(cert);
    if (pubkey == NULL) {
        ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_EXTRACTING_PUBKEY);
        goto sig_err;
    }

    prot_part.header = msg->header;
    prot_part.body = msg->body;

    if (ASN1_item_verify_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART),
                            msg->header->protectionAlg, msg->protection,
                            &prot_part, NULL, pubkey, cmp_ctx->libctx,
                            cmp_ctx->propq) > 0) {
        res = 1;
        goto end;
    }

 sig_err:
    res = ossl_x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS);
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_SIGNATURE);
    if (res)
        ERR_add_error_mem_bio("\n", bio);
    res = 0;

 end:
    EVP_PKEY_free(pubkey);
    BIO_free(bio);

    return res;
}

/* Verify a message protected with PBMAC */
static int verify_PBMAC(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
{
    ASN1_BIT_STRING *protection = NULL;
    int valid = 0;

    /* generate expected protection for the message */
    if ((protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)
        return 0; /* failed to generate protection string! */

    valid = msg->protection != NULL && msg->protection->length >= 0
            && msg->protection->type == protection->type
            && msg->protection->length == protection->length
            && CRYPTO_memcmp(msg->protection->data, protection->data,
                             protection->length) == 0;
    ASN1_BIT_STRING_free(protection);
    if (!valid)
        ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_PBM_VALUE);

    return valid;
}

/*-
 * Attempt to validate certificate and path using any given store with trusted
 * certs (possibly including CRLs and a cert verification callback function)
 * and non-trusted intermediate certs from the given ctx.
 *
 * Returns 1 on successful validation and 0 otherwise.
 */
int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
                                X509_STORE *trusted_store, X509 *cert)
{
    int valid = 0;
    X509_STORE_CTX *csc = NULL;
    int err;

    if (ctx == NULL || cert == NULL) {
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
        return 0;
    }

    if (trusted_store == NULL) {
        ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_TRUST_STORE);
        return 0;
    }

    if ((csc = X509_STORE_CTX_new_ex(ctx->libctx, ctx->propq)) == NULL
            || !X509_STORE_CTX_init(csc, trusted_store,
                                    cert, ctx->untrusted))
        goto err;

    valid = X509_verify_cert(csc) > 0;

    /* make sure suitable error is queued even if callback did not do */
    err = ERR_peek_last_error();
    if (!valid && ERR_GET_REASON(err) != CMP_R_POTENTIALLY_INVALID_CERTIFICATE)
        ERR_raise(ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE);

 err:
    /* directly output any fresh errors, needed for check_msg_find_cert() */
    OSSL_CMP_CTX_print_errors(ctx);
    X509_STORE_CTX_free(csc);
    return valid;
}

/* Return 0 if expect_name != NULL and there is no matching actual_name */
static int check_name(const OSSL_CMP_CTX *ctx, int log_success,
                      const char *actual_desc, const X509_NAME *actual_name,
                      const char *expect_desc, const X509_NAME *expect_name)
{
    char *str;

    if (expect_name == NULL)
        return 1; /* no expectation, thus trivially fulfilled */

    /* make sure that a matching name is there */
    if (actual_name == NULL) {
        ossl_cmp_log1(WARN, ctx, "missing %s", actual_desc);
        return 0;
    }
    str = X509_NAME_oneline(actual_name, NULL, 0);
    if (X509_NAME_cmp(actual_name, expect_name) == 0) {
        if (log_success && str != NULL)
            ossl_cmp_log2(INFO, ctx, " subject matches %s: %s", expect_desc,
                          str);
        OPENSSL_free(str);
        return 1;
    }

    if (str != NULL)
        ossl_cmp_log2(INFO, ctx, " actual name in %s = %s", actual_desc, str);
    OPENSSL_free(str);
    if ((str = X509_NAME_oneline(expect_name, NULL, 0)) != NULL)
        ossl_cmp_log2(INFO, ctx, " does not match %s = %s", expect_desc, str);
    OPENSSL_free(str);
    return 0;
}

/* Return 0 if skid != NULL and there is no matching subject key ID in cert */
static int check_kid(const OSSL_CMP_CTX *ctx,
                     const ASN1_OCTET_STRING *ckid,
                     const ASN1_OCTET_STRING *skid)
{
    char *str;

    if (skid == NULL)
        return 1; /* no expectation, thus trivially fulfilled */

    /* make sure that the expected subject key identifier is there */
    if (ckid == NULL) {
        ossl_cmp_warn(ctx, "missing Subject Key Identifier in certificate");
        return 0;
    }
    str = OPENSSL_buf2hexstr(ckid->data, ckid->length);
    if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0) {
        if (str != NULL)
            ossl_cmp_log1(INFO, ctx, " subjectKID matches senderKID: %s", str);
        OPENSSL_free(str);
        return 1;
    }

    if (str != NULL)
        ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", str);
    OPENSSL_free(str);
    if ((str = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL)
        ossl_cmp_log1(INFO, ctx, " does not match senderKID    = %s", str);
    OPENSSL_free(str);
    return 0;
}

static int already_checked(const X509 *cert,
                           const STACK_OF(X509) *already_checked)
{
    int i;

    for (i = sk_X509_num(already_checked /* may be NULL */); i > 0; i--)
        if (X509_cmp(sk_X509_value(already_checked, i - 1), cert) == 0)
            return 1;
    return 0;
}

/*-
 * Check if the given cert is acceptable as sender cert of the given message.
 * The subject DN must match, the subject key ID as well if present in the msg,
 * and the cert must be current (checked if ctx->trusted is not NULL).
 * Note that cert revocation etc. is checked by OSSL_CMP_validate_cert_path().
 *
 * Returns 0 on error or not acceptable, else 1.
 */
static int cert_acceptable(const OSSL_CMP_CTX *ctx,
                           const char *desc1, const char *desc2, X509 *cert,
                           const STACK_OF(X509) *already_checked1,
                           const STACK_OF(X509) *already_checked2,
                           const OSSL_CMP_MSG *msg)
{
    X509_STORE *ts = ctx->trusted;
    int self_issued = X509_check_issued(cert, cert) == X509_V_OK;
    char *str;
    X509_VERIFY_PARAM *vpm = ts != NULL ? X509_STORE_get0_param(ts) : NULL;
    int time_cmp;

    ossl_cmp_log3(INFO, ctx, " considering %s%s %s with..",
                  self_issued ? "self-issued ": "", desc1, desc2);
    if ((str = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)) != NULL)
        ossl_cmp_log1(INFO, ctx, "  subject = %s", str);
    OPENSSL_free(str);
    if (!self_issued) {
        str = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
        if (str != NULL)
            ossl_cmp_log1(INFO, ctx, "  issuer  = %s", str);
        OPENSSL_free(str);
    }

    if (already_checked(cert, already_checked1)
            || already_checked(cert, already_checked2)) {
        ossl_cmp_info(ctx, " cert has already been checked");
        return 0;
    }

    time_cmp = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert),
                                  X509_get0_notAfter(cert));
    if (time_cmp != 0) {
        ossl_cmp_warn(ctx, time_cmp > 0 ? "cert has expired"
                                        : "cert is not yet valid");
        return 0;
    }

    if (!check_name(ctx, 1,
                    "cert subject", X509_get_subject_name(cert),
                    "sender field", msg->header->sender->d.directoryName))
        return 0;

    if (!check_kid(ctx, X509_get0_subject_key_id(cert), msg->header->senderKID))
        return 0;
    /* prevent misleading error later in case x509v3_cache_extensions() fails */
    if (!ossl_x509v3_cache_extensions(cert)) {
        ossl_cmp_warn(ctx, "cert appears to be invalid");
        return 0;
    }
    if (!verify_signature(ctx, msg, cert)) {
        ossl_cmp_warn(ctx, "msg signature verification failed");
        return 0;
    }
    /* acceptable also if there is no senderKID in msg header */
    ossl_cmp_info(ctx, " cert seems acceptable");
    return 1;
}

static int check_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *store,
                           X509 *scrt)
{
    if (OSSL_CMP_validate_cert_path(ctx, store, scrt))
        return 1;

    ossl_cmp_warn(ctx,
                  "msg signature validates but cert path validation failed");
    return 0;
}

/*
 * Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security
 * (NDS); Authentication Framework (AF)], only to use for IP messages
 * and if the ctx option is explicitly set: use self-issued certificates
 * from extraCerts as trust anchor to validate sender cert -
 * provided it also can validate the newly enrolled certificate
 */
static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx,
                                const OSSL_CMP_MSG *msg, X509 *scrt)
{
    int valid = 0;
    X509_STORE *store;

    if (!ctx->permitTAInExtraCertsForIR)
        return 0;

    if ((store = X509_STORE_new()) == NULL
            || !ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts,
                                               1 /* self-issued only */))
        goto err;

    /* store does not include CRLs */
    valid = OSSL_CMP_validate_cert_path(ctx, store, scrt);
    if (!valid) {
        ossl_cmp_warn(ctx,
                      "also exceptional 3GPP mode cert path validation failed");
    } else {
        /*
         * verify that the newly enrolled certificate (which assumed rid ==
         * OSSL_CMP_CERTREQID) can also be validated with the same trusted store
         */
        EVP_PKEY *pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
        OSSL_CMP_CERTRESPONSE *crep =
            ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip,
                                                      OSSL_CMP_CERTREQID);
        X509 *newcrt = ossl_cmp_certresponse_get1_cert(crep, ctx, pkey);
        /*
         * maybe better use get_cert_status() from cmp_client.c, which catches
         * errors
         */
        valid = OSSL_CMP_validate_cert_path(ctx, store, newcrt);
        X509_free(newcrt);
    }

 err:
    X509_STORE_free(store);
    return valid;
}

static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert,
                                const OSSL_CMP_MSG *msg)
{
    return cert_acceptable(ctx, "previously validated", "sender cert",
                           cert, NULL, NULL, msg)
        && (check_cert_path(ctx, ctx->trusted, cert)
            || check_cert_path_3gpp(ctx, msg, cert));
}

/*-
 * Try all certs in given list for verifying msg, normally or in 3GPP mode.
 * If already_checked1 == NULL then certs are assumed to be the msg->extraCerts.
 * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
 */
static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
                                const char *desc,
                                const STACK_OF(X509) *already_checked1,
                                const STACK_OF(X509) *already_checked2,
                                const OSSL_CMP_MSG *msg, int mode_3gpp)
{
    int in_extraCerts = already_checked1 == NULL;
    int n_acceptable_certs = 0;
    int i;

    if (sk_X509_num(certs) <= 0) {
        ossl_cmp_log1(WARN, ctx, "no %s", desc);
        return 0;
    }

    for (i = 0; i < sk_X509_num(certs); i++) { /* certs may be NULL */
        X509 *cert = sk_X509_value(certs, i);

        if (!ossl_assert(cert != NULL))
            return 0;
        if (!cert_acceptable(ctx, "cert from", desc, cert,
                             already_checked1, already_checked2, msg))
            continue;
        n_acceptable_certs++;
        if (mode_3gpp ? check_cert_path_3gpp(ctx, msg, cert)
                      : check_cert_path(ctx, ctx->trusted, cert)) {
            /* store successful sender cert for further msgs in transaction */
            if (!X509_up_ref(cert))
                return 0;
            if (!ossl_cmp_ctx_set0_validatedSrvCert(ctx, cert)) {
                X509_free(cert);
                return 0;
            }
            return 1;
        }
    }
    if (in_extraCerts && n_acceptable_certs == 0)
        ossl_cmp_warn(ctx, "no acceptable cert in extraCerts");
    return 0;
}

/*-
 * Verify msg trying first ctx->untrusted, which should include extraCerts
 * at its front, then trying the trusted certs in truststore (if any) of ctx.
 * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
 */
static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
                               int mode_3gpp)
{
    int ret = 0;

    if (mode_3gpp
            && ((!ctx->permitTAInExtraCertsForIR
                     || ossl_cmp_msg_get_bodytype(msg) != OSSL_CMP_PKIBODY_IP)))
        return 0;

    ossl_cmp_info(ctx,
                  mode_3gpp ? "normal mode failed; trying now 3GPP mode trusting extraCerts"
                            : "trying first normal mode using trust store");
    if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts",
                             NULL, NULL, msg, mode_3gpp))
        return 1;
    if (check_msg_with_certs(ctx, ctx->untrusted, "untrusted certs",
                             msg->extraCerts, NULL, msg, mode_3gpp))
        return 1;

    if (ctx->trusted == NULL) {
        ossl_cmp_warn(ctx, mode_3gpp ? "no self-issued extraCerts"
                                     : "no trusted store");
    } else {
        STACK_OF(X509) *trusted = X509_STORE_get1_all_certs(ctx->trusted);
        ret = check_msg_with_certs(ctx, trusted,
                                   mode_3gpp ? "self-issued extraCerts"
                                             : "certs in trusted store",
                                   msg->extraCerts, ctx->untrusted,
                                   msg, mode_3gpp);
        sk_X509_pop_free(trusted, X509_free);
    }
    return ret;
}

static int no_log_cb(const char *func, const char *file, int line,
                     OSSL_CMP_severity level, const char *msg)
{
    return 1;
}

/*-
 * Verify message signature with any acceptable and valid candidate cert.
 * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
 */
static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
{
    X509 *scrt = ctx->validatedSrvCert; /* previous successful sender cert */
    GENERAL_NAME *sender = msg->header->sender;
    char *sname = NULL;
    char *skid_str = NULL;
    const ASN1_OCTET_STRING *skid = msg->header->senderKID;
    OSSL_CMP_log_cb_t backup_log_cb = ctx->log_cb;
    int res = 0;

    if (sender == NULL || msg->body == NULL)
        return 0; /* other NULL cases already have been checked */
    if (sender->type != GEN_DIRNAME) {
        ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
        return 0;
    }

    /* dump any hitherto errors to avoid confusion when printing further ones */
    OSSL_CMP_CTX_print_errors(ctx);

    /* enable clearing irrelevant errors in attempts to validate sender certs */
    (void)ERR_set_mark();
    ctx->log_cb = no_log_cb; /* temporarily disable logging */

    /*
     * try first cached scrt, used successfully earlier in same transaction,
     * for validating this and any further msgs where extraCerts may be left out
     */
    if (scrt != NULL) {
        if (check_msg_given_cert(ctx, scrt, msg)) {
            ctx->log_cb = backup_log_cb;
            (void)ERR_pop_to_mark();
            return 1;
        }
        /* cached sender cert has shown to be no more successfully usable */
        (void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
        /* re-do the above check (just) for adding diagnostic information */
        ossl_cmp_info(ctx,
                      "trying to verify msg signature with previously validated cert");
        (void)check_msg_given_cert(ctx, scrt, msg);
    }

    res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
            || check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
    ctx->log_cb = backup_log_cb;
    if (res) {
        /* discard any diagnostic information on trying to use certs */
        (void)ERR_pop_to_mark();
        goto end;
    }
    /* failed finding a sender cert that verifies the message signature */
    (void)ERR_clear_last_mark();

    sname = X509_NAME_oneline(sender->d.directoryName, NULL, 0);
    skid_str = skid == NULL ? NULL
                            : OPENSSL_buf2hexstr(skid->data, skid->length);
    if (ctx->log_cb != NULL) {
        ossl_cmp_info(ctx, "trying to verify msg signature with a valid cert that..");
        if (sname != NULL)
            ossl_cmp_log1(INFO, ctx, "matches msg sender    = %s", sname);
        if (skid_str != NULL)
            ossl_cmp_log1(INFO, ctx, "matches msg senderKID = %s", skid_str);
        else
            ossl_cmp_info(ctx, "while msg header does not contain senderKID");
        /* re-do the above checks (just) for adding diagnostic information */
        (void)check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */);
        (void)check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
    }

    ERR_raise(ERR_LIB_CMP, CMP_R_NO_SUITABLE_SENDER_CERT);
    if (sname != NULL) {
        ERR_add_error_txt(NULL, "for msg sender name = ");
        ERR_add_error_txt(NULL, sname);
    }
    if (skid_str != NULL) {
        ERR_add_error_txt(" and ", "for msg senderKID = ");
        ERR_add_error_txt(NULL, skid_str);
    }

 end:
    OPENSSL_free(sname);
    OPENSSL_free(skid_str);
    return res;
}

/*-
 * Validate the protection of the given PKIMessage using either password-
 * based mac (PBM) or a signature algorithm. In the case of signature algorithm,
 * the sender certificate can have been pinned by providing it in ctx->srvCert,
 * else it is searched in msg->extraCerts, ctx->untrusted, in ctx->trusted
 * (in this order) and is path is validated against ctx->trusted.
 * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
 *
 * If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg,
 * the trust anchor for validating the IP msg may be taken from msg->extraCerts
 * if a self-issued certificate is found there that can be used to
 * validate the enrolled certificate returned in the IP.
 * This is according to the need given in 3GPP TS 33.310.
 *
 * Returns 1 on success, 0 on error or validation failed.
 */
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
{
    X509 *scrt;

    ossl_cmp_debug(ctx, "validating CMP message");
    if (ctx == NULL || msg == NULL
            || msg->header == NULL || msg->body == NULL) {
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
        return 0;
    }

    if (msg->header->protectionAlg == NULL /* unprotected message */
            || msg->protection == NULL || msg->protection->data == NULL) {
        ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PROTECTION);
        return 0;
    }

    switch (ossl_cmp_hdr_get_protection_nid(msg->header)) {
        /* 5.1.3.1.  Shared Secret Information */
    case NID_id_PasswordBasedMAC:
        if (ctx->secretValue == NULL) {
            ossl_cmp_warn(ctx, "no secret available for verifying PBM-based CMP message protection");
            return 1;
        }
        if (verify_PBMAC(ctx, msg)) {
            /*
             * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
             * "shared secret information", then any certificate transported in
             * the caPubs field may be directly trusted as a root CA
             * certificate by the initiator.'
             */
            switch (ossl_cmp_msg_get_bodytype(msg)) {
            case -1:
                return 0;
            case OSSL_CMP_PKIBODY_IP:
            case OSSL_CMP_PKIBODY_CP:
            case OSSL_CMP_PKIBODY_KUP:
            case OSSL_CMP_PKIBODY_CCP:
                if (ctx->trusted != NULL) {
                    STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
                    /* value.ip is same for cp, kup, and ccp */

                    if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
                        /* adds both self-issued and not self-issued certs */
                        return 0;
                }
                break;
            default:
                break;
            }
            ossl_cmp_debug(ctx,
                           "sucessfully validated PBM-based CMP message protection");
            return 1;
        }
        ossl_cmp_warn(ctx, "verifying PBM-based CMP message protection failed");
        break;

        /*
         * 5.1.3.2 DH Key Pairs
         * Not yet supported
         */
    case NID_id_DHBasedMac:
        ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC);
        break;

        /*
         * 5.1.3.3.  Signature
         */
    default:
        scrt = ctx->srvCert;
        if (scrt == NULL) {
            if (ctx->trusted == NULL) {
                ossl_cmp_warn(ctx, "no trust store nor pinned server cert available for verifying signature-based CMP message protection");
                return 1;
            }
            if (check_msg_find_cert(ctx, msg))
                return 1;
        } else { /* use pinned sender cert */
            /* use ctx->srvCert for signature check even if not acceptable */
            if (verify_signature(ctx, msg, scrt)) {
                ossl_cmp_debug(ctx,
                               "sucessfully validated signature-based CMP message protection");

                return 1;
            }
            ossl_cmp_warn(ctx, "CMP message signature verification failed");
            ERR_raise(ERR_LIB_CMP, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG);
        }
        break;
    }
    return 0;
}


/*-
 * Check received message (i.e., response by server or request from client)
 * Any msg->extraCerts are prepended to ctx->untrusted.
 *
 * Ensures that:
 * its sender is of appropriate type (curently only X509_NAME) and
 *     matches any expected sender or srvCert subject given in the ctx
 * it has a valid body type
 * its protection is valid (or invalid/absent, but only if a callback function
 *     is present and yields a positive result using also the supplied argument)
 * its transaction ID matches the previous transaction ID stored in ctx (if any)
 * its recipNonce matches the previous senderNonce stored in the ctx (if any)
 *
 * If everything is fine:
 * learns the senderNonce from the received message,
 * learns the transaction ID if it is not yet in ctx,
 * and makes any certs in caPubs directly trusted.
 *
 * Returns 1 on success, 0 on error.
 */
int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
                              ossl_cmp_allow_unprotected_cb_t cb, int cb_arg)
{
    OSSL_CMP_PKIHEADER *hdr;
    const X509_NAME *expected_sender;

    if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL))
        return 0;
    hdr = OSSL_CMP_MSG_get0_header(msg);

    /* validate sender name of received msg */
    if (hdr->sender->type != GEN_DIRNAME) {
        ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
        return 0; /* TODO FR#42: support for more than X509_NAME */
    }
    /*
     * Compare actual sender name of response with expected sender name.
     * Mitigates risk to accept misused PBM secret
     * or misused certificate of an unauthorized entity of a trusted hierarchy.
     */
    expected_sender = ctx->expected_sender;
    if (expected_sender == NULL && ctx->srvCert != NULL)
        expected_sender = X509_get_subject_name(ctx->srvCert);
    if (!check_name(ctx, 0, "sender DN field", hdr->sender->d.directoryName,
                    "expected sender", expected_sender))
        return 0;
    /* Note: if recipient was NULL-DN it could be learned here if needed */

    if (sk_X509_num(msg->extraCerts) > 10)
        ossl_cmp_warn(ctx,
                      "received CMP message contains more than 10 extraCerts");
    /*
     * Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg()
     * and for future use, such that they are available to ctx->certConf_cb and
     * the peer does not need to send them again in the same transaction.
     * Note that it does not help validating the message before storing the
     * extraCerts because they do not belong to the protected msg part anyway.
     * For efficiency, the extraCerts are prepended so they get used first.
     */
    if (!X509_add_certs(ctx->untrusted, msg->extraCerts,
                        /* this allows self-signed certs */
                        X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
                        | X509_ADD_FLAG_PREPEND))
        return 0;

    /* validate message protection */
    if (hdr->protectionAlg != NULL) {
        /* detect explicitly permitted exceptions for invalid protection */
        if (!OSSL_CMP_validate_msg(ctx, msg)
                && (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
            ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION);
            return 0;
#endif
        }
    } else {
        /* detect explicitly permitted exceptions for missing protection */
        if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
            ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PROTECTION);
            return 0;
#endif
        }
    }

    /* check CMP version number in header */
    if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PVNO);
        return 0;
#endif
    }

    if (ossl_cmp_msg_get_bodytype(msg) < 0) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        ERR_raise(ERR_LIB_CMP, CMP_R_PKIBODY_ERROR);
        return 0;
#endif
    }

    /* compare received transactionID with the expected one in previous msg */
    if (ctx->transactionID != NULL
            && (hdr->transactionID == NULL
                || ASN1_OCTET_STRING_cmp(ctx->transactionID,
                                         hdr->transactionID) != 0)) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        ERR_raise(ERR_LIB_CMP, CMP_R_TRANSACTIONID_UNMATCHED);
        return 0;
#endif
    }

    /* compare received nonce with the one we sent */
    if (ctx->senderNonce != NULL
            && (msg->header->recipNonce == NULL
                || ASN1_OCTET_STRING_cmp(ctx->senderNonce,
                                         hdr->recipNonce) != 0)) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        ERR_raise(ERR_LIB_CMP, CMP_R_RECIPNONCE_UNMATCHED);
        return 0;
#endif
    }

    /*
     * RFC 4210 section 5.1.1 states: the recipNonce is copied from
     * the senderNonce of the previous message in the transaction.
     * --> Store for setting in next message
     */
    if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
        return 0;

    /* if not yet present, learn transactionID */
    if (ctx->transactionID == NULL
        && !OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID))
        return -1;

    /*
     * Store any provided extraCerts in ctx for future use,
     * such that they are available to ctx->certConf_cb and
     * the peer does not need to send them again in the same transaction.
     * For efficiency, the extraCerts are prepended so they get used first.
     */
    if (!X509_add_certs(ctx->untrusted, msg->extraCerts,
                        /* this allows self-signed certs */
                        X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
                        | X509_ADD_FLAG_PREPEND))
        return -1;

    if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) {
        /*
         * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
         * "shared secret information", then any certificate transported in
         * the caPubs field may be directly trusted as a root CA
         * certificate by the initiator.'
         */
        switch (ossl_cmp_msg_get_bodytype(msg)) {
        case OSSL_CMP_PKIBODY_IP:
        case OSSL_CMP_PKIBODY_CP:
        case OSSL_CMP_PKIBODY_KUP:
        case OSSL_CMP_PKIBODY_CCP:
            if (ctx->trusted != NULL) {
                STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
                /* value.ip is same for cp, kup, and ccp */

                if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
                    /* adds both self-issued and not self-issued certs */
                    return 0;
            }
            break;
        default:
            break;
        }
    }
    return 1;
}

int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx,
                         const OSSL_CMP_MSG *msg, int acceptRAVerified)
{
    if (!ossl_assert(msg != NULL && msg->body != NULL))
        return 0;
    switch (msg->body->type) {
    case OSSL_CMP_PKIBODY_P10CR:
        {
            X509_REQ *req = msg->body->value.p10cr;

            if (X509_REQ_verify_ex(req, X509_REQ_get0_pubkey(req), ctx->libctx,
                                   ctx->propq) <= 0) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
                ERR_raise(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED);
                return 0;
#endif
            }
        }
        break;
    case OSSL_CMP_PKIBODY_IR:
    case OSSL_CMP_PKIBODY_CR:
    case OSSL_CMP_PKIBODY_KUR:
        if (!OSSL_CRMF_MSGS_verify_popo(msg->body->value.ir, OSSL_CMP_CERTREQID,
                                        acceptRAVerified,
                                        ctx->libctx, ctx->propq)) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
            return 0;
#endif
        }
        break;
    default:
        ERR_raise(ERR_LIB_CMP, CMP_R_PKIBODY_ERROR);
        return 0;
    }
    return 1;
}
