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

/* general CMP server functions */

#include <openssl/asn1t.h>

#include "cmp_local.h"

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

DEFINE_STACK_OF(OSSL_CRMF_MSG)
DEFINE_STACK_OF(X509)
DEFINE_STACK_OF(OSSL_CMP_ITAV)
DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS)

/* the context for the generic CMP server */
struct ossl_cmp_srv_ctx_st
{
    OSSL_CMP_CTX *ctx; /* Client CMP context, partly reused for srv */
    void *custom_ctx;  /* pointer to specific server context */

    OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
    OSSL_CMP_SRV_rr_cb_t process_rr;
    OSSL_CMP_SRV_genm_cb_t process_genm;
    OSSL_CMP_SRV_error_cb_t process_error;
    OSSL_CMP_SRV_certConf_cb_t process_certConf;
    OSSL_CMP_SRV_pollReq_cb_t process_pollReq;

    int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
    int acceptUnprotected;     /* Accept requests with no/invalid prot. */
    int acceptRAVerified;      /* Accept ir/cr/kur with POPO RAVerified */
    int grantImplicitConfirm;  /* Grant implicit confirmation if requested */

}; /* OSSL_CMP_SRV_CTX */

void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx)
{
    if (srv_ctx == NULL)
        return;

    OSSL_CMP_CTX_free(srv_ctx->ctx);
    OPENSSL_free(srv_ctx);
}

OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void)
{
    OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));

    if (ctx == NULL)
        goto err;

    if ((ctx->ctx = OSSL_CMP_CTX_new()) == NULL)
        goto err;

    /* all other elements are initialized to 0 or NULL, respectively */
    return ctx;
 err:
    OSSL_CMP_SRV_CTX_free(ctx);
    return NULL;
}

int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
                          OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
                          OSSL_CMP_SRV_rr_cb_t process_rr,
                          OSSL_CMP_SRV_genm_cb_t process_genm,
                          OSSL_CMP_SRV_error_cb_t process_error,
                          OSSL_CMP_SRV_certConf_cb_t process_certConf,
                          OSSL_CMP_SRV_pollReq_cb_t process_pollReq)
{
    if (srv_ctx == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return 0;
    }
    srv_ctx->custom_ctx = custom_ctx;
    srv_ctx->process_cert_request = process_cert_request;
    srv_ctx->process_rr = process_rr;
    srv_ctx->process_genm = process_genm;
    srv_ctx->process_error = process_error;
    srv_ctx->process_certConf = process_certConf;
    srv_ctx->process_pollReq = process_pollReq;
    return 1;
}

OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
{
    if (srv_ctx == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return NULL;
    }
    return srv_ctx->ctx;
}

void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
{
    if (srv_ctx == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return NULL;
    }
    return srv_ctx->custom_ctx;
}

int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
                                                 int val)
{
    if (srv_ctx == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return 0;
    }
    srv_ctx->sendUnprotectedErrors = val != 0;
    return 1;
}

int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val)
{
    if (srv_ctx == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return 0;
    }
    srv_ctx->acceptUnprotected = val != 0;
    return 1;
}

int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val)
{
    if (srv_ctx == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return 0;
    }
    srv_ctx->acceptRAVerified = val != 0;
    return 1;
}

int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
                                                int val)
{
    if (srv_ctx == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return 0;
    }
    srv_ctx->grantImplicitConfirm = val != 0;
    return 1;
}

/*
 * Processes an ir/cr/p10cr/kur and returns a certification response.
 * Only handles the first certification request contained in req
 * returns an ip/cp/kup on success and NULL on error
 */
