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