Coverage Report

Created: 2023-09-25 06:41

/src/openssl30/crypto/cmp/cmp_msg.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2007-2023 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
/* CMP functions for PKIMessage construction */
13
14
#include "cmp_local.h"
15
16
/* explicit #includes not strictly needed since implied by the above: */
17
#include <openssl/asn1t.h>
18
#include <openssl/cmp.h>
19
#include <openssl/crmf.h>
20
#include <openssl/err.h>
21
#include <openssl/x509.h>
22
23
OSSL_CMP_MSG *OSSL_CMP_MSG_new(OSSL_LIB_CTX *libctx, const char *propq)
24
5.62k
{
25
5.62k
    OSSL_CMP_MSG *msg = NULL;
26
27
5.62k
    msg = (OSSL_CMP_MSG *)ASN1_item_new_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG),
28
5.62k
                                           libctx, propq);
29
5.62k
    if (!ossl_cmp_msg_set0_libctx(msg, libctx, propq)) {
30
0
        OSSL_CMP_MSG_free(msg);
31
0
        msg = NULL;
32
0
    }
33
5.62k
    return msg;
34
5.62k
}
35
36
void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg)
37
16.8k
{
38
16.8k
    ASN1_item_free((ASN1_VALUE *)msg, ASN1_ITEM_rptr(OSSL_CMP_MSG));
39
16.8k
}
40
41
/*
42
 * This should only be used if the X509 object was embedded inside another
43
 * asn1 object and it needs a libctx to operate.
44
 * Use OSSL_CMP_MSG_new() instead if possible.
45
 */
46
int ossl_cmp_msg_set0_libctx(OSSL_CMP_MSG *msg, OSSL_LIB_CTX *libctx,
47
                             const char *propq)
48
5.62k
{
49
5.62k
    if (msg != NULL) {
50
5.62k
        msg->libctx = libctx;
51
5.62k
        OPENSSL_free(msg->propq);
52
5.62k
        msg->propq = NULL;
53
5.62k
        if (propq != NULL) {
54
0
            msg->propq = OPENSSL_strdup(propq);
55
0
            if (msg->propq == NULL)
56
0
                return 0;
57
0
        }
58
5.62k
    }
59
5.62k
    return 1;
60
5.62k
}
61
62
63
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg)
64
13.3k
{
65
13.3k
    if (msg == NULL) {
66
0
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
67
0
        return NULL;
68
0
    }
69
13.3k
    return msg->header;
70
13.3k
}
71
72
const char *ossl_cmp_bodytype_to_string(int type)
73
5.31k
{
74
5.31k
    static const char *type_names[] = {
75
5.31k
        "IR", "IP", "CR", "CP", "P10CR",
76
5.31k
        "POPDECC", "POPDECR", "KUR", "KUP",
77
5.31k
        "KRR", "KRP", "RR", "RP", "CCR", "CCP",
78
5.31k
        "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
79
5.31k
        "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
80
5.31k
    };
81
82
5.31k
    if (type < 0 || type > OSSL_CMP_PKIBODY_TYPE_MAX)
83
0
        return "illegal body type";
84
5.31k
    return type_names[type];
85
5.31k
}
86
87
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type)
88
5.62k
{
89
5.62k
    if (!ossl_assert(msg != NULL && msg->body != NULL))
90
0
        return 0;
91
92
5.62k
    msg->body->type = type;
93
5.62k
    return 1;
94
5.62k
}
95
96
int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg)
97
14.0k
{
98
14.0k
    if (!ossl_assert(msg != NULL && msg->body != NULL))
99
0
        return -1;
100
101
14.0k
    return msg->body->type;
102
14.0k
}
103
104
/* Add an extension to the referenced extension stack, which may be NULL */
105
static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex)
106
0
{
107
0
    X509_EXTENSION *ext;
108
0
    int res;
109
110
0
    if (!ossl_assert(pexts != NULL)) /* pointer to var must not be NULL */
111
0
        return 0;
112
113
0
    if ((ext = X509V3_EXT_i2d(nid, crit, ex)) == NULL)
114
0
        return 0;
115
116
0
    res = X509v3_add_ext(pexts, ext, 0) != NULL;
117
0
    X509_EXTENSION_free(ext);
118
0
    return res;
119
0
}
120
121
/* Add extension list to the referenced extension stack, which may be NULL */
122
static int add_extensions(STACK_OF(X509_EXTENSION) **target,
123
                          const STACK_OF(X509_EXTENSION) *exts)
124
0
{
125
0
    int i;
126
127
0
    if (target == NULL)
128
0
        return 0;
129
130
0
    for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
131
0
        X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
132
0
        ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext);
133
0
        int idx = X509v3_get_ext_by_OBJ(*target, obj, -1);
134
135
        /* Does extension exist in target? */
136
0
        if (idx != -1) {
137
            /* Delete all extensions of same type */
138
0
            do {
139
0
                X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target, idx));
140
0
                idx = X509v3_get_ext_by_OBJ(*target, obj, -1);
141
0
            } while (idx != -1);
142
0
        }
143
0
        if (!X509v3_add_ext(target, ext, -1))
144
0
            return 0;
145
0
    }
146
0
    return 1;
