xref: /openssl/crypto/cmp/cmp_msg.c (revision 577ec498)
1 /*
2  * Copyright 2007-2024 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 
OSSL_CMP_MSG_new(OSSL_LIB_CTX * libctx,const char * propq)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 
OSSL_CMP_MSG_free(OSSL_CMP_MSG * msg)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  */
ossl_cmp_msg_set0_libctx(OSSL_CMP_MSG * msg,OSSL_LIB_CTX * libctx,const char * propq)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 
OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG * msg)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 
ossl_cmp_bodytype_to_string(int type)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 
ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG * msg,int type)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 
OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG * msg)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 
OSSL_CMP_MSG_get0_certreq_publickey(const OSSL_CMP_MSG * msg)103 X509_PUBKEY *OSSL_CMP_MSG_get0_certreq_publickey(const OSSL_CMP_MSG *msg)
104 {
105     const OSSL_CRMF_MSGS *reqs;
106     const OSSL_CRMF_MSG *crm;
107     const OSSL_CRMF_CERTTEMPLATE *tmpl;
108     X509_PUBKEY *pubkey;
109 
110     switch (OSSL_CMP_MSG_get_bodytype(msg)) {
111     case OSSL_CMP_PKIBODY_IR:
112     case OSSL_CMP_PKIBODY_CR:
113     case OSSL_CMP_PKIBODY_KUR:
114         reqs = msg->body->value.ir; /* value.ir is same for cr and kur */
115         if ((crm = sk_OSSL_CRMF_MSG_value(reqs, 0)) == NULL) {
116             ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND);
117             return NULL;
118         }
119         if ((tmpl = OSSL_CRMF_MSG_get0_tmpl(crm)) == NULL
120             || (pubkey = OSSL_CRMF_CERTTEMPLATE_get0_publicKey(tmpl)) == NULL) {
121             ERR_raise(ERR_LIB_CMP, CRMF_R_POPO_MISSING_PUBLIC_KEY);
122             return NULL;
123         }
124         return pubkey;
125     default:
126         ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
127         return NULL;
128     }
129 }
130 
131 /* Add an extension to the referenced extension stack, which may be NULL */
add1_extension(X509_EXTENSIONS ** pexts,int nid,int crit,void * ex)132 static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex)
133 {
134     X509_EXTENSION *ext;
135     int res;
136 
137     if (!ossl_assert(pexts != NULL)) /* pointer to var must not be NULL */
138         return 0;
139 
140     if ((ext = X509V3_EXT_i2d(nid, crit, ex)) == NULL)
141         return 0;
142 
143     res = X509v3_add_ext(pexts, ext, 0) != NULL;
144     X509_EXTENSION_free(ext);
145     return res;
146 }
147 
148 /* Add a CRL revocation reason code to extension stack, which may be NULL */
add_crl_reason_extension(X509_EXTENSIONS ** pexts,int reason_code)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 
ossl_cmp_msg_create(OSSL_CMP_CTX * ctx,int bodytype)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 
determine_subj(OSSL_CMP_CTX * ctx,int for_KUR,const X509_NAME * ref_subj)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 
OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX * ctx,int for_KUR,int rid)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 (sk_X509_EXTENSION_num(ctx->reqExtensions) > 0 /* augment/override existing ones */
334             && X509v3_add_extensions(&exts, ctx->reqExtensions) == NULL)
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 
ossl_cmp_certreq_new(OSSL_CMP_CTX * ctx,int type,const OSSL_CRMF_MSG * crm)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 
ossl_cmp_certrep_new(OSSL_CMP_CTX * ctx,int bodytype,int certReqId,const OSSL_CMP_PKISI * si,X509 * cert,const X509 * encryption_recip,STACK_OF (X509)* chain,STACK_OF (X509)* caPubs,int unprotectedErrors)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 
ossl_cmp_rr_new(OSSL_CMP_CTX * ctx)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     } else {
546         goto err;
547     }
548 
549     /* Fill the template from the contents of the certificate to be revoked */
550     ret = OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, pubkey, subject,
551                                       issuer, serialNumber);
552     if (!ret)
553         goto err;
554 
555     /* revocation reason code is optional */
556     if (ctx->revocationReason != CRL_REASON_NONE
557             && !add_crl_reason_extension(&rd->crlEntryDetails,
558                                          ctx->revocationReason))
559         goto err;
560 
561     if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RR)) == NULL)
562         goto err;
563 
564     if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd))
565         goto err;
566     rd = NULL;
567     /* Revocation Passphrase according to section 5.3.19.9 could be set here */
568 
569     if (!ossl_cmp_msg_protect(ctx, msg))
570         goto err;
571 
572     return msg;
573 
574  err:
575     ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR);
576     OSSL_CMP_MSG_free(msg);
577     OSSL_CMP_REVDETAILS_free(rd);
578     return NULL;
579 }
580 
ossl_cmp_rp_new(OSSL_CMP_CTX * ctx,const OSSL_CMP_PKISI * si,const OSSL_CRMF_CERTID * cid,int unprotectedErrors)581 OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si,
582                               const OSSL_CRMF_CERTID *cid, int unprotectedErrors)
583 {
584     OSSL_CMP_REVREPCONTENT *rep = NULL;
585     OSSL_CMP_PKISI *si1 = NULL;
586     OSSL_CRMF_CERTID *cid_copy = NULL;
587     OSSL_CMP_MSG *msg = NULL;
588 
589     if (!ossl_assert(ctx != NULL && si != NULL))
590         return NULL;
591 
592     if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RP)) == NULL)
593         goto err;
594     rep = msg->body->value.rp;
595 
596     if ((si1 = OSSL_CMP_PKISI_dup(si)) == NULL)
597         goto err;
598 
599     if (!sk_OSSL_CMP_PKISI_push(rep->status, si1)) {
600         OSSL_CMP_PKISI_free(si1);
601         goto err;
602     }
603 
604     if ((rep->revCerts = sk_OSSL_CRMF_CERTID_new_null()) == NULL)
605         goto err;
606     if (cid != NULL) {
607         if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL)
608             goto err;
609         if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) {
610             OSSL_CRMF_CERTID_free(cid_copy);
611             goto err;
612         }
613     }
614 
615     if (!unprotectedErrors
616             || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
617         if (!ossl_cmp_msg_protect(ctx, msg))
618             goto err;
619 
620     return msg;
621 
622  err:
623     ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RP);
624     OSSL_CMP_MSG_free(msg);
625     return NULL;
626 }
627 
ossl_cmp_pkiconf_new(OSSL_CMP_CTX * ctx)628 OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx)
629 {
630     OSSL_CMP_MSG *msg;
631 
632     if (!ossl_assert(ctx != NULL))
633         return NULL;
634 
635     if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_PKICONF)) == NULL)
636         goto err;
637     if (ossl_cmp_msg_protect(ctx, msg))
638         return msg;
639 
640  err:
641     ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF);
642     OSSL_CMP_MSG_free(msg);
643     return NULL;
644 }
645 
ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG * msg,OSSL_CMP_ITAV * itav)646 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav)
647 {
648     int bodytype;
649 
650     if (!ossl_assert(msg != NULL && itav != NULL))
651         return 0;
652 
653     bodytype = OSSL_CMP_MSG_get_bodytype(msg);
654     if (bodytype != OSSL_CMP_PKIBODY_GENM
655             && bodytype != OSSL_CMP_PKIBODY_GENP) {
656         ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS);
657         return 0;
658     }
659 
660     /* value.genp has the same structure, so this works for genp as well */
661     return OSSL_CMP_ITAV_push0_stack_item(&msg->body->value.genm, itav);
662 }
663 
ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG * msg,const STACK_OF (OSSL_CMP_ITAV)* itavs)664 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
665                                  const STACK_OF(OSSL_CMP_ITAV) *itavs)
666 {
667     int i;
668     OSSL_CMP_ITAV *itav = NULL;
669 
670     if (!ossl_assert(msg != NULL))
671         return 0;
672 
673     for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
674         itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i));
675         if (itav == NULL
676                 || !ossl_cmp_msg_gen_push0_ITAV(msg, itav)) {
677             OSSL_CMP_ITAV_free(itav);
678             return 0;
679         }
680     }
681     return 1;
682 }
683 
684 /*
685  * Creates a new General Message/Response with a copy of the given itav stack
686  * returns a pointer to the PKIMessage on success, NULL on error
687  */
gen_new(OSSL_CMP_CTX * ctx,const STACK_OF (OSSL_CMP_ITAV)* itavs,int body_type,int err_code)688 static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx,
689                              const STACK_OF(OSSL_CMP_ITAV) *itavs,
690                              int body_type, int err_code)
691 {
692     OSSL_CMP_MSG *msg = NULL;
693 
694     if (!ossl_assert(ctx != NULL))
695         return NULL;
696 
697     if ((msg = ossl_cmp_msg_create(ctx, body_type)) == NULL)
698         return NULL;
699 
700     if (itavs != NULL && !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs))
701         goto err;
702 
703     if (!ossl_cmp_msg_protect(ctx, msg))
704         goto err;
705 
706     return msg;
707 
708  err:
709     ERR_raise(ERR_LIB_CMP, err_code);
710     OSSL_CMP_MSG_free(msg);
711     return NULL;
712 }
713 
ossl_cmp_genm_new(OSSL_CMP_CTX * ctx)714 OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
715 {
716     return gen_new(ctx, ctx->genm_ITAVs,
717                    OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
718 }
719 
ossl_cmp_genp_new(OSSL_CMP_CTX * ctx,const STACK_OF (OSSL_CMP_ITAV)* itavs)720 OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
721                                 const STACK_OF(OSSL_CMP_ITAV) *itavs)
722 {
723     return gen_new(ctx, itavs,
724                    OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
725 }
726 
ossl_cmp_error_new(OSSL_CMP_CTX * ctx,const OSSL_CMP_PKISI * si,int64_t errorCode,const char * details,int unprotected)727 OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si,
728                                  int64_t errorCode, const char *details,
729                                  int unprotected)
730 {
731     OSSL_CMP_MSG *msg = NULL;
732     const char *lib = NULL, *reason = NULL;
733     OSSL_CMP_PKIFREETEXT *ft;
734 
735     if (!ossl_assert(ctx != NULL && si != NULL))
736         return NULL;
737 
738     if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_ERROR)) == NULL)
739         goto err;
740 
741     OSSL_CMP_PKISI_free(msg->body->value.error->pKIStatusInfo);
742     if ((msg->body->value.error->pKIStatusInfo = OSSL_CMP_PKISI_dup(si))
743         == NULL)
744         goto err;
745     if ((msg->body->value.error->errorCode = ASN1_INTEGER_new()) == NULL)
746         goto err;
747     if (!ASN1_INTEGER_set_int64(msg->body->value.error->errorCode, errorCode))
748         goto err;
749     if (errorCode > 0
750             && (uint64_t)errorCode < ((uint64_t)ERR_SYSTEM_FLAG << 1)) {
751         lib = ERR_lib_error_string((unsigned long)errorCode);
752         reason = ERR_reason_error_string((unsigned long)errorCode);
753     }
754     if (lib != NULL || reason != NULL || details != NULL) {
755         if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL)
756             goto err;
757         msg->body->value.error->errorDetails = ft;
758         if (lib != NULL && *lib != '\0'
759                 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, lib, -1))
760             goto err;
761         if (reason != NULL && *reason != '\0'
762                 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, reason, -1))
763             goto err;
764         if (details != NULL
765                 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details, -1))
766             goto err;
767     }
768 
769     if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
770         goto err;
771     return msg;
772 
773  err:
774     ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_ERROR);
775     OSSL_CMP_MSG_free(msg);
776     return NULL;
777 }
778 
779 /*
780  * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
781  * This is used in the certConf message, for example,
782  * to confirm that the certificate was received successfully.
783  */
ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS * certStatus,ASN1_OCTET_STRING * hash)784 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
785                                       ASN1_OCTET_STRING *hash)
786 {
787     if (!ossl_assert(certStatus != NULL))
788         return 0;
789     ASN1_OCTET_STRING_free(certStatus->certHash);
790     certStatus->certHash = hash;
791     return 1;
792 }
793 
ossl_cmp_certConf_new(OSSL_CMP_CTX * ctx,int certReqId,int fail_info,const char * text)794 OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int certReqId,
795                                     int fail_info, const char *text)
796 {
797     OSSL_CMP_MSG *msg = NULL;
798     OSSL_CMP_CERTSTATUS *certStatus = NULL;
799     EVP_MD *md;
800     int is_fallback;
801     ASN1_OCTET_STRING *certHash = NULL;
802     OSSL_CMP_PKISI *sinfo;
803 
804     if (!ossl_assert(ctx != NULL && ctx->newCert != NULL
805                      && (certReqId == OSSL_CMP_CERTREQID
806                          || certReqId == OSSL_CMP_CERTREQID_NONE)))
807         return NULL;
808 
809     if ((unsigned)fail_info > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) {
810         ERR_raise(ERR_LIB_CMP, CMP_R_FAIL_INFO_OUT_OF_RANGE);
811         return NULL;
812     }
813 
814     if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_CERTCONF)) == NULL)
815         goto err;
816 
817     if ((certStatus = OSSL_CMP_CERTSTATUS_new()) == NULL)
818         goto err;
819     /* consume certStatus into msg right away so it gets deallocated with msg */
820     if (sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus) < 1) {
821         OSSL_CMP_CERTSTATUS_free(certStatus);
822         goto err;
823     }
824 
825     /* set the ID of the certReq */
826     if (!ASN1_INTEGER_set(certStatus->certReqId, certReqId))
827         goto err;
828 
829     certStatus->hashAlg = NULL;
830     /*
831      * The hash of the certificate, using the same hash algorithm
832      * as is used to create and verify the certificate signature.
833      * If not available, a fallback hash algorithm is used.
834      */
835     if ((certHash = X509_digest_sig(ctx->newCert, &md, &is_fallback)) == NULL)
836         goto err;
837     if (is_fallback) {
838         if (!ossl_cmp_hdr_set_pvno(msg->header, OSSL_CMP_PVNO_3))
839             goto err;
840         if ((certStatus->hashAlg = X509_ALGOR_new()) == NULL)
841             goto err;
842         X509_ALGOR_set_md(certStatus->hashAlg, md);
843     }
844     EVP_MD_free(md);
845 
846     if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash))
847         goto err;
848     certHash = NULL;
849     /*
850      * For any particular CertStatus, omission of the statusInfo field
851      * indicates ACCEPTANCE of the specified certificate.  Alternatively,
852      * explicit status details (with respect to acceptance or rejection) MAY
853      * be provided in the statusInfo field, perhaps for auditing purposes at
854      * the CA/RA.
855      */
856     sinfo = fail_info != 0 ?
857         OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
858         OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
859     if (sinfo == NULL)
860         goto err;
861     certStatus->statusInfo = sinfo;
862 
863     if (!ossl_cmp_msg_protect(ctx, msg))
864         goto err;
865 
866     return msg;
867 
868  err:
869     ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTCONF);
870     OSSL_CMP_MSG_free(msg);
871     ASN1_OCTET_STRING_free(certHash);
872     return NULL;
873 }
874 
ossl_cmp_pollReq_new(OSSL_CMP_CTX * ctx,int crid)875 OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid)
876 {
877     OSSL_CMP_MSG *msg = NULL;
878     OSSL_CMP_POLLREQ *preq = NULL;
879 
880     if (!ossl_assert(ctx != NULL))
881         return NULL;
882 
883     if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREQ)) == NULL)
884         goto err;
885 
886     if ((preq = OSSL_CMP_POLLREQ_new()) == NULL
887             || !ASN1_INTEGER_set(preq->certReqId, crid)
888             || !sk_OSSL_CMP_POLLREQ_push(msg->body->value.pollReq, preq))
889         goto err;
890 
891     preq = NULL;
892     if (!ossl_cmp_msg_protect(ctx, msg))
893         goto err;
894 
895     return msg;
896 
897  err:
898     ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREQ);
899     OSSL_CMP_POLLREQ_free(preq);
900     OSSL_CMP_MSG_free(msg);
901     return NULL;
902 }
903 
ossl_cmp_pollRep_new(OSSL_CMP_CTX * ctx,int crid,int64_t poll_after)904 OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
905                                    int64_t poll_after)
906 {
907     OSSL_CMP_MSG *msg;
908     OSSL_CMP_POLLREP *prep;
909 
910     if (!ossl_assert(ctx != NULL))
911         return NULL;
912 
913     if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREP)) == NULL)
914         goto err;
915     if ((prep = OSSL_CMP_POLLREP_new()) == NULL)
916         goto err;
917     if (!sk_OSSL_CMP_POLLREP_push(msg->body->value.pollRep, prep))
918         goto err;
919     if (!ASN1_INTEGER_set(prep->certReqId, crid))
920         goto err;
921     if (!ASN1_INTEGER_set_int64(prep->checkAfter, poll_after))
922         goto err;
923 
924     if (!ossl_cmp_msg_protect(ctx, msg))
925         goto err;
926     return msg;
927 
928  err:
929     ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP);
930     OSSL_CMP_MSG_free(msg);
931     return NULL;
932 }
933 
934 /*-
935  * returns the status field of the RevRepContent with the given
936  * request/sequence id inside a revocation response.
937  * RevRepContent has the revocation statuses in same order as they were sent in
938  * RevReqContent.
939  * returns NULL on error
940  */
941 OSSL_CMP_PKISI *
ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT * rrep,int rsid)942 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
943 {
944     OSSL_CMP_PKISI *status;
945 
946     if (!ossl_assert(rrep != NULL))
947         return NULL;
948 
949     if ((status = sk_OSSL_CMP_PKISI_value(rrep->status, rsid)) != NULL)
950         return status;
951 
952     ERR_raise(ERR_LIB_CMP, CMP_R_PKISTATUSINFO_NOT_FOUND);
953     return NULL;
954 }
955 
956 /*
957  * returns the CertId field in the revCerts part of the RevRepContent
958  * with the given request/sequence id inside a revocation response.
959  * RevRepContent has the CertIds in same order as they were sent in
960  * RevReqContent.
961  * returns NULL on error
962  */
963 OSSL_CRMF_CERTID *
ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT * rrep,int rsid)964 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
965 {
966     OSSL_CRMF_CERTID *cid = NULL;
967 
968     if (!ossl_assert(rrep != NULL))
969         return NULL;
970 
971     if ((cid = sk_OSSL_CRMF_CERTID_value(rrep->revCerts, rsid)) != NULL)
972         return cid;
973 
974     ERR_raise(ERR_LIB_CMP, CMP_R_CERTID_NOT_FOUND);
975     return NULL;
976 }
977 
suitable_rid(const ASN1_INTEGER * certReqId,int rid)978 static int suitable_rid(const ASN1_INTEGER *certReqId, int rid)
979 {
980     int trid;
981 
982     if (rid == OSSL_CMP_CERTREQID_NONE)
983         return 1;
984 
985     trid = ossl_cmp_asn1_get_int(certReqId);
986     if (trid <= OSSL_CMP_CERTREQID_INVALID) {
987         ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
988         return 0;
989     }
990     return rid == trid;
991 }
992 
993 /*
994  * returns a pointer to the PollResponse with the given CertReqId
995  * (or the first one in case -1) inside a PollRepContent
996  * returns NULL on error or if no suitable PollResponse available
997  */
998 OSSL_CMP_POLLREP *
ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT * prc,int rid)999 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc,
1000                                      int rid)
1001 {
1002     OSSL_CMP_POLLREP *pollRep = NULL;
1003     int i;
1004 
1005     if (!ossl_assert(prc != NULL))
1006         return NULL;
1007 
1008     for (i = 0; i < sk_OSSL_CMP_POLLREP_num(prc); i++) {
1009         pollRep = sk_OSSL_CMP_POLLREP_value(prc, i);
1010         if (suitable_rid(pollRep->certReqId, rid))
1011             return pollRep;
1012     }
1013 
1014     ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND,
1015                    "expected certReqId = %d", rid);
1016     return NULL;
1017 }
1018 
1019 /*
1020  * returns a pointer to the CertResponse with the given CertReqId
1021  * (or the first one in case -1) inside a CertRepMessage
1022  * returns NULL on error or if no suitable CertResponse available
1023  */
1024 OSSL_CMP_CERTRESPONSE *
ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE * crm,int rid)1025 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
1026                                           int rid)
1027 {
1028     OSSL_CMP_CERTRESPONSE *crep = NULL;
1029     int i;
1030 
1031     if (!ossl_assert(crm != NULL && crm->response != NULL))
1032         return NULL;
1033 
1034     for (i = 0; i < sk_OSSL_CMP_CERTRESPONSE_num(crm->response); i++) {
1035         crep = sk_OSSL_CMP_CERTRESPONSE_value(crm->response, i);
1036         if (suitable_rid(crep->certReqId, rid))
1037             return crep;
1038     }
1039 
1040     ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND,
1041                    "expected certReqId = %d", rid);
1042     return NULL;
1043 }
1044 
1045 /*-
1046  * Retrieve the newly enrolled certificate from the given certResponse crep.
1047  * Uses libctx and propq from ctx, in case of indirect POPO also private key.
1048  * Returns a pointer to a copy of the found certificate, or NULL if not found.
1049  */
ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX * ctx,const OSSL_CMP_CERTRESPONSE * crep)1050 X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx,
1051                                       const OSSL_CMP_CERTRESPONSE *crep)
1052 {
1053     OSSL_CMP_CERTORENCCERT *coec;
1054     X509 *crt = NULL;
1055     EVP_PKEY *pkey;
1056 
1057     if (!ossl_assert(crep != NULL && ctx != NULL))
1058         return NULL;
1059 
1060     if (crep->certifiedKeyPair
1061             && (coec = crep->certifiedKeyPair->certOrEncCert) != NULL) {
1062         switch (coec->type) {
1063         case OSSL_CMP_CERTORENCCERT_CERTIFICATE:
1064             crt = X509_dup(coec->value.certificate);
1065             break;
1066         case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT:
1067             /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
1068             pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
1069             /* pkey is ctx->newPkey (if private, else NULL) or ctx->pkey */
1070             if (pkey == NULL) {
1071                 ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY);
1072                 return NULL;
1073             }
1074             crt =
1075                 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert,
1076                                                       ctx->libctx, ctx->propq,
1077                                                       pkey);
1078             break;
1079         default:
1080             ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CERT_TYPE);
1081             return NULL;
1082         }
1083     }
1084     if (crt == NULL)
1085         ERR_raise(ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND);
1086     else
1087         (void)ossl_x509_set0_libctx(crt, ctx->libctx, ctx->propq);
1088     return crt;
1089 }
1090 
OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX * ctx,OSSL_CMP_MSG * msg)1091 int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
1092 {
1093     if (ctx == NULL || msg == NULL) {
1094         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1095         return 0;
1096     }
1097     if (!ossl_cmp_hdr_set_transactionID(ctx, msg->header))
1098         return 0;
1099     return msg->header->protectionAlg == NULL
1100             || ossl_cmp_msg_protect(ctx, msg);
1101 }
1102 
OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX * ctx,OSSL_CMP_MSG * msg)1103 int OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
1104 {
1105     if (ctx == NULL || msg == NULL || msg->header == NULL) {
1106         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1107         return 0;
1108     }
1109     if (ctx->recipNonce == NULL) /* nothing to do for 1st msg in transaction */
1110         return 1;
1111     if (!ossl_cmp_asn1_octet_string_set1(&msg->header->recipNonce,
1112                                          ctx->recipNonce))
1113         return 0;
1114     return msg->header->protectionAlg == NULL || ossl_cmp_msg_protect(ctx, msg);
1115 }
1116 
OSSL_CMP_MSG_read(const char * file,OSSL_LIB_CTX * libctx,const char * propq)1117 OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx,
1118                                 const char *propq)
1119 {
1120     OSSL_CMP_MSG *msg;
1121     BIO *bio = NULL;
1122 
1123     if (file == NULL) {
1124         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1125         return NULL;
1126     }
1127 
1128     msg = OSSL_CMP_MSG_new(libctx, propq);
1129     if (msg == NULL) {
1130         ERR_raise(ERR_LIB_CMP, ERR_R_CMP_LIB);
1131         return NULL;
1132     }
1133 
1134     if ((bio = BIO_new_file(file, "rb")) == NULL
1135             || d2i_OSSL_CMP_MSG_bio(bio, &msg) == NULL) {
1136         OSSL_CMP_MSG_free(msg);
1137         msg = NULL;
1138     }
1139     BIO_free(bio);
1140     return msg;
1141 }
1142 
OSSL_CMP_MSG_write(const char * file,const OSSL_CMP_MSG * msg)1143 int OSSL_CMP_MSG_write(const char *file, const OSSL_CMP_MSG *msg)
1144 {
1145     BIO *bio;
1146     int res;
1147 
1148     if (file == NULL || msg == NULL) {
1149         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1150         return -1;
1151     }
1152 
1153     bio = BIO_new_file(file, "wb");
1154     if (bio == NULL)
1155         return -2;
1156     res = i2d_OSSL_CMP_MSG_bio(bio, msg);
1157     BIO_free(bio);
1158     return res;
1159 }
1160 
d2i_OSSL_CMP_MSG(OSSL_CMP_MSG ** msg,const unsigned char ** in,long len)1161 OSSL_CMP_MSG *d2i_OSSL_CMP_MSG(OSSL_CMP_MSG **msg, const unsigned char **in,
1162                                long len)
1163 {
1164     OSSL_LIB_CTX *libctx = NULL;
1165     const char *propq = NULL;
1166 
1167     if (msg != NULL && *msg != NULL) {
1168         libctx  = (*msg)->libctx;
1169         propq = (*msg)->propq;
1170     }
1171 
1172     return (OSSL_CMP_MSG *)ASN1_item_d2i_ex((ASN1_VALUE **)msg, in, len,
1173                                             ASN1_ITEM_rptr(OSSL_CMP_MSG),
1174                                             libctx, propq);
1175 }
1176 
i2d_OSSL_CMP_MSG(const OSSL_CMP_MSG * msg,unsigned char ** out)1177 int i2d_OSSL_CMP_MSG(const OSSL_CMP_MSG *msg, unsigned char **out)
1178 {
1179     return ASN1_item_i2d((const ASN1_VALUE *)msg, out,
1180                          ASN1_ITEM_rptr(OSSL_CMP_MSG));
1181 }
1182 
d2i_OSSL_CMP_MSG_bio(BIO * bio,OSSL_CMP_MSG ** msg)1183 OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg)
1184 {
1185     OSSL_LIB_CTX *libctx = NULL;
1186     const char *propq = NULL;
1187 
1188     if (msg != NULL && *msg != NULL) {
1189         libctx  = (*msg)->libctx;
1190         propq = (*msg)->propq;
1191     }
1192 
1193     return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG), bio, msg, libctx,
1194                                 propq);
1195 }
1196 
i2d_OSSL_CMP_MSG_bio(BIO * bio,const OSSL_CMP_MSG * msg)1197 int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
1198 {
1199     return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
1200 }
1201 
ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG * msg)1202 int ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG *msg)
1203 {
1204     if (!ossl_assert(msg != NULL))
1205         return 0;
1206 
1207     return (OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_ERROR
1208             && ossl_cmp_pkisi_get_status(msg->body->value.error->pKIStatusInfo)
1209             == OSSL_CMP_PKISTATUS_waiting);
1210 }
1211