1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery * Copyright Nokia 2007-2019
4*b077aed3SPierre Pronchery * Copyright Siemens AG 2015-2019
5*b077aed3SPierre Pronchery *
6*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
7*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
8*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
9*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
10*b077aed3SPierre Pronchery */
11*b077aed3SPierre Pronchery
12*b077aed3SPierre Pronchery /* general CMP server functions */
13*b077aed3SPierre Pronchery
14*b077aed3SPierre Pronchery #include <openssl/asn1t.h>
15*b077aed3SPierre Pronchery
16*b077aed3SPierre Pronchery #include "cmp_local.h"
17*b077aed3SPierre Pronchery
18*b077aed3SPierre Pronchery /* explicit #includes not strictly needed since implied by the above: */
19*b077aed3SPierre Pronchery #include <openssl/cmp.h>
20*b077aed3SPierre Pronchery #include <openssl/err.h>
21*b077aed3SPierre Pronchery
22*b077aed3SPierre Pronchery /* the context for the generic CMP server */
23*b077aed3SPierre Pronchery struct ossl_cmp_srv_ctx_st
24*b077aed3SPierre Pronchery {
25*b077aed3SPierre Pronchery void *custom_ctx; /* pointer to application-specific server context */
26*b077aed3SPierre Pronchery OSSL_CMP_CTX *ctx; /* Client CMP context, reusing transactionID etc. */
27*b077aed3SPierre Pronchery int certReqId; /* id of last ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */
28*b077aed3SPierre Pronchery
29*b077aed3SPierre Pronchery OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
30*b077aed3SPierre Pronchery OSSL_CMP_SRV_rr_cb_t process_rr;
31*b077aed3SPierre Pronchery OSSL_CMP_SRV_genm_cb_t process_genm;
32*b077aed3SPierre Pronchery OSSL_CMP_SRV_error_cb_t process_error;
33*b077aed3SPierre Pronchery OSSL_CMP_SRV_certConf_cb_t process_certConf;
34*b077aed3SPierre Pronchery OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
35*b077aed3SPierre Pronchery
36*b077aed3SPierre Pronchery int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
37*b077aed3SPierre Pronchery int acceptUnprotected; /* Accept requests with no/invalid prot. */
38*b077aed3SPierre Pronchery int acceptRAVerified; /* Accept ir/cr/kur with POPO RAVerified */
39*b077aed3SPierre Pronchery int grantImplicitConfirm; /* Grant implicit confirmation if requested */
40*b077aed3SPierre Pronchery
41*b077aed3SPierre Pronchery }; /* OSSL_CMP_SRV_CTX */
42*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX * srv_ctx)43*b077aed3SPierre Pronchery void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx)
44*b077aed3SPierre Pronchery {
45*b077aed3SPierre Pronchery if (srv_ctx == NULL)
46*b077aed3SPierre Pronchery return;
47*b077aed3SPierre Pronchery
48*b077aed3SPierre Pronchery OSSL_CMP_CTX_free(srv_ctx->ctx);
49*b077aed3SPierre Pronchery OPENSSL_free(srv_ctx);
50*b077aed3SPierre Pronchery }
51*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX * libctx,const char * propq)52*b077aed3SPierre Pronchery OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq)
53*b077aed3SPierre Pronchery {
54*b077aed3SPierre Pronchery OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));
55*b077aed3SPierre Pronchery
56*b077aed3SPierre Pronchery if (ctx == NULL)
57*b077aed3SPierre Pronchery goto err;
58*b077aed3SPierre Pronchery
59*b077aed3SPierre Pronchery if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL)
60*b077aed3SPierre Pronchery goto err;
61*b077aed3SPierre Pronchery ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
62*b077aed3SPierre Pronchery
63*b077aed3SPierre Pronchery /* all other elements are initialized to 0 or NULL, respectively */
64*b077aed3SPierre Pronchery return ctx;
65*b077aed3SPierre Pronchery err:
66*b077aed3SPierre Pronchery OSSL_CMP_SRV_CTX_free(ctx);
67*b077aed3SPierre Pronchery return NULL;
68*b077aed3SPierre Pronchery }
69*b077aed3SPierre Pronchery
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)70*b077aed3SPierre Pronchery int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
71*b077aed3SPierre Pronchery OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
72*b077aed3SPierre Pronchery OSSL_CMP_SRV_rr_cb_t process_rr,
73*b077aed3SPierre Pronchery OSSL_CMP_SRV_genm_cb_t process_genm,
74*b077aed3SPierre Pronchery OSSL_CMP_SRV_error_cb_t process_error,
75*b077aed3SPierre Pronchery OSSL_CMP_SRV_certConf_cb_t process_certConf,
76*b077aed3SPierre Pronchery OSSL_CMP_SRV_pollReq_cb_t process_pollReq)
77*b077aed3SPierre Pronchery {
78*b077aed3SPierre Pronchery if (srv_ctx == NULL) {
79*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
80*b077aed3SPierre Pronchery return 0;
81*b077aed3SPierre Pronchery }
82*b077aed3SPierre Pronchery srv_ctx->custom_ctx = custom_ctx;
83*b077aed3SPierre Pronchery srv_ctx->process_cert_request = process_cert_request;
84*b077aed3SPierre Pronchery srv_ctx->process_rr = process_rr;
85*b077aed3SPierre Pronchery srv_ctx->process_genm = process_genm;
86*b077aed3SPierre Pronchery srv_ctx->process_error = process_error;
87*b077aed3SPierre Pronchery srv_ctx->process_certConf = process_certConf;
88*b077aed3SPierre Pronchery srv_ctx->process_pollReq = process_pollReq;
89*b077aed3SPierre Pronchery return 1;
90*b077aed3SPierre Pronchery }
91*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX * srv_ctx)92*b077aed3SPierre Pronchery OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
93*b077aed3SPierre Pronchery {
94*b077aed3SPierre Pronchery if (srv_ctx == NULL) {
95*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
96*b077aed3SPierre Pronchery return NULL;
97*b077aed3SPierre Pronchery }
98*b077aed3SPierre Pronchery return srv_ctx->ctx;
99*b077aed3SPierre Pronchery }
100*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX * srv_ctx)101*b077aed3SPierre Pronchery void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
102*b077aed3SPierre Pronchery {
103*b077aed3SPierre Pronchery if (srv_ctx == NULL) {
104*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
105*b077aed3SPierre Pronchery return NULL;
106*b077aed3SPierre Pronchery }
107*b077aed3SPierre Pronchery return srv_ctx->custom_ctx;
108*b077aed3SPierre Pronchery }
109*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX * srv_ctx,int val)110*b077aed3SPierre Pronchery int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
111*b077aed3SPierre Pronchery int val)
112*b077aed3SPierre Pronchery {
113*b077aed3SPierre Pronchery if (srv_ctx == NULL) {
114*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
115*b077aed3SPierre Pronchery return 0;
116*b077aed3SPierre Pronchery }
117*b077aed3SPierre Pronchery srv_ctx->sendUnprotectedErrors = val != 0;
118*b077aed3SPierre Pronchery return 1;
119*b077aed3SPierre Pronchery }
120*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX * srv_ctx,int val)121*b077aed3SPierre Pronchery int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val)
122*b077aed3SPierre Pronchery {
123*b077aed3SPierre Pronchery if (srv_ctx == NULL) {
124*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
125*b077aed3SPierre Pronchery return 0;
126*b077aed3SPierre Pronchery }
127*b077aed3SPierre Pronchery srv_ctx->acceptUnprotected = val != 0;
128*b077aed3SPierre Pronchery return 1;
129*b077aed3SPierre Pronchery }
130*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX * srv_ctx,int val)131*b077aed3SPierre Pronchery int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val)
132*b077aed3SPierre Pronchery {
133*b077aed3SPierre Pronchery if (srv_ctx == NULL) {
134*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
135*b077aed3SPierre Pronchery return 0;
136*b077aed3SPierre Pronchery }
137*b077aed3SPierre Pronchery srv_ctx->acceptRAVerified = val != 0;
138*b077aed3SPierre Pronchery return 1;
139*b077aed3SPierre Pronchery }
140*b077aed3SPierre Pronchery
OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX * srv_ctx,int val)141*b077aed3SPierre Pronchery int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
142*b077aed3SPierre Pronchery int val)
143*b077aed3SPierre Pronchery {
144*b077aed3SPierre Pronchery if (srv_ctx == NULL) {
145*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
146*b077aed3SPierre Pronchery return 0;
147*b077aed3SPierre Pronchery }
148*b077aed3SPierre Pronchery srv_ctx->grantImplicitConfirm = val != 0;
149*b077aed3SPierre Pronchery return 1;
150*b077aed3SPierre Pronchery }
151*b077aed3SPierre Pronchery
152*b077aed3SPierre Pronchery /*
153*b077aed3SPierre Pronchery * Processes an ir/cr/p10cr/kur and returns a certification response.
154*b077aed3SPierre Pronchery * Only handles the first certification request contained in req
155*b077aed3SPierre Pronchery * returns an ip/cp/kup on success and NULL on error
156*b077aed3SPierre Pronchery */
process_cert_request(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * req)157*b077aed3SPierre Pronchery static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
158*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
159*b077aed3SPierre Pronchery {
160*b077aed3SPierre Pronchery OSSL_CMP_MSG *msg = NULL;
161*b077aed3SPierre Pronchery OSSL_CMP_PKISI *si = NULL;
162*b077aed3SPierre Pronchery X509 *certOut = NULL;
163*b077aed3SPierre Pronchery STACK_OF(X509) *chainOut = NULL, *caPubs = NULL;
164*b077aed3SPierre Pronchery const OSSL_CRMF_MSG *crm = NULL;
165*b077aed3SPierre Pronchery const X509_REQ *p10cr = NULL;
166*b077aed3SPierre Pronchery int bodytype;
167*b077aed3SPierre Pronchery int certReqId;
168*b077aed3SPierre Pronchery
169*b077aed3SPierre Pronchery if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
170*b077aed3SPierre Pronchery return NULL;
171*b077aed3SPierre Pronchery
172*b077aed3SPierre Pronchery switch (OSSL_CMP_MSG_get_bodytype(req)) {
173*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_P10CR:
174*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_CR:
175*b077aed3SPierre Pronchery bodytype = OSSL_CMP_PKIBODY_CP;
176*b077aed3SPierre Pronchery break;
177*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_IR:
178*b077aed3SPierre Pronchery bodytype = OSSL_CMP_PKIBODY_IP;
179*b077aed3SPierre Pronchery break;
180*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_KUR:
181*b077aed3SPierre Pronchery bodytype = OSSL_CMP_PKIBODY_KUP;
182*b077aed3SPierre Pronchery break;
183*b077aed3SPierre Pronchery default:
184*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
185*b077aed3SPierre Pronchery return NULL;
186*b077aed3SPierre Pronchery }
187*b077aed3SPierre Pronchery
188*b077aed3SPierre Pronchery if (OSSL_CMP_MSG_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) {
189*b077aed3SPierre Pronchery certReqId = OSSL_CMP_CERTREQID_NONE; /* p10cr does not include an Id */
190*b077aed3SPierre Pronchery p10cr = req->body->value.p10cr;
191*b077aed3SPierre Pronchery } else {
192*b077aed3SPierre Pronchery OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */
193*b077aed3SPierre Pronchery
194*b077aed3SPierre Pronchery if (sk_OSSL_CRMF_MSG_num(reqs) != 1) {
195*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
196*b077aed3SPierre Pronchery return NULL;
197*b077aed3SPierre Pronchery }
198*b077aed3SPierre Pronchery
199*b077aed3SPierre Pronchery if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
200*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND);
201*b077aed3SPierre Pronchery return NULL;
202*b077aed3SPierre Pronchery }
203*b077aed3SPierre Pronchery certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
204*b077aed3SPierre Pronchery if (certReqId != OSSL_CMP_CERTREQID) {
205*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
206*b077aed3SPierre Pronchery return 0;
207*b077aed3SPierre Pronchery }
208*b077aed3SPierre Pronchery }
209*b077aed3SPierre Pronchery srv_ctx->certReqId = certReqId;
210*b077aed3SPierre Pronchery
211*b077aed3SPierre Pronchery if (!ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) {
212*b077aed3SPierre Pronchery /* Proof of possession could not be verified */
213*b077aed3SPierre Pronchery si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
214*b077aed3SPierre Pronchery 1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
215*b077aed3SPierre Pronchery ERR_reason_error_string(ERR_peek_error()));
216*b077aed3SPierre Pronchery if (si == NULL)
217*b077aed3SPierre Pronchery return NULL;
218*b077aed3SPierre Pronchery } else {
219*b077aed3SPierre Pronchery OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(req);
220*b077aed3SPierre Pronchery
221*b077aed3SPierre Pronchery si = srv_ctx->process_cert_request(srv_ctx, req, certReqId, crm, p10cr,
222*b077aed3SPierre Pronchery &certOut, &chainOut, &caPubs);
223*b077aed3SPierre Pronchery if (si == NULL)
224*b077aed3SPierre Pronchery goto err;
225*b077aed3SPierre Pronchery /* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */
226*b077aed3SPierre Pronchery if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx,
227*b077aed3SPierre Pronchery OSSL_CMP_OPT_IMPLICIT_CONFIRM,
228*b077aed3SPierre Pronchery ossl_cmp_hdr_has_implicitConfirm(hdr)
229*b077aed3SPierre Pronchery && srv_ctx->grantImplicitConfirm
230*b077aed3SPierre Pronchery /* do not set if polling starts: */
231*b077aed3SPierre Pronchery && certOut != NULL))
232*b077aed3SPierre Pronchery goto err;
233*b077aed3SPierre Pronchery }
234*b077aed3SPierre Pronchery
235*b077aed3SPierre Pronchery msg = ossl_cmp_certrep_new(srv_ctx->ctx, bodytype, certReqId, si,
236*b077aed3SPierre Pronchery certOut, NULL /* enc */, chainOut, caPubs,
237*b077aed3SPierre Pronchery srv_ctx->sendUnprotectedErrors);
238*b077aed3SPierre Pronchery if (msg == NULL)
239*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP);
240*b077aed3SPierre Pronchery
241*b077aed3SPierre Pronchery err:
242*b077aed3SPierre Pronchery OSSL_CMP_PKISI_free(si);
243*b077aed3SPierre Pronchery X509_free(certOut);
244*b077aed3SPierre Pronchery sk_X509_pop_free(chainOut, X509_free);
245*b077aed3SPierre Pronchery sk_X509_pop_free(caPubs, X509_free);
246*b077aed3SPierre Pronchery return msg;
247*b077aed3SPierre Pronchery }
248*b077aed3SPierre Pronchery
process_rr(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * req)249*b077aed3SPierre Pronchery static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
250*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
251*b077aed3SPierre Pronchery {
252*b077aed3SPierre Pronchery OSSL_CMP_MSG *msg = NULL;
253*b077aed3SPierre Pronchery OSSL_CMP_REVDETAILS *details;
254*b077aed3SPierre Pronchery OSSL_CRMF_CERTID *certId = NULL;
255*b077aed3SPierre Pronchery OSSL_CRMF_CERTTEMPLATE *tmpl;
256*b077aed3SPierre Pronchery const X509_NAME *issuer;
257*b077aed3SPierre Pronchery const ASN1_INTEGER *serial;
258*b077aed3SPierre Pronchery OSSL_CMP_PKISI *si;
259*b077aed3SPierre Pronchery
260*b077aed3SPierre Pronchery if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
261*b077aed3SPierre Pronchery return NULL;
262*b077aed3SPierre Pronchery
263*b077aed3SPierre Pronchery if (sk_OSSL_CMP_REVDETAILS_num(req->body->value.rr) != 1) {
264*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
265*b077aed3SPierre Pronchery return NULL;
266*b077aed3SPierre Pronchery }
267*b077aed3SPierre Pronchery
268*b077aed3SPierre Pronchery if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr,
269*b077aed3SPierre Pronchery OSSL_CMP_REVREQSID)) == NULL) {
270*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
271*b077aed3SPierre Pronchery return NULL;
272*b077aed3SPierre Pronchery }
273*b077aed3SPierre Pronchery
274*b077aed3SPierre Pronchery tmpl = details->certDetails;
275*b077aed3SPierre Pronchery issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
276*b077aed3SPierre Pronchery serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
277*b077aed3SPierre Pronchery if (issuer != NULL && serial != NULL
278*b077aed3SPierre Pronchery && (certId = OSSL_CRMF_CERTID_gen(issuer, serial)) == NULL)
279*b077aed3SPierre Pronchery return NULL;
280*b077aed3SPierre Pronchery if ((si = srv_ctx->process_rr(srv_ctx, req, issuer, serial)) == NULL)
281*b077aed3SPierre Pronchery goto err;
282*b077aed3SPierre Pronchery
283*b077aed3SPierre Pronchery if ((msg = ossl_cmp_rp_new(srv_ctx->ctx, si, certId,
284*b077aed3SPierre Pronchery srv_ctx->sendUnprotectedErrors)) == NULL)
285*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR);
286*b077aed3SPierre Pronchery
287*b077aed3SPierre Pronchery err:
288*b077aed3SPierre Pronchery OSSL_CRMF_CERTID_free(certId);
289*b077aed3SPierre Pronchery OSSL_CMP_PKISI_free(si);
290*b077aed3SPierre Pronchery return msg;
291*b077aed3SPierre Pronchery }
292*b077aed3SPierre Pronchery
293*b077aed3SPierre Pronchery /*
294*b077aed3SPierre Pronchery * Processes genm and creates a genp message mirroring the contents of the
295*b077aed3SPierre Pronchery * incoming message
296*b077aed3SPierre Pronchery */
process_genm(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * req)297*b077aed3SPierre Pronchery static OSSL_CMP_MSG *process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
298*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
299*b077aed3SPierre Pronchery {
300*b077aed3SPierre Pronchery OSSL_CMP_GENMSGCONTENT *itavs;
301*b077aed3SPierre Pronchery OSSL_CMP_MSG *msg;
302*b077aed3SPierre Pronchery
303*b077aed3SPierre Pronchery if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
304*b077aed3SPierre Pronchery return NULL;
305*b077aed3SPierre Pronchery
306*b077aed3SPierre Pronchery if (!srv_ctx->process_genm(srv_ctx, req, req->body->value.genm, &itavs))
307*b077aed3SPierre Pronchery return NULL;
308*b077aed3SPierre Pronchery
309*b077aed3SPierre Pronchery msg = ossl_cmp_genp_new(srv_ctx->ctx, itavs);
310*b077aed3SPierre Pronchery sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
311*b077aed3SPierre Pronchery return msg;
312*b077aed3SPierre Pronchery }
313*b077aed3SPierre Pronchery
process_error(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * req)314*b077aed3SPierre Pronchery static OSSL_CMP_MSG *process_error(OSSL_CMP_SRV_CTX *srv_ctx,
315*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
316*b077aed3SPierre Pronchery {
317*b077aed3SPierre Pronchery OSSL_CMP_ERRORMSGCONTENT *errorContent;
318*b077aed3SPierre Pronchery OSSL_CMP_MSG *msg;
319*b077aed3SPierre Pronchery
320*b077aed3SPierre Pronchery if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
321*b077aed3SPierre Pronchery return NULL;
322*b077aed3SPierre Pronchery errorContent = req->body->value.error;
323*b077aed3SPierre Pronchery srv_ctx->process_error(srv_ctx, req, errorContent->pKIStatusInfo,
324*b077aed3SPierre Pronchery errorContent->errorCode, errorContent->errorDetails);
325*b077aed3SPierre Pronchery
326*b077aed3SPierre Pronchery if ((msg = ossl_cmp_pkiconf_new(srv_ctx->ctx)) == NULL)
327*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF);
328*b077aed3SPierre Pronchery return msg;
329*b077aed3SPierre Pronchery }
330*b077aed3SPierre Pronchery
process_certConf(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * req)331*b077aed3SPierre Pronchery static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
332*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
333*b077aed3SPierre Pronchery {
334*b077aed3SPierre Pronchery OSSL_CMP_CTX *ctx;
335*b077aed3SPierre Pronchery OSSL_CMP_CERTCONFIRMCONTENT *ccc;
336*b077aed3SPierre Pronchery int num;
337*b077aed3SPierre Pronchery OSSL_CMP_MSG *msg = NULL;
338*b077aed3SPierre Pronchery OSSL_CMP_CERTSTATUS *status = NULL;
339*b077aed3SPierre Pronchery
340*b077aed3SPierre Pronchery if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
341*b077aed3SPierre Pronchery return NULL;
342*b077aed3SPierre Pronchery
343*b077aed3SPierre Pronchery ctx = srv_ctx->ctx;
344*b077aed3SPierre Pronchery ccc = req->body->value.certConf;
345*b077aed3SPierre Pronchery num = sk_OSSL_CMP_CERTSTATUS_num(ccc);
346*b077aed3SPierre Pronchery
347*b077aed3SPierre Pronchery if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 1
348*b077aed3SPierre Pronchery || ctx->status != OSSL_CMP_PKISTATUS_trans) {
349*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_UNEXPECTED_CERTCONF);
350*b077aed3SPierre Pronchery return NULL;
351*b077aed3SPierre Pronchery }
352*b077aed3SPierre Pronchery
353*b077aed3SPierre Pronchery if (num == 0) {
354*b077aed3SPierre Pronchery ossl_cmp_err(ctx, "certificate rejected by client");
355*b077aed3SPierre Pronchery } else {
356*b077aed3SPierre Pronchery if (num > 1)
357*b077aed3SPierre Pronchery ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
358*b077aed3SPierre Pronchery status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID);
359*b077aed3SPierre Pronchery }
360*b077aed3SPierre Pronchery
361*b077aed3SPierre Pronchery if (status != NULL) {
362*b077aed3SPierre Pronchery int certReqId = ossl_cmp_asn1_get_int(status->certReqId);
363*b077aed3SPierre Pronchery ASN1_OCTET_STRING *certHash = status->certHash;
364*b077aed3SPierre Pronchery OSSL_CMP_PKISI *si = status->statusInfo;
365*b077aed3SPierre Pronchery
366*b077aed3SPierre Pronchery if (certReqId != srv_ctx->certReqId) {
367*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
368*b077aed3SPierre Pronchery return NULL;
369*b077aed3SPierre Pronchery }
370*b077aed3SPierre Pronchery if (!srv_ctx->process_certConf(srv_ctx, req, certReqId, certHash, si))
371*b077aed3SPierre Pronchery return NULL; /* reason code may be: CMP_R_CERTHASH_UNMATCHED */
372*b077aed3SPierre Pronchery
373*b077aed3SPierre Pronchery if (si != NULL
374*b077aed3SPierre Pronchery && ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_accepted) {
375*b077aed3SPierre Pronchery int pki_status = ossl_cmp_pkisi_get_status(si);
376*b077aed3SPierre Pronchery const char *str = ossl_cmp_PKIStatus_to_string(pki_status);
377*b077aed3SPierre Pronchery
378*b077aed3SPierre Pronchery ossl_cmp_log2(INFO, ctx, "certificate rejected by client %s %s",
379*b077aed3SPierre Pronchery str == NULL ? "without" : "with",
380*b077aed3SPierre Pronchery str == NULL ? "PKIStatus" : str);
381*b077aed3SPierre Pronchery }
382*b077aed3SPierre Pronchery }
383*b077aed3SPierre Pronchery
384*b077aed3SPierre Pronchery if ((msg = ossl_cmp_pkiconf_new(ctx)) == NULL)
385*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF);
386*b077aed3SPierre Pronchery return msg;
387*b077aed3SPierre Pronchery }
388*b077aed3SPierre Pronchery
process_pollReq(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * req)389*b077aed3SPierre Pronchery static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
390*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
391*b077aed3SPierre Pronchery {
392*b077aed3SPierre Pronchery OSSL_CMP_POLLREQCONTENT *prc;
393*b077aed3SPierre Pronchery OSSL_CMP_POLLREQ *pr;
394*b077aed3SPierre Pronchery int certReqId;
395*b077aed3SPierre Pronchery OSSL_CMP_MSG *certReq;
396*b077aed3SPierre Pronchery int64_t check_after = 0;
397*b077aed3SPierre Pronchery OSSL_CMP_MSG *msg = NULL;
398*b077aed3SPierre Pronchery
399*b077aed3SPierre Pronchery if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
400*b077aed3SPierre Pronchery return NULL;
401*b077aed3SPierre Pronchery
402*b077aed3SPierre Pronchery prc = req->body->value.pollReq;
403*b077aed3SPierre Pronchery if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) {
404*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
405*b077aed3SPierre Pronchery return NULL;
406*b077aed3SPierre Pronchery }
407*b077aed3SPierre Pronchery
408*b077aed3SPierre Pronchery pr = sk_OSSL_CMP_POLLREQ_value(prc, OSSL_CMP_CERTREQID);
409*b077aed3SPierre Pronchery certReqId = ossl_cmp_asn1_get_int(pr->certReqId);
410*b077aed3SPierre Pronchery if (certReqId != srv_ctx->certReqId) {
411*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
412*b077aed3SPierre Pronchery return NULL;
413*b077aed3SPierre Pronchery }
414*b077aed3SPierre Pronchery if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
415*b077aed3SPierre Pronchery &certReq, &check_after))
416*b077aed3SPierre Pronchery return NULL;
417*b077aed3SPierre Pronchery
418*b077aed3SPierre Pronchery if (certReq != NULL) {
419*b077aed3SPierre Pronchery msg = process_cert_request(srv_ctx, certReq);
420*b077aed3SPierre Pronchery OSSL_CMP_MSG_free(certReq);
421*b077aed3SPierre Pronchery } else {
422*b077aed3SPierre Pronchery if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId,
423*b077aed3SPierre Pronchery check_after)) == NULL)
424*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP);
425*b077aed3SPierre Pronchery }
426*b077aed3SPierre Pronchery return msg;
427*b077aed3SPierre Pronchery }
428*b077aed3SPierre Pronchery
429*b077aed3SPierre Pronchery /*
430*b077aed3SPierre Pronchery * Determine whether missing/invalid protection of request message is allowed.
431*b077aed3SPierre Pronchery * Return 1 on acceptance, 0 on rejection, or -1 on (internal) error.
432*b077aed3SPierre Pronchery */
unprotected_exception(const OSSL_CMP_CTX * ctx,const OSSL_CMP_MSG * req,int invalid_protection,int accept_unprotected_requests)433*b077aed3SPierre Pronchery static int unprotected_exception(const OSSL_CMP_CTX *ctx,
434*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req,
435*b077aed3SPierre Pronchery int invalid_protection,
436*b077aed3SPierre Pronchery int accept_unprotected_requests)
437*b077aed3SPierre Pronchery {
438*b077aed3SPierre Pronchery if (!ossl_assert(ctx != NULL && req != NULL))
439*b077aed3SPierre Pronchery return -1;
440*b077aed3SPierre Pronchery
441*b077aed3SPierre Pronchery if (accept_unprotected_requests) {
442*b077aed3SPierre Pronchery ossl_cmp_log1(WARN, ctx, "ignoring %s protection of request message",
443*b077aed3SPierre Pronchery invalid_protection ? "invalid" : "missing");
444*b077aed3SPierre Pronchery return 1;
445*b077aed3SPierre Pronchery }
446*b077aed3SPierre Pronchery if (OSSL_CMP_MSG_get_bodytype(req) == OSSL_CMP_PKIBODY_ERROR
447*b077aed3SPierre Pronchery && OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS) == 1) {
448*b077aed3SPierre Pronchery ossl_cmp_warn(ctx, "ignoring missing protection of error message");
449*b077aed3SPierre Pronchery return 1;
450*b077aed3SPierre Pronchery }
451*b077aed3SPierre Pronchery return 0;
452*b077aed3SPierre Pronchery }
453*b077aed3SPierre Pronchery
454*b077aed3SPierre Pronchery /*
455*b077aed3SPierre Pronchery * returns created message and NULL on internal error
456*b077aed3SPierre Pronchery */
OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * req)457*b077aed3SPierre Pronchery OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
458*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
459*b077aed3SPierre Pronchery {
460*b077aed3SPierre Pronchery OSSL_CMP_CTX *ctx;
461*b077aed3SPierre Pronchery ASN1_OCTET_STRING *backup_secret;
462*b077aed3SPierre Pronchery OSSL_CMP_PKIHEADER *hdr;
463*b077aed3SPierre Pronchery int req_type, rsp_type;
464*b077aed3SPierre Pronchery int req_verified = 0;
465*b077aed3SPierre Pronchery OSSL_CMP_MSG *rsp = NULL;
466*b077aed3SPierre Pronchery
467*b077aed3SPierre Pronchery if (srv_ctx == NULL || srv_ctx->ctx == NULL
468*b077aed3SPierre Pronchery || req == NULL || req->body == NULL
469*b077aed3SPierre Pronchery || (hdr = OSSL_CMP_MSG_get0_header(req)) == NULL) {
470*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
471*b077aed3SPierre Pronchery return 0;
472*b077aed3SPierre Pronchery }
473*b077aed3SPierre Pronchery ctx = srv_ctx->ctx;
474*b077aed3SPierre Pronchery backup_secret = ctx->secretValue;
475*b077aed3SPierre Pronchery req_type = OSSL_CMP_MSG_get_bodytype(req);
476*b077aed3SPierre Pronchery ossl_cmp_log1(DEBUG, ctx,
477*b077aed3SPierre Pronchery "received %s", ossl_cmp_bodytype_to_string(req_type));
478*b077aed3SPierre Pronchery
479*b077aed3SPierre Pronchery /*
480*b077aed3SPierre Pronchery * Some things need to be done already before validating the message in
481*b077aed3SPierre Pronchery * order to be able to send an error message as far as needed and possible.
482*b077aed3SPierre Pronchery */
483*b077aed3SPierre Pronchery if (hdr->sender->type != GEN_DIRNAME) {
484*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
485*b077aed3SPierre Pronchery goto err;
486*b077aed3SPierre Pronchery }
487*b077aed3SPierre Pronchery if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
488*b077aed3SPierre Pronchery goto err;
489*b077aed3SPierre Pronchery
490*b077aed3SPierre Pronchery switch (req_type) {
491*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_IR:
492*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_CR:
493*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_P10CR:
494*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_KUR:
495*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_RR:
496*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_GENM:
497*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_ERROR:
498*b077aed3SPierre Pronchery if (ctx->transactionID != NULL) {
499*b077aed3SPierre Pronchery char *tid;
500*b077aed3SPierre Pronchery
501*b077aed3SPierre Pronchery tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
502*b077aed3SPierre Pronchery ctx->transactionID->length);
503*b077aed3SPierre Pronchery if (tid != NULL)
504*b077aed3SPierre Pronchery ossl_cmp_log1(WARN, ctx,
505*b077aed3SPierre Pronchery "Assuming that last transaction with ID=%s got aborted",
506*b077aed3SPierre Pronchery tid);
507*b077aed3SPierre Pronchery OPENSSL_free(tid);
508*b077aed3SPierre Pronchery }
509*b077aed3SPierre Pronchery /* start of a new transaction, reset transactionID and senderNonce */
510*b077aed3SPierre Pronchery if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
511*b077aed3SPierre Pronchery || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL))
512*b077aed3SPierre Pronchery goto err;
513*b077aed3SPierre Pronchery break;
514*b077aed3SPierre Pronchery default:
515*b077aed3SPierre Pronchery /* transactionID should be already initialized */
516*b077aed3SPierre Pronchery if (ctx->transactionID == NULL) {
517*b077aed3SPierre Pronchery #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
518*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
519*b077aed3SPierre Pronchery goto err;
520*b077aed3SPierre Pronchery #endif
521*b077aed3SPierre Pronchery }
522*b077aed3SPierre Pronchery }
523*b077aed3SPierre Pronchery
524*b077aed3SPierre Pronchery req_verified = ossl_cmp_msg_check_update(ctx, req, unprotected_exception,
525*b077aed3SPierre Pronchery srv_ctx->acceptUnprotected);
526*b077aed3SPierre Pronchery if (ctx->secretValue != NULL && ctx->pkey != NULL
527*b077aed3SPierre Pronchery && ossl_cmp_hdr_get_protection_nid(hdr) != NID_id_PasswordBasedMAC)
528*b077aed3SPierre Pronchery ctx->secretValue = NULL; /* use MSG_SIG_ALG when protecting rsp */
529*b077aed3SPierre Pronchery if (!req_verified)
530*b077aed3SPierre Pronchery goto err;
531*b077aed3SPierre Pronchery
532*b077aed3SPierre Pronchery switch (req_type) {
533*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_IR:
534*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_CR:
535*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_P10CR:
536*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_KUR:
537*b077aed3SPierre Pronchery if (srv_ctx->process_cert_request == NULL)
538*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
539*b077aed3SPierre Pronchery else
540*b077aed3SPierre Pronchery rsp = process_cert_request(srv_ctx, req);
541*b077aed3SPierre Pronchery break;
542*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_RR:
543*b077aed3SPierre Pronchery if (srv_ctx->process_rr == NULL)
544*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
545*b077aed3SPierre Pronchery else
546*b077aed3SPierre Pronchery rsp = process_rr(srv_ctx, req);
547*b077aed3SPierre Pronchery break;
548*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_GENM:
549*b077aed3SPierre Pronchery if (srv_ctx->process_genm == NULL)
550*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
551*b077aed3SPierre Pronchery else
552*b077aed3SPierre Pronchery rsp = process_genm(srv_ctx, req);
553*b077aed3SPierre Pronchery break;
554*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_ERROR:
555*b077aed3SPierre Pronchery if (srv_ctx->process_error == NULL)
556*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
557*b077aed3SPierre Pronchery else
558*b077aed3SPierre Pronchery rsp = process_error(srv_ctx, req);
559*b077aed3SPierre Pronchery break;
560*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_CERTCONF:
561*b077aed3SPierre Pronchery if (srv_ctx->process_certConf == NULL)
562*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
563*b077aed3SPierre Pronchery else
564*b077aed3SPierre Pronchery rsp = process_certConf(srv_ctx, req);
565*b077aed3SPierre Pronchery break;
566*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_POLLREQ:
567*b077aed3SPierre Pronchery if (srv_ctx->process_pollReq == NULL)
568*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
569*b077aed3SPierre Pronchery else
570*b077aed3SPierre Pronchery rsp = process_pollReq(srv_ctx, req);
571*b077aed3SPierre Pronchery break;
572*b077aed3SPierre Pronchery default:
573*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
574*b077aed3SPierre Pronchery break;
575*b077aed3SPierre Pronchery }
576*b077aed3SPierre Pronchery
577*b077aed3SPierre Pronchery err:
578*b077aed3SPierre Pronchery if (rsp == NULL) {
579*b077aed3SPierre Pronchery /* on error, try to respond with CMP error message to client */
580*b077aed3SPierre Pronchery const char *data = NULL, *reason = NULL;
581*b077aed3SPierre Pronchery int flags = 0;
582*b077aed3SPierre Pronchery unsigned long err = ERR_peek_error_data(&data, &flags);
583*b077aed3SPierre Pronchery int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest;
584*b077aed3SPierre Pronchery OSSL_CMP_PKISI *si = NULL;
585*b077aed3SPierre Pronchery
586*b077aed3SPierre Pronchery if (!req_verified) {
587*b077aed3SPierre Pronchery /*
588*b077aed3SPierre Pronchery * Above ossl_cmp_msg_check_update() was not successfully executed,
589*b077aed3SPierre Pronchery * which normally would set ctx->transactionID and ctx->recipNonce.
590*b077aed3SPierre Pronchery * So anyway try to provide the right transactionID and recipNonce,
591*b077aed3SPierre Pronchery * while ignoring any (extra) error in next two function calls.
592*b077aed3SPierre Pronchery */
593*b077aed3SPierre Pronchery if (ctx->transactionID == NULL)
594*b077aed3SPierre Pronchery (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
595*b077aed3SPierre Pronchery (void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
596*b077aed3SPierre Pronchery }
597*b077aed3SPierre Pronchery
598*b077aed3SPierre Pronchery if ((flags & ERR_TXT_STRING) == 0 || *data == '\0')
599*b077aed3SPierre Pronchery data = NULL;
600*b077aed3SPierre Pronchery reason = ERR_reason_error_string(err);
601*b077aed3SPierre Pronchery if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
602*b077aed3SPierre Pronchery fail_info, reason)) != NULL) {
603*b077aed3SPierre Pronchery rsp = ossl_cmp_error_new(srv_ctx->ctx, si, err,
604*b077aed3SPierre Pronchery data, srv_ctx->sendUnprotectedErrors);
605*b077aed3SPierre Pronchery OSSL_CMP_PKISI_free(si);
606*b077aed3SPierre Pronchery }
607*b077aed3SPierre Pronchery }
608*b077aed3SPierre Pronchery OSSL_CMP_CTX_print_errors(ctx);
609*b077aed3SPierre Pronchery ctx->secretValue = backup_secret;
610*b077aed3SPierre Pronchery
611*b077aed3SPierre Pronchery rsp_type =
612*b077aed3SPierre Pronchery rsp != NULL ? OSSL_CMP_MSG_get_bodytype(rsp) : OSSL_CMP_PKIBODY_ERROR;
613*b077aed3SPierre Pronchery if (rsp != NULL)
614*b077aed3SPierre Pronchery ossl_cmp_log1(DEBUG, ctx,
615*b077aed3SPierre Pronchery "sending %s", ossl_cmp_bodytype_to_string(rsp_type));
616*b077aed3SPierre Pronchery else
617*b077aed3SPierre Pronchery ossl_cmp_log(ERR, ctx, "cannot send proper CMP response");
618*b077aed3SPierre Pronchery
619*b077aed3SPierre Pronchery /* determine whether to keep the transaction open or not */
620*b077aed3SPierre Pronchery ctx->status = OSSL_CMP_PKISTATUS_trans;
621*b077aed3SPierre Pronchery switch (rsp_type) {
622*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_IP:
623*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_CP:
624*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_KUP:
625*b077aed3SPierre Pronchery if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 0)
626*b077aed3SPierre Pronchery break;
627*b077aed3SPierre Pronchery /* fall through */
628*b077aed3SPierre Pronchery
629*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_RP:
630*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_PKICONF:
631*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_GENP:
632*b077aed3SPierre Pronchery case OSSL_CMP_PKIBODY_ERROR:
633*b077aed3SPierre Pronchery (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL);
634*b077aed3SPierre Pronchery (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL);
635*b077aed3SPierre Pronchery ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */
636*b077aed3SPierre Pronchery
637*b077aed3SPierre Pronchery default: /* not closing transaction in other cases */
638*b077aed3SPierre Pronchery break;
639*b077aed3SPierre Pronchery }
640*b077aed3SPierre Pronchery return rsp;
641*b077aed3SPierre Pronchery }
642*b077aed3SPierre Pronchery
643*b077aed3SPierre Pronchery /*
644*b077aed3SPierre Pronchery * Server interface that may substitute OSSL_CMP_MSG_http_perform at the client.
645*b077aed3SPierre Pronchery * The OSSL_CMP_SRV_CTX must be set as client_ctx->transfer_cb_arg.
646*b077aed3SPierre Pronchery * returns received message on success, else NULL and pushes an element on the
647*b077aed3SPierre Pronchery * error stack.
648*b077aed3SPierre Pronchery */
OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX * client_ctx,const OSSL_CMP_MSG * req)649*b077aed3SPierre Pronchery OSSL_CMP_MSG *OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
650*b077aed3SPierre Pronchery const OSSL_CMP_MSG *req)
651*b077aed3SPierre Pronchery {
652*b077aed3SPierre Pronchery OSSL_CMP_SRV_CTX *srv_ctx = NULL;
653*b077aed3SPierre Pronchery
654*b077aed3SPierre Pronchery if (client_ctx == NULL || req == NULL) {
655*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
656*b077aed3SPierre Pronchery return NULL;
657*b077aed3SPierre Pronchery }
658*b077aed3SPierre Pronchery
659*b077aed3SPierre Pronchery if ((srv_ctx = OSSL_CMP_CTX_get_transfer_cb_arg(client_ctx)) == NULL) {
660*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_CMP, CMP_R_TRANSFER_ERROR);
661*b077aed3SPierre Pronchery return NULL;
662*b077aed3SPierre Pronchery }
663*b077aed3SPierre Pronchery
664*b077aed3SPierre Pronchery return OSSL_CMP_SRV_process_request(srv_ctx, req);
665*b077aed3SPierre Pronchery }
666