Coverage Report

Created: 2023-06-08 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
7.16k
{
25
7.16k
    OSSL_CMP_MSG *msg = NULL;
26
27
7.16k
    msg = (OSSL_CMP_MSG *)ASN1_item_new_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG),
28
7.16k
                                           libctx, propq);
29
7.16k
    if (!ossl_cmp_msg_set0_libctx(msg, libctx, propq)) {
30
0
        OSSL_CMP_MSG_free(msg);
31
0
        msg = NULL;
32
0
    }
33
7.16k
    return msg;
34
7.16k
}
35
36
void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg)
37
21.4k
{
38
21.4k
    ASN1_item_free((ASN1_VALUE *)msg, ASN1_ITEM_rptr(OSSL_CMP_MSG));
39
21.4k
}
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
7.16k
{
49
7.16k
    if (msg != NULL) {
50
7.16k
        msg->libctx = libctx;
51
7.16k
        OPENSSL_free(msg->propq);
52
7.16k
        msg->propq = NULL;
53
7.16k
        if (propq != NULL) {
54
0
            msg->propq = OPENSSL_strdup(propq);
55
0
            if (msg->propq == NULL)
56
0
                return 0;
57
0
        }
58
7.16k
    }
59
7.16k
    return 1;
60
7.16k
}
61
62
63
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg)
64
16.6k
{
65
16.6k
    if (msg == NULL) {
66
0
        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
67
0
        return NULL;
68
0
    }
69
16.6k
    return msg->header;
70
16.6k
}
71
72
const char *ossl_cmp_bodytype_to_string(int type)
73
6.75k
{
74
6.75k
    static const char *type_names[] = {
75
6.75k
        "IR", "IP", "CR", "CP", "P10CR",
76
6.75k
        "POPDECC", "POPDECR", "KUR", "KUP",
77
6.75k
        "KRR", "KRP", "RR", "RP", "CCR", "CCP",
78
6.75k
        "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
79
6.75k
        "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
80
6.75k
    };
81
82
6.75k
    if (type < 0 || type > OSSL_CMP_PKIBODY_TYPE_MAX)
83
0
        return "illegal body type";
84
6.75k
    return type_names[type];
85
6.75k
}
86
87
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type)
88
7.16k
{
89
7.16k
    if (!ossl_assert(msg != NULL && msg->body != NULL))
90
0
        return 0;
91
92
7.16k
    msg->body->type = type;
93
7.16k
    return 1;
94
7.16k
}
95
96
int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg)
97
16.9k
{
98
16.9k
    if (!ossl_assert(msg != NULL && msg->body != NULL))
99
0
        return -1;
100
101
16.9k
    return msg->body->type;
102
16.9k
}
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
7.16k
{
163
7.16k
    OSSL_CMP_MSG *msg = NULL;
164
165
7.16k
    if (!ossl_assert(ctx != NULL))
166
0
        return NULL;
167
168
7.16k
    if ((msg = OSSL_CMP_MSG_new(ctx->libctx, ctx->propq)) == NULL)
169
0
        return NULL;
170
7.16k
    if (!ossl_cmp_hdr_init(ctx, msg->header)
171
7.16k
            || !ossl_cmp_msg_set_bodytype(msg, bodytype))
172
0
        goto err;
173
7.16k
    if (ctx->geninfo_ITAVs != NULL
174
7.16k
            && !ossl_cmp_hdr_generalInfo_push1_items(msg->header,
175
0
                                                     ctx->geninfo_ITAVs))
176
0
        goto err;
177
178
7.16k
    switch (bodytype) {
179
13
    case OSSL_CMP_PKIBODY_IR:
180
29
    case OSSL_CMP_PKIBODY_CR:
181
34
    case OSSL_CMP_PKIBODY_KUR:
182
34
        if ((msg->body->value.ir = OSSL_CRMF_MSGS_new()) == NULL)
183
0
            goto err;
184
34
        return msg;
185
186
16
    case OSSL_CMP_PKIBODY_P10CR:
187
16
        if (ctx->p10CSR == NULL) {
188
16
            ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_P10CSR);
189
16
            goto err;
190
16
        }
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
33
    case OSSL_CMP_PKIBODY_RR:
203
33
        if ((msg->body->value.rr = sk_OSSL_CMP_REVDETAILS_new_null()) == NULL)
204
0
            goto err;
205
33
        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
5
    case OSSL_CMP_PKIBODY_PKICONF:
217
5
        if ((msg->body->value.pkiconf = ASN1_TYPE_new()) == NULL)
218
0
            goto err;
219
5
        ASN1_TYPE_set(msg->body->value.pkiconf, V_ASN1_NULL, NULL);
220
5
        return msg;
221
222
152
    case OSSL_CMP_PKIBODY_POLLREQ:
223
152
        if ((msg->body->value.pollReq = sk_OSSL_CMP_POLLREQ_new_null()) == NULL)
224
0
            goto err;
225
152
        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
168
    case OSSL_CMP_PKIBODY_GENM:
232
168
    case OSSL_CMP_PKIBODY_GENP:
233
168
        if ((msg->body->value.genm = sk_OSSL_CMP_ITAV_new_null()) == NULL)
234
0
            goto err;
235
168
        return msg;
236
237
6.75k
    case OSSL_CMP_PKIBODY_ERROR:
238
6.75k
        if ((msg->body->value.error = OSSL_CMP_ERRORMSGCONTENT_new()) == NULL)
239
0
            goto err;
240
6.75k
        return msg;
241
242
0
    default:
243
0
        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
244
0
        goto err;
245
7.16k
    }