static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                          const OSSL_CMP_MSG *req)
{
    OSSL_CMP_MSG *msg = NULL;
    OSSL_CMP_PKISI *si = NULL;
    X509 *certOut = NULL;
    STACK_OF(X509) *chainOut = NULL, *caPubs = NULL;
    const OSSL_CRMF_MSG *crm = NULL;
    const X509_REQ *p10cr = NULL;
    int bodytype;
    int certReqId;

    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
        return NULL;

    switch (ossl_cmp_msg_get_bodytype(req)) {
    case OSSL_CMP_PKIBODY_P10CR:
    case OSSL_CMP_PKIBODY_CR:
        bodytype = OSSL_CMP_PKIBODY_CP;
        break;
    case OSSL_CMP_PKIBODY_IR:
        bodytype = OSSL_CMP_PKIBODY_IP;
        break;
    case OSSL_CMP_PKIBODY_KUR:
        bodytype = OSSL_CMP_PKIBODY_KUP;
        break;
    default:
        CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        return NULL;
    }

    if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) {
        certReqId = OSSL_CMP_CERTREQID;
        p10cr = req->body->value.p10cr;
    } else {
        OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */

        if (sk_OSSL_CRMF_MSG_num(reqs) != 1) { /* TODO: handle case > 1 */
            CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
            return NULL;
        }

        if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
            CMPerr(0, CMP_R_CERTREQMSG_NOT_FOUND);
            return NULL;
        }
        certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
    }

    if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) {
        /* Proof of possession could not be verified */
        si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
                                     1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
                                     ERR_reason_error_string(ERR_peek_error()));
        if (si == NULL)
            return NULL;
    } else {
        OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(req);

        si = srv_ctx->process_cert_request(srv_ctx, req, certReqId, crm, p10cr,
                                           &certOut, &chainOut, &caPubs);
        if (si == NULL)
            goto err;
        /* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */
        if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx,
                                     OSSL_CMP_OPT_IMPLICIT_CONFIRM,
                                     ossl_cmp_hdr_has_implicitConfirm(hdr)
                                         && srv_ctx->grantImplicitConfirm
                                         /* do not set if polling starts: */
                                         && certOut != NULL))
            goto err;
    }

    msg = ossl_cmp_certRep_new(srv_ctx->ctx, bodytype, certReqId, si,
                               certOut, chainOut, caPubs, 0 /* encrypted */,
                               srv_ctx->sendUnprotectedErrors);
    /*
     * TODO when implemented in ossl_cmp_certrep_new():
     * in case OSSL_CRMF_POPO_KEYENC, set encrypted
     */
    if (msg == NULL)
        CMPerr(0, CMP_R_ERROR_CREATING_CERTREP);

 err:
    OSSL_CMP_PKISI_free(si);
    X509_free(certOut);
    sk_X509_pop_free(chainOut, X509_free);
    sk_X509_pop_free(caPubs, X509_free);
    return msg;
}

static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
                                const OSSL_CMP_MSG *req)
{
    OSSL_CMP_MSG *msg = NULL;
    OSSL_CMP_REVDETAILS *details;
    OSSL_CRMF_CERTID *certId;
    OSSL_CRMF_CERTTEMPLATE *tmpl;
    const X509_NAME *issuer;
    ASN1_INTEGER *serial;
    OSSL_CMP_PKISI *si;

    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
        return NULL;

    if (sk_OSSL_CMP_REVDETAILS_num(req->body->value.rr) != 1) {
        /* TODO: handle multiple elements if multiple requests have been sent */
        CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
        return NULL;
    }

    if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr,
                                                OSSL_CMP_REVREQSID)) == NULL) {
        CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
        return NULL;
    }

    tmpl = details->certDetails;
    issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
    serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
    /* here issuer and serial may safely be NULL */
    if ((certId = OSSL_CRMF_CERTID_gen(issuer, serial)) == NULL)
        return NULL;
    if ((si = srv_ctx->process_rr(srv_ctx, req, issuer, serial)) == NULL)
        goto err;

    if ((msg = ossl_cmp_rp_new(srv_ctx->ctx, si, certId,
                               srv_ctx->sendUnprotectedErrors)) == NULL)
        CMPerr(0, CMP_R_ERROR_CREATING_RR);

 err:
    OSSL_CRMF_CERTID_free(certId);
    OSSL_CMP_PKISI_free(si);
    return msg;
}

/*
 * Processes genm and creates a genp message mirroring the contents of the
 * incoming message
 */
static OSSL_CMP_MSG *process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
                                  const OSSL_CMP_MSG *req)
{
    OSSL_CMP_GENMSGCONTENT *itavs;
    OSSL_CMP_MSG *msg;

    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
        return NULL;

    if (!srv_ctx->process_genm(srv_ctx, req, req->body->value.genm, &itavs))
        return NULL;

    msg = ossl_cmp_genp_new(srv_ctx->ctx, itavs);
    sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
    return msg;
}

static OSSL_CMP_MSG *process_error(OSSL_CMP_SRV_CTX *srv_ctx,
                                   const OSSL_CMP_MSG *req)
{
    OSSL_CMP_ERRORMSGCONTENT *errorContent;
    OSSL_CMP_MSG *msg;

    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
        return NULL;
    errorContent = req->body->value.error;
    srv_ctx->process_error(srv_ctx, req, errorContent->pKIStatusInfo,
                           errorContent->errorCode, errorContent->errorDetails);

    if ((msg = ossl_cmp_pkiconf_new(srv_ctx->ctx)) == NULL)
        CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
    return msg;
}

