2 * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright Nokia 2007-2019
4 * Copyright Siemens AG 2015-2019
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
12 /* CMP functions for PKIMessage construction */
14 #include "cmp_local.h"
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>
23 OSSL_CMP_MSG
*OSSL_CMP_MSG_new(OSSL_LIB_CTX
*libctx
, const char *propq
)
25 OSSL_CMP_MSG
*msg
= NULL
;
27 msg
= (OSSL_CMP_MSG
*)ASN1_item_new_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG
),
29 if (!ossl_cmp_msg_set0_libctx(msg
, libctx
, propq
)) {
30 OSSL_CMP_MSG_free(msg
);
36 void OSSL_CMP_MSG_free(OSSL_CMP_MSG
*msg
)
38 ASN1_item_free((ASN1_VALUE
*)msg
, ASN1_ITEM_rptr(OSSL_CMP_MSG
));
42 * This should only be used if the X509 object was embedded inside another
43 * asn1 object and it needs a libctx to operate.
44 * Use OSSL_CMP_MSG_new() instead if possible.
46 int ossl_cmp_msg_set0_libctx(OSSL_CMP_MSG
*msg
, OSSL_LIB_CTX
*libctx
,
51 OPENSSL_free(msg
->propq
);
54 msg
->propq
= OPENSSL_strdup(propq
);
55 if (msg
->propq
== NULL
)
62 OSSL_CMP_PKIHEADER
*OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG
*msg
)
65 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
71 const char *ossl_cmp_bodytype_to_string(int type
)
73 static const char *type_names
[] = {
74 "IR", "IP", "CR", "CP", "P10CR",
75 "POPDECC", "POPDECR", "KUR", "KUP",
76 "KRR", "KRP", "RR", "RP", "CCR", "CCP",
77 "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
78 "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
81 if (type
< 0 || type
> OSSL_CMP_PKIBODY_TYPE_MAX
)
82 return "illegal body type";
83 return type_names
[type
];
86 int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG
*msg
, int type
)
88 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
91 msg
->body
->type
= type
;
95 int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG
*msg
)
97 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
100 return msg
->body
->type
;
103 X509_PUBKEY
*OSSL_CMP_MSG_get0_certreq_publickey(const OSSL_CMP_MSG
*msg
)
105 const OSSL_CRMF_MSGS
*reqs
;
106 const OSSL_CRMF_MSG
*crm
;
107 const OSSL_CRMF_CERTTEMPLATE
*tmpl
;
110 switch (OSSL_CMP_MSG_get_bodytype(msg
)) {
111 case OSSL_CMP_PKIBODY_IR
:
112 case OSSL_CMP_PKIBODY_CR
:
113 case OSSL_CMP_PKIBODY_KUR
:
114 reqs
= msg
->body
->value
.ir
; /* value.ir is same for cr and kur */
115 if ((crm
= sk_OSSL_CRMF_MSG_value(reqs
, 0)) == NULL
) {
116 ERR_raise(ERR_LIB_CMP
, CMP_R_CERTREQMSG_NOT_FOUND
);
119 if ((tmpl
= OSSL_CRMF_MSG_get0_tmpl(crm
)) == NULL
120 || (pubkey
= OSSL_CRMF_CERTTEMPLATE_get0_publicKey(tmpl
)) == NULL
) {
121 ERR_raise(ERR_LIB_CMP
, CRMF_R_POPO_MISSING_PUBLIC_KEY
);
126 ERR_raise(ERR_LIB_CMP
, CMP_R_UNEXPECTED_PKIBODY
);
131 /* Add an extension to the referenced extension stack, which may be NULL */
132 static int add1_extension(X509_EXTENSIONS
**pexts
, int nid
, int crit
, void *ex
)
137 if (!ossl_assert(pexts
!= NULL
)) /* pointer to var must not be NULL */
140 if ((ext
= X509V3_EXT_i2d(nid
, crit
, ex
)) == NULL
)
143 res
= X509v3_add_ext(pexts
, ext
, 0) != NULL
;
144 X509_EXTENSION_free(ext
);
148 /* Add extension list to the referenced extension stack, which may be NULL */
149 static int add_extensions(STACK_OF(X509_EXTENSION
) **target
,
150 const STACK_OF(X509_EXTENSION
) *exts
)
157 for (i
= 0; i
< sk_X509_EXTENSION_num(exts
); i
++) {
158 X509_EXTENSION
*ext
= sk_X509_EXTENSION_value(exts
, i
);
159 ASN1_OBJECT
*obj
= X509_EXTENSION_get_object(ext
);
160 int idx
= X509v3_get_ext_by_OBJ(*target
, obj
, -1);
162 /* Does extension exist in target? */
164 /* Delete all extensions of same type */
166 X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target
, idx
));
167 idx
= X509v3_get_ext_by_OBJ(*target
, obj
, -1);
170 if (!X509v3_add_ext(target
, ext
, -1))
176 /* Add a CRL revocation reason code to extension stack, which may be NULL */
177 static int add_crl_reason_extension(X509_EXTENSIONS
**pexts
, int reason_code
)
179 ASN1_ENUMERATED
*val
= ASN1_ENUMERATED_new();
182 if (val
!= NULL
&& ASN1_ENUMERATED_set(val
, reason_code
))
183 res
= add1_extension(pexts
, NID_crl_reason
, 0 /* non-critical */, val
);
184 ASN1_ENUMERATED_free(val
);
188 OSSL_CMP_MSG
*ossl_cmp_msg_create(OSSL_CMP_CTX
*ctx
, int bodytype
)
190 OSSL_CMP_MSG
*msg
= NULL
;
192 if (!ossl_assert(ctx
!= NULL
))
195 if ((msg
= OSSL_CMP_MSG_new(ctx
->libctx
, ctx
->propq
)) == NULL
)
197 if (!ossl_cmp_hdr_init(ctx
, msg
->header
)
198 || !ossl_cmp_msg_set_bodytype(msg
, bodytype
))
200 if (ctx
->geninfo_ITAVs
!= NULL
201 && !ossl_cmp_hdr_generalInfo_push1_items(msg
->header
,
206 case OSSL_CMP_PKIBODY_IR
:
207 case OSSL_CMP_PKIBODY_CR
:
208 case OSSL_CMP_PKIBODY_KUR
:
209 if ((msg
->body
->value
.ir
= OSSL_CRMF_MSGS_new()) == NULL
)
213 case OSSL_CMP_PKIBODY_P10CR
:
214 if (ctx
->p10CSR
== NULL
) {
215 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_P10CSR
);
218 if ((msg
->body
->value
.p10cr
= X509_REQ_dup(ctx
->p10CSR
)) == NULL
)
222 case OSSL_CMP_PKIBODY_IP
:
223 case OSSL_CMP_PKIBODY_CP
:
224 case OSSL_CMP_PKIBODY_KUP
:
225 if ((msg
->body
->value
.ip
= OSSL_CMP_CERTREPMESSAGE_new()) == NULL
)
229 case OSSL_CMP_PKIBODY_RR
:
230 if ((msg
->body
->value
.rr
= sk_OSSL_CMP_REVDETAILS_new_null()) == NULL
)
233 case OSSL_CMP_PKIBODY_RP
:
234 if ((msg
->body
->value
.rp
= OSSL_CMP_REVREPCONTENT_new()) == NULL
)
238 case OSSL_CMP_PKIBODY_CERTCONF
:
239 if ((msg
->body
->value
.certConf
=
240 sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL
)
243 case OSSL_CMP_PKIBODY_PKICONF
:
244 if ((msg
->body
->value
.pkiconf
= ASN1_TYPE_new()) == NULL
)
246 ASN1_TYPE_set(msg
->body
->value
.pkiconf
, V_ASN1_NULL
, NULL
);
249 case OSSL_CMP_PKIBODY_POLLREQ
:
250 if ((msg
->body
->value
.pollReq
= sk_OSSL_CMP_POLLREQ_new_null()) == NULL
)
253 case OSSL_CMP_PKIBODY_POLLREP
:
254 if ((msg
->body
->value
.pollRep
= sk_OSSL_CMP_POLLREP_new_null()) == NULL
)
258 case OSSL_CMP_PKIBODY_GENM
:
259 case OSSL_CMP_PKIBODY_GENP
:
260 if ((msg
->body
->value
.genm
= sk_OSSL_CMP_ITAV_new_null()) == NULL
)
264 case OSSL_CMP_PKIBODY_ERROR
:
265 if ((msg
->body
->value
.error
= OSSL_CMP_ERRORMSGCONTENT_new()) == NULL
)
270 ERR_raise(ERR_LIB_CMP
, CMP_R_UNEXPECTED_PKIBODY
);
275 OSSL_CMP_MSG_free(msg
);
279 #define HAS_SAN(ctx) \
280 (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
281 || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
283 static const X509_NAME
*determine_subj(OSSL_CMP_CTX
*ctx
, int for_KUR
,
284 const X509_NAME
*ref_subj
)
286 if (ctx
->subjectName
!= NULL
)
287 return IS_NULL_DN(ctx
->subjectName
) ? NULL
: ctx
->subjectName
;
288 if (ctx
->p10CSR
!= NULL
) /* first default is from any given CSR */
289 return X509_REQ_get_subject_name(ctx
->p10CSR
);
290 if (for_KUR
|| !HAS_SAN(ctx
))
292 * For KUR, copy subject from any reference cert as fallback.
293 * For IR or CR, do the same only if there is no subjectAltName.
299 OSSL_CRMF_MSG
*OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX
*ctx
, int for_KUR
, int rid
)
301 OSSL_CRMF_MSG
*crm
= NULL
;
302 X509
*refcert
= ctx
->oldCert
!= NULL
? ctx
->oldCert
: ctx
->cert
;
303 /* refcert defaults to current client cert */
304 EVP_PKEY
*rkey
= ossl_cmp_ctx_get0_newPubkey(ctx
);
305 STACK_OF(GENERAL_NAME
) *default_sans
= NULL
;
306 const X509_NAME
*ref_subj
=
307 refcert
!= NULL
? X509_get_subject_name(refcert
) : NULL
;
308 const X509_NAME
*subject
= determine_subj(ctx
, for_KUR
, ref_subj
);
309 const X509_NAME
*issuer
= ctx
->issuer
!= NULL
|| refcert
== NULL
310 ? (IS_NULL_DN(ctx
->issuer
) ? NULL
: ctx
->issuer
)
311 : X509_get_issuer_name(refcert
);
312 int crit
= ctx
->setSubjectAltNameCritical
|| subject
== NULL
;
313 /* RFC5280: subjectAltName MUST be critical if subject is null */
314 X509_EXTENSIONS
*exts
= NULL
;
317 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
318 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_PUBLIC_KEY
);
322 if (for_KUR
&& refcert
== NULL
&& ctx
->p10CSR
== NULL
) {
323 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_REFERENCE_CERT
);
326 if ((crm
= OSSL_CRMF_MSG_new()) == NULL
)
328 if (!OSSL_CRMF_MSG_set_certReqId(crm
, rid
)
330 * fill certTemplate, corresponding to CertificationRequestInfo
331 * of PKCS#10. The rkey param cannot be NULL so far -
332 * it could be NULL if centralized key creation was supported
334 || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm
), rkey
,
335 subject
, issuer
, NULL
/* serial */))
337 if (ctx
->days
!= 0) {
338 time_t now
= time(NULL
);
339 ASN1_TIME
*notBefore
= ASN1_TIME_adj(NULL
, now
, 0, 0);
340 ASN1_TIME
*notAfter
= ASN1_TIME_adj(NULL
, now
, ctx
->days
, 0);
342 if (notBefore
== NULL
344 || !OSSL_CRMF_MSG_set0_validity(crm
, notBefore
, notAfter
)) {
345 ASN1_TIME_free(notBefore
);
346 ASN1_TIME_free(notAfter
);
352 if (ctx
->p10CSR
!= NULL
353 && (exts
= X509_REQ_get_extensions(ctx
->p10CSR
)) == NULL
)
355 if (!ctx
->SubjectAltName_nodefault
&& !HAS_SAN(ctx
) && refcert
!= NULL
356 && (default_sans
= X509V3_get_d2i(X509_get0_extensions(refcert
),
357 NID_subject_alt_name
, NULL
, NULL
))
359 && !add1_extension(&exts
, NID_subject_alt_name
, crit
, default_sans
))
361 if (ctx
->reqExtensions
!= NULL
/* augment/override existing ones */
362 && !add_extensions(&exts
, ctx
->reqExtensions
))
364 if (sk_GENERAL_NAME_num(ctx
->subjectAltNames
) > 0
365 && !add1_extension(&exts
, NID_subject_alt_name
,
366 crit
, ctx
->subjectAltNames
))
368 if (ctx
->policies
!= NULL
369 && !add1_extension(&exts
, NID_certificate_policies
,
370 ctx
->setPoliciesCritical
, ctx
->policies
))
372 if (!OSSL_CRMF_MSG_set0_extensions(crm
, exts
))
375 /* end fill certTemplate, now set any controls */
377 /* for KUR, set OldCertId according to D.6 */
378 if (for_KUR
&& refcert
!= NULL
) {
379 OSSL_CRMF_CERTID
*cid
=
380 OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert
),
381 X509_get0_serialNumber(refcert
));
386 ret
= OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm
, cid
);
387 OSSL_CRMF_CERTID_free(cid
);
395 OSSL_CRMF_MSG_free(crm
);
399 sk_X509_EXTENSION_pop_free(exts
, X509_EXTENSION_free
);
400 sk_GENERAL_NAME_pop_free(default_sans
, GENERAL_NAME_free
);
404 OSSL_CMP_MSG
*ossl_cmp_certreq_new(OSSL_CMP_CTX
*ctx
, int type
,
405 const OSSL_CRMF_MSG
*crm
)
408 OSSL_CRMF_MSG
*local_crm
= NULL
;
410 if (!ossl_assert(ctx
!= NULL
))
413 if (type
!= OSSL_CMP_PKIBODY_IR
&& type
!= OSSL_CMP_PKIBODY_CR
414 && type
!= OSSL_CMP_PKIBODY_KUR
&& type
!= OSSL_CMP_PKIBODY_P10CR
) {
415 ERR_raise(ERR_LIB_CMP
, CMP_R_INVALID_ARGS
);
418 if (type
== OSSL_CMP_PKIBODY_P10CR
&& crm
!= NULL
) {
419 ERR_raise(ERR_LIB_CMP
, CMP_R_INVALID_ARGS
);
423 if ((msg
= ossl_cmp_msg_create(ctx
, type
)) == NULL
)
427 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
431 /* For P10CR the content has already been set in OSSL_CMP_MSG_create */
432 if (type
!= OSSL_CMP_PKIBODY_P10CR
) {
433 EVP_PKEY
*privkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 1);
435 /* privkey is ctx->newPkey (if private, else NULL) or ctx->pkey */
436 if (ctx
->popoMethod
>= OSSL_CRMF_POPO_SIGNATURE
&& privkey
== NULL
) {
437 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO
);
441 local_crm
= OSSL_CMP_CTX_setup_CRM(ctx
,
442 type
== OSSL_CMP_PKIBODY_KUR
,
444 if (local_crm
== NULL
445 || !OSSL_CRMF_MSG_create_popo(ctx
->popoMethod
, local_crm
,
446 privkey
, ctx
->digest
,
447 ctx
->libctx
, ctx
->propq
))
450 if ((local_crm
= OSSL_CRMF_MSG_dup(crm
)) == NULL
)
454 /* value.ir is same for cr and kur */
455 if (!sk_OSSL_CRMF_MSG_push(msg
->body
->value
.ir
, local_crm
))
460 if (!ossl_cmp_msg_protect(ctx
, msg
))
466 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_CERTREQ
);
467 OSSL_CRMF_MSG_free(local_crm
);
468 OSSL_CMP_MSG_free(msg
);
472 OSSL_CMP_MSG
*ossl_cmp_certrep_new(OSSL_CMP_CTX
*ctx
, int bodytype
,
473 int certReqId
, const OSSL_CMP_PKISI
*si
,
474 X509
*cert
, const X509
*encryption_recip
,
475 STACK_OF(X509
) *chain
, STACK_OF(X509
) *caPubs
,
476 int unprotectedErrors
)
478 OSSL_CMP_MSG
*msg
= NULL
;
479 OSSL_CMP_CERTREPMESSAGE
*repMsg
= NULL
;
480 OSSL_CMP_CERTRESPONSE
*resp
= NULL
;
481 int status
= OSSL_CMP_PKISTATUS_unspecified
;
483 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
486 if ((msg
= ossl_cmp_msg_create(ctx
, bodytype
)) == NULL
)
488 repMsg
= msg
->body
->value
.ip
; /* value.ip is same for cp and kup */
491 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
495 if ((resp
= OSSL_CMP_CERTRESPONSE_new()) == NULL
)
497 OSSL_CMP_PKISI_free(resp
->status
);
498 if ((resp
->status
= OSSL_CMP_PKISI_dup(si
)) == NULL
499 || !ASN1_INTEGER_set(resp
->certReqId
, certReqId
))
502 status
= ossl_cmp_pkisi_get_status(resp
->status
);
503 if (status
!= OSSL_CMP_PKISTATUS_rejection
504 && status
!= OSSL_CMP_PKISTATUS_waiting
&& cert
!= NULL
) {
505 if (encryption_recip
!= NULL
) {
506 ERR_raise(ERR_LIB_CMP
, ERR_R_UNSUPPORTED
);
510 if ((resp
->certifiedKeyPair
= OSSL_CMP_CERTIFIEDKEYPAIR_new())
513 resp
->certifiedKeyPair
->certOrEncCert
->type
=
514 OSSL_CMP_CERTORENCCERT_CERTIFICATE
;
515 if (!X509_up_ref(cert
))
517 resp
->certifiedKeyPair
->certOrEncCert
->value
.certificate
= cert
;
520 if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg
->response
, resp
))
524 if (bodytype
== OSSL_CMP_PKIBODY_IP
&& caPubs
!= NULL
525 && (repMsg
->caPubs
= X509_chain_up_ref(caPubs
)) == NULL
)
527 if (sk_X509_num(chain
) > 0
528 && !ossl_x509_add_certs_new(&msg
->extraCerts
, chain
,
529 X509_ADD_FLAG_UP_REF
| X509_ADD_FLAG_NO_DUP
))
532 if (!unprotectedErrors
533 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
534 if (!ossl_cmp_msg_protect(ctx
, msg
))
540 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_CERTREP
);
541 OSSL_CMP_CERTRESPONSE_free(resp
);
542 OSSL_CMP_MSG_free(msg
);
546 OSSL_CMP_MSG
*ossl_cmp_rr_new(OSSL_CMP_CTX
*ctx
)
548 OSSL_CMP_MSG
*msg
= NULL
;
549 const X509_NAME
*issuer
= NULL
;
550 const X509_NAME
*subject
= NULL
;
551 const ASN1_INTEGER
*serialNumber
= NULL
;
552 EVP_PKEY
*pubkey
= NULL
;
553 OSSL_CMP_REVDETAILS
*rd
;
556 if (!ossl_assert(ctx
!= NULL
557 && (ctx
->oldCert
!= NULL
|| ctx
->p10CSR
!= NULL
558 || (ctx
->serialNumber
!= NULL
&& ctx
->issuer
!= NULL
))))
561 if ((rd
= OSSL_CMP_REVDETAILS_new()) == NULL
)
564 if (ctx
->serialNumber
!= NULL
&& ctx
->issuer
!= NULL
) {
565 issuer
= ctx
->issuer
;
566 serialNumber
= ctx
->serialNumber
;
567 } else if (ctx
->oldCert
!= NULL
) {
568 issuer
= X509_get_issuer_name(ctx
->oldCert
);
569 serialNumber
= X509_get0_serialNumber(ctx
->oldCert
);
570 } else if (ctx
->p10CSR
!= NULL
) {
571 pubkey
= X509_REQ_get0_pubkey(ctx
->p10CSR
);
572 subject
= X509_REQ_get_subject_name(ctx
->p10CSR
);
577 /* Fill the template from the contents of the certificate to be revoked */
578 ret
= OSSL_CRMF_CERTTEMPLATE_fill(rd
->certDetails
, pubkey
, subject
,
579 issuer
, serialNumber
);
583 /* revocation reason code is optional */
584 if (ctx
->revocationReason
!= CRL_REASON_NONE
585 && !add_crl_reason_extension(&rd
->crlEntryDetails
,
586 ctx
->revocationReason
))
589 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RR
)) == NULL
)
592 if (!sk_OSSL_CMP_REVDETAILS_push(msg
->body
->value
.rr
, rd
))
595 /* Revocation Passphrase according to section 5.3.19.9 could be set here */
597 if (!ossl_cmp_msg_protect(ctx
, msg
))
603 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_RR
);
604 OSSL_CMP_MSG_free(msg
);
605 OSSL_CMP_REVDETAILS_free(rd
);
609 OSSL_CMP_MSG
*ossl_cmp_rp_new(OSSL_CMP_CTX
*ctx
, const OSSL_CMP_PKISI
*si
,
610 const OSSL_CRMF_CERTID
*cid
, int unprotectedErrors
)
612 OSSL_CMP_REVREPCONTENT
*rep
= NULL
;
613 OSSL_CMP_PKISI
*si1
= NULL
;
614 OSSL_CRMF_CERTID
*cid_copy
= NULL
;
615 OSSL_CMP_MSG
*msg
= NULL
;
617 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
620 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RP
)) == NULL
)
622 rep
= msg
->body
->value
.rp
;
624 if ((si1
= OSSL_CMP_PKISI_dup(si
)) == NULL
)
627 if (!sk_OSSL_CMP_PKISI_push(rep
->status
, si1
)) {
628 OSSL_CMP_PKISI_free(si1
);
632 if ((rep
->revCerts
= sk_OSSL_CRMF_CERTID_new_null()) == NULL
)
635 if ((cid_copy
= OSSL_CRMF_CERTID_dup(cid
)) == NULL
)
637 if (!sk_OSSL_CRMF_CERTID_push(rep
->revCerts
, cid_copy
)) {
638 OSSL_CRMF_CERTID_free(cid_copy
);
643 if (!unprotectedErrors
644 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
645 if (!ossl_cmp_msg_protect(ctx
, msg
))
651 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_RP
);
652 OSSL_CMP_MSG_free(msg
);
656 OSSL_CMP_MSG
*ossl_cmp_pkiconf_new(OSSL_CMP_CTX
*ctx
)
660 if (!ossl_assert(ctx
!= NULL
))
663 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_PKICONF
)) == NULL
)
665 if (ossl_cmp_msg_protect(ctx
, msg
))
669 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_PKICONF
);
670 OSSL_CMP_MSG_free(msg
);
674 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG
*msg
, OSSL_CMP_ITAV
*itav
)
678 if (!ossl_assert(msg
!= NULL
&& itav
!= NULL
))
681 bodytype
= OSSL_CMP_MSG_get_bodytype(msg
);
682 if (bodytype
!= OSSL_CMP_PKIBODY_GENM
683 && bodytype
!= OSSL_CMP_PKIBODY_GENP
) {
684 ERR_raise(ERR_LIB_CMP
, CMP_R_INVALID_ARGS
);
688 /* value.genp has the same structure, so this works for genp as well */
689 return OSSL_CMP_ITAV_push0_stack_item(&msg
->body
->value
.genm
, itav
);
692 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG
*msg
,
693 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
696 OSSL_CMP_ITAV
*itav
= NULL
;
698 if (!ossl_assert(msg
!= NULL
))
701 for (i
= 0; i
< sk_OSSL_CMP_ITAV_num(itavs
); i
++) {
702 itav
= OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs
, i
));
704 || !ossl_cmp_msg_gen_push0_ITAV(msg
, itav
)) {
705 OSSL_CMP_ITAV_free(itav
);
713 * Creates a new General Message/Response with a copy of the given itav stack
714 * returns a pointer to the PKIMessage on success, NULL on error
716 static OSSL_CMP_MSG
*gen_new(OSSL_CMP_CTX
*ctx
,
717 const STACK_OF(OSSL_CMP_ITAV
) *itavs
,
718 int body_type
, int err_code
)
720 OSSL_CMP_MSG
*msg
= NULL
;
722 if (!ossl_assert(ctx
!= NULL
))
725 if ((msg
= ossl_cmp_msg_create(ctx
, body_type
)) == NULL
)
728 if (itavs
!= NULL
&& !ossl_cmp_msg_gen_push1_ITAVs(msg
, itavs
))
731 if (!ossl_cmp_msg_protect(ctx
, msg
))
737 ERR_raise(ERR_LIB_CMP
, err_code
);
738 OSSL_CMP_MSG_free(msg
);
742 OSSL_CMP_MSG
*ossl_cmp_genm_new(OSSL_CMP_CTX
*ctx
)
744 return gen_new(ctx
, ctx
->genm_ITAVs
,
745 OSSL_CMP_PKIBODY_GENM
, CMP_R_ERROR_CREATING_GENM
);
748 OSSL_CMP_MSG
*ossl_cmp_genp_new(OSSL_CMP_CTX
*ctx
,
749 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
751 return gen_new(ctx
, itavs
,
752 OSSL_CMP_PKIBODY_GENP
, CMP_R_ERROR_CREATING_GENP
);
755 OSSL_CMP_MSG
*ossl_cmp_error_new(OSSL_CMP_CTX
*ctx
, const OSSL_CMP_PKISI
*si
,
756 int64_t errorCode
, const char *details
,
759 OSSL_CMP_MSG
*msg
= NULL
;
760 const char *lib
= NULL
, *reason
= NULL
;
761 OSSL_CMP_PKIFREETEXT
*ft
;
763 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
766 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_ERROR
)) == NULL
)
769 OSSL_CMP_PKISI_free(msg
->body
->value
.error
->pKIStatusInfo
);
770 if ((msg
->body
->value
.error
->pKIStatusInfo
= OSSL_CMP_PKISI_dup(si
))
773 if ((msg
->body
->value
.error
->errorCode
= ASN1_INTEGER_new()) == NULL
)
775 if (!ASN1_INTEGER_set_int64(msg
->body
->value
.error
->errorCode
, errorCode
))
778 && (uint64_t)errorCode
< ((uint64_t)ERR_SYSTEM_FLAG
<< 1)) {
779 lib
= ERR_lib_error_string((unsigned long)errorCode
);
780 reason
= ERR_reason_error_string((unsigned long)errorCode
);
782 if (lib
!= NULL
|| reason
!= NULL
|| details
!= NULL
) {
783 if ((ft
= sk_ASN1_UTF8STRING_new_null()) == NULL
)
785 msg
->body
->value
.error
->errorDetails
= ft
;
786 if (lib
!= NULL
&& *lib
!= '\0'
787 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, lib
, -1))
789 if (reason
!= NULL
&& *reason
!= '\0'
790 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, reason
, -1))
793 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, details
, -1))
797 if (!unprotected
&& !ossl_cmp_msg_protect(ctx
, msg
))
802 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_ERROR
);
803 OSSL_CMP_MSG_free(msg
);
808 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
809 * This is used in the certConf message, for example,
810 * to confirm that the certificate was received successfully.
812 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS
*certStatus
,
813 ASN1_OCTET_STRING
*hash
)
815 if (!ossl_assert(certStatus
!= NULL
))
817 ASN1_OCTET_STRING_free(certStatus
->certHash
);
818 certStatus
->certHash
= hash
;
822 OSSL_CMP_MSG
*ossl_cmp_certConf_new(OSSL_CMP_CTX
*ctx
, int certReqId
,
823 int fail_info
, const char *text
)
825 OSSL_CMP_MSG
*msg
= NULL
;
826 OSSL_CMP_CERTSTATUS
*certStatus
= NULL
;
829 ASN1_OCTET_STRING
*certHash
= NULL
;
830 OSSL_CMP_PKISI
*sinfo
;
832 if (!ossl_assert(ctx
!= NULL
&& ctx
->newCert
!= NULL
833 && (certReqId
== OSSL_CMP_CERTREQID
834 || certReqId
== OSSL_CMP_CERTREQID_NONE
)))
837 if ((unsigned)fail_info
> OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN
) {
838 ERR_raise(ERR_LIB_CMP
, CMP_R_FAIL_INFO_OUT_OF_RANGE
);
842 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_CERTCONF
)) == NULL
)
845 if ((certStatus
= OSSL_CMP_CERTSTATUS_new()) == NULL
)
847 /* consume certStatus into msg right away so it gets deallocated with msg */
848 if (sk_OSSL_CMP_CERTSTATUS_push(msg
->body
->value
.certConf
, certStatus
) < 1) {
849 OSSL_CMP_CERTSTATUS_free(certStatus
);
853 /* set the ID of the certReq */
854 if (!ASN1_INTEGER_set(certStatus
->certReqId
, certReqId
))
857 certStatus
->hashAlg
= NULL
;
859 * The hash of the certificate, using the same hash algorithm
860 * as is used to create and verify the certificate signature.
861 * If not available, a fallback hash algorithm is used.
863 if ((certHash
= X509_digest_sig(ctx
->newCert
, &md
, &is_fallback
)) == NULL
)
866 if (!ossl_cmp_hdr_set_pvno(msg
->header
, OSSL_CMP_PVNO_3
))
868 if ((certStatus
->hashAlg
= X509_ALGOR_new()) == NULL
)
870 X509_ALGOR_set_md(certStatus
->hashAlg
, md
);
874 if (!ossl_cmp_certstatus_set0_certHash(certStatus
, certHash
))
878 * For any particular CertStatus, omission of the statusInfo field
879 * indicates ACCEPTANCE of the specified certificate. Alternatively,
880 * explicit status details (with respect to acceptance or rejection) MAY
881 * be provided in the statusInfo field, perhaps for auditing purposes at
884 sinfo
= fail_info
!= 0 ?
885 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection
, fail_info
, text
) :
886 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted
, 0, text
);
889 certStatus
->statusInfo
= sinfo
;
891 if (!ossl_cmp_msg_protect(ctx
, msg
))
897 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_CERTCONF
);
898 OSSL_CMP_MSG_free(msg
);
899 ASN1_OCTET_STRING_free(certHash
);
903 OSSL_CMP_MSG
*ossl_cmp_pollReq_new(OSSL_CMP_CTX
*ctx
, int crid
)
905 OSSL_CMP_MSG
*msg
= NULL
;
906 OSSL_CMP_POLLREQ
*preq
= NULL
;
908 if (!ossl_assert(ctx
!= NULL
))
911 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREQ
)) == NULL
)
914 if ((preq
= OSSL_CMP_POLLREQ_new()) == NULL
915 || !ASN1_INTEGER_set(preq
->certReqId
, crid
)
916 || !sk_OSSL_CMP_POLLREQ_push(msg
->body
->value
.pollReq
, preq
))
920 if (!ossl_cmp_msg_protect(ctx
, msg
))
926 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_POLLREQ
);
927 OSSL_CMP_POLLREQ_free(preq
);
928 OSSL_CMP_MSG_free(msg
);
932 OSSL_CMP_MSG
*ossl_cmp_pollRep_new(OSSL_CMP_CTX
*ctx
, int crid
,
936 OSSL_CMP_POLLREP
*prep
;
938 if (!ossl_assert(ctx
!= NULL
))
941 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREP
)) == NULL
)
943 if ((prep
= OSSL_CMP_POLLREP_new()) == NULL
)
945 if (!sk_OSSL_CMP_POLLREP_push(msg
->body
->value
.pollRep
, prep
))
947 if (!ASN1_INTEGER_set(prep
->certReqId
, crid
))
949 if (!ASN1_INTEGER_set_int64(prep
->checkAfter
, poll_after
))
952 if (!ossl_cmp_msg_protect(ctx
, msg
))
957 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_POLLREP
);
958 OSSL_CMP_MSG_free(msg
);
963 * returns the status field of the RevRepContent with the given
964 * request/sequence id inside a revocation response.
965 * RevRepContent has the revocation statuses in same order as they were sent in
967 * returns NULL on error
970 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
972 OSSL_CMP_PKISI
*status
;
974 if (!ossl_assert(rrep
!= NULL
))
977 if ((status
= sk_OSSL_CMP_PKISI_value(rrep
->status
, rsid
)) != NULL
)
980 ERR_raise(ERR_LIB_CMP
, CMP_R_PKISTATUSINFO_NOT_FOUND
);
985 * returns the CertId field in the revCerts part of the RevRepContent
986 * with the given request/sequence id inside a revocation response.
987 * RevRepContent has the CertIds in same order as they were sent in
989 * returns NULL on error
992 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
994 OSSL_CRMF_CERTID
*cid
= NULL
;
996 if (!ossl_assert(rrep
!= NULL
))
999 if ((cid
= sk_OSSL_CRMF_CERTID_value(rrep
->revCerts
, rsid
)) != NULL
)
1002 ERR_raise(ERR_LIB_CMP
, CMP_R_CERTID_NOT_FOUND
);
1006 static int suitable_rid(const ASN1_INTEGER
*certReqId
, int rid
)
1010 if (rid
== OSSL_CMP_CERTREQID_NONE
)
1013 trid
= ossl_cmp_asn1_get_int(certReqId
);
1014 if (trid
<= OSSL_CMP_CERTREQID_INVALID
) {
1015 ERR_raise(ERR_LIB_CMP
, CMP_R_BAD_REQUEST_ID
);
1022 * returns a pointer to the PollResponse with the given CertReqId
1023 * (or the first one in case -1) inside a PollRepContent
1024 * returns NULL on error or if no suitable PollResponse available
1027 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT
*prc
,
1030 OSSL_CMP_POLLREP
*pollRep
= NULL
;
1033 if (!ossl_assert(prc
!= NULL
))
1036 for (i
= 0; i
< sk_OSSL_CMP_POLLREP_num(prc
); i
++) {
1037 pollRep
= sk_OSSL_CMP_POLLREP_value(prc
, i
);
1038 if (suitable_rid(pollRep
->certReqId
, rid
))
1042 ERR_raise_data(ERR_LIB_CMP
, CMP_R_CERTRESPONSE_NOT_FOUND
,
1043 "expected certReqId = %d", rid
);
1048 * returns a pointer to the CertResponse with the given CertReqId
1049 * (or the first one in case -1) inside a CertRepMessage
1050 * returns NULL on error or if no suitable CertResponse available
1052 OSSL_CMP_CERTRESPONSE
*
1053 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE
*crm
,
1056 OSSL_CMP_CERTRESPONSE
*crep
= NULL
;
1059 if (!ossl_assert(crm
!= NULL
&& crm
->response
!= NULL
))
1062 for (i
= 0; i
< sk_OSSL_CMP_CERTRESPONSE_num(crm
->response
); i
++) {
1063 crep
= sk_OSSL_CMP_CERTRESPONSE_value(crm
->response
, i
);
1064 if (suitable_rid(crep
->certReqId
, rid
))
1068 ERR_raise_data(ERR_LIB_CMP
, CMP_R_CERTRESPONSE_NOT_FOUND
,
1069 "expected certReqId = %d", rid
);
1074 * Retrieve the newly enrolled certificate from the given certResponse crep.
1075 * Uses libctx and propq from ctx, in case of indirect POPO also private key.
1076 * Returns a pointer to a copy of the found certificate, or NULL if not found.
1078 X509
*ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX
*ctx
,
1079 const OSSL_CMP_CERTRESPONSE
*crep
)
1081 OSSL_CMP_CERTORENCCERT
*coec
;
1085 if (!ossl_assert(crep
!= NULL
&& ctx
!= NULL
))
1088 if (crep
->certifiedKeyPair
1089 && (coec
= crep
->certifiedKeyPair
->certOrEncCert
) != NULL
) {
1090 switch (coec
->type
) {
1091 case OSSL_CMP_CERTORENCCERT_CERTIFICATE
:
1092 crt
= X509_dup(coec
->value
.certificate
);
1094 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT
:
1095 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
1096 pkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 1);
1097 /* pkey is ctx->newPkey (if private, else NULL) or ctx->pkey */
1099 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_PRIVATE_KEY
);
1103 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec
->value
.encryptedCert
,
1104 ctx
->libctx
, ctx
->propq
,
1108 ERR_raise(ERR_LIB_CMP
, CMP_R_UNKNOWN_CERT_TYPE
);
1113 ERR_raise(ERR_LIB_CMP
, CMP_R_CERTIFICATE_NOT_FOUND
);
1115 (void)ossl_x509_set0_libctx(crt
, ctx
->libctx
, ctx
->propq
);
1119 int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX
*ctx
, OSSL_CMP_MSG
*msg
)
1121 if (ctx
== NULL
|| msg
== NULL
) {
1122 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
1125 if (!ossl_cmp_hdr_set_transactionID(ctx
, msg
->header
))
1127 return msg
->header
->protectionAlg
== NULL
1128 || ossl_cmp_msg_protect(ctx
, msg
);
1131 int OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX
*ctx
, OSSL_CMP_MSG
*msg
)
1133 if (ctx
== NULL
|| msg
== NULL
|| msg
->header
== NULL
) {
1134 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
1137 if (ctx
->recipNonce
== NULL
) /* nothing to do for 1st msg in transaction */
1139 if (!ossl_cmp_asn1_octet_string_set1(&msg
->header
->recipNonce
,
1142 return msg
->header
->protectionAlg
== NULL
|| ossl_cmp_msg_protect(ctx
, msg
);
1145 OSSL_CMP_MSG
*OSSL_CMP_MSG_read(const char *file
, OSSL_LIB_CTX
*libctx
,
1152 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
1156 msg
= OSSL_CMP_MSG_new(libctx
, propq
);
1158 ERR_raise(ERR_LIB_CMP
, ERR_R_CMP_LIB
);
1162 if ((bio
= BIO_new_file(file
, "rb")) == NULL
1163 || d2i_OSSL_CMP_MSG_bio(bio
, &msg
) == NULL
) {
1164 OSSL_CMP_MSG_free(msg
);
1171 int OSSL_CMP_MSG_write(const char *file
, const OSSL_CMP_MSG
*msg
)
1176 if (file
== NULL
|| msg
== NULL
) {
1177 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
1181 bio
= BIO_new_file(file
, "wb");
1184 res
= i2d_OSSL_CMP_MSG_bio(bio
, msg
);
1189 OSSL_CMP_MSG
*d2i_OSSL_CMP_MSG(OSSL_CMP_MSG
**msg
, const unsigned char **in
,
1192 OSSL_LIB_CTX
*libctx
= NULL
;
1193 const char *propq
= NULL
;
1195 if (msg
!= NULL
&& *msg
!= NULL
) {
1196 libctx
= (*msg
)->libctx
;
1197 propq
= (*msg
)->propq
;
1200 return (OSSL_CMP_MSG
*)ASN1_item_d2i_ex((ASN1_VALUE
**)msg
, in
, len
,
1201 ASN1_ITEM_rptr(OSSL_CMP_MSG
),
1205 int i2d_OSSL_CMP_MSG(const OSSL_CMP_MSG
*msg
, unsigned char **out
)
1207 return ASN1_item_i2d((const ASN1_VALUE
*)msg
, out
,
1208 ASN1_ITEM_rptr(OSSL_CMP_MSG
));
1211 OSSL_CMP_MSG
*d2i_OSSL_CMP_MSG_bio(BIO
*bio
, OSSL_CMP_MSG
**msg
)
1213 OSSL_LIB_CTX
*libctx
= NULL
;
1214 const char *propq
= NULL
;
1216 if (msg
!= NULL
&& *msg
!= NULL
) {
1217 libctx
= (*msg
)->libctx
;
1218 propq
= (*msg
)->propq
;
1221 return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG
), bio
, msg
, libctx
,
1225 int i2d_OSSL_CMP_MSG_bio(BIO
*bio
, const OSSL_CMP_MSG
*msg
)
1227 return ASN1_i2d_bio_of(OSSL_CMP_MSG
, i2d_OSSL_CMP_MSG
, bio
, msg
);
1230 int ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG
*msg
)
1232 if (!ossl_assert(msg
!= NULL
))
1235 return (OSSL_CMP_MSG_get_bodytype(msg
) == OSSL_CMP_PKIBODY_ERROR
1236 && ossl_cmp_pkisi_get_status(msg
->body
->value
.error
->pKIStatusInfo
)
1237 == OSSL_CMP_PKISTATUS_waiting
);