246
247
16
 err:
248
16
    OSSL_CMP_MSG_free(msg);
249
16
    return NULL;
250
7.16k
}
251
252
#define HAS_SAN(ctx) \
253
97
    (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
254
97
         || 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
34
{
259
34
    if (ctx->subjectName != NULL)
260
0
        return IS_NULL_DN(ctx->subjectName) ? NULL : ctx->subjectName;
261
34
    if (ctx->p10CSR != NULL) /* first default is from any given CSR */
262
0
        return X509_REQ_get_subject_name(ctx->p10CSR);
263
34
    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
34
        return ref_subj;
269
0
    return NULL;
270
34
}
271
272
OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)
273
34
{
274
34
    OSSL_CRMF_MSG *crm = NULL;
275
34
    X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->cert;
276
    /* refcert defaults to current client cert */
277
34
    EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx);
278
34
    STACK_OF(GENERAL_NAME) *default_sans = NULL;
279
34
    const X509_NAME *ref_subj =
280
34
        refcert != NULL ? X509_get_subject_name(refcert) : NULL;
281
34
    const X509_NAME *subject = determine_subj(ctx, for_KUR, ref_subj);
282
34
    const X509_NAME *issuer = ctx->issuer != NULL || refcert == NULL
283
34
        ? (IS_NULL_DN(ctx->issuer) ? NULL : ctx->issuer)
284
34
        : X509_get_issuer_name(refcert);
285
34
    int crit = ctx->setSubjectAltNameCritical || subject == NULL;
286
    /* RFC5280: subjectAltName MUST be critical if subject is null */
287
34
    X509_EXTENSIONS *exts = NULL;
288
289
34
    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
34
    }
295
34
    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
34
    if ((crm = OSSL_CRMF_MSG_new()) == NULL)
300
0
        return NULL;
301
34
    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
34
            || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm), rkey,
308
34
                                            subject, issuer, NULL /* serial */))
309
0
        goto err;
310
34
    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
34
    if (ctx->p10CSR != NULL
326
34
            && (exts = X509_REQ_get_extensions(ctx->p10CSR)) == NULL)
327
0
        goto err;
328
34
    if (!ctx->SubjectAltName_nodefault && !HAS_SAN(ctx) && refcert != NULL
329
34
            && (default_sans = X509V3_get_d2i(X509_get0_extensions(refcert),
330
34
                                              NID_subject_alt_name, NULL, NULL))
331
34
            != NULL
332
34
            && !add1_extension(&exts, NID_subject_alt_name, crit, default_sans))
333
0
        goto err;
334
    if (ctx->reqExtensions != NULL /* augment/override existing ones */
335
34
            && !add_extensions(&exts, ctx->reqExtensions))
336
0
        goto err;
337
34
    if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0
338
34
            && !add1_extension(&exts, NID_subject_alt_name,
339
0
                               crit, ctx->subjectAltNames))
340
0
        goto err;
341
34
    if (ctx->policies != NULL
342
34
            && !add1_extension(&exts, NID_certificate_policies,
343
0
                               ctx->setPoliciesCritical, ctx->policies))
344
0
        goto err;
345
34
    if (!OSSL_CRMF_MSG_set0_extensions(crm, exts))
346
0
        goto err;
347
34
    exts = NULL;
348
    /* end fill certTemplate, now set any controls */
349
350
    /* for KUR, set OldCertId according to D.6 */
351
34
    if (for_KUR && refcert != NULL) {
352
5
        OSSL_CRMF_CERTID *cid =
353
5
            OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert),
354
5
                                 X509_get0_serialNumber(refcert));
355
5
        int ret;
356
357
5
        if (cid == NULL)
358
0
            goto err;
359
5
        ret = OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm, cid);
