]>
Commit | Line | Data |
---|---|---|
62dcd2aa | 1 | /* |
da1c088f | 2 | * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. |
62dcd2aa DDO |
3 | * Copyright Siemens AG 2018-2020 |
4 | * | |
5 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
6 | * this file except in compliance with the License. You can obtain a copy | |
7 | * in the file LICENSE in the source distribution or atf | |
8 | * https://www.openssl.org/source/license.html | |
9 | */ | |
10 | ||
11 | #include "apps.h" | |
12 | #include "cmp_mock_srv.h" | |
13 | ||
14 | #include <openssl/cmp.h> | |
15 | #include <openssl/err.h> | |
16 | #include <openssl/cmperr.h> | |
1287dabd | 17 | |
62dcd2aa DDO |
18 | /* the context for the CMP mock server */ |
19 | typedef struct | |
20 | { | |
b971d419 | 21 | X509 *refCert; /* cert to expect for oldCertID in kur/rr msg */ |
62dcd2aa DDO |
22 | X509 *certOut; /* certificate to be returned in cp/ip/kup msg */ |
23 | STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */ | |
d477484d | 24 | STACK_OF(X509) *caPubsOut; /* used in caPubs of ip and in caCerts of genp */ |
01b04851 DDO |
25 | X509 *newWithNew; /* to return in newWithNew of rootKeyUpdate */ |
26 | X509 *newWithOld; /* to return in newWithOld of rootKeyUpdate */ | |
27 | X509 *oldWithNew; /* to return in oldWithNew of rootKeyUpdate */ | |
62dcd2aa | 28 | OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */ |
6f88876d | 29 | int sendError; /* send error response on given request type */ |
62dcd2aa | 30 | OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */ |
62dcd2aa | 31 | int pollCount; /* number of polls before actual cert response */ |
dad79ffa | 32 | int curr_pollCount; /* number of polls so far for current request */ |
62dcd2aa DDO |
33 | int checkAfterTime; /* time the client should wait between polling */ |
34 | } mock_srv_ctx; | |
35 | ||
62dcd2aa DDO |
36 | static void mock_srv_ctx_free(mock_srv_ctx *ctx) |
37 | { | |
38 | if (ctx == NULL) | |
39 | return; | |
40 | ||
41 | OSSL_CMP_PKISI_free(ctx->statusOut); | |
b971d419 | 42 | X509_free(ctx->refCert); |
62dcd2aa | 43 | X509_free(ctx->certOut); |
79b2a2f2 DDO |
44 | OSSL_STACK_OF_X509_free(ctx->chainOut); |
45 | OSSL_STACK_OF_X509_free(ctx->caPubsOut); | |
62dcd2aa DDO |
46 | OSSL_CMP_MSG_free(ctx->certReq); |
47 | OPENSSL_free(ctx); | |
48 | } | |
49 | ||
50 | static mock_srv_ctx *mock_srv_ctx_new(void) | |
51 | { | |
52 | mock_srv_ctx *ctx = OPENSSL_zalloc(sizeof(mock_srv_ctx)); | |
53 | ||
54 | if (ctx == NULL) | |
55 | goto err; | |
56 | ||
57 | if ((ctx->statusOut = OSSL_CMP_PKISI_new()) == NULL) | |
58 | goto err; | |
59 | ||
6f88876d | 60 | ctx->sendError = -1; |
62dcd2aa DDO |
61 | |
62 | /* all other elements are initialized to 0 or NULL, respectively */ | |
63 | return ctx; | |
64 | err: | |
65 | mock_srv_ctx_free(ctx); | |
66 | return NULL; | |
67 | } | |
68 | ||
01b04851 DDO |
69 | #define DEFINE_OSSL_SET1_CERT(FIELD) \ |
70 | int ossl_cmp_mock_srv_set1_##FIELD(OSSL_CMP_SRV_CTX *srv_ctx, \ | |
71 | X509 *cert) \ | |
72 | { \ | |
73 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); \ | |
74 | \ | |
75 | if (ctx == NULL) { \ | |
76 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ | |
77 | return 0; \ | |
78 | } \ | |
79 | if (cert == NULL || X509_up_ref(cert)) { \ | |
80 | X509_free(ctx->FIELD); \ | |
81 | ctx->FIELD = cert; \ | |
82 | return 1; \ | |
83 | } \ | |
84 | return 0; \ | |
b971d419 | 85 | } |
b971d419 | 86 | |
01b04851 DDO |
87 | DEFINE_OSSL_SET1_CERT(refCert) |
88 | DEFINE_OSSL_SET1_CERT(certOut) | |
62dcd2aa DDO |
89 | |
90 | int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, | |
91 | STACK_OF(X509) *chain) | |
92 | { | |
93 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
94 | STACK_OF(X509) *chain_copy = NULL; | |
95 | ||
96 | if (ctx == NULL) { | |
9311d0c4 | 97 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
98 | return 0; |
99 | } | |
100 | if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL) | |
101 | return 0; | |
79b2a2f2 | 102 | OSSL_STACK_OF_X509_free(ctx->chainOut); |
62dcd2aa DDO |
103 | ctx->chainOut = chain_copy; |
104 | return 1; | |
105 | } | |
106 | ||
107 | int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, | |
108 | STACK_OF(X509) *caPubs) | |
109 | { | |
110 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
111 | STACK_OF(X509) *caPubs_copy = NULL; | |
112 | ||
113 | if (ctx == NULL) { | |
9311d0c4 | 114 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
115 | return 0; |
116 | } | |
117 | if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL) | |
118 | return 0; | |
79b2a2f2 | 119 | OSSL_STACK_OF_X509_free(ctx->caPubsOut); |
62dcd2aa DDO |
120 | ctx->caPubsOut = caPubs_copy; |
121 | return 1; | |
122 | } | |
123 | ||
01b04851 DDO |
124 | DEFINE_OSSL_SET1_CERT(newWithNew) |
125 | DEFINE_OSSL_SET1_CERT(newWithOld) | |
126 | DEFINE_OSSL_SET1_CERT(oldWithNew) | |
127 | ||
62dcd2aa DDO |
128 | int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, |
129 | int fail_info, const char *text) | |
130 | { | |
131 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
132 | OSSL_CMP_PKISI *si; | |
133 | ||
134 | if (ctx == NULL) { | |
9311d0c4 | 135 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
136 | return 0; |
137 | } | |
138 | if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, text)) == NULL) | |
139 | return 0; | |
140 | OSSL_CMP_PKISI_free(ctx->statusOut); | |
141 | ctx->statusOut = si; | |
142 | return 1; | |
143 | } | |
144 | ||
6f88876d | 145 | int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype) |
62dcd2aa DDO |
146 | { |
147 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
148 | ||
149 | if (ctx == NULL) { | |
9311d0c4 | 150 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
151 | return 0; |
152 | } | |
6f88876d DDO |
153 | /* might check bodytype, but this would require exporting all body types */ |
154 | ctx->sendError = bodytype; | |
62dcd2aa DDO |
155 | return 1; |
156 | } | |
157 | ||
158 | int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count) | |
159 | { | |
160 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
161 | ||
162 | if (ctx == NULL) { | |
9311d0c4 | 163 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
164 | return 0; |
165 | } | |
166 | if (count < 0) { | |
9311d0c4 | 167 | ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); |
62dcd2aa DDO |
168 | return 0; |
169 | } | |
170 | ctx->pollCount = count; | |
171 | return 1; | |
172 | } | |
173 | ||
174 | int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec) | |
175 | { | |
176 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
177 | ||
178 | if (ctx == NULL) { | |
9311d0c4 | 179 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
180 | return 0; |
181 | } | |
182 | ctx->checkAfterTime = sec; | |
183 | return 1; | |
184 | } | |
185 | ||
b971d419 DDO |
186 | /* check for matching reference cert components, as far as given */ |
187 | static int refcert_cmp(const X509 *refcert, | |
188 | const X509_NAME *issuer, const ASN1_INTEGER *serial) | |
189 | { | |
190 | const X509_NAME *ref_issuer; | |
191 | const ASN1_INTEGER *ref_serial; | |
192 | ||
193 | if (refcert == NULL) | |
194 | return 1; | |
195 | ref_issuer = X509_get_issuer_name(refcert); | |
196 | ref_serial = X509_get0_serialNumber(refcert); | |
197 | return (ref_issuer == NULL || X509_NAME_cmp(issuer, ref_issuer) == 0) | |
198 | && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0); | |
199 | } | |
200 | ||
62dcd2aa DDO |
201 | static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, |
202 | const OSSL_CMP_MSG *cert_req, | |
25b18e62 | 203 | ossl_unused int certReqId, |
62dcd2aa DDO |
204 | const OSSL_CRMF_MSG *crm, |
205 | const X509_REQ *p10cr, | |
206 | X509 **certOut, | |
207 | STACK_OF(X509) **chainOut, | |
208 | STACK_OF(X509) **caPubs) | |
209 | { | |
210 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
01b04851 | 211 | int bodytype; |
62dcd2aa DDO |
212 | OSSL_CMP_PKISI *si = NULL; |
213 | ||
214 | if (ctx == NULL || cert_req == NULL | |
215 | || certOut == NULL || chainOut == NULL || caPubs == NULL) { | |
9311d0c4 | 216 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
217 | return NULL; |
218 | } | |
01b04851 DDO |
219 | bodytype = OSSL_CMP_MSG_get_bodytype(cert_req); |
220 | if (ctx->sendError == 1 || ctx->sendError == bodytype) { | |
9311d0c4 | 221 | ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); |
62dcd2aa DDO |
222 | return NULL; |
223 | } | |
224 | ||
225 | *certOut = NULL; | |
226 | *chainOut = NULL; | |
227 | *caPubs = NULL; | |
dad79ffa DDO |
228 | |
229 | if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) { | |
230 | /* start polling */ | |
231 | if (ctx->certReq != NULL) { | |
232 | /* already in polling mode */ | |
233 | ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); | |
234 | return NULL; | |
235 | } | |
62dcd2aa DDO |
236 | if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL) |
237 | return NULL; | |
238 | return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL); | |
239 | } | |
dad79ffa DDO |
240 | if (ctx->curr_pollCount >= ctx->pollCount) |
241 | /* give final response after polling */ | |
242 | ctx->curr_pollCount = 0; | |
243 | ||
7c6577ba DDO |
244 | /* accept cert profile for cr messages only with the configured name */ |
245 | if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_CR) { | |
246 | STACK_OF(OSSL_CMP_ITAV) *itavs = | |
247 | OSSL_CMP_HDR_get0_geninfo_ITAVs(OSSL_CMP_MSG_get0_header(cert_req)); | |
248 | int i; | |
249 | ||
250 | for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) { | |
251 | OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_value(itavs, i); | |
252 | ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(itav); | |
253 | STACK_OF(ASN1_UTF8STRING) *strs; | |
254 | ASN1_UTF8STRING *str; | |
255 | const char *data; | |
256 | ||
257 | if (OBJ_obj2nid(obj) == NID_id_it_certProfile) { | |
258 | if (!OSSL_CMP_ITAV_get0_certProfile(itav, &strs)) | |
259 | return NULL; | |
260 | if (sk_ASN1_UTF8STRING_num(strs) < 1) { | |
261 | ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE); | |
262 | return NULL; | |
263 | } | |
264 | str = sk_ASN1_UTF8STRING_value(strs, 0); | |
265 | if (str == NULL | |
266 | || (data = | |
267 | (const char *)ASN1_STRING_get0_data(str)) == NULL) { | |
268 | ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); | |
269 | return NULL; | |
270 | } | |
271 | if (strcmp(data, "profile1") != 0) { | |
272 | ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE); | |
273 | return NULL; | |
274 | } | |
275 | break; | |
276 | } | |
277 | } | |
278 | } | |
279 | ||
b971d419 | 280 | /* accept cert update request only for the reference cert, if given */ |
01b04851 | 281 | if (bodytype == OSSL_CMP_KUR |
b971d419 | 282 | && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) { |
66be663b | 283 | const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm); |
66be663b DDO |
284 | |
285 | if (cid == NULL) { | |
286 | ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID); | |
287 | return NULL; | |
288 | } | |
b971d419 DDO |
289 | if (!refcert_cmp(ctx->refCert, |
290 | OSSL_CRMF_CERTID_get0_issuer(cid), | |
291 | OSSL_CRMF_CERTID_get0_serialNumber(cid))) { | |
66be663b DDO |
292 | ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID); |
293 | return NULL; | |
294 | } | |
295 | } | |
296 | ||
62dcd2aa DDO |
297 | if (ctx->certOut != NULL |
298 | && (*certOut = X509_dup(ctx->certOut)) == NULL) | |
5def4bbb | 299 | /* Should return a cert produced from request template, see FR #16054 */ |
62dcd2aa DDO |
300 | goto err; |
301 | if (ctx->chainOut != NULL | |
302 | && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL) | |
303 | goto err; | |
01b04851 | 304 | if (ctx->caPubsOut != NULL /* OSSL_CMP_PKIBODY_IP not visible here */ |
62dcd2aa DDO |
305 | && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL) |
306 | goto err; | |
307 | if (ctx->statusOut != NULL | |
308 | && (si = OSSL_CMP_PKISI_dup(ctx->statusOut)) == NULL) | |
309 | goto err; | |
310 | return si; | |
311 | ||
312 | err: | |
313 | X509_free(*certOut); | |
314 | *certOut = NULL; | |
79b2a2f2 | 315 | OSSL_STACK_OF_X509_free(*chainOut); |
62dcd2aa | 316 | *chainOut = NULL; |
79b2a2f2 | 317 | OSSL_STACK_OF_X509_free(*caPubs); |
62dcd2aa DDO |
318 | *caPubs = NULL; |
319 | return NULL; | |
320 | } | |
321 | ||
322 | static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, | |
323 | const OSSL_CMP_MSG *rr, | |
324 | const X509_NAME *issuer, | |
325 | const ASN1_INTEGER *serial) | |
326 | { | |
327 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
328 | ||
3d46c81a | 329 | if (ctx == NULL || rr == NULL) { |
9311d0c4 | 330 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
331 | return NULL; |
332 | } | |
6f88876d DDO |
333 | if (ctx->sendError == 1 |
334 | || ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) { | |
9311d0c4 | 335 | ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); |
62dcd2aa DDO |
336 | return NULL; |
337 | } | |
338 | ||
b971d419 DDO |
339 | /* allow any RR derived from CSR which does not include issuer and serial */ |
340 | if ((issuer != NULL || serial != NULL) | |
341 | /* accept revocation only for the reference cert, if given */ | |
342 | && !refcert_cmp(ctx->refCert, issuer, serial)) { | |
ca8f823f DDO |
343 | ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED, |
344 | "wrong certificate to revoke"); | |
62dcd2aa DDO |
345 | return NULL; |
346 | } | |
347 | return OSSL_CMP_PKISI_dup(ctx->statusOut); | |
348 | } | |
349 | ||
01b04851 DDO |
350 | static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid, |
351 | const OSSL_CMP_ITAV *req) | |
352 | { | |
353 | OSSL_CMP_ITAV *rsp; | |
354 | ||
355 | switch (req_nid) { | |
356 | case NID_id_it_caCerts: | |
357 | rsp = OSSL_CMP_ITAV_new_caCerts(ctx->caPubsOut); | |
358 | break; | |
359 | case NID_id_it_rootCaCert: | |
360 | rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(ctx->newWithNew, | |
361 | ctx->newWithOld, | |
362 | ctx->oldWithNew); | |
363 | break; | |
364 | default: | |
365 | rsp = OSSL_CMP_ITAV_dup(req); | |
366 | } | |
367 | return rsp; | |
368 | } | |
369 | ||
62dcd2aa DDO |
370 | static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx, |
371 | const OSSL_CMP_MSG *genm, | |
372 | const STACK_OF(OSSL_CMP_ITAV) *in, | |
373 | STACK_OF(OSSL_CMP_ITAV) **out) | |
374 | { | |
375 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
376 | ||
377 | if (ctx == NULL || genm == NULL || in == NULL || out == NULL) { | |
9311d0c4 | 378 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
379 | return 0; |
380 | } | |
6f88876d DDO |
381 | if (ctx->sendError == 1 |
382 | || ctx->sendError == OSSL_CMP_MSG_get_bodytype(genm) | |
383 | || sk_OSSL_CMP_ITAV_num(in) > 1) { | |
9311d0c4 | 384 | ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); |
62dcd2aa DDO |
385 | return 0; |
386 | } | |
d477484d DDO |
387 | if (sk_OSSL_CMP_ITAV_num(in) == 1) { |
388 | OSSL_CMP_ITAV *req = sk_OSSL_CMP_ITAV_value(in, 0), *rsp; | |
389 | ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req); | |
390 | ||
01b04851 DDO |
391 | if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL) |
392 | return 0; | |
393 | rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req); | |
394 | if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp)) | |
d477484d | 395 | return 1; |
01b04851 DDO |
396 | sk_OSSL_CMP_ITAV_free(*out); |
397 | return 0; | |
d477484d | 398 | } |
62dcd2aa DDO |
399 | |
400 | *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup, | |
401 | OSSL_CMP_ITAV_free); | |
402 | return *out != NULL; | |
403 | } | |
404 | ||
405 | static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error, | |
406 | const OSSL_CMP_PKISI *statusInfo, | |
407 | const ASN1_INTEGER *errorCode, | |
408 | const OSSL_CMP_PKIFREETEXT *errorDetails) | |
409 | { | |
410 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
411 | char buf[OSSL_CMP_PKISI_BUFLEN]; | |
412 | char *sibuf; | |
413 | int i; | |
414 | ||
415 | if (ctx == NULL || error == NULL) { | |
9311d0c4 | 416 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
417 | return; |
418 | } | |
419 | ||
420 | BIO_printf(bio_err, "mock server received error:\n"); | |
421 | ||
422 | if (statusInfo == NULL) { | |
423 | BIO_printf(bio_err, "pkiStatusInfo absent\n"); | |
424 | } else { | |
425 | sibuf = OSSL_CMP_snprint_PKIStatusInfo(statusInfo, buf, sizeof(buf)); | |
426 | BIO_printf(bio_err, "pkiStatusInfo: %s\n", | |
427 | sibuf != NULL ? sibuf: "<invalid>"); | |
428 | } | |
429 | ||
430 | if (errorCode == NULL) | |
431 | BIO_printf(bio_err, "errorCode absent\n"); | |
432 | else | |
433 | BIO_printf(bio_err, "errorCode: %ld\n", ASN1_INTEGER_get(errorCode)); | |
434 | ||
435 | if (sk_ASN1_UTF8STRING_num(errorDetails) <= 0) { | |
436 | BIO_printf(bio_err, "errorDetails absent\n"); | |
437 | } else { | |
438 | BIO_printf(bio_err, "errorDetails: "); | |
439 | for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) { | |
440 | if (i > 0) | |
441 | BIO_printf(bio_err, ", "); | |
084d3afd DDO |
442 | ASN1_STRING_print_ex(bio_err, |
443 | sk_ASN1_UTF8STRING_value(errorDetails, i), | |
444 | ASN1_STRFLGS_ESC_QUOTE); | |
62dcd2aa DDO |
445 | } |
446 | BIO_printf(bio_err, "\n"); | |
447 | } | |
448 | } | |
449 | ||
450 | static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx, | |
25b18e62 DDO |
451 | const OSSL_CMP_MSG *certConf, |
452 | ossl_unused int certReqId, | |
62dcd2aa DDO |
453 | const ASN1_OCTET_STRING *certHash, |
454 | const OSSL_CMP_PKISI *si) | |
455 | { | |
456 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
457 | ASN1_OCTET_STRING *digest; | |
458 | ||
459 | if (ctx == NULL || certConf == NULL || certHash == NULL) { | |
9311d0c4 | 460 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
461 | return 0; |
462 | } | |
6f88876d DDO |
463 | if (ctx->sendError == 1 |
464 | || ctx->sendError == OSSL_CMP_MSG_get_bodytype(certConf) | |
465 | || ctx->certOut == NULL) { | |
9311d0c4 | 466 | ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); |
62dcd2aa DDO |
467 | return 0; |
468 | } | |
469 | ||
eefdb8e0 | 470 | if ((digest = X509_digest_sig(ctx->certOut, NULL, NULL)) == NULL) |
62dcd2aa DDO |
471 | return 0; |
472 | if (ASN1_OCTET_STRING_cmp(certHash, digest) != 0) { | |
473 | ASN1_OCTET_STRING_free(digest); | |
9311d0c4 | 474 | ERR_raise(ERR_LIB_CMP, CMP_R_CERTHASH_UNMATCHED); |
62dcd2aa DDO |
475 | return 0; |
476 | } | |
477 | ASN1_OCTET_STRING_free(digest); | |
478 | return 1; | |
479 | } | |
480 | ||
481 | static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, | |
25b18e62 DDO |
482 | const OSSL_CMP_MSG *pollReq, |
483 | ossl_unused int certReqId, | |
62dcd2aa DDO |
484 | OSSL_CMP_MSG **certReq, int64_t *check_after) |
485 | { | |
486 | mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); | |
487 | ||
488 | if (ctx == NULL || pollReq == NULL | |
489 | || certReq == NULL || check_after == NULL) { | |
9311d0c4 | 490 | ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); |
62dcd2aa DDO |
491 | return 0; |
492 | } | |
6f88876d DDO |
493 | if (ctx->sendError == 1 |
494 | || ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) { | |
62dcd2aa | 495 | *certReq = NULL; |
9311d0c4 | 496 | ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); |
62dcd2aa DDO |
497 | return 0; |
498 | } | |
dad79ffa DDO |
499 | if (ctx->certReq == NULL) { |
500 | /* not currently in polling mode */ | |
501 | *certReq = NULL; | |
502 | ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); | |
503 | return 0; | |
504 | } | |
62dcd2aa | 505 | |
dad79ffa DDO |
506 | if (++ctx->curr_pollCount >= ctx->pollCount) { |
507 | /* end polling */ | |
62dcd2aa DDO |
508 | *certReq = ctx->certReq; |
509 | ctx->certReq = NULL; | |
510 | *check_after = 0; | |
511 | } else { | |
62dcd2aa DDO |
512 | *certReq = NULL; |
513 | *check_after = ctx->checkAfterTime; | |
514 | } | |
515 | return 1; | |
516 | } | |
517 | ||
b4250010 | 518 | OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq) |
62dcd2aa | 519 | { |
1a7cd250 | 520 | OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(libctx, propq); |
62dcd2aa DDO |
521 | mock_srv_ctx *ctx = mock_srv_ctx_new(); |
522 | ||
523 | if (srv_ctx != NULL && ctx != NULL | |
524 | && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request, | |
525 | process_rr, process_genm, process_error, | |
526 | process_certConf, process_pollReq)) | |
527 | return srv_ctx; | |
528 | ||
529 | mock_srv_ctx_free(ctx); | |
530 | OSSL_CMP_SRV_CTX_free(srv_ctx); | |
531 | return NULL; | |
532 | } | |
533 | ||
534 | void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx) | |
535 | { | |
536 | if (srv_ctx != NULL) | |
537 | mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx)); | |
538 | OSSL_CMP_SRV_CTX_free(srv_ctx); | |
539 | } |