static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
                                      const OSSL_CMP_MSG *req)
{
    OSSL_CMP_CTX *ctx;
    OSSL_CMP_CERTCONFIRMCONTENT *ccc;
    int num;
    OSSL_CMP_MSG *msg = NULL;
    OSSL_CMP_CERTSTATUS *status = NULL;

    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
        return NULL;

    ctx = srv_ctx->ctx;
    ccc = req->body->value.certConf;
    num = sk_OSSL_CMP_CERTSTATUS_num(ccc);

    if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 1) {
        CMPerr(0, CMP_R_ERROR_UNEXPECTED_CERTCONF);
        return NULL;
    }

    if (num == 0) {
        ossl_cmp_err(ctx, "certificate rejected by client");
    } else {
        if (num > 1)
            ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
        status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID);
    }

    if (status != NULL) {
        int certReqId = ossl_cmp_asn1_get_int(status->certReqId);
        ASN1_OCTET_STRING *certHash = status->certHash;
        OSSL_CMP_PKISI *si = status->statusInfo;

        if (!srv_ctx->process_certConf(srv_ctx, req, certReqId, certHash, si))
            return NULL; /* reason code may be: CMP_R_CERTHASH_UNMATCHED */

        if (si != NULL && ossl_cmp_pkisi_get_status(si)
            != OSSL_CMP_PKISTATUS_accepted) {
            int pki_status = ossl_cmp_pkisi_get_status(si);
            const char *str = ossl_cmp_PKIStatus_to_string(pki_status);

            ossl_cmp_log2(INFO, ctx, "certificate rejected by client %s %s",
                          str == NULL ? "without" : "with",
                          str == NULL ? "PKIStatus" : str);
        }
    }

    if ((msg = ossl_cmp_pkiconf_new(ctx)) == NULL)
        CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
    return msg;
}

static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
                                     const OSSL_CMP_MSG *req)
{
    OSSL_CMP_POLLREQCONTENT *prc;
    OSSL_CMP_POLLREQ *pr;
    int certReqId;
    OSSL_CMP_MSG *certReq;
    int64_t check_after = 0;
    OSSL_CMP_MSG *msg = NULL;

    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
        return NULL;

    prc = req->body->value.pollReq;
    if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) { /* TODO: handle case > 1 */
        CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
        return NULL;
    }

    pr = sk_OSSL_CMP_POLLREQ_value(prc, 0);
    certReqId = ossl_cmp_asn1_get_int(pr->certReqId);
    if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
                                  &certReq, &check_after))
        return NULL;

    if (certReq != NULL) {
        msg = process_cert_request(srv_ctx, certReq);
        OSSL_CMP_MSG_free(certReq);
    } else {
        if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId,
                                        check_after)) == NULL)
            CMPerr(0, CMP_R_ERROR_CREATING_POLLREP);
    }
    return msg;
}

/*
 * Determine whether missing/invalid protection of request message is allowed.
 * Return 1 on acceptance, 0 on rejection, or -1 on (internal) error.
 */
static int unprotected_exception(const OSSL_CMP_CTX *ctx,
                                 const OSSL_CMP_MSG *req,
                                 int invalid_protection,
                                 int accept_unprotected_requests)
{
    if (!ossl_assert(ctx != NULL && req != NULL))
        return -1;

    if (accept_unprotected_requests) {
        ossl_cmp_log1(WARN, ctx, "ignoring %s protection of request message",
                      invalid_protection ? "invalid" : "missing");
        return 1;
    }
    if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_ERROR
        && OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS) == 1) {
        ossl_cmp_warn(ctx, "ignoring missing protection of error message");
        return 1;
    }
    return 0;
}

/*
 * returns created message and NULL on internal error
 */
OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                           const OSSL_CMP_MSG *req)
{
    OSSL_CMP_CTX *ctx;
    ASN1_OCTET_STRING *backup_secret;
    OSSL_CMP_PKIHEADER *hdr;
    int req_type, rsp_type;
    int res;
    OSSL_CMP_MSG *rsp = NULL;

    if (srv_ctx == NULL || srv_ctx->ctx == NULL
            || req == NULL || req->body == NULL
            || (hdr = OSSL_CMP_MSG_get0_header(req)) == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return 0;
    }
    ctx = srv_ctx->ctx;
    backup_secret = ctx->secretValue;

    /*
     * Some things need to be done already before validating the message in
     * order to be able to send an error message as far as needed and possible.
     */
    if (hdr->sender->type != GEN_DIRNAME) {
        CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
        goto err;
    }
    if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
        goto err;

    req_type = ossl_cmp_msg_get_bodytype(req);
    switch (req_type) {
    case OSSL_CMP_PKIBODY_IR:
    case OSSL_CMP_PKIBODY_CR:
    case OSSL_CMP_PKIBODY_P10CR:
    case OSSL_CMP_PKIBODY_KUR:
    case OSSL_CMP_PKIBODY_RR:
    case OSSL_CMP_PKIBODY_GENM:
    case OSSL_CMP_PKIBODY_ERROR:
        if (ctx->transactionID != NULL) {
            char *tid;

            tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
                                     ctx->transactionID->length);
            if (tid != NULL)
                ossl_cmp_log1(WARN, ctx,
                              "Assuming that last transaction with ID=%s got aborted",
                              tid);
            OPENSSL_free(tid);
        }
        /* start of a new transaction, reset transactionID and senderNonce */
        if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
                || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL))
            goto err;
        break;
    default:
        /* transactionID should be already initialized */
        if (ctx->transactionID == NULL) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
            CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
            goto err;