360
5
        OSSL_CRMF_CERTID_free(cid);
361
5
        if (ret == 0)
362
0
            goto err;
363
5
    }
364
365
34
    goto end;
366
367
34
 err:
368
0
    OSSL_CRMF_MSG_free(crm);
369
0
    crm = NULL;
370
371
34
 end:
372
34
    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
373
34
    sk_GENERAL_NAME_pop_free(default_sans, GENERAL_NAME_free);
374
34
    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
50
{
380
50
    OSSL_CMP_MSG *msg;
381
50
    OSSL_CRMF_MSG *local_crm = NULL;
382
383
50
    if (!ossl_assert(ctx != NULL))
384
0
        return NULL;
385
386
50
    if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR
387
50
            && 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
50
    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
50
    if ((msg = ossl_cmp_msg_create(ctx, type)) == NULL)
397
16
        goto err;
398
399
    /* header */
400
34
    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
34
    if (type != OSSL_CMP_PKIBODY_P10CR) {
406
34
        EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
407
408
        /* privkey is ctx->newPkey (if private, else NULL) or ctx->pkey */
409
34
        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
34
        if (crm == NULL) {
414
34
            local_crm = OSSL_CMP_CTX_setup_CRM(ctx,
415
34
                                               type == OSSL_CMP_PKIBODY_KUR,
416
34
                                               OSSL_CMP_CERTREQID);
417
34
            if (local_crm == NULL
418
34
                || !OSSL_CRMF_MSG_create_popo(ctx->popoMethod, local_crm,
419
34
                                              privkey, ctx->digest,
420
34
                                              ctx->libctx, ctx->propq))
421
0
                goto err;
422
34
        } 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
34
        if (!sk_OSSL_CRMF_MSG_push(msg->body->value.ir, local_crm))
429
0
            goto err;
430
34
        local_crm = NULL;
431
34
    }
432
433
34
    if (!ossl_cmp_msg_protect(ctx, msg))
434
34
        goto err;
435
436
0
    return msg;
437
438
50
 err:
439
50
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREQ);
440
50
    OSSL_CRMF_MSG_free(local_crm);
441
50
    OSSL_CMP_MSG_free(msg);
442
50
    return NULL;
443
34
}
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
33
{
521
33
    OSSL_CMP_MSG *msg = NULL;
522
33
    OSSL_CMP_REVDETAILS *rd;
523
33
    int ret;
524
525
33
    if (!ossl_assert(ctx != NULL && (ctx->oldCert != NULL
526
33
                                     || ctx->p10CSR != NULL)))
527
0
        return NULL;
528
529
33
    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
33
    ret = ctx->oldCert != NULL
534
33
    ? OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails,
535
33
                                  NULL /* pubkey would be redundant */,
536
33
                                  NULL /* subject would be redundant */,
537
33
                                  X509_get_issuer_name(ctx->oldCert),
538
33
                                  X509_get0_serialNumber(ctx->oldCert))
539
33
    : 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
33
    if (!ret)
544
0
        goto err;
545
546
    /* revocation reason code is optional */
547
33
    if (ctx->revocationReason != CRL_REASON_NONE
548
33
            && !add_crl_reason_extension(&rd->crlEntryDetails,
549
0
                                         ctx->revocationReason))
550
0
        goto err;
551
552
33
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RR)) == NULL)
553
0
        goto err;
554
555
33
    if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd))
556
0
        goto err;
557
33
    rd = NULL;
558
    /* Revocation Passphrase according to section 5.3.19.9 could be set here */
559
560
33
    if (!ossl_cmp_msg_protect(ctx, msg))
561
33
        goto err;
562
563
0
    return msg;
564
565
33
 err:
566
33
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR);
567
33
    OSSL_CMP_MSG_free(msg);
568
33
    OSSL_CMP_REVDETAILS_free(rd);
569
33
    return NULL;
570
33
}
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
5
{
621
5
    OSSL_CMP_MSG *msg;
622
623
5
    if (!ossl_assert(ctx != NULL))
624
0
        return NULL;
625
626
5
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_PKICONF)) == NULL)
627
0
        goto err;
628
5
    if (ossl_cmp_msg_protect(ctx, msg))
629
0
        return msg;
630
631
5
 err:
632
5
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF);
633
5
    OSSL_CMP_MSG_free(msg);
634
5
    return NULL;
635
5
}
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
168
{
683
168
    OSSL_CMP_MSG *msg = NULL;
684
685
168
    if (!ossl_assert(ctx != NULL))
686
0
        return NULL;
687
688
168
    if ((msg = ossl_cmp_msg_create(ctx, body_type)) == NULL)
689
0
        return NULL;
690
691
168
    if (itavs != NULL && !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs))
