Coverage Report

Created: 2026-09-12 06:55

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