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