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