aboutsummaryrefslogtreecommitdiff
path: root/apps/lib/cmp_mock_srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/lib/cmp_mock_srv.c')
-rw-r--r--apps/lib/cmp_mock_srv.c421
1 files changed, 357 insertions, 64 deletions
diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c
index 637bd1d0b7a4..73ab1eb5600e 100644
--- a/apps/lib/cmp_mock_srv.c
+++ b/apps/lib/cmp_mock_srv.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Siemens AG 2018-2020
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -16,30 +16,35 @@
#include <openssl/cmperr.h>
/* the context for the CMP mock server */
-typedef struct
-{
+typedef struct {
+ X509 *refCert; /* cert to expect for oldCertID in kur/rr msg */
X509 *certOut; /* certificate to be returned in cp/ip/kup msg */
+ EVP_PKEY *keyOut; /* Private key to be returned for central keygen */
+ X509_CRL *crlOut; /* CRL to be returned in genp for crls */
STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */
- STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */
+ STACK_OF(X509) *caPubsOut; /* used in caPubs of ip and in caCerts of genp */
+ X509 *newWithNew; /* to return in newWithNew of rootKeyUpdate */
+ X509 *newWithOld; /* to return in newWithOld of rootKeyUpdate */
+ X509 *oldWithNew; /* to return in oldWithNew of rootKeyUpdate */
OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
int sendError; /* send error response on given request type */
- OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */
+ OSSL_CMP_MSG *req; /* original request message during polling */
int pollCount; /* number of polls before actual cert response */
int curr_pollCount; /* number of polls so far for current request */
int checkAfterTime; /* time the client should wait between polling */
} mock_srv_ctx;
-
static void mock_srv_ctx_free(mock_srv_ctx *ctx)
{
if (ctx == NULL)
return;
OSSL_CMP_PKISI_free(ctx->statusOut);
+ X509_free(ctx->refCert);
X509_free(ctx->certOut);
- sk_X509_pop_free(ctx->chainOut, X509_free);
- sk_X509_pop_free(ctx->caPubsOut, X509_free);
- OSSL_CMP_MSG_free(ctx->certReq);
+ OSSL_STACK_OF_X509_free(ctx->chainOut);
+ OSSL_STACK_OF_X509_free(ctx->caPubsOut);
+ OSSL_CMP_MSG_free(ctx->req);
OPENSSL_free(ctx);
}
@@ -62,7 +67,28 @@ static mock_srv_ctx *mock_srv_ctx_new(void)
return NULL;
}
-int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
+#define DEFINE_OSSL_SET1_CERT(FIELD) \
+ int ossl_cmp_mock_srv_set1_##FIELD(OSSL_CMP_SRV_CTX *srv_ctx, \
+ X509 *cert) \
+ { \
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); \
+ \
+ if (ctx == NULL) { \
+ ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
+ return 0; \
+ } \
+ if (cert == NULL || X509_up_ref(cert)) { \
+ X509_free(ctx->FIELD); \
+ ctx->FIELD = cert; \
+ return 1; \
+ } \
+ return 0; \
+ }
+
+DEFINE_OSSL_SET1_CERT(refCert)
+DEFINE_OSSL_SET1_CERT(certOut)
+
+int ossl_cmp_mock_srv_set1_keyOut(OSSL_CMP_SRV_CTX *srv_ctx, EVP_PKEY *pkey)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
@@ -70,12 +96,27 @@ int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
- if (cert == NULL || X509_up_ref(cert)) {
- X509_free(ctx->certOut);
- ctx->certOut = cert;
- return 1;
+ if (pkey != NULL && !EVP_PKEY_up_ref(pkey))
+ return 0;
+ EVP_PKEY_free(ctx->keyOut);
+ ctx->keyOut = pkey;
+ return 1;
+}
+
+int ossl_cmp_mock_srv_set1_crlOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ X509_CRL *crl)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+ return 0;
}
- return 0;
+ if (crl != NULL && !X509_CRL_up_ref(crl))
+ return 0;
+ X509_CRL_free(ctx->crlOut);
+ ctx->crlOut = crl;
+ return 1;
}
int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
@@ -90,7 +131,7 @@ int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
}
if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL)
return 0;
- sk_X509_pop_free(ctx->chainOut, X509_free);
+ OSSL_STACK_OF_X509_free(ctx->chainOut);
ctx->chainOut = chain_copy;
return 1;
}
@@ -107,11 +148,15 @@ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
}
if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL)
return 0;
- sk_X509_pop_free(ctx->caPubsOut, X509_free);
+ OSSL_STACK_OF_X509_free(ctx->caPubsOut);
ctx->caPubsOut = caPubs_copy;
return 1;
}
+DEFINE_OSSL_SET1_CERT(newWithNew)
+DEFINE_OSSL_SET1_CERT(newWithOld)
+DEFINE_OSSL_SET1_CERT(oldWithNew)
+
int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
int fail_info, const char *text)
{
@@ -170,6 +215,70 @@ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
return 1;
}
+/* determine whether to delay response to (non-polling) request */
+static int delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ int req_type = OSSL_CMP_MSG_get_bodytype(req);
+
+ if (ctx == NULL || req == NULL) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+ return -1;
+ }
+
+ /*
+ * For ir/cr/p10cr/kur delayed delivery is handled separately in
+ * process_cert_request
+ */
+ if (req_type == OSSL_CMP_IR
+ || req_type == OSSL_CMP_CR
+ || req_type == OSSL_CMP_P10CR
+ || req_type == OSSL_CMP_KUR
+ /* Client may use error to abort the ongoing polling */
+ || req_type == OSSL_CMP_ERROR)
+ return 0;
+
+ if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
+ /* start polling */
+ if ((ctx->req = OSSL_CMP_MSG_dup(req)) == NULL)
+ return -1;
+ return 1;
+ }
+ return 0;
+}
+
+/* check for matching reference cert components, as far as given */
+static int refcert_cmp(const X509 *refcert,
+ const X509_NAME *issuer, const ASN1_INTEGER *serial)
+{
+ const X509_NAME *ref_issuer;
+ const ASN1_INTEGER *ref_serial;
+
+ if (refcert == NULL)
+ return 1;
+ ref_issuer = X509_get_issuer_name(refcert);
+ ref_serial = X509_get0_serialNumber(refcert);
+ return (ref_issuer == NULL || X509_NAME_cmp(issuer, ref_issuer) == 0)
+ && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0);
+}
+
+/* reset the state that belongs to a transaction */
+static int clean_transaction(OSSL_CMP_SRV_CTX *srv_ctx,
+ ossl_unused const ASN1_OCTET_STRING *id)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+
+ ctx->curr_pollCount = 0;
+ OSSL_CMP_MSG_free(ctx->req);
+ ctx->req = NULL;
+ return 1;
+}
+
static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *cert_req,
ossl_unused int certReqId,
@@ -180,15 +289,17 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
STACK_OF(X509) **caPubs)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ int bodytype, central_keygen;
OSSL_CMP_PKISI *si = NULL;
+ EVP_PKEY *keyOut = NULL;
if (ctx == NULL || cert_req == NULL
|| certOut == NULL || chainOut == NULL || caPubs == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return NULL;
}
- if (ctx->sendError == 1
- || ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) {
+ bodytype = OSSL_CMP_MSG_get_bodytype(cert_req);
+ if (ctx->sendError == 1 || ctx->sendError == bodytype) {
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return NULL;
}
@@ -199,12 +310,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
/* start polling */
- if (ctx->certReq != NULL) {
- /* already in polling mode */
- ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
- return NULL;
- }
- if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL)
+ if ((ctx->req = OSSL_CMP_MSG_dup(cert_req)) == NULL)
return NULL;
return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
}
@@ -212,24 +318,54 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
/* give final response after polling */
ctx->curr_pollCount = 0;
- if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR
- && crm != NULL && ctx->certOut != NULL) {
+ /* accept cert profile for cr messages only with the configured name */
+ if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_CR) {
+ STACK_OF(OSSL_CMP_ITAV) *itavs =
+ OSSL_CMP_HDR_get0_geninfo_ITAVs(OSSL_CMP_MSG_get0_header(cert_req));
+ int i;
+
+ for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
+ OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_value(itavs, i);
+ ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(itav);
+ STACK_OF(ASN1_UTF8STRING) *strs;
+ ASN1_UTF8STRING *str;
+ const char *data;
+
+ if (OBJ_obj2nid(obj) == NID_id_it_certProfile) {
+ if (!OSSL_CMP_ITAV_get0_certProfile(itav, &strs))
+ return NULL;
+ if (sk_ASN1_UTF8STRING_num(strs) < 1) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
+ return NULL;
+ }
+ str = sk_ASN1_UTF8STRING_value(strs, 0);
+ if (str == NULL
+ || (data =
+ (const char *)ASN1_STRING_get0_data(str)) == NULL) {
+ ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
+ return NULL;
+ }
+ if (strcmp(data, "profile1") != 0) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
+ return NULL;
+ }
+ break;
+ }
+ }
+ }
+
+ /* accept cert update request only for the reference cert, if given */
+ if (bodytype == OSSL_CMP_KUR
+ && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) {
const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm);
- const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut);
- const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut);
if (cid == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID);
return NULL;
}
- if (issuer != NULL
- && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
- ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
- return NULL;
- }
- if (serial != NULL
- && ASN1_INTEGER_cmp(serial,
- OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) {
+ if (!refcert_cmp(ctx->refCert,
+ OSSL_CRMF_CERTID_get0_issuer(cid),
+ OSSL_CRMF_CERTID_get0_serialNumber(cid))) {
ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
return NULL;
}
@@ -237,11 +373,29 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
if (ctx->certOut != NULL
&& (*certOut = X509_dup(ctx->certOut)) == NULL)
+ /* Should return a cert produced from request template, see FR #16054 */
+ goto err;
+
+ central_keygen = OSSL_CRMF_MSG_centralkeygen_requested(crm, p10cr);
+ if (central_keygen < 0)
+ goto err;
+ if (central_keygen == 1
+ && (ctx->keyOut == NULL
+ || (keyOut = EVP_PKEY_dup(ctx->keyOut)) == NULL
+ || !OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx),
+ 1 /* priv */, keyOut))) {
+ EVP_PKEY_free(keyOut);
goto err;
+ }
+ /*
+ * Note that this uses newPkey to return the private key
+ * and does not check whether the 'popo' field is absent.
+ */
+
if (ctx->chainOut != NULL
&& (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
goto err;
- if (ctx->caPubsOut != NULL
+ if (ctx->caPubsOut != NULL /* OSSL_CMP_PKIBODY_IP not visible here */
&& (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL)
goto err;
if (ctx->statusOut != NULL
@@ -252,9 +406,9 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
err:
X509_free(*certOut);
*certOut = NULL;
- sk_X509_pop_free(*chainOut, X509_free);
+ OSSL_STACK_OF_X509_free(*chainOut);
*chainOut = NULL;
- sk_X509_pop_free(*caPubs, X509_free);
+ OSSL_STACK_OF_X509_free(*caPubs);
*caPubs = NULL;
return NULL;
}
@@ -270,20 +424,16 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return NULL;
}
- if (ctx->certOut == NULL || ctx->sendError == 1
+ if (ctx->sendError == 1
|| ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) {
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return NULL;
}
- /* Allow any RR derived from CSR, which may include subject and serial */
- if (issuer == NULL || serial == NULL)
- return OSSL_CMP_PKISI_dup(ctx->statusOut);
-
- /* accept revocation only for the certificate we sent in ir/cr/kur */
- if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0
- || ASN1_INTEGER_cmp(serial,
- X509_get0_serialNumber(ctx->certOut)) != 0) {
+ /* allow any RR derived from CSR which does not include issuer and serial */
+ if ((issuer != NULL || serial != NULL)
+ /* accept revocation only for the reference cert, if given */
+ && !refcert_cmp(ctx->refCert, issuer, serial)) {
ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED,
"wrong certificate to revoke");
return NULL;
@@ -291,6 +441,136 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
return OSSL_CMP_PKISI_dup(ctx->statusOut);
}
+/* return -1 for error, 0 for no update available */
+static int check_client_crl(const STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList,
+ const X509_CRL *crl)
+{
+ OSSL_CMP_CRLSTATUS *crlstatus;
+ DIST_POINT_NAME *dpn = NULL;
+ GENERAL_NAMES *issuer = NULL;
+ ASN1_TIME *thisupd = NULL;
+
+ if (sk_OSSL_CMP_CRLSTATUS_num(crlStatusList) != 1) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CRLSTATUSLIST);
+ return -1;
+ }
+ if (crl == NULL)
+ return 0;
+
+ crlstatus = sk_OSSL_CMP_CRLSTATUS_value(crlStatusList, 0);
+ if (!OSSL_CMP_CRLSTATUS_get0(crlstatus, &dpn, &issuer, &thisupd))
+ return -1;
+
+ if (issuer != NULL) {
+ GENERAL_NAME *gn = sk_GENERAL_NAME_value(issuer, 0);
+
+ if (gn != NULL && gn->type == GEN_DIRNAME) {
+ X509_NAME *gen_name = gn->d.dirn;
+
+ if (X509_NAME_cmp(gen_name, X509_CRL_get_issuer(crl)) != 0) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CRL_ISSUER);
+ return -1;
+ }
+ } else {
+ ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
+ return -1; /* error according to RFC 9483 section 4.3.4 */
+ }
+ }
+
+ return thisupd == NULL
+ || ASN1_TIME_compare(thisupd, X509_CRL_get0_lastUpdate(crl)) < 0;
+}
+
+static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
+ const OSSL_CMP_ITAV *req)
+{
+ OSSL_CMP_ITAV *rsp = NULL;
+
+ switch (req_nid) {
+ case NID_id_it_caCerts:
+ rsp = OSSL_CMP_ITAV_new_caCerts(ctx->caPubsOut);
+ break;
+ case NID_id_it_rootCaCert:
+ {
+ X509 *rootcacert = NULL;
+
+ if (!OSSL_CMP_ITAV_get0_rootCaCert(req, &rootcacert))
+ return NULL;
+
+ if (rootcacert != NULL
+ && X509_NAME_cmp(X509_get_subject_name(rootcacert),
+ X509_get_subject_name(ctx->newWithNew)) != 0)
+ /* The subjects do not match */
+ rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(NULL, NULL, NULL);
+ else
+ rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(ctx->newWithNew,
+ ctx->newWithOld,
+ ctx->oldWithNew);
+ }
+ break;
+ case NID_id_it_crlStatusList:
+ {
+ STACK_OF(OSSL_CMP_CRLSTATUS) *crlstatuslist = NULL;
+ int res = 0;
+
+ if (!OSSL_CMP_ITAV_get0_crlStatusList(req, &crlstatuslist))
+ return NULL;
+
+ res = check_client_crl(crlstatuslist, ctx->crlOut);
+ if (res < 0)
+ rsp = NULL;
+ else
+ rsp = OSSL_CMP_ITAV_new_crls(res == 0 ? NULL : ctx->crlOut);
+ }
+ break;
+ case NID_id_it_certReqTemplate:
+ {
+ OSSL_CRMF_CERTTEMPLATE *reqtemp;
+ OSSL_CMP_ATAVS *keyspec = NULL;
+ X509_ALGOR *keyalg = NULL;
+ OSSL_CMP_ATAV *rsakeylen, *eckeyalg;
+ int ok = 0;
+
+ if ((reqtemp = OSSL_CRMF_CERTTEMPLATE_new()) == NULL)
+ return NULL;
+
+ if (!OSSL_CRMF_CERTTEMPLATE_fill(reqtemp, NULL, NULL,
+ X509_get_issuer_name(ctx->refCert),
+ NULL))
+ goto crt_err;
+
+ if ((keyalg = X509_ALGOR_new()) == NULL)
+ goto crt_err;
+
+ (void)X509_ALGOR_set0(keyalg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
+ V_ASN1_UNDEF, NULL); /* cannot fail */
+
+ eckeyalg = OSSL_CMP_ATAV_new_algId(keyalg);
+ rsakeylen = OSSL_CMP_ATAV_new_rsaKeyLen(4096);
+ ok = OSSL_CMP_ATAV_push1(&keyspec, eckeyalg)
+ && OSSL_CMP_ATAV_push1(&keyspec, rsakeylen);
+ OSSL_CMP_ATAV_free(eckeyalg);
+ OSSL_CMP_ATAV_free(rsakeylen);
+ X509_ALGOR_free(keyalg);
+
+ if (!ok)
+ goto crt_err;
+
+ rsp = OSSL_CMP_ITAV_new0_certReqTemplate(reqtemp, keyspec);
+ return rsp;
+
+ crt_err:
+ OSSL_CRMF_CERTTEMPLATE_free(reqtemp);
+ OSSL_CMP_ATAVS_free(keyspec);
+ return NULL;
+ }
+ break;
+ default:
+ rsp = OSSL_CMP_ITAV_dup(req);
+ }
+ return rsp;
+}
+
static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *genm,
const STACK_OF(OSSL_CMP_ITAV) *in,
@@ -308,6 +588,18 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return 0;
}
+ if (sk_OSSL_CMP_ITAV_num(in) == 1) {
+ OSSL_CMP_ITAV *req = sk_OSSL_CMP_ITAV_value(in, 0), *rsp;
+ ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req);
+
+ if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL)
+ return 0;
+ rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req);
+ if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp))
+ return 1;
+ sk_OSSL_CMP_ITAV_free(*out);
+ return 0;
+ }
*out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup,
OSSL_CMP_ITAV_free);
@@ -351,10 +643,9 @@ static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error,
for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) {
if (i > 0)
BIO_printf(bio_err, ", ");
- BIO_printf(bio_err, "\"");
- ASN1_STRING_print(bio_err,
- sk_ASN1_UTF8STRING_value(errorDetails, i));
- BIO_printf(bio_err, "\"");
+ ASN1_STRING_print_ex(bio_err,
+ sk_ASN1_UTF8STRING_value(errorDetails, i),
+ ASN1_STRFLGS_ESC_QUOTE);
}
BIO_printf(bio_err, "\n");
}
@@ -391,38 +682,38 @@ static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
return 1;
}
+/* return 0 on failure, 1 on success, setting *req or otherwise *check_after */
static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *pollReq,
ossl_unused int certReqId,
- OSSL_CMP_MSG **certReq, int64_t *check_after)
+ OSSL_CMP_MSG **req, int64_t *check_after)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ if (req != NULL)
+ *req = NULL;
if (ctx == NULL || pollReq == NULL
- || certReq == NULL || check_after == NULL) {
+ || req == NULL || check_after == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
+
if (ctx->sendError == 1
|| ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) {
- *certReq = NULL;
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return 0;
}
- if (ctx->certReq == NULL) {
- /* not currently in polling mode */
- *certReq = NULL;
- ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+ if (ctx->req == NULL) { /* not currently in polling mode */
+ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_POLLREQ);
return 0;
}
if (++ctx->curr_pollCount >= ctx->pollCount) {
/* end polling */
- *certReq = ctx->certReq;
- ctx->certReq = NULL;
+ *req = ctx->req;
+ ctx->req = NULL;
*check_after = 0;
} else {
- *certReq = NULL;
*check_after = ctx->checkAfterTime;
}
return 1;
@@ -436,7 +727,9 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq)
if (srv_ctx != NULL && ctx != NULL
&& OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request,
process_rr, process_genm, process_error,
- process_certConf, process_pollReq))
+ process_certConf, process_pollReq)
+ && OSSL_CMP_SRV_CTX_init_trans(srv_ctx,
+ delayed_delivery, clean_transaction))
return srv_ctx;
mock_srv_ctx_free(ctx);