/*
 * Copyright 2007-2021 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>

/* 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(OSSL_LIB_CTX *libctx, const char *propq)
{
    OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));

    if (ctx == NULL)
        goto err;

    if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == 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) {
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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:
        ERR_raise(ERR_LIB_CMP, 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 */
            ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
            return NULL;
        }

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

    if (!ossl_cmp_verify_popo(srv_ctx->ctx, 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)
        ERR_raise(ERR_LIB_CMP, 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 = NULL;
    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 */
        ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
        return NULL;
    }

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

    tmpl = details->certDetails;
    issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
    serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
    if (issuer != NULL && serial != NULL
            && (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)
        ERR_raise(ERR_LIB_CMP, 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)
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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)
        ERR_raise(ERR_LIB_CMP, 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 */
        ERR_raise(ERR_LIB_CMP, 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)
            ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, 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
            ERR_raise(ERR_LIB_CMP, 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)
            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_cert_request(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_RR:
        if (srv_ctx->process_rr == NULL)
            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_rr(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_GENM:
        if (srv_ctx->process_genm == NULL)
            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_genm(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_ERROR:
        if (srv_ctx->process_error == NULL)
            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_error(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_CERTCONF:
        if (srv_ctx->process_certConf == NULL)
            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_certConf(srv_ctx, req);
        break;
    case OSSL_CMP_PKIBODY_POLLREQ:
        if (srv_ctx->process_pollReq == NULL)
            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
        else
            rsp = process_pollReq(srv_ctx, req);
        break;
    default:
        /* TODO possibly support further request message types */
        ERR_raise(ERR_LIB_CMP, 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) {
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
        return 0;
    }

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

    return OSSL_CMP_SRV_process_request(srv_ctx, req);
}
