Coverage Report

Created: 2026-09-12 06:55

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