/*
 * Copyright 2007-2020 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>
#include "crypto/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 = 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 (!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;
}