#endif
        }
    }

    res = ossl_cmp_msg_check_update(ctx, req, unprotected_exception,
                                    srv_ctx->acceptUnprotected);
    if (ctx->secretValue != NULL && ctx->pkey != NULL
            && ossl_cmp_hdr_get_protection_nid(hdr) != NID_id_PasswordBasedMAC)
        ctx->secretValue = NULL; /* use MSG_SIG_ALG when protecting rsp */
    if (!res)
        goto err;

    switch (req_type) {
    case OSSL_CMP_PKIBODY_IR:
    case OSSL_CMP_PKIBODY_CR:
    case OSSL_CMP_PKIBODY_P10CR:
    case OSSL_CMP_PKIBODY_KUR:
        if (srv_ctx->process_cert_request == NULL)
            CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_cert_request(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_RR:
        if (srv_ctx->process_rr == NULL)
            CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_rr(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_GENM:
        if (srv_ctx->process_genm == NULL)
            CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_genm(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_ERROR:
        if (srv_ctx->process_error == NULL)
            CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_error(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_CERTCONF:
        if (srv_ctx->process_certConf == NULL)
            CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_certConf(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_POLLREQ:
        if (srv_ctx->process_pollReq == NULL)
            CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_pollReq(srv_ctx, req);
        break;
    default:
        /* TODO possibly support further request message types */
        CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
        break;
    }

 err:
    if (rsp == NULL) {
        /* on error, try to respond with CMP error message to client */
        const char *data = NULL;
        int flags = 0;
        unsigned long err = ERR_peek_error_data(&data, &flags);
        int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest;
        /* TODO fail_info could be more specific */
        OSSL_CMP_PKISI *si = NULL;

        if (ctx->transactionID == NULL) {
            /* ignore any (extra) error in next two function calls: */
            (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
            (void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
        }

        if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
                                          fail_info, NULL)) != NULL) {
            if (err != 0 && (flags & ERR_TXT_STRING) != 0)
                data = ERR_reason_error_string(err);
            rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
                                     err != 0 ? ERR_GET_REASON(err) : -1,
                                     data, srv_ctx->sendUnprotectedErrors);
            OSSL_CMP_PKISI_free(si);
        }
    }
    ctx->secretValue = backup_secret;

    /* possibly close the transaction */
    rsp_type =
        rsp != NULL ? ossl_cmp_msg_get_bodytype(rsp) : OSSL_CMP_PKIBODY_ERROR;
    switch (rsp_type) {
    case OSSL_CMP_PKIBODY_IP:
    case OSSL_CMP_PKIBODY_CP:
    case OSSL_CMP_PKIBODY_KUP:
    case OSSL_CMP_PKIBODY_RP:
        if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 0)
            break;
        /* fall through */

    case OSSL_CMP_PKIBODY_PKICONF:
    case OSSL_CMP_PKIBODY_GENP:
    case OSSL_CMP_PKIBODY_ERROR:
        /* TODO possibly support further terminating response message types */
        /* prepare for next transaction, ignoring any errors here: */
        (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL);
        (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL);

    default: /* not closing transaction in other cases */
        break;
    }
    return rsp;
}

/*
 * Server interface that may substitute OSSL_CMP_MSG_http_perform at the client.
 * The OSSL_CMP_SRV_CTX must be set as client_ctx->transfer_cb_arg.
 * returns received message on success, else NULL and pushes an element on the
 * error stack.
 */
OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
                                           const OSSL_CMP_MSG *req)
{
    OSSL_CMP_SRV_CTX *srv_ctx = NULL;

    if (client_ctx == NULL || req == NULL) {
        CMPerr(0, CMP_R_NULL_ARGUMENT);
        return 0;
    }

    if ((srv_ctx = OSSL_CMP_CTX_get_transfer_cb_arg(client_ctx)) == NULL) {
        CMPerr(0, CMP_R_TRANSFER_ERROR);
        return 0;
    }

    return OSSL_CMP_SRV_process_request(srv_ctx, req);
}