692
0
        goto err;
693
694
168
    if (!ossl_cmp_msg_protect(ctx, msg))
695
168
        goto err;
696
697
0
    return msg;
698
699
168
 err:
700
168
    ERR_raise(ERR_LIB_CMP, err_code);
701
168
    OSSL_CMP_MSG_free(msg);
702
168
    return NULL;
703
168
}
704
705
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
706
168
{
707
168
    return gen_new(ctx, ctx->genm_ITAVs,
708
168
                   OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
709
168
}
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
6.75k
{
722
6.75k
    OSSL_CMP_MSG *msg = NULL;
723
6.75k
    const char *lib = NULL, *reason = NULL;
724
6.75k
    OSSL_CMP_PKIFREETEXT *ft;
725
726
6.75k
    if (!ossl_assert(ctx != NULL && si != NULL))
727
0
        return NULL;
728
729
6.75k
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_ERROR)) == NULL)
730
0
        goto err;
731
732
6.75k
    OSSL_CMP_PKISI_free(msg->body->value.error->pKIStatusInfo);
733
6.75k
    if ((msg->body->value.error->pKIStatusInfo = OSSL_CMP_PKISI_dup(si))
734
6.75k
        == NULL)
735
0
        goto err;
736
6.75k
    if ((msg->body->value.error->errorCode = ASN1_INTEGER_new()) == NULL)
737
0
        goto err;
738
6.75k
    if (!ASN1_INTEGER_set_int64(msg->body->value.error->errorCode, errorCode))
739
0
        goto err;
740
6.75k
    if (errorCode > 0
741
6.75k
            && (uint64_t)errorCode < ((uint64_t)ERR_SYSTEM_FLAG << 1)) {
742
6.75k
        lib = ERR_lib_error_string((unsigned long)errorCode);
743
6.75k
        reason = ERR_reason_error_string((unsigned long)errorCode);
744
6.75k
    }
745
6.75k
    if (lib != NULL || reason != NULL || details != NULL) {
746
6.75k
        if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL)
747
0
            goto err;
748
6.75k
        msg->body->value.error->errorDetails = ft;
749
6.75k
        if (lib != NULL && *lib != '\0'
750
6.75k
                && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, lib, -1))
751
0
            goto err;
752
6.75k
        if (reason != NULL && *reason != '\0'
753
6.75k
                && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, reason, -1))
754
0
            goto err;
755
6.75k
        if (details != NULL
756
6.75k
                && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details, -1))
757
0
            goto err;
758
6.75k
    }
759
760
6.75k
    if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
761
6.75k
        goto err;
762
0
    return msg;
763
764
6.75k
 err:
765
6.75k
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_ERROR);
766
6.75k
    OSSL_CMP_MSG_free(msg);
767
6.75k
    return NULL;
768
6.75k
}
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
152
{
856
152
    OSSL_CMP_MSG *msg = NULL;
857
152
    OSSL_CMP_POLLREQ *preq = NULL;
858
859
152
    if (!ossl_assert(ctx != NULL))
860
0
        return NULL;
861
862
152
    if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREQ)) == NULL)
863
0
        goto err;
864
865
152
    if ((preq = OSSL_CMP_POLLREQ_new()) == NULL
866
152
            || !ASN1_INTEGER_set(preq->certReqId, crid)
867
152
            || !sk_OSSL_CMP_POLLREQ_push(msg->body->value.pollReq, preq))
868
0
        goto err;
869
870
152
    preq = NULL;
871
152
    if (!ossl_cmp_msg_protect(ctx, msg))
872
152
        goto err;
873
874
0
    return msg;
875
876
152
 err:
877
152
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREQ);
878
152
    OSSL_CMP_POLLREQ_free(preq);
879
152
    OSSL_CMP_MSG_free(msg);
880
152
    return NULL;
881
152
}
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
13.5k
{
1159
13.5k
    return ASN1_item_i2d((const ASN1_VALUE *)msg, out,
1160
13.5k
                         ASN1_ITEM_rptr(OSSL_CMP_MSG));
1161
13.5k
}
1162
1163
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg)
1164
10.1k
{
1165
10.1k
    OSSL_LIB_CTX *libctx = NULL;
1166
10.1k
    const char *propq = NULL;
1167
1168
10.1k
    if (msg != NULL && *msg != NULL) {
1169
0
        libctx  = (*msg)->libctx;
1170
0
        propq = (*msg)->propq;
1171
0
    }
1172
1173
10.1k
    return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG), bio, msg, libctx,
1174
10.1k
                                propq);
1175
10.1k
}
1176
1177
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
1178
6.75k
{
1179
6.75k
    return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
1180
6.75k
}