147
0
}
148
149
/* Add a CRL revocation reason code to extension stack, which may be NULL */
150
static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code)
151
0
{
152
0
    ASN1_ENUMERATED *val = ASN1_ENUMERATED_new();
153
0
    int res = 0;
154
155
0
    if (val != NULL && ASN1_ENUMERATED_set(val, reason_code))
156
0
        res = add1_extension(pexts, NID_crl_reason, 0 /* non-critical */, val);
157
0
    ASN1_ENUMERATED_free(val);
158
0
    return res;
159
0
}
160
161
OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype)
162
5.62k
{
163
5.62k
    OSSL_CMP_MSG *msg = NULL;
164
165
5.62k
    if (!ossl_assert(ctx != NULL))
166
0
        return NULL;
167
168
5.62k
    if ((msg = OSSL_CMP_MSG_new(ctx->libctx, ctx->propq)) == NULL)
169
0
        return NULL;
170
5.62k
    if (!ossl_cmp_hdr_init(ctx, msg->header)
171
5.62k
            || !ossl_cmp_msg_set_bodytype(msg, bodytype))
172
0
        goto err;
173
5.62k
    if (ctx->geninfo_ITAVs != NULL
174
5.62k
            && !ossl_cmp_hdr_generalInfo_push1_items(msg->header,
175
0
                                                     ctx->geninfo_ITAVs))
176
0
        goto err;
177
178
5.62k
    switch (bodytype) {
179
10
    case OSSL_CMP_PKIBODY_IR:
180
17
    case OSSL_CMP_PKIBODY_CR:
181
20
    case OSSL_CMP_PKIBODY_KUR:
182
20
        if ((msg->body->value.ir = OSSL_CRMF_MSGS_new()) == NULL)
183
0
            goto err;
184
20
        return msg;
185
186
7
    case OSSL_CMP_PKIBODY_P10CR:
187
7
        if (ctx->p10CSR == NULL) {
188
7
            ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_P10CSR);
189
7
            goto err;
190
7
        }
191
0
        if ((msg->body->value.p10cr = X509_REQ_dup(ctx->p10CSR)) == NULL)
192
0
            goto err;
193
0
        return msg;
194
195
0
    case OSSL_CMP_PKIBODY_IP:
196
0
    case OSSL_CMP_PKIBODY_CP:
197
0
    case OSSL_CMP_PKIBODY_KUP:
198
0
        if ((msg->body->value.ip = OSSL_CMP_CERTREPMESSAGE_new()) == NULL)
199
0
            goto err;
200
0
        return msg;
201
202
30
    case OSSL_CMP_PKIBODY_RR:
203
30
        if ((msg->body->value.rr = sk_OSSL_CMP_REVDETAILS_new_null()) == NULL)
204
0
            goto err;
205
30
        return msg;
206
0
    case OSSL_CMP_PKIBODY_RP:
207
0
        if ((msg->body->value.rp = OSSL_CMP_REVREPCONTENT_new()) == NULL)
208
0
            goto err;
209
0
        return msg;
210
211
0
    case OSSL_CMP_PKIBODY_CERTCONF:
212
0
        if ((msg->body->value.certConf =
213
0
             sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL)
214
0
            goto err;
215
0
        return msg;
216
4
    case OSSL_CMP_PKIBODY_PKICONF:
217
4
        if ((msg->body->value.pkiconf = ASN1_TYPE_new()) == NULL)
218
0
            goto err;
219
4
        ASN1_TYPE_set(msg->body->value.pkiconf, V_ASN1_NULL, NULL);
220
4
        return msg;
221
222
130
    case OSSL_CMP_PKIBODY_POLLREQ:
223
130
        if ((msg->body->value.pollReq = sk_OSSL_CMP_POLLREQ_new_null()) == NULL)
224
0
            goto err;
225
130
        return msg;
226
0
    case OSSL_CMP_PKIBODY_POLLREP:
227
0
        if ((msg->body->value.pollRep = sk_OSSL_CMP_POLLREP_new_null()) == NULL)
228
0
            goto err;
229
0
        return msg;
230
231
118
    case OSSL_CMP_PKIBODY_GENM:
232
118
    case OSSL_CMP_PKIBODY_GENP:
233
118
        if ((msg->body->value.genm = sk_OSSL_CMP_ITAV_new_null()) == NULL)
234
0
            goto err;
235
118
        return msg;
236
237
5.31k
    case OSSL_CMP_PKIBODY_ERROR:
238
5.31k
        if ((msg->body->value.error = OSSL_CMP_ERRORMSGCONTENT_new()) == NULL)
239
0
            goto err;
240
5.31k
        return msg;
241
242
0
    default:
243
0
        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
244
0
        goto err;
245
5.62k
    }
246
247
7
 err:
248
7
    OSSL_CMP_MSG_free(msg);
249
7
    return NULL;
250
5.62k
}
251
252
#define HAS_SAN(ctx) \
253
57
    (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
254
57
         || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
255
256
static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, int for_KUR,
257
                                       const X509_NAME *ref_subj)
258
20
{
259
20
    if (ctx->subjectName != NULL)
260
0
        return IS_NULL_DN(ctx->subjectName) ? NULL : ctx->subjectName;
261
20
    if (ctx->p10CSR != NULL) /* first default is from any given CSR */
262
0
        return X509_REQ_get_subject_name(ctx->p10CSR);
263
20
    if (for_KUR || !HAS_SAN(ctx))
264
        /*
265
         * For KUR, copy subject from any reference cert as fallback.
266
         * For IR or CR, do the same only if there is no subjectAltName.
267
         */
268
20
        return ref_subj;
269
0
    return NULL;
270
20
}
271
272
OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)
273
20
{
274
20
    OSSL_CRMF_MSG *crm = NULL;
275
20
    X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->cert;
276
    /* refcert defaults to current client cert */
277
20
    EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx);
278
20
    STACK_OF(GENERAL_NAME) *default_sans = NULL;
279
20
    const X509_NAME *ref_subj =
280
20
        refcert != NULL ? X509_get_subject_name(refcert) : NULL;
281
20
    const X509_NAME *subject = determine_subj(ctx, for_KUR, ref_subj);
282
20
    const X509_NAME *issuer = ctx->issuer != NULL || refcert == NULL
283
20
        ? (IS_NULL_DN(ctx->issuer) ? NULL : ctx->issuer)
284
20
        : X509_get_issuer_name(refcert);
