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