xref: /freebsd/crypto/openssl/apps/lib/cmp_mock_srv.c (revision b077aed3)
1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery  * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery  * Copyright Siemens AG 2018-2020
4*b077aed3SPierre Pronchery  *
5*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
6*b077aed3SPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
7*b077aed3SPierre Pronchery  * in the file LICENSE in the source distribution or atf
8*b077aed3SPierre Pronchery  * https://www.openssl.org/source/license.html
9*b077aed3SPierre Pronchery  */
10*b077aed3SPierre Pronchery 
11*b077aed3SPierre Pronchery #include "apps.h"
12*b077aed3SPierre Pronchery #include "cmp_mock_srv.h"
13*b077aed3SPierre Pronchery 
14*b077aed3SPierre Pronchery #include <openssl/cmp.h>
15*b077aed3SPierre Pronchery #include <openssl/err.h>
16*b077aed3SPierre Pronchery #include <openssl/cmperr.h>
17*b077aed3SPierre Pronchery 
18*b077aed3SPierre Pronchery /* the context for the CMP mock server */
19*b077aed3SPierre Pronchery typedef struct
20*b077aed3SPierre Pronchery {
21*b077aed3SPierre Pronchery     X509 *certOut;             /* certificate to be returned in cp/ip/kup msg */
22*b077aed3SPierre Pronchery     STACK_OF(X509) *chainOut;  /* chain of certOut to add to extraCerts field */
23*b077aed3SPierre Pronchery     STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */
24*b077aed3SPierre Pronchery     OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
25*b077aed3SPierre Pronchery     int sendError;             /* send error response on given request type */
26*b077aed3SPierre Pronchery     OSSL_CMP_MSG *certReq;     /* ir/cr/p10cr/kur remembered while polling */
27*b077aed3SPierre Pronchery     int pollCount;             /* number of polls before actual cert response */
28*b077aed3SPierre Pronchery     int curr_pollCount;        /* number of polls so far for current request */
29*b077aed3SPierre Pronchery     int checkAfterTime;        /* time the client should wait between polling */
30*b077aed3SPierre Pronchery } mock_srv_ctx;
31*b077aed3SPierre Pronchery 
32*b077aed3SPierre Pronchery 
mock_srv_ctx_free(mock_srv_ctx * ctx)33*b077aed3SPierre Pronchery static void mock_srv_ctx_free(mock_srv_ctx *ctx)
34*b077aed3SPierre Pronchery {
35*b077aed3SPierre Pronchery     if (ctx == NULL)
36*b077aed3SPierre Pronchery         return;
37*b077aed3SPierre Pronchery 
38*b077aed3SPierre Pronchery     OSSL_CMP_PKISI_free(ctx->statusOut);
39*b077aed3SPierre Pronchery     X509_free(ctx->certOut);
40*b077aed3SPierre Pronchery     sk_X509_pop_free(ctx->chainOut, X509_free);
41*b077aed3SPierre Pronchery     sk_X509_pop_free(ctx->caPubsOut, X509_free);
42*b077aed3SPierre Pronchery     OSSL_CMP_MSG_free(ctx->certReq);
43*b077aed3SPierre Pronchery     OPENSSL_free(ctx);
44*b077aed3SPierre Pronchery }
45*b077aed3SPierre Pronchery 
mock_srv_ctx_new(void)46*b077aed3SPierre Pronchery static mock_srv_ctx *mock_srv_ctx_new(void)
47*b077aed3SPierre Pronchery {
48*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OPENSSL_zalloc(sizeof(mock_srv_ctx));
49*b077aed3SPierre Pronchery 
50*b077aed3SPierre Pronchery     if (ctx == NULL)
51*b077aed3SPierre Pronchery         goto err;
52*b077aed3SPierre Pronchery 
53*b077aed3SPierre Pronchery     if ((ctx->statusOut = OSSL_CMP_PKISI_new()) == NULL)
54*b077aed3SPierre Pronchery         goto err;
55*b077aed3SPierre Pronchery 
56*b077aed3SPierre Pronchery     ctx->sendError = -1;
57*b077aed3SPierre Pronchery 
58*b077aed3SPierre Pronchery     /* all other elements are initialized to 0 or NULL, respectively */
59*b077aed3SPierre Pronchery     return ctx;
60*b077aed3SPierre Pronchery  err:
61*b077aed3SPierre Pronchery     mock_srv_ctx_free(ctx);
62*b077aed3SPierre Pronchery     return NULL;
63*b077aed3SPierre Pronchery }
64*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX * srv_ctx,X509 * cert)65*b077aed3SPierre Pronchery int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
66*b077aed3SPierre Pronchery {
67*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
68*b077aed3SPierre Pronchery 
69*b077aed3SPierre Pronchery     if (ctx == NULL) {
70*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
71*b077aed3SPierre Pronchery         return 0;
72*b077aed3SPierre Pronchery     }
73*b077aed3SPierre Pronchery     if (cert == NULL || X509_up_ref(cert)) {
74*b077aed3SPierre Pronchery         X509_free(ctx->certOut);
75*b077aed3SPierre Pronchery         ctx->certOut = cert;
76*b077aed3SPierre Pronchery         return 1;
77*b077aed3SPierre Pronchery     }
78*b077aed3SPierre Pronchery     return 0;
79*b077aed3SPierre Pronchery }
80*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX * srv_ctx,STACK_OF (X509)* chain)81*b077aed3SPierre Pronchery int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
82*b077aed3SPierre Pronchery                                     STACK_OF(X509) *chain)
83*b077aed3SPierre Pronchery {
84*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
85*b077aed3SPierre Pronchery     STACK_OF(X509) *chain_copy = NULL;
86*b077aed3SPierre Pronchery 
87*b077aed3SPierre Pronchery     if (ctx == NULL) {
88*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
89*b077aed3SPierre Pronchery         return 0;
90*b077aed3SPierre Pronchery     }
91*b077aed3SPierre Pronchery     if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL)
92*b077aed3SPierre Pronchery         return 0;
93*b077aed3SPierre Pronchery     sk_X509_pop_free(ctx->chainOut, X509_free);
94*b077aed3SPierre Pronchery     ctx->chainOut = chain_copy;
95*b077aed3SPierre Pronchery     return 1;
96*b077aed3SPierre Pronchery }
97*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX * srv_ctx,STACK_OF (X509)* caPubs)98*b077aed3SPierre Pronchery int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
99*b077aed3SPierre Pronchery                                      STACK_OF(X509) *caPubs)
100*b077aed3SPierre Pronchery {
101*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
102*b077aed3SPierre Pronchery     STACK_OF(X509) *caPubs_copy = NULL;
103*b077aed3SPierre Pronchery 
104*b077aed3SPierre Pronchery     if (ctx == NULL) {
105*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
106*b077aed3SPierre Pronchery         return 0;
107*b077aed3SPierre Pronchery     }
108*b077aed3SPierre Pronchery     if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL)
109*b077aed3SPierre Pronchery         return 0;
110*b077aed3SPierre Pronchery     sk_X509_pop_free(ctx->caPubsOut, X509_free);
111*b077aed3SPierre Pronchery     ctx->caPubsOut = caPubs_copy;
112*b077aed3SPierre Pronchery     return 1;
113*b077aed3SPierre Pronchery }
114*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX * srv_ctx,int status,int fail_info,const char * text)115*b077aed3SPierre Pronchery int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
116*b077aed3SPierre Pronchery                                      int fail_info, const char *text)
117*b077aed3SPierre Pronchery {
118*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
119*b077aed3SPierre Pronchery     OSSL_CMP_PKISI *si;
120*b077aed3SPierre Pronchery 
121*b077aed3SPierre Pronchery     if (ctx == NULL) {
122*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
123*b077aed3SPierre Pronchery         return 0;
124*b077aed3SPierre Pronchery     }
125*b077aed3SPierre Pronchery     if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, text)) == NULL)
126*b077aed3SPierre Pronchery         return 0;
127*b077aed3SPierre Pronchery     OSSL_CMP_PKISI_free(ctx->statusOut);
128*b077aed3SPierre Pronchery     ctx->statusOut = si;
129*b077aed3SPierre Pronchery     return 1;
130*b077aed3SPierre Pronchery }
131*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX * srv_ctx,int bodytype)132*b077aed3SPierre Pronchery int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype)
133*b077aed3SPierre Pronchery {
134*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
135*b077aed3SPierre Pronchery 
136*b077aed3SPierre Pronchery     if (ctx == NULL) {
137*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
138*b077aed3SPierre Pronchery         return 0;
139*b077aed3SPierre Pronchery     }
140*b077aed3SPierre Pronchery     /* might check bodytype, but this would require exporting all body types */
141*b077aed3SPierre Pronchery     ctx->sendError = bodytype;
142*b077aed3SPierre Pronchery     return 1;
143*b077aed3SPierre Pronchery }
144*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX * srv_ctx,int count)145*b077aed3SPierre Pronchery int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count)
146*b077aed3SPierre Pronchery {
147*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
148*b077aed3SPierre Pronchery 
149*b077aed3SPierre Pronchery     if (ctx == NULL) {
150*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
151*b077aed3SPierre Pronchery         return 0;
152*b077aed3SPierre Pronchery     }
153*b077aed3SPierre Pronchery     if (count < 0) {
154*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS);
155*b077aed3SPierre Pronchery         return 0;
156*b077aed3SPierre Pronchery     }
157*b077aed3SPierre Pronchery     ctx->pollCount = count;
158*b077aed3SPierre Pronchery     return 1;
159*b077aed3SPierre Pronchery }
160*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX * srv_ctx,int sec)161*b077aed3SPierre Pronchery int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
162*b077aed3SPierre Pronchery {
163*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
164*b077aed3SPierre Pronchery 
165*b077aed3SPierre Pronchery     if (ctx == NULL) {
166*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
167*b077aed3SPierre Pronchery         return 0;
168*b077aed3SPierre Pronchery     }
169*b077aed3SPierre Pronchery     ctx->checkAfterTime = sec;
170*b077aed3SPierre Pronchery     return 1;
171*b077aed3SPierre Pronchery }
172*b077aed3SPierre Pronchery 
process_cert_request(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * cert_req,ossl_unused int certReqId,const OSSL_CRMF_MSG * crm,const X509_REQ * p10cr,X509 ** certOut,STACK_OF (X509)** chainOut,STACK_OF (X509)** caPubs)173*b077aed3SPierre Pronchery static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
174*b077aed3SPierre Pronchery                                             const OSSL_CMP_MSG *cert_req,
175*b077aed3SPierre Pronchery                                             ossl_unused int certReqId,
176*b077aed3SPierre Pronchery                                             const OSSL_CRMF_MSG *crm,
177*b077aed3SPierre Pronchery                                             const X509_REQ *p10cr,
178*b077aed3SPierre Pronchery                                             X509 **certOut,
179*b077aed3SPierre Pronchery                                             STACK_OF(X509) **chainOut,
180*b077aed3SPierre Pronchery                                             STACK_OF(X509) **caPubs)
181*b077aed3SPierre Pronchery {
182*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
183*b077aed3SPierre Pronchery     OSSL_CMP_PKISI *si = NULL;
184*b077aed3SPierre Pronchery 
185*b077aed3SPierre Pronchery     if (ctx == NULL || cert_req == NULL
186*b077aed3SPierre Pronchery             || certOut == NULL || chainOut == NULL || caPubs == NULL) {
187*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
188*b077aed3SPierre Pronchery         return NULL;
189*b077aed3SPierre Pronchery     }
190*b077aed3SPierre Pronchery     if (ctx->sendError == 1
191*b077aed3SPierre Pronchery             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) {
192*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
193*b077aed3SPierre Pronchery         return NULL;
194*b077aed3SPierre Pronchery     }
195*b077aed3SPierre Pronchery 
196*b077aed3SPierre Pronchery     *certOut = NULL;
197*b077aed3SPierre Pronchery     *chainOut = NULL;
198*b077aed3SPierre Pronchery     *caPubs = NULL;
199*b077aed3SPierre Pronchery 
200*b077aed3SPierre Pronchery     if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
201*b077aed3SPierre Pronchery         /* start polling */
202*b077aed3SPierre Pronchery         if (ctx->certReq != NULL) {
203*b077aed3SPierre Pronchery             /* already in polling mode */
204*b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
205*b077aed3SPierre Pronchery             return NULL;
206*b077aed3SPierre Pronchery         }
207*b077aed3SPierre Pronchery         if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL)
208*b077aed3SPierre Pronchery             return NULL;
209*b077aed3SPierre Pronchery         return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
210*b077aed3SPierre Pronchery     }
211*b077aed3SPierre Pronchery     if (ctx->curr_pollCount >= ctx->pollCount)
212*b077aed3SPierre Pronchery         /* give final response after polling */
213*b077aed3SPierre Pronchery         ctx->curr_pollCount = 0;
214*b077aed3SPierre Pronchery 
215*b077aed3SPierre Pronchery     if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR
216*b077aed3SPierre Pronchery             && crm != NULL && ctx->certOut != NULL) {
217*b077aed3SPierre Pronchery         const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm);
218*b077aed3SPierre Pronchery         const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut);
219*b077aed3SPierre Pronchery         const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut);
220*b077aed3SPierre Pronchery 
221*b077aed3SPierre Pronchery         if (cid == NULL) {
222*b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID);
223*b077aed3SPierre Pronchery             return NULL;
224*b077aed3SPierre Pronchery         }
225*b077aed3SPierre Pronchery         if (issuer != NULL
226*b077aed3SPierre Pronchery             && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
227*b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
228*b077aed3SPierre Pronchery             return NULL;
229*b077aed3SPierre Pronchery         }
230*b077aed3SPierre Pronchery         if (serial != NULL
231*b077aed3SPierre Pronchery             && ASN1_INTEGER_cmp(serial,
232*b077aed3SPierre Pronchery                                 OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) {
233*b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
234*b077aed3SPierre Pronchery             return NULL;
235*b077aed3SPierre Pronchery         }
236*b077aed3SPierre Pronchery     }
237*b077aed3SPierre Pronchery 
238*b077aed3SPierre Pronchery     if (ctx->certOut != NULL
239*b077aed3SPierre Pronchery             && (*certOut = X509_dup(ctx->certOut)) == NULL)
240*b077aed3SPierre Pronchery         goto err;
241*b077aed3SPierre Pronchery     if (ctx->chainOut != NULL
242*b077aed3SPierre Pronchery             && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
243*b077aed3SPierre Pronchery         goto err;
244*b077aed3SPierre Pronchery     if (ctx->caPubsOut != NULL
245*b077aed3SPierre Pronchery             && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL)
246*b077aed3SPierre Pronchery         goto err;
247*b077aed3SPierre Pronchery     if (ctx->statusOut != NULL
248*b077aed3SPierre Pronchery             && (si = OSSL_CMP_PKISI_dup(ctx->statusOut)) == NULL)
249*b077aed3SPierre Pronchery         goto err;
250*b077aed3SPierre Pronchery     return si;
251*b077aed3SPierre Pronchery 
252*b077aed3SPierre Pronchery  err:
253*b077aed3SPierre Pronchery     X509_free(*certOut);
254*b077aed3SPierre Pronchery     *certOut = NULL;
255*b077aed3SPierre Pronchery     sk_X509_pop_free(*chainOut, X509_free);
256*b077aed3SPierre Pronchery     *chainOut = NULL;
257*b077aed3SPierre Pronchery     sk_X509_pop_free(*caPubs, X509_free);
258*b077aed3SPierre Pronchery     *caPubs = NULL;
259*b077aed3SPierre Pronchery     return NULL;
260*b077aed3SPierre Pronchery }
261*b077aed3SPierre Pronchery 
process_rr(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * rr,const X509_NAME * issuer,const ASN1_INTEGER * serial)262*b077aed3SPierre Pronchery static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
263*b077aed3SPierre Pronchery                                   const OSSL_CMP_MSG *rr,
264*b077aed3SPierre Pronchery                                   const X509_NAME *issuer,
265*b077aed3SPierre Pronchery                                   const ASN1_INTEGER *serial)
266*b077aed3SPierre Pronchery {
267*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
268*b077aed3SPierre Pronchery 
269*b077aed3SPierre Pronchery     if (ctx == NULL || rr == NULL) {
270*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
271*b077aed3SPierre Pronchery         return NULL;
272*b077aed3SPierre Pronchery     }
273*b077aed3SPierre Pronchery     if (ctx->certOut == NULL || ctx->sendError == 1
274*b077aed3SPierre Pronchery             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) {
275*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
276*b077aed3SPierre Pronchery         return NULL;
277*b077aed3SPierre Pronchery     }
278*b077aed3SPierre Pronchery 
279*b077aed3SPierre Pronchery     /* Allow any RR derived from CSR, which may include subject and serial */
280*b077aed3SPierre Pronchery     if (issuer == NULL || serial == NULL)
281*b077aed3SPierre Pronchery         return OSSL_CMP_PKISI_dup(ctx->statusOut);
282*b077aed3SPierre Pronchery 
283*b077aed3SPierre Pronchery     /* accept revocation only for the certificate we sent in ir/cr/kur */
284*b077aed3SPierre Pronchery     if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0
285*b077aed3SPierre Pronchery             || ASN1_INTEGER_cmp(serial,
286*b077aed3SPierre Pronchery                                 X509_get0_serialNumber(ctx->certOut)) != 0) {
287*b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED,
288*b077aed3SPierre Pronchery                        "wrong certificate to revoke");
289*b077aed3SPierre Pronchery         return NULL;
290*b077aed3SPierre Pronchery     }
291*b077aed3SPierre Pronchery     return OSSL_CMP_PKISI_dup(ctx->statusOut);
292*b077aed3SPierre Pronchery }
293*b077aed3SPierre Pronchery 
process_genm(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * genm,const STACK_OF (OSSL_CMP_ITAV)* in,STACK_OF (OSSL_CMP_ITAV)** out)294*b077aed3SPierre Pronchery static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
295*b077aed3SPierre Pronchery                         const OSSL_CMP_MSG *genm,
296*b077aed3SPierre Pronchery                         const STACK_OF(OSSL_CMP_ITAV) *in,
297*b077aed3SPierre Pronchery                         STACK_OF(OSSL_CMP_ITAV) **out)
298*b077aed3SPierre Pronchery {
299*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
300*b077aed3SPierre Pronchery 
301*b077aed3SPierre Pronchery     if (ctx == NULL || genm == NULL || in == NULL || out == NULL) {
302*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
303*b077aed3SPierre Pronchery         return 0;
304*b077aed3SPierre Pronchery     }
305*b077aed3SPierre Pronchery     if (ctx->sendError == 1
306*b077aed3SPierre Pronchery             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(genm)
307*b077aed3SPierre Pronchery             || sk_OSSL_CMP_ITAV_num(in) > 1) {
308*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
309*b077aed3SPierre Pronchery         return 0;
310*b077aed3SPierre Pronchery     }
311*b077aed3SPierre Pronchery 
312*b077aed3SPierre Pronchery     *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup,
313*b077aed3SPierre Pronchery                                       OSSL_CMP_ITAV_free);
314*b077aed3SPierre Pronchery     return *out != NULL;
315*b077aed3SPierre Pronchery }
316*b077aed3SPierre Pronchery 
process_error(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * error,const OSSL_CMP_PKISI * statusInfo,const ASN1_INTEGER * errorCode,const OSSL_CMP_PKIFREETEXT * errorDetails)317*b077aed3SPierre Pronchery static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error,
318*b077aed3SPierre Pronchery                           const OSSL_CMP_PKISI *statusInfo,
319*b077aed3SPierre Pronchery                           const ASN1_INTEGER *errorCode,
320*b077aed3SPierre Pronchery                           const OSSL_CMP_PKIFREETEXT *errorDetails)
321*b077aed3SPierre Pronchery {
322*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
323*b077aed3SPierre Pronchery     char buf[OSSL_CMP_PKISI_BUFLEN];
324*b077aed3SPierre Pronchery     char *sibuf;
325*b077aed3SPierre Pronchery     int i;
326*b077aed3SPierre Pronchery 
327*b077aed3SPierre Pronchery     if (ctx == NULL || error == NULL) {
328*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
329*b077aed3SPierre Pronchery         return;
330*b077aed3SPierre Pronchery     }
331*b077aed3SPierre Pronchery 
332*b077aed3SPierre Pronchery     BIO_printf(bio_err, "mock server received error:\n");
333*b077aed3SPierre Pronchery 
334*b077aed3SPierre Pronchery     if (statusInfo == NULL) {
335*b077aed3SPierre Pronchery         BIO_printf(bio_err, "pkiStatusInfo absent\n");
336*b077aed3SPierre Pronchery     } else {
337*b077aed3SPierre Pronchery         sibuf = OSSL_CMP_snprint_PKIStatusInfo(statusInfo, buf, sizeof(buf));
338*b077aed3SPierre Pronchery         BIO_printf(bio_err, "pkiStatusInfo: %s\n",
339*b077aed3SPierre Pronchery                    sibuf != NULL ? sibuf: "<invalid>");
340*b077aed3SPierre Pronchery     }
341*b077aed3SPierre Pronchery 
342*b077aed3SPierre Pronchery     if (errorCode == NULL)
343*b077aed3SPierre Pronchery         BIO_printf(bio_err, "errorCode absent\n");
344*b077aed3SPierre Pronchery     else
345*b077aed3SPierre Pronchery         BIO_printf(bio_err, "errorCode: %ld\n", ASN1_INTEGER_get(errorCode));
346*b077aed3SPierre Pronchery 
347*b077aed3SPierre Pronchery     if (sk_ASN1_UTF8STRING_num(errorDetails) <= 0) {
348*b077aed3SPierre Pronchery         BIO_printf(bio_err, "errorDetails absent\n");
349*b077aed3SPierre Pronchery     } else {
350*b077aed3SPierre Pronchery         BIO_printf(bio_err, "errorDetails: ");
351*b077aed3SPierre Pronchery         for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) {
352*b077aed3SPierre Pronchery             if (i > 0)
353*b077aed3SPierre Pronchery                 BIO_printf(bio_err, ", ");
354*b077aed3SPierre Pronchery             BIO_printf(bio_err, "\"");
355*b077aed3SPierre Pronchery             ASN1_STRING_print(bio_err,
356*b077aed3SPierre Pronchery                               sk_ASN1_UTF8STRING_value(errorDetails, i));
357*b077aed3SPierre Pronchery             BIO_printf(bio_err, "\"");
358*b077aed3SPierre Pronchery         }
359*b077aed3SPierre Pronchery         BIO_printf(bio_err, "\n");
360*b077aed3SPierre Pronchery     }
361*b077aed3SPierre Pronchery }
362*b077aed3SPierre Pronchery 
process_certConf(OSSL_CMP_SRV_CTX * srv_ctx,const OSSL_CMP_MSG * certConf,ossl_unused int certReqId,const ASN1_OCTET_STRING * certHash,const OSSL_CMP_PKISI * si)363*b077aed3SPierre Pronchery static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
364*b077aed3SPierre Pronchery                             const OSSL_CMP_MSG *certConf,
365*b077aed3SPierre Pronchery                             ossl_unused int certReqId,
366*b077aed3SPierre Pronchery                             const ASN1_OCTET_STRING *certHash,
367*b077aed3SPierre Pronchery                             const OSSL_CMP_PKISI *si)
368*b077aed3SPierre Pronchery {
369*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
370*b077aed3SPierre Pronchery     ASN1_OCTET_STRING *digest;
371*b077aed3SPierre Pronchery 
372*b077aed3SPierre Pronchery     if (ctx == NULL || certConf == NULL || certHash == NULL) {
373*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
374*b077aed3SPierre Pronchery         return 0;
375*b077aed3SPierre Pronchery     }
376*b077aed3SPierre Pronchery     if (ctx->sendError == 1
377*b077aed3SPierre Pronchery             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(certConf)
378*b077aed3SPierre Pronchery             || ctx->certOut == NULL) {
379*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
380*b077aed3SPierre Pronchery         return 0;
381*b077aed3SPierre Pronchery     }
382*b077aed3SPierre Pronchery 
383*b077aed3SPierre Pronchery     if ((digest = X509_digest_sig(ctx->certOut, NULL, NULL)) == NULL)
384*b077aed3SPierre Pronchery         return 0;
385*b077aed3SPierre Pronchery     if (ASN1_OCTET_STRING_cmp(certHash, digest) != 0) {
386*b077aed3SPierre Pronchery         ASN1_OCTET_STRING_free(digest);
387*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_CERTHASH_UNMATCHED);
388*b077aed3SPierre Pronchery         return 0;
389*b077aed3SPierre Pronchery     }
390*b077aed3SPierre Pronchery     ASN1_OCTET_STRING_free(digest);
391*b077aed3SPierre Pronchery     return 1;
392*b077aed3SPierre Pronchery }
393*b077aed3SPierre Pronchery 
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)394*b077aed3SPierre Pronchery static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
395*b077aed3SPierre Pronchery                            const OSSL_CMP_MSG *pollReq,
396*b077aed3SPierre Pronchery                            ossl_unused int certReqId,
397*b077aed3SPierre Pronchery                            OSSL_CMP_MSG **certReq, int64_t *check_after)
398*b077aed3SPierre Pronchery {
399*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
400*b077aed3SPierre Pronchery 
401*b077aed3SPierre Pronchery     if (ctx == NULL || pollReq == NULL
402*b077aed3SPierre Pronchery             || certReq == NULL || check_after == NULL) {
403*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
404*b077aed3SPierre Pronchery         return 0;
405*b077aed3SPierre Pronchery     }
406*b077aed3SPierre Pronchery     if (ctx->sendError == 1
407*b077aed3SPierre Pronchery             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) {
408*b077aed3SPierre Pronchery         *certReq = NULL;
409*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
410*b077aed3SPierre Pronchery         return 0;
411*b077aed3SPierre Pronchery     }
412*b077aed3SPierre Pronchery     if (ctx->certReq == NULL) {
413*b077aed3SPierre Pronchery         /* not currently in polling mode */
414*b077aed3SPierre Pronchery         *certReq = NULL;
415*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
416*b077aed3SPierre Pronchery         return 0;
417*b077aed3SPierre Pronchery     }
418*b077aed3SPierre Pronchery 
419*b077aed3SPierre Pronchery     if (++ctx->curr_pollCount >= ctx->pollCount) {
420*b077aed3SPierre Pronchery         /* end polling */
421*b077aed3SPierre Pronchery         *certReq = ctx->certReq;
422*b077aed3SPierre Pronchery         ctx->certReq = NULL;
423*b077aed3SPierre Pronchery         *check_after = 0;
424*b077aed3SPierre Pronchery     } else {
425*b077aed3SPierre Pronchery         *certReq = NULL;
426*b077aed3SPierre Pronchery         *check_after = ctx->checkAfterTime;
427*b077aed3SPierre Pronchery     }
428*b077aed3SPierre Pronchery     return 1;
429*b077aed3SPierre Pronchery }
430*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_new(OSSL_LIB_CTX * libctx,const char * propq)431*b077aed3SPierre Pronchery OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq)
432*b077aed3SPierre Pronchery {
433*b077aed3SPierre Pronchery     OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(libctx, propq);
434*b077aed3SPierre Pronchery     mock_srv_ctx *ctx = mock_srv_ctx_new();
435*b077aed3SPierre Pronchery 
436*b077aed3SPierre Pronchery     if (srv_ctx != NULL && ctx != NULL
437*b077aed3SPierre Pronchery             && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request,
438*b077aed3SPierre Pronchery                                      process_rr, process_genm, process_error,
439*b077aed3SPierre Pronchery                                      process_certConf, process_pollReq))
440*b077aed3SPierre Pronchery         return srv_ctx;
441*b077aed3SPierre Pronchery 
442*b077aed3SPierre Pronchery     mock_srv_ctx_free(ctx);
443*b077aed3SPierre Pronchery     OSSL_CMP_SRV_CTX_free(srv_ctx);
444*b077aed3SPierre Pronchery     return NULL;
445*b077aed3SPierre Pronchery }
446*b077aed3SPierre Pronchery 
ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX * srv_ctx)447*b077aed3SPierre Pronchery void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx)
448*b077aed3SPierre Pronchery {
449*b077aed3SPierre Pronchery     if (srv_ctx != NULL)
450*b077aed3SPierre Pronchery         mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx));
451*b077aed3SPierre Pronchery     OSSL_CMP_SRV_CTX_free(srv_ctx);
452*b077aed3SPierre Pronchery }
453