285
20
    int crit = ctx->setSubjectAltNameCritical || subject == NULL;
286
    /* RFC5280: subjectAltName MUST be critical if subject is null */
287
20
    X509_EXTENSIONS *exts = NULL;
288
289
20
    if (rkey == NULL) {
290
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
291
        ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PUBLIC_KEY);
292
        return NULL;
293
#endif
294
20
    }
295
20
    if (for_KUR && refcert == NULL && ctx->p10CSR == NULL) {
296
0
        ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT);
297
0
        return NULL;
298
0
    }
299
20
    if ((crm = OSSL_CRMF_MSG_new()) == NULL)
300
0
        return NULL;
301
20
    if (!OSSL_CRMF_MSG_set_certReqId(crm, rid)
302
            /*
303
             * fill certTemplate, corresponding to CertificationRequestInfo
304
             * of PKCS#10. The rkey param cannot be NULL so far -
305
             * it could be NULL if centralized key creation was supported
306
             */
307
20
            || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm), rkey,
308
20
                                            subject, issuer, NULL /* serial */))
309
0
        goto err;
310
20
    if (ctx->days != 0) {
311
0
        time_t now = time(NULL);
312
0
        ASN1_TIME *notBefore = ASN1_TIME_adj(NULL, now, 0, 0);
313
0
        ASN1_TIME *notAfter = ASN1_TIME_adj(NULL, now, ctx->days, 0);
314
315
0
        if (notBefore == NULL
316
0
                || notAfter == NULL
317
0
                || !OSSL_CRMF_MSG_set0_validity(crm, notBefore, notAfter)) {
318
0
            ASN1_TIME_free(notBefore);
319
0
            ASN1_TIME_free(notAfter);
320
0
            goto err;
321
0
        }
322
0
    }
323
324
    /* extensions */
325
20
    if (ctx->p10CSR != NULL
326
20
            && (exts = X509_REQ_get_extensions(ctx->p10CSR)) == NULL)
327
0
        goto err;
328
20
    if (!ctx->SubjectAltName_nodefault && !HAS_SAN(ctx) && refcert != NULL
329
20
            && (default_sans = X509V3_get_d2i(X509_get0_extensions(refcert),
330
20
                                              NID_subject_alt_name, NULL, NULL))
331
20
            != NULL
332
20
            && !add1_extension(&exts, NID_subject_alt_name, crit, default_sans))
333
0
        goto err;
334
    if (ctx->reqExtensions != NULL /* augment/override existing ones */
335
20
            && !add_extensions(&exts, ctx->reqExtensions))
336
0
        goto err;
337
20
    if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0
338
20
            && !add1_extension(&exts, NID_subject_alt_name,
339
0
                               crit, ctx->subjectAltNames))
340
0
        goto err;
341
20
    if (ctx->policies != NULL
342
20
            && !add1_extension(&exts, NID_certificate_policies,
343
0
                               ctx->setPoliciesCritical, ctx->policies))
344
0
        goto err;
345
20
    if (!OSSL_CRMF_MSG_set0_extensions(crm, exts))
346
0
        goto err;
347
20
    exts = NULL;
348
    /* end fill certTemplate, now set any controls */
349
350
    /* for KUR, set OldCertId according to D.6 */
351
20
    if (for_KUR && refcert != NULL) {
352
3
        OSSL_CRMF_CERTID *cid =
353
3
            OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert),
354
3
                                 X509_get0_serialNumber(refcert));
355
3
        int ret;
356
357
3
        if (cid == NULL)
358
0
            goto err;
359
3
        ret = OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm, cid);
360
3
        OSSL_CRMF_CERTID_free(cid);
361
3
        if (ret == 0)
362
0
            goto err;
363
3
    }
364
365
20
    goto end;
366
367
20
 err:
368
0
    OSSL_CRMF_MSG_free(crm);
369
0
    crm = NULL;
370
371
20
 end:
372
20
    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
373
20
    sk_GENERAL_NAME_pop_free(default_sans, GENERAL_NAME_free);
374
20
    return crm;
375
0
}
376
377
OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type,
378
                                   const OSSL_CRMF_MSG *crm)
379
27
{
380
27
    OSSL_CMP_MSG *msg;
381
27
    OSSL_CRMF_MSG *local_crm = NULL;
382
383
27
    if (!ossl_assert(ctx != NULL))
384
0
        return NULL;
385
386
27
    if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR
387
27
            && type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) {
388
0
        ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS);
389
0
        return NULL;
390
0
    }
391
27
    if (type == OSSL_CMP_PKIBODY_P10CR && crm != NULL) {
392
0
        ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS);
393
0
        return NULL;
394
0
    }
395
396
27
    if ((msg = ossl_cmp_msg_create(ctx, type)) == NULL)
397
7
        goto err;
398
399
    /* header */
400
20
    if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header))
401
0
        goto err;
402
403
    /* body */
404
    /* For P10CR the content has already been set in OSSL_CMP_MSG_create */
405
20
    if (type != OSSL_CMP_PKIBODY_P10CR) {
406
20
        EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
407
408
        /* privkey is ctx->newPkey (if private, else NULL) or ctx->pkey */
409
20
        if (ctx->popoMethod >= OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) {
410
0
            ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO);
411
0
            goto err;
412
0
        }
413
20
        if (crm == NULL) {
414
20
            local_crm = OSSL_CMP_CTX_setup_CRM(ctx,
415
20
                                               type == OSSL_CMP_PKIBODY_KUR,
416
20
                                               OSSL_CMP_CERTREQID);
417
20
            if (local_crm == NULL
418
20
                || !OSSL_CRMF_MSG_create_popo(ctx->popoMethod, local_crm,
419
20
                                              privkey, ctx->digest,
420
20
                                              ctx->libctx, ctx->propq))
421
0
                goto err;
422
20
        } else {
423
0
            if ((local_crm = OSSL_CRMF_MSG_dup(crm)) == NULL)
424
0
                goto err;
425
0
        }
