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