426
427
        /* value.ir is same for cr and kur */
428
20
        if (!sk_OSSL_CRMF_MSG_push(msg->body->value.ir, local_crm))
429
0
            goto err;
430
20
        local_crm = NULL;
431
20
    }
432
433
20
    if (!ossl_cmp_msg_protect(ctx, msg))
434
20
        goto err;
435
436
0
    return msg;
437
438
27
 err:
439
27
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREQ);
440
27
    OSSL_CRMF_MSG_free(local_crm);
441
27
    OSSL_CMP_MSG_free(msg);
442
27
    return NULL;
443
20
}
444
445
OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype,
446
                                   int certReqId, const OSSL_CMP_PKISI *si,
447
                                   X509 *cert, const X509 *encryption_recip,
448
                                   STACK_OF(X509) *chain, STACK_OF(X509) *caPubs,
449
                                   int unprotectedErrors)
450
0
{
451
0
    OSSL_CMP_MSG *msg = NULL;
452
0
    OSSL_CMP_CERTREPMESSAGE *repMsg = NULL;
453
0
    OSSL_CMP_CERTRESPONSE *resp = NULL;
454
0
    int status = OSSL_CMP_PKISTATUS_unspecified;
455
456
0
    if (!ossl_assert(ctx != NULL && si != NULL))
457
0
        return NULL;
458
459
0
    if ((msg = ossl_cmp_msg_create(ctx, bodytype)) == NULL)
460
0
        goto err;
461
0
    repMsg = msg->body->value.ip; /* value.ip is same for cp and kup */
462
463
    /* header */
464
0
    if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header))
465
0
        goto err;
466
467
    /* body */
468
0
    if ((resp = OSSL_CMP_CERTRESPONSE_new()) == NULL)
469
0
        goto err;
470
0
    OSSL_CMP_PKISI_free(resp->status);
471
0
    if ((resp->status = OSSL_CMP_PKISI_dup(si)) == NULL
472
0
            || !ASN1_INTEGER_set(resp->certReqId, certReqId))
473
0
        goto err;
474
475
0
    status = ossl_cmp_pkisi_get_status(resp->status);
476
0
    if (status != OSSL_CMP_PKISTATUS_rejection
477
0
            && status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) {
478
0
        if (encryption_recip != NULL) {
479
0
            ERR_raise(ERR_LIB_CMP, ERR_R_UNSUPPORTED);
480
0
            goto err;
481
0
        }
482
483
0
        if ((resp->certifiedKeyPair = OSSL_CMP_CERTIFIEDKEYPAIR_new())
484
0
            == NULL)
485
0
            goto err;
486
0
        resp->certifiedKeyPair->certOrEncCert->type =
487
0
            OSSL_CMP_CERTORENCCERT_CERTIFICATE;
488
0
        if (!X509_up_ref(cert))
489
0
            goto err;
490
0
        resp->certifiedKeyPair->certOrEncCert->value.certificate = cert;
491
0
    }
492
493
0
    if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg->response, resp))
494
0
        goto err;
495
0
    resp = NULL;
496
497
0
    if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL
498
0
            && (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL)
499
0
        goto err;
500
0
    if (sk_X509_num(chain) > 0
501
0
        && !ossl_x509_add_certs_new(&msg->extraCerts, chain,
502
0
                                    X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
503
0
        goto err;
504
505
0
    if (!unprotectedErrors
506
0
            || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
507
0
        if (!ossl_cmp_msg_protect(ctx, msg))
508
0
            goto err;
509
510
0
    return msg;
511
512
0
 err:
513
0
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP);
514
0
    OSSL_CMP_CERTRESPONSE_free(resp);
515
0
    OSSL_CMP_MSG_free(msg);
516
0
    return NULL;
517
0
}
518
519
OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx)
520
30
{
521
30
    OSSL_CMP_MSG *msg = NULL;
522
30
    OSSL_CMP_REVDETAILS *rd;
523
30
    int ret;
524
525
30
    if (!ossl_assert(ctx != NULL && (ctx->oldCert != NULL
526
30
                                     || ctx->p10CSR != NULL)))
527
0
        return NULL;
528
529
30
    if ((rd = OSSL_CMP_REVDETAILS_new()) == NULL)
530
0
        goto err;
531
532
    /* Fill the template from the contents of the certificate to be revoked */
533
30
    ret = ctx->oldCert != NULL
534
30
    ? OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails,
535
30
                                  NULL /* pubkey would be redundant */,
536
30
                                  NULL /* subject would be redundant */,
537
30
                                  X509_get_issuer_name(ctx->oldCert),
538
30
                                  X509_get0_serialNumber(ctx->oldCert))
539
30
    : OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails,
540
0
                                  X509_REQ_get0_pubkey(ctx->p10CSR),
541
0
                                  X509_REQ_get_subject_name(ctx->p10CSR),
542
0
                                  NULL, NULL);
543
30
    if (!ret)
544
0
        goto err;
545
546
    /* revocation reason code is optional */
547
30
    if (ctx->revocationReason != CRL_REASON_NONE
548
30
            && !add_crl_reason_extension(&rd->crlEntryDetails,
549
0
                                         ctx->revocationReason))
550
0
        goto err;
551
552
30
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RR)) == NULL)
553
0
        goto err;
554
555
30
    if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd))
556
0
        goto err;
557
30
    rd = NULL;
558
    /* Revocation Passphrase according to section 5.3.19.9 could be set here */
559
560
30
    if (!ossl_cmp_msg_protect(ctx, msg))
561
30
        goto err;
562
563
0
    return msg;
564
565
30
 err:
566
30
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR);
567
30
    OSSL_CMP_MSG_free(msg);
568
30
    OSSL_CMP_REVDETAILS_free(rd);
569
30
    return NULL;
570
30
}
571
572
OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si,
573
                              const OSSL_CRMF_CERTID *cid, int unprotectedErrors)
574
0
{
575
0
    OSSL_CMP_REVREPCONTENT *rep = NULL;
576
0
    OSSL_CMP_PKISI *si1 = NULL;
577
0
    OSSL_CRMF_CERTID *cid_copy = NULL;
578
0
    OSSL_CMP_MSG *msg = NULL;
579
580
0
    if (!ossl_assert(ctx != NULL && si != NULL))
581
0
        return NULL;
582
583
0
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RP)) == NULL)
584
0
        goto err;
585
0
    rep = msg->body->value.rp;
586
587
0
    if ((si1 = OSSL_CMP_PKISI_dup(si)) == NULL)
588
0
        goto err;
589
590
0
    if (!sk_OSSL_CMP_PKISI_push(rep->status, si1)) {
591
0
        OSSL_CMP_PKISI_free(si1);
592
0
        goto err;
593
0
    }
594
595
0
    if ((rep->revCerts = sk_OSSL_CRMF_CERTID_new_null()) == NULL)
596
0
        goto err;
597
0
    if (cid != NULL) {
598
0
        if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL)
599
0
            goto err;
600
0
        if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) {
601
0
            OSSL_CRMF_CERTID_free(cid_copy);
602
0
            goto err;
603
0
        }
604
0
    }
605
606
0
    if (!unprotectedErrors
607
0
            || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
608
0
        if (!ossl_cmp_msg_protect(ctx, msg))
609
0
            goto err;
610
611
0
    return msg;
612
613
0
 err:
614
0
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RP);
615
0
    OSSL_CMP_MSG_free(msg);
616
0
    return NULL;
617
0
}
618
619
OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx)
620
4
{
621
4
    OSSL_CMP_MSG *msg;
622
623
4
    if (!ossl_assert(ctx != NULL))
624
0
        return NULL;
625
626
4
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_PKICONF)) == NULL)
627
0
        goto err;
628
4
    if (ossl_cmp_msg_protect(ctx, msg))
629
0
        return msg;
630
631
4
 err:
632
4
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF);
633
4
    OSSL_CMP_MSG_free(msg);
634
4
    return NULL;
635
4
}
636
637
int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav)
638
0
{
639
0
    int bodytype;
640
641
0
    if (!ossl_assert(msg != NULL && itav != NULL))
642
0
        return 0;
643
644
0
    bodytype = OSSL_CMP_MSG_get_bodytype(msg);
645
0
    if (bodytype != OSSL_CMP_PKIBODY_GENM
646
0
            && bodytype != OSSL_CMP_PKIBODY_GENP) {
647
0
        ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS);
648
0
        return 0;
649
0
    }
650
651
    /* value.genp has the same structure, so this works for genp as well */
652
0
    return OSSL_CMP_ITAV_push0_stack_item(&msg->body->value.genm, itav);
653
0
}
654
655
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
656
                                 const STACK_OF(OSSL_CMP_ITAV) *itavs)
657
0
{
658
0
    int i;
659
0
    OSSL_CMP_ITAV *itav = NULL;
660
661
0
    if (!ossl_assert(msg != NULL))
662
0
        return 0;
663
664
0
    for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
665
0
        itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i));
666
0
        if (itav == NULL
667
0
                || !ossl_cmp_msg_gen_push0_ITAV(msg, itav)) {
668
0
            OSSL_CMP_ITAV_free(itav);
669
0
            return 0;
670
0
        }
671
0
    }
672
0
    return 1;
673
0
}
674
675
/*
676
 * Creates a new General Message/Response with an empty itav stack
677
 * returns a pointer to the PKIMessage on success, NULL on error
678
 */
679
static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx,
680
                             const STACK_OF(OSSL_CMP_ITAV) *itavs,
681
                             int body_type, int err_code)
682
118
{
683
118
    OSSL_CMP_MSG *msg = NULL;
684
685
118
    if (!ossl_assert(ctx != NULL))
686
0
        return NULL;
687
688
118
    if ((msg = ossl_cmp_msg_create(ctx, body_type)) == NULL)
689
0
        return NULL;
690
691
118
    if (itavs != NULL && !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs))
692
0
        goto err;
693
694
118
    if (!ossl_cmp_msg_protect(ctx, msg))
695
118
        goto err;
696
697
0
    return msg;
698
699
118
 err:
700
118
    ERR_raise(ERR_LIB_CMP, err_code);
701
118
    OSSL_CMP_MSG_free(msg);
702
118
    return NULL;
703
118
}
704
705
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
706
118
{
707
118
    return gen_new(ctx, ctx->genm_ITAVs,
708
118
                   OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
709
118
}
710
711
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
712
                                const STACK_OF(OSSL_CMP_ITAV) *itavs)
713
0
{
714
0
    return gen_new(ctx, itavs,
715
0
                   OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
716
0
}
717
718
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si,
719
                                 int64_t errorCode, const char *details,
720
                                 int unprotected)
721
5.31k
{
722
5.31k
    OSSL_CMP_MSG *msg = NULL;
723
5.31k
    const char *lib = NULL, *reason = NULL;
724
5.31k
    OSSL_CMP_PKIFREETEXT *ft;
725
726
5.31k
    if (!ossl_assert(ctx != NULL && si != NULL))
727
0
        return NULL;
728
729
5.31k
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_ERROR)) == NULL)
730
0
        goto err;
731
732
5.31k
    OSSL_CMP_PKISI_free(msg->body->value.error->pKIStatusInfo);
733
5.31k
    if ((msg->body->value.error->pKIStatusInfo = OSSL_CMP_PKISI_dup(si))
734
5.31k
        == NULL)
735
0
        goto err;
736
5.31k
    if ((msg->body->value.error->errorCode = ASN1_INTEGER_new()) == NULL)
737
0
        goto err;
738
5.31k
    if (!ASN1_INTEGER_set_int64(msg->body->value.error->errorCode, errorCode))
739
0
        goto err;
740
5.31k
    if (errorCode > 0
741
5.31k
            && (uint64_t)errorCode < ((uint64_t)ERR_SYSTEM_FLAG << 1)) {
742
5.31k
        lib = ERR_lib_error_string((unsigned long)errorCode);
743
5.31k
        reason = ERR_reason_error_string((unsigned long)errorCode);
744
5.31k
    }
745
5.31k
    if (lib != NULL || reason != NULL || details != NULL) {
746
5.31k
        if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL)
747
0
            goto err;
748
5.31k
        msg->body->value.error->errorDetails = ft;
749
5.31k
        if (lib != NULL && *lib != '\0'
750
5.31k
                && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, lib, -1))
751
0
            goto err;
752
5.31k
        if (reason != NULL && *reason != '\0'
753
5.31k
                && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, reason, -1))
754
0
            goto err;
755
5.31k
        if (details != NULL
756
5.31k
                && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details, -1))
757
0
            goto err;
758
5.31k
    }
759
760
5.31k
    if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
761
5.31k
        goto err;
762
0
    return msg;
763
764
5.31k
 err:
765
5.31k
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_ERROR);
766
5.31k
    OSSL_CMP_MSG_free(msg);
767
5.31k
    return NULL;
768
5.31k
}
769
770
/*
771
 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
772
 * This is used in the certConf message, for example,
773
 * to confirm that the certificate was received successfully.
774
 */
775
int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
776
                                      ASN1_OCTET_STRING *hash)
777
0
{
778
0
    if (!ossl_assert(certStatus != NULL))
779
0
        return 0;
780
0
    ASN1_OCTET_STRING_free(certStatus->certHash);
781
0
    certStatus->certHash = hash;
782
0
    return 1;
783
0
}
784
785
OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int certReqId,
786
                                    int fail_info, const char *text)
787
0
{
788
0
    OSSL_CMP_MSG *msg = NULL;
789
0
    OSSL_CMP_CERTSTATUS *certStatus = NULL;
790
0
    ASN1_OCTET_STRING *certHash = NULL;
791
0
    OSSL_CMP_PKISI *sinfo;
792
793
0
    if (!ossl_assert(ctx != NULL && ctx->newCert != NULL
794
0
                     && (certReqId == OSSL_CMP_CERTREQID
795
0
                         || certReqId == OSSL_CMP_CERTREQID_NONE)))
796
0
        return NULL;
797
798
0
    if ((unsigned)fail_info > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) {
799
0
        ERR_raise(ERR_LIB_CMP, CMP_R_FAIL_INFO_OUT_OF_RANGE);
800
0
        return NULL;
801
0
    }
802
803
0
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_CERTCONF)) == NULL)
804
0
        goto err;
805
806
0
    if ((certStatus = OSSL_CMP_CERTSTATUS_new()) == NULL)
807
0
        goto err;
808
    /* consume certStatus into msg right away so it gets deallocated with msg */
809
0
    if (sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus) < 1) {
810
0
        OSSL_CMP_CERTSTATUS_free(certStatus);
811
0
        goto err;
812
0
    }
813
814
    /* set the ID of the certReq */
815
0
    if (!ASN1_INTEGER_set(certStatus->certReqId, certReqId))
816
0
        goto err;
817
    /*
818
     * The hash of the certificate, using the same hash algorithm
819
     * as is used to create and verify the certificate signature.
820
     * If not available, a default hash algorithm is used.
821
     */
822
0
    if ((certHash = X509_digest_sig(ctx->newCert, NULL, NULL)) == NULL)
823
0
        goto err;
824
825
0
    if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash))
826
0
        goto err;
827
0
    certHash = NULL;
828
    /*
829
     * For any particular CertStatus, omission of the statusInfo field
830
     * indicates ACCEPTANCE of the specified certificate.  Alternatively,
831
     * explicit status details (with respect to acceptance or rejection) MAY
832
     * be provided in the statusInfo field, perhaps for auditing purposes at
833
     * the CA/RA.
834
     */
835
0
    sinfo = fail_info != 0 ?
836
0
        OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
837
0
        OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
838
0
    if (sinfo == NULL)
839
0
        goto err;
840
0
    certStatus->statusInfo = sinfo;
841
842
0
    if (!ossl_cmp_msg_protect(ctx, msg))
843
0
        goto err;
844
845
0
    return msg;
846
847
0
 err:
848
0
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTCONF);
849
0
    OSSL_CMP_MSG_free(msg);
850
0
    ASN1_OCTET_STRING_free(certHash);
851
0
    return NULL;
852
0
}
853
854
OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid)
855
130
{
856
130
    OSSL_CMP_MSG *msg = NULL;
857
130
    OSSL_CMP_POLLREQ *preq = NULL;
858
859
130
    if (!ossl_assert(ctx != NULL))
860
0
        return NULL;
861
862
130
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREQ)) == NULL)
863
0
        goto err;
864
865
130
    if ((preq = OSSL_CMP_POLLREQ_new()) == NULL
866
130
            || !ASN1_INTEGER_set(preq->certReqId, crid)
867
130
            || !sk_OSSL_CMP_POLLREQ_push(msg->body->value.pollReq, preq))
868
0
        goto err;
869
870
130
    preq = NULL;
871
130
    if (!ossl_cmp_msg_protect(ctx, msg))
872
130
        goto err;
873
874
0
    return msg;
875
876
130
 err:
877
130
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREQ);
878
130
    OSSL_CMP_POLLREQ_free(preq);
879
130
    OSSL_CMP_MSG_free(msg);
880
130
    return NULL;
881
130
}
882
883
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
884
                                   int64_t poll_after)
885
0
{
886
0
    OSSL_CMP_MSG *msg;
887
0
    OSSL_CMP_POLLREP *prep;
888
889
0
    if (!ossl_assert(ctx != NULL))
890
0
        return NULL;
891
892
0
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREP)) == NULL)
893
0
        goto err;
894
0
    if ((prep = OSSL_CMP_POLLREP_new()) == NULL)
895
0
        goto err;
896
0
    if (!sk_OSSL_CMP_POLLREP_push(msg->body->value.pollRep, prep))
897
0
        goto err;
898
0
    if (!ASN1_INTEGER_set(prep->certReqId, crid))
899
0
        goto err;
900
0
    if (!ASN1_INTEGER_set_int64(prep->checkAfter, poll_after))
901
0
        goto err;
902
903
0
    if (!ossl_cmp_msg_protect(ctx, msg))
904
0
        goto err;
905
0
    return msg;
906
907
0
 err:
908
0
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP);
909
0
    OSSL_CMP_MSG_free(msg);
910
0
    return NULL;
911
0
}
912
913
/*-
914
 * returns the status field of the RevRepContent with the given
915
 * request/sequence id inside a revocation response.
916
 * RevRepContent has the revocation statuses in same order as they were sent in
917
 * RevReqContent.
918
 * returns NULL on error
919
 */
920
OSSL_CMP_PKISI *
921
ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
922
0
{
923
0
    OSSL_CMP_PKISI *status;
924
925
0
    if (!ossl_assert(rrep != NULL))
926
0
        return NULL;
927
928
0
    if ((status = sk_OSSL_CMP_PKISI_value(rrep->status, rsid)) != NULL)
929
0
        return status;
930
931
0
    ERR_raise(ERR_LIB_CMP, CMP_R_PKISTATUSINFO_NOT_FOUND);
932
0
    return NULL;
933
0
}
934
935
/*
936
 * returns the CertId field in the revCerts part of the RevRepContent
937
 * with the given request/sequence id inside a revocation response.
938
 * RevRepContent has the CertIds in same order as they were sent in
939
 * RevReqContent.
940
 * returns NULL on error
941
 */
942
OSSL_CRMF_CERTID *
943
ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
944
0
{
945
0
    OSSL_CRMF_CERTID *cid = NULL;
946
947
0
    if (!ossl_assert(rrep != NULL))
948
0
        return NULL;
949
950
0
    if ((cid = sk_OSSL_CRMF_CERTID_value(rrep->revCerts, rsid)) != NULL)
951
0
        return cid;
952
953
0
    ERR_raise(ERR_LIB_CMP, CMP_R_CERTID_NOT_FOUND);
954
0
    return NULL;
955
0
}
956
957
static int suitable_rid(const ASN1_INTEGER *certReqId, int rid)
958
0
{
959
0
    int trid;
960
961
0
    if (rid == OSSL_CMP_CERTREQID_NONE)
962
0
        return 1;
963
964
0
    trid = ossl_cmp_asn1_get_int(certReqId);
965
966
0
    if (trid == OSSL_CMP_CERTREQID_NONE) {
967
0
        ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
968
0
        return 0;
969
0
    }
970
0
    return rid == trid;
971
0
}
972
973
/*
974
 * returns a pointer to the PollResponse with the given CertReqId
975
 * (or the first one in case -1) inside a PollRepContent
976
 * returns NULL on error or if no suitable PollResponse available
977
 */
978
OSSL_CMP_POLLREP *
979
ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc,
980
                                     int rid)
981
0
{
982
0
    OSSL_CMP_POLLREP *pollRep = NULL;
983
0
    int i;
984
985
0
    if (!ossl_assert(prc != NULL))
986
0
        return NULL;
987
988
0
    for (i = 0; i < sk_OSSL_CMP_POLLREP_num(prc); i++) {
989
0
        pollRep = sk_OSSL_CMP_POLLREP_value(prc, i);
990
0
        if (suitable_rid(pollRep->certReqId, rid))
991
0
            return pollRep;
992
0
    }
993
994
0
    ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND,
995
0
                   "expected certReqId = %d", rid);
996
0
    return NULL;
997
0
}
998
999
/*
1000
 * returns a pointer to the CertResponse with the given CertReqId
1001
 * (or the first one in case -1) inside a CertRepMessage
1002
 * returns NULL on error or if no suitable CertResponse available
1003
 */
1004
OSSL_CMP_CERTRESPONSE *
1005
ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
1006
                                          int rid)
1007
0
{
1008
0
    OSSL_CMP_CERTRESPONSE *crep = NULL;
1009
0
    int i;
1010
1011
0
    if (!ossl_assert(crm != NULL && crm->response != NULL))
1012
0
        return NULL;
1013
1014
0
    for (i = 0; i < sk_OSSL_CMP_CERTRESPONSE_num(crm->response); i++) {
1015
0
        crep = sk_OSSL_CMP_CERTRESPONSE_value(crm->response, i);
1016
0
        if (suitable_rid(crep->certReqId, rid))
1017
0
            return crep;
1018
0
    }
1019
1020
0
    ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND,
1021
0
                   "expected certReqId = %d", rid);
1022
0
    return NULL;
1023
0
}
1024
1025
/*-
1026
 * Retrieve the newly enrolled certificate from the given certResponse crep.
1027
 * Uses libctx and propq from ctx, in case of indirect POPO also private key.
1028
 * Returns a pointer to a copy of the found certificate, or NULL if not found.
1029
 */
1030
X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx,
1031
                                      const OSSL_CMP_CERTRESPONSE *crep)
1032
0
{
1033
0
    OSSL_CMP_CERTORENCCERT *coec;
1034
0
    X509 *crt = NULL;
1035
0
    EVP_PKEY *pkey;
1036
1037
0
    if (!ossl_assert(crep != NULL && ctx != NULL))
1038
0
        return NULL;
1039
1040
0
    if (crep->certifiedKeyPair
1041
0
            && (coec = crep->certifiedKeyPair->certOrEncCert) != NULL) {
1042
0
        switch (coec->type) {
1043
0
        case OSSL_CMP_CERTORENCCERT_CERTIFICATE:
1044
0
            crt = X509_dup(coec->value.certificate);
1045
0
            break;
1046
0
        case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT:
1047
            /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
1048
0
            pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
1049
            /* pkey is ctx->newPkey (if private, else NULL) or ctx->pkey */
1050
0
            if (pkey == NULL) {
1051
0
                ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY);
1052
0
                return NULL;
1053
0
            }
1054
0
            crt =
1055
0
                OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert,
1056
0
                                                      ctx->libctx, ctx->propq,
1057
0
                                                      pkey);
1058
0
            break;
1059
0
        default:
1060
0
            ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CERT_TYPE);
1061
0
            return NULL;
1062
0
        }
1063
0
    }
1064
0
    if (crt == NULL)
1065
0
        ERR_raise(ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND);
1066
0
    else
1067
0
        (void)ossl_x509_set0_libctx(crt, ctx->libctx, ctx->propq);
1068
0
    return crt;
1069
0
}
1070
1071
int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
1072
0
{
1073
0
    if (ctx == NULL || msg == NULL) {
1074
0
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1075
0
        return 0;
1076
0
    }
1077
0
    if (!ossl_cmp_hdr_set_transactionID(ctx, msg->header))
1078
0
        return 0;
1079
0
    return msg->header->protectionAlg == NULL
1080
0
            || ossl_cmp_msg_protect(ctx, msg);
1081
0
}
1082
1083
int OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
1084
0
{
1085
0
    if (ctx == NULL || msg == NULL || msg->header == NULL) {
1086
0
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1087
0
        return 0;
1088
0
    }
1089
0
    if (ctx->recipNonce == NULL) /* nothing to do for 1st msg in transaction */
1090
0
        return 1;
1091
0
    if (!ossl_cmp_asn1_octet_string_set1(&msg->header->recipNonce,
1092
0
                                         ctx->recipNonce))
1093
0
        return 0;
1094
0
    return msg->header->protectionAlg == NULL || ossl_cmp_msg_protect(ctx, msg);
1095
0
}
1096
1097
OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx,
1098
                                const char *propq)
1099
0
{
1100
0
    OSSL_CMP_MSG *msg;
1101
0
    BIO *bio = NULL;
1102
1103
0
    if (file == NULL) {
1104
0
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1105
0
        return NULL;
1106
0
    }
1107
1108
0
    msg = OSSL_CMP_MSG_new(libctx, propq);
1109
0
    if (msg == NULL){
1110
0
        ERR_raise(ERR_LIB_CMP, ERR_R_MALLOC_FAILURE);
1111
0
        return NULL;
1112
0
    }
1113
1114
0
    if ((bio = BIO_new_file(file, "rb")) == NULL
1115
0
            || d2i_OSSL_CMP_MSG_bio(bio, &msg) == NULL) {
1116
0
        OSSL_CMP_MSG_free(msg);
1117
0
        msg = NULL;
1118
0
    }
1119
0
    BIO_free(bio);
1120
0
    return msg;
1121
0
}
1122
1123
int OSSL_CMP_MSG_write(const char *file, const OSSL_CMP_MSG *msg)
1124
0
{
1125
0
    BIO *bio;
1126
0
    int res;
1127
1128
0
    if (file == NULL || msg == NULL) {
1129
0
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1130
0
        return -1;
1131
0
    }
1132
1133
0
    bio = BIO_new_file(file, "wb");
1134
0
    if (bio == NULL)
1135
0
        return -2;
1136
0
    res = i2d_OSSL_CMP_MSG_bio(bio, msg);
1137
0
    BIO_free(bio);
1138
0
    return res;
1139
0
}
1140
1141
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG(OSSL_CMP_MSG **msg, const unsigned char **in,
1142
                               long len)
1143
0
{
1144
0
    OSSL_LIB_CTX *libctx = NULL;
1145
0
    const char *propq = NULL;
1146
1147
0
    if (msg != NULL && *msg != NULL) {
1148
0
        libctx  = (*msg)->libctx;
1149
0
        propq = (*msg)->propq;
1150
0
    }
1151
1152
0
    return (OSSL_CMP_MSG *)ASN1_item_d2i_ex((ASN1_VALUE **)msg, in, len,
1153
0
                                            ASN1_ITEM_rptr(OSSL_CMP_MSG),
1154
0
                                            libctx, propq);
1155
0
}
1156
1157
int i2d_OSSL_CMP_MSG(const OSSL_CMP_MSG *msg, unsigned char **out)
1158
10.6k
{
1159
10.6k
    return ASN1_item_i2d((const ASN1_VALUE *)msg, out,
1160
10.6k
                         ASN1_ITEM_rptr(OSSL_CMP_MSG));
1161
10.6k
}
1162
1163
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg)
1164
8.24k
{
1165
8.24k
    OSSL_LIB_CTX *libctx = NULL;
1166
8.24k
    const char *propq = NULL;
1167
1168
8.24k
    if (msg != NULL && *msg != NULL) {
1169
0
        libctx  = (*msg)->libctx;
1170
0
        propq = (*msg)->propq;
1171
0
    }
1172
1173
8.24k
    return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG), bio, msg, libctx,
1174
8.24k
                                propq);
1175
8.24k
}
1176
1177
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
1178
5.31k
{
1179
5.31k
    return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
1180
5.31k
}