2 * Copyright 2007-2021 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
)
63 OSSL_CMP_PKIHEADER
*OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG
*msg
)
66 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
72 const char *ossl_cmp_bodytype_to_string(int type
)
74 static const char *type_names
[] = {
75 "IR", "IP", "CR", "CP", "P10CR",
76 "POPDECC", "POPDECR", "KUR", "KUP",
77 "KRR", "KRP", "RR", "RP", "CCR", "CCP",
78 "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
79 "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
82 if (type
< 0 || type
> OSSL_CMP_PKIBODY_TYPE_MAX
)
83 return "illegal body type";
84 return type_names
[type
];
87 int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG
*msg
, int type
)
89 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
92 msg
->body
->type
= type
;
96 int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG
*msg
)
98 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
101 return msg
->body
->type
;
104 /* Add an extension to the referenced extension stack, which may be NULL */
105 static int add1_extension(X509_EXTENSIONS
**pexts
, int nid
, int crit
, void *ex
)
110 if (!ossl_assert(pexts
!= NULL
)) /* pointer to var must not be NULL */
113 if ((ext
= X509V3_EXT_i2d(nid
, crit
, ex
)) == NULL
)
116 res
= X509v3_add_ext(pexts
, ext
, 0) != NULL
;
117 X509_EXTENSION_free(ext
);
121 /* Add extension list to the referenced extension stack, which may be NULL */
122 static int add_extensions(STACK_OF(X509_EXTENSION
) **target
,
123 const STACK_OF(X509_EXTENSION
) *exts
)
130 for (i
= 0; i
< sk_X509_EXTENSION_num(exts
); i
++) {
131 X509_EXTENSION
*ext
= sk_X509_EXTENSION_value(exts
, i
);
132 ASN1_OBJECT
*obj
= X509_EXTENSION_get_object(ext
);
133 int idx
= X509v3_get_ext_by_OBJ(*target
, obj
, -1);
135 /* Does extension exist in target? */
137 /* Delete all extensions of same type */
139 X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target
, idx
));
140 idx
= X509v3_get_ext_by_OBJ(*target
, obj
, -1);
143 if (!X509v3_add_ext(target
, ext
, -1))
149 /* Add a CRL revocation reason code to extension stack, which may be NULL */
150 static int add_crl_reason_extension(X509_EXTENSIONS
**pexts
, int reason_code
)
152 ASN1_ENUMERATED
*val
= ASN1_ENUMERATED_new();
155 if (val
!= NULL
&& ASN1_ENUMERATED_set(val
, reason_code
))
156 res
= add1_extension(pexts
, NID_crl_reason
, 0 /* non-critical */, val
);
157 ASN1_ENUMERATED_free(val
);
161 OSSL_CMP_MSG
*ossl_cmp_msg_create(OSSL_CMP_CTX
*ctx
, int bodytype
)
163 OSSL_CMP_MSG
*msg
= NULL
;
165 if (!ossl_assert(ctx
!= NULL
))
168 if ((msg
= OSSL_CMP_MSG_new(ctx
->libctx
, ctx
->propq
)) == NULL
)
170 if (!ossl_cmp_hdr_init(ctx
, msg
->header
)
171 || !ossl_cmp_msg_set_bodytype(msg
, bodytype
))
173 if (ctx
->geninfo_ITAVs
!= NULL
174 && !ossl_cmp_hdr_generalInfo_push1_items(msg
->header
,
179 case OSSL_CMP_PKIBODY_IR
:
180 case OSSL_CMP_PKIBODY_CR
:
181 case OSSL_CMP_PKIBODY_KUR
:
182 if ((msg
->body
->value
.ir
= OSSL_CRMF_MSGS_new()) == NULL
)
186 case OSSL_CMP_PKIBODY_P10CR
:
187 if (ctx
->p10CSR
== NULL
) {
188 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_P10CSR
);
191 if ((msg
->body
->value
.p10cr
= X509_REQ_dup(ctx
->p10CSR
)) == NULL
)
195 case OSSL_CMP_PKIBODY_IP
:
196 case OSSL_CMP_PKIBODY_CP
:
197 case OSSL_CMP_PKIBODY_KUP
:
198 if ((msg
->body
->value
.ip
= OSSL_CMP_CERTREPMESSAGE_new()) == NULL
)
202 case OSSL_CMP_PKIBODY_RR
:
203 if ((msg
->body
->value
.rr
= sk_OSSL_CMP_REVDETAILS_new_null()) == NULL
)
206 case OSSL_CMP_PKIBODY_RP
:
207 if ((msg
->body
->value
.rp
= OSSL_CMP_REVREPCONTENT_new()) == NULL
)
211 case OSSL_CMP_PKIBODY_CERTCONF
:
212 if ((msg
->body
->value
.certConf
=
213 sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL
)
216 case OSSL_CMP_PKIBODY_PKICONF
:
217 if ((msg
->body
->value
.pkiconf
= ASN1_TYPE_new()) == NULL
)
219 ASN1_TYPE_set(msg
->body
->value
.pkiconf
, V_ASN1_NULL
, NULL
);
222 case OSSL_CMP_PKIBODY_POLLREQ
:
223 if ((msg
->body
->value
.pollReq
= sk_OSSL_CMP_POLLREQ_new_null()) == NULL
)
226 case OSSL_CMP_PKIBODY_POLLREP
:
227 if ((msg
->body
->value
.pollRep
= sk_OSSL_CMP_POLLREP_new_null()) == NULL
)
231 case OSSL_CMP_PKIBODY_GENM
:
232 case OSSL_CMP_PKIBODY_GENP
:
233 if ((msg
->body
->value
.genm
= sk_OSSL_CMP_ITAV_new_null()) == NULL
)
237 case OSSL_CMP_PKIBODY_ERROR
:
238 if ((msg
->body
->value
.error
= OSSL_CMP_ERRORMSGCONTENT_new()) == NULL
)
243 ERR_raise(ERR_LIB_CMP
, CMP_R_UNEXPECTED_PKIBODY
);
248 OSSL_CMP_MSG_free(msg
);
252 #define HAS_SAN(ctx) \
253 (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
254 || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
256 static const X509_NAME
*determine_subj(OSSL_CMP_CTX
*ctx
,
257 const X509_NAME
*ref_subj
,
260 if (ctx
->subjectName
!= NULL
)
261 return IS_NULL_DN(ctx
->subjectName
) ? NULL
: ctx
->subjectName
;
263 if (ref_subj
!= NULL
&& (for_KUR
|| !HAS_SAN(ctx
)))
265 * For KUR, copy subject from the reference.
266 * For IR or CR, do the same only if there is no subjectAltName.
272 OSSL_CRMF_MSG
*OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX
*ctx
, int for_KUR
, int rid
)
274 OSSL_CRMF_MSG
*crm
= NULL
;
275 X509
*refcert
= ctx
->oldCert
!= NULL
? ctx
->oldCert
: ctx
->cert
;
276 /* refcert defaults to current client cert */
277 EVP_PKEY
*rkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 0);
278 STACK_OF(GENERAL_NAME
) *default_sans
= NULL
;
279 const X509_NAME
*ref_subj
=
280 ctx
->p10CSR
!= NULL
? X509_REQ_get_subject_name(ctx
->p10CSR
) :
281 refcert
!= NULL
? X509_get_subject_name(refcert
) : NULL
;
282 const X509_NAME
*subject
= determine_subj(ctx
, ref_subj
, for_KUR
);
283 const X509_NAME
*issuer
= ctx
->issuer
!= NULL
|| refcert
== NULL
284 ? (IS_NULL_DN(ctx
->issuer
) ? NULL
: ctx
->issuer
)
285 : X509_get_issuer_name(refcert
);
286 int crit
= ctx
->setSubjectAltNameCritical
|| subject
== NULL
;
287 /* RFC5280: subjectAltName MUST be critical if subject is null */
288 X509_EXTENSIONS
*exts
= NULL
;
290 if (rkey
== NULL
&& ctx
->p10CSR
!= NULL
)
291 rkey
= X509_REQ_get0_pubkey(ctx
->p10CSR
);
293 rkey
= ctx
->pkey
; /* default is independent of ctx->oldCert */
295 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
296 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
300 if (for_KUR
&& refcert
== NULL
&& ctx
->p10CSR
== NULL
) {
301 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_REFERENCE_CERT
);
304 if ((crm
= OSSL_CRMF_MSG_new()) == NULL
)
306 if (!OSSL_CRMF_MSG_set_certReqId(crm
, rid
)
308 * fill certTemplate, corresponding to CertificationRequestInfo
309 * of PKCS#10. The rkey param cannot be NULL so far -
310 * it could be NULL if centralized key creation was supported
312 || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm
), rkey
,
313 subject
, issuer
, NULL
/* serial */))
315 if (ctx
->days
!= 0) {
316 time_t now
= time(NULL
);
317 ASN1_TIME
*notBefore
= ASN1_TIME_adj(NULL
, now
, 0, 0);
318 ASN1_TIME
*notAfter
= ASN1_TIME_adj(NULL
, now
, ctx
->days
, 0);
320 if (notBefore
== NULL
322 || !OSSL_CRMF_MSG_set0_validity(crm
, notBefore
, notAfter
)) {
323 ASN1_TIME_free(notBefore
);
324 ASN1_TIME_free(notAfter
);
330 if (refcert
!= NULL
&& !ctx
->SubjectAltName_nodefault
)
331 default_sans
= X509V3_get_d2i(X509_get0_extensions(refcert
),
332 NID_subject_alt_name
, NULL
, NULL
);
333 if (ctx
->p10CSR
!= NULL
334 && (exts
= X509_REQ_get_extensions(ctx
->p10CSR
)) == NULL
)
336 if (ctx
->reqExtensions
!= NULL
/* augment/override existing ones */
337 && !add_extensions(&exts
, ctx
->reqExtensions
))
339 if (sk_GENERAL_NAME_num(ctx
->subjectAltNames
) > 0
340 && !add1_extension(&exts
, NID_subject_alt_name
,
341 crit
, ctx
->subjectAltNames
))
343 if (!HAS_SAN(ctx
) && default_sans
!= NULL
344 && !add1_extension(&exts
, NID_subject_alt_name
, crit
, default_sans
))
346 if (ctx
->policies
!= NULL
347 && !add1_extension(&exts
, NID_certificate_policies
,
348 ctx
->setPoliciesCritical
, ctx
->policies
))
350 if (!OSSL_CRMF_MSG_set0_extensions(crm
, exts
))
353 /* end fill certTemplate, now set any controls */
355 /* for KUR, set OldCertId according to D.6 */
356 if (for_KUR
&& refcert
!= NULL
) {
357 OSSL_CRMF_CERTID
*cid
=
358 OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert
),
359 X509_get0_serialNumber(refcert
));
364 ret
= OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm
, cid
);
365 OSSL_CRMF_CERTID_free(cid
);
373 OSSL_CRMF_MSG_free(crm
);
377 sk_X509_EXTENSION_pop_free(exts
, X509_EXTENSION_free
);
378 sk_GENERAL_NAME_pop_free(default_sans
, GENERAL_NAME_free
);
382 OSSL_CMP_MSG
*ossl_cmp_certreq_new(OSSL_CMP_CTX
*ctx
, int type
,
383 const OSSL_CRMF_MSG
*crm
)
386 OSSL_CRMF_MSG
*local_crm
= NULL
;
388 if (!ossl_assert(ctx
!= NULL
))
391 if (type
!= OSSL_CMP_PKIBODY_IR
&& type
!= OSSL_CMP_PKIBODY_CR
392 && type
!= OSSL_CMP_PKIBODY_KUR
&& type
!= OSSL_CMP_PKIBODY_P10CR
) {
393 ERR_raise(ERR_LIB_CMP
, CMP_R_INVALID_ARGS
);
396 if (type
== OSSL_CMP_PKIBODY_P10CR
&& crm
!= NULL
) {
397 ERR_raise(ERR_LIB_CMP
, CMP_R_INVALID_ARGS
);
401 if ((msg
= ossl_cmp_msg_create(ctx
, type
)) == NULL
)
405 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
409 /* For P10CR the content has already been set in OSSL_CMP_MSG_create */
410 if (type
!= OSSL_CMP_PKIBODY_P10CR
) {
411 EVP_PKEY
*privkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 1);
414 * privkey is NULL in case ctx->newPkey does not include a private key.
415 * We then may try to use ctx->pkey as fallback/default, but only
416 * if ctx-> newPkey does not include a (non-matching) public key:
418 if (privkey
== NULL
&& OSSL_CMP_CTX_get0_newPkey(ctx
, 0) == NULL
)
419 privkey
= ctx
->pkey
; /* default is independent of ctx->oldCert */
420 if (ctx
->popoMethod
== OSSL_CRMF_POPO_SIGNATURE
&& privkey
== NULL
) {
421 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_PRIVATE_KEY
);
425 local_crm
= OSSL_CMP_CTX_setup_CRM(ctx
,
426 type
== OSSL_CMP_PKIBODY_KUR
,
428 if (local_crm
== NULL
429 || !OSSL_CRMF_MSG_create_popo(ctx
->popoMethod
, local_crm
,
430 privkey
, ctx
->digest
,
431 ctx
->libctx
, ctx
->propq
))
434 if ((local_crm
= OSSL_CRMF_MSG_dup(crm
)) == NULL
)
438 /* value.ir is same for cr and kur */
439 if (!sk_OSSL_CRMF_MSG_push(msg
->body
->value
.ir
, local_crm
))
444 if (!ossl_cmp_msg_protect(ctx
, msg
))
450 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_CERTREQ
);
451 OSSL_CRMF_MSG_free(local_crm
);
452 OSSL_CMP_MSG_free(msg
);
456 OSSL_CMP_MSG
*ossl_cmp_certrep_new(OSSL_CMP_CTX
*ctx
, int bodytype
,
457 int certReqId
, const OSSL_CMP_PKISI
*si
,
458 X509
*cert
, const X509
*encryption_recip
,
459 STACK_OF(X509
) *chain
, STACK_OF(X509
) *caPubs
,
460 int unprotectedErrors
)
462 OSSL_CMP_MSG
*msg
= NULL
;
463 OSSL_CMP_CERTREPMESSAGE
*repMsg
= NULL
;
464 OSSL_CMP_CERTRESPONSE
*resp
= NULL
;
467 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
470 if ((msg
= ossl_cmp_msg_create(ctx
, bodytype
)) == NULL
)
472 repMsg
= msg
->body
->value
.ip
; /* value.ip is same for cp and kup */
475 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
479 if ((resp
= OSSL_CMP_CERTRESPONSE_new()) == NULL
)
481 OSSL_CMP_PKISI_free(resp
->status
);
482 if ((resp
->status
= OSSL_CMP_PKISI_dup(si
)) == NULL
483 || !ASN1_INTEGER_set(resp
->certReqId
, certReqId
))
486 status
= ossl_cmp_pkisi_get_status(resp
->status
);
487 if (status
!= OSSL_CMP_PKISTATUS_rejection
488 && status
!= OSSL_CMP_PKISTATUS_waiting
&& cert
!= NULL
) {
489 if (encryption_recip
!= NULL
) {
490 ERR_raise(ERR_LIB_CMP
, ERR_R_UNSUPPORTED
);
494 if ((resp
->certifiedKeyPair
= OSSL_CMP_CERTIFIEDKEYPAIR_new())
497 resp
->certifiedKeyPair
->certOrEncCert
->type
=
498 OSSL_CMP_CERTORENCCERT_CERTIFICATE
;
499 if (!X509_up_ref(cert
))
501 resp
->certifiedKeyPair
->certOrEncCert
->value
.certificate
= cert
;
504 if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg
->response
, resp
))
508 if (bodytype
== OSSL_CMP_PKIBODY_IP
&& caPubs
!= NULL
509 && (repMsg
->caPubs
= X509_chain_up_ref(caPubs
)) == NULL
)
511 if (sk_X509_num(chain
) > 0
512 && !ossl_x509_add_certs_new(&msg
->extraCerts
, chain
,
513 X509_ADD_FLAG_UP_REF
| X509_ADD_FLAG_NO_DUP
))
516 if (!unprotectedErrors
517 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
518 if (!ossl_cmp_msg_protect(ctx
, msg
))
524 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_CERTREP
);
525 OSSL_CMP_CERTRESPONSE_free(resp
);
526 OSSL_CMP_MSG_free(msg
);
530 OSSL_CMP_MSG
*ossl_cmp_rr_new(OSSL_CMP_CTX
*ctx
)
532 OSSL_CMP_MSG
*msg
= NULL
;
533 OSSL_CMP_REVDETAILS
*rd
;
536 if (!ossl_assert(ctx
!= NULL
&& (ctx
->oldCert
!= NULL
537 || ctx
->p10CSR
!= NULL
)))
540 if ((rd
= OSSL_CMP_REVDETAILS_new()) == NULL
)
543 /* Fill the template from the contents of the certificate to be revoked */
544 ret
= ctx
->oldCert
!= NULL
545 ? OSSL_CRMF_CERTTEMPLATE_fill(rd
->certDetails
,
546 NULL
/* pubkey would be redundant */,
547 NULL
/* subject would be redundant */,
548 X509_get_issuer_name(ctx
->oldCert
),
549 X509_get0_serialNumber(ctx
->oldCert
))
550 : OSSL_CRMF_CERTTEMPLATE_fill(rd
->certDetails
,
551 X509_REQ_get0_pubkey(ctx
->p10CSR
),
552 X509_REQ_get_subject_name(ctx
->p10CSR
),
557 /* revocation reason code is optional */
558 if (ctx
->revocationReason
!= CRL_REASON_NONE
559 && !add_crl_reason_extension(&rd
->crlEntryDetails
,
560 ctx
->revocationReason
))
563 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RR
)) == NULL
)
566 if (!sk_OSSL_CMP_REVDETAILS_push(msg
->body
->value
.rr
, rd
))
570 if (!ossl_cmp_msg_protect(ctx
, msg
))
576 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_RR
);
577 OSSL_CMP_MSG_free(msg
);
578 OSSL_CMP_REVDETAILS_free(rd
);
582 OSSL_CMP_MSG
*ossl_cmp_rp_new(OSSL_CMP_CTX
*ctx
, const OSSL_CMP_PKISI
*si
,
583 const OSSL_CRMF_CERTID
*cid
, int unprotectedErrors
)
585 OSSL_CMP_REVREPCONTENT
*rep
= NULL
;
586 OSSL_CMP_PKISI
*si1
= NULL
;
587 OSSL_CRMF_CERTID
*cid_copy
= NULL
;
588 OSSL_CMP_MSG
*msg
= NULL
;
590 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
593 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RP
)) == NULL
)
595 rep
= msg
->body
->value
.rp
;
597 if ((si1
= OSSL_CMP_PKISI_dup(si
)) == NULL
)
600 if (!sk_OSSL_CMP_PKISI_push(rep
->status
, si1
)) {
601 OSSL_CMP_PKISI_free(si1
);
605 if ((rep
->revCerts
= sk_OSSL_CRMF_CERTID_new_null()) == NULL
)
608 if ((cid_copy
= OSSL_CRMF_CERTID_dup(cid
)) == NULL
)
610 if (!sk_OSSL_CRMF_CERTID_push(rep
->revCerts
, cid_copy
)) {
611 OSSL_CRMF_CERTID_free(cid_copy
);
616 if (!unprotectedErrors
617 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
618 if (!ossl_cmp_msg_protect(ctx
, msg
))
624 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_RP
);
625 OSSL_CMP_MSG_free(msg
);
629 OSSL_CMP_MSG
*ossl_cmp_pkiconf_new(OSSL_CMP_CTX
*ctx
)
633 if (!ossl_assert(ctx
!= NULL
))
636 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_PKICONF
)) == NULL
)
638 if (ossl_cmp_msg_protect(ctx
, msg
))
642 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_PKICONF
);
643 OSSL_CMP_MSG_free(msg
);
647 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG
*msg
, OSSL_CMP_ITAV
*itav
)
651 if (!ossl_assert(msg
!= NULL
&& itav
!= NULL
))
654 bodytype
= OSSL_CMP_MSG_get_bodytype(msg
);
655 if (bodytype
!= OSSL_CMP_PKIBODY_GENM
656 && bodytype
!= OSSL_CMP_PKIBODY_GENP
) {
657 ERR_raise(ERR_LIB_CMP
, CMP_R_INVALID_ARGS
);
661 /* value.genp has the same structure, so this works for genp as well */
662 return OSSL_CMP_ITAV_push0_stack_item(&msg
->body
->value
.genm
, itav
);
665 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG
*msg
,
666 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
669 OSSL_CMP_ITAV
*itav
= NULL
;
671 if (!ossl_assert(msg
!= NULL
))
674 for (i
= 0; i
< sk_OSSL_CMP_ITAV_num(itavs
); i
++) {
675 itav
= OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs
, i
));
677 || !ossl_cmp_msg_gen_push0_ITAV(msg
, itav
)) {
678 OSSL_CMP_ITAV_free(itav
);
686 * Creates a new General Message/Response with an empty itav stack
687 * returns a pointer to the PKIMessage on success, NULL on error
689 static OSSL_CMP_MSG
*gen_new(OSSL_CMP_CTX
*ctx
,
690 const STACK_OF(OSSL_CMP_ITAV
) *itavs
,
691 int body_type
, int err_code
)
693 OSSL_CMP_MSG
*msg
= NULL
;
695 if (!ossl_assert(ctx
!= NULL
))
698 if ((msg
= ossl_cmp_msg_create(ctx
, body_type
)) == NULL
)
701 if (ctx
->genm_ITAVs
!= NULL
702 && !ossl_cmp_msg_gen_push1_ITAVs(msg
, itavs
))
705 if (!ossl_cmp_msg_protect(ctx
, msg
))
711 ERR_raise(ERR_LIB_CMP
, err_code
);
712 OSSL_CMP_MSG_free(msg
);
716 OSSL_CMP_MSG
*ossl_cmp_genm_new(OSSL_CMP_CTX
*ctx
)
718 return gen_new(ctx
, ctx
->genm_ITAVs
,
719 OSSL_CMP_PKIBODY_GENM
, CMP_R_ERROR_CREATING_GENM
);
722 OSSL_CMP_MSG
*ossl_cmp_genp_new(OSSL_CMP_CTX
*ctx
,
723 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
725 return gen_new(ctx
, itavs
,
726 OSSL_CMP_PKIBODY_GENP
, CMP_R_ERROR_CREATING_GENP
);
729 OSSL_CMP_MSG
*ossl_cmp_error_new(OSSL_CMP_CTX
*ctx
, const OSSL_CMP_PKISI
*si
,
730 int64_t errorCode
, const char *details
,
733 OSSL_CMP_MSG
*msg
= NULL
;
734 const char *lib
= NULL
, *reason
= NULL
;
735 OSSL_CMP_PKIFREETEXT
*ft
;
737 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
740 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_ERROR
)) == NULL
)
743 OSSL_CMP_PKISI_free(msg
->body
->value
.error
->pKIStatusInfo
);
744 if ((msg
->body
->value
.error
->pKIStatusInfo
= OSSL_CMP_PKISI_dup(si
))
747 if ((msg
->body
->value
.error
->errorCode
= ASN1_INTEGER_new()) == NULL
)
749 if (!ASN1_INTEGER_set_int64(msg
->body
->value
.error
->errorCode
, errorCode
))
752 && (uint64_t)errorCode
< ((uint64_t)ERR_SYSTEM_FLAG
<< 1)) {
753 lib
= ERR_lib_error_string((unsigned long)errorCode
);
754 reason
= ERR_reason_error_string((unsigned long)errorCode
);
756 if (lib
!= NULL
|| reason
!= NULL
|| details
!= NULL
) {
757 if ((ft
= sk_ASN1_UTF8STRING_new_null()) == NULL
)
759 msg
->body
->value
.error
->errorDetails
= ft
;
760 if (lib
!= NULL
&& *lib
!= '\0'
761 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, lib
))
763 if (reason
!= NULL
&& *reason
!= '\0'
764 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, reason
))
767 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, details
))
771 if (!unprotected
&& !ossl_cmp_msg_protect(ctx
, msg
))
776 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_ERROR
);
777 OSSL_CMP_MSG_free(msg
);
782 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
783 * This is used in the certConf message, for example,
784 * to confirm that the certificate was received successfully.
786 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS
*certStatus
,
787 ASN1_OCTET_STRING
*hash
)
789 if (!ossl_assert(certStatus
!= NULL
))
791 ASN1_OCTET_STRING_free(certStatus
->certHash
);
792 certStatus
->certHash
= hash
;
796 OSSL_CMP_MSG
*ossl_cmp_certConf_new(OSSL_CMP_CTX
*ctx
, int fail_info
,
799 OSSL_CMP_MSG
*msg
= NULL
;
800 OSSL_CMP_CERTSTATUS
*certStatus
= NULL
;
801 ASN1_OCTET_STRING
*certHash
= NULL
;
802 OSSL_CMP_PKISI
*sinfo
;
804 if (!ossl_assert(ctx
!= NULL
&& ctx
->newCert
!= NULL
))
807 if ((unsigned)fail_info
> OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN
) {
808 ERR_raise(ERR_LIB_CMP
, CMP_R_FAIL_INFO_OUT_OF_RANGE
);
812 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_CERTCONF
)) == NULL
)
815 if ((certStatus
= OSSL_CMP_CERTSTATUS_new()) == NULL
)
817 /* consume certStatus into msg right away so it gets deallocated with msg */
818 if (!sk_OSSL_CMP_CERTSTATUS_push(msg
->body
->value
.certConf
, certStatus
))
820 /* set the ID of the certReq */
821 if (!ASN1_INTEGER_set(certStatus
->certReqId
, OSSL_CMP_CERTREQID
))
824 * The hash of the certificate, using the same hash algorithm
825 * as is used to create and verify the certificate signature.
826 * If not available, a default hash algorithm is used.
828 if ((certHash
= X509_digest_sig(ctx
->newCert
, NULL
, NULL
)) == NULL
)
831 if (!ossl_cmp_certstatus_set0_certHash(certStatus
, certHash
))
835 * For any particular CertStatus, omission of the statusInfo field
836 * indicates ACCEPTANCE of the specified certificate. Alternatively,
837 * explicit status details (with respect to acceptance or rejection) MAY
838 * be provided in the statusInfo field, perhaps for auditing purposes at
841 sinfo
= fail_info
!= 0 ?
842 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection
, fail_info
, text
) :
843 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted
, 0, text
);
846 certStatus
->statusInfo
= sinfo
;
848 if (!ossl_cmp_msg_protect(ctx
, msg
))
854 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_CERTCONF
);
855 OSSL_CMP_MSG_free(msg
);
856 ASN1_OCTET_STRING_free(certHash
);
860 OSSL_CMP_MSG
*ossl_cmp_pollReq_new(OSSL_CMP_CTX
*ctx
, int crid
)
862 OSSL_CMP_MSG
*msg
= NULL
;
863 OSSL_CMP_POLLREQ
*preq
= NULL
;
865 if (!ossl_assert(ctx
!= NULL
))
868 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREQ
)) == NULL
)
871 if ((preq
= OSSL_CMP_POLLREQ_new()) == NULL
872 || !ASN1_INTEGER_set(preq
->certReqId
, crid
)
873 || !sk_OSSL_CMP_POLLREQ_push(msg
->body
->value
.pollReq
, preq
))
877 if (!ossl_cmp_msg_protect(ctx
, msg
))
883 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_POLLREQ
);
884 OSSL_CMP_POLLREQ_free(preq
);
885 OSSL_CMP_MSG_free(msg
);
889 OSSL_CMP_MSG
*ossl_cmp_pollRep_new(OSSL_CMP_CTX
*ctx
, int crid
,
893 OSSL_CMP_POLLREP
*prep
;
895 if (!ossl_assert(ctx
!= NULL
))
898 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREP
)) == NULL
)
900 if ((prep
= OSSL_CMP_POLLREP_new()) == NULL
)
902 if (!sk_OSSL_CMP_POLLREP_push(msg
->body
->value
.pollRep
, prep
))
904 if (!ASN1_INTEGER_set(prep
->certReqId
, crid
))
906 if (!ASN1_INTEGER_set_int64(prep
->checkAfter
, poll_after
))
909 if (!ossl_cmp_msg_protect(ctx
, msg
))
914 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_CREATING_POLLREP
);
915 OSSL_CMP_MSG_free(msg
);
920 * returns the status field of the RevRepContent with the given
921 * request/sequence id inside a revocation response.
922 * RevRepContent has the revocation statuses in same order as they were sent in
924 * returns NULL on error
927 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
929 OSSL_CMP_PKISI
*status
;
931 if (!ossl_assert(rrep
!= NULL
))
934 if ((status
= sk_OSSL_CMP_PKISI_value(rrep
->status
, rsid
)) != NULL
)
937 ERR_raise(ERR_LIB_CMP
, CMP_R_PKISTATUSINFO_NOT_FOUND
);
942 * returns the CertId field in the revCerts part of the RevRepContent
943 * with the given request/sequence id inside a revocation response.
944 * RevRepContent has the CertIds in same order as they were sent in
946 * returns NULL on error
949 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
951 OSSL_CRMF_CERTID
*cid
= NULL
;
953 if (!ossl_assert(rrep
!= NULL
))
956 if ((cid
= sk_OSSL_CRMF_CERTID_value(rrep
->revCerts
, rsid
)) != NULL
)
959 ERR_raise(ERR_LIB_CMP
, CMP_R_CERTID_NOT_FOUND
);
963 static int suitable_rid(const ASN1_INTEGER
*certReqId
, int rid
)
970 trid
= ossl_cmp_asn1_get_int(certReqId
);
973 ERR_raise(ERR_LIB_CMP
, CMP_R_BAD_REQUEST_ID
);
980 * returns a pointer to the PollResponse with the given CertReqId
981 * (or the first one in case -1) inside a PollRepContent
982 * returns NULL on error or if no suitable PollResponse available
985 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT
*prc
,
988 OSSL_CMP_POLLREP
*pollRep
= NULL
;
991 if (!ossl_assert(prc
!= NULL
))
994 for (i
= 0; i
< sk_OSSL_CMP_POLLREP_num(prc
); i
++) {
995 pollRep
= sk_OSSL_CMP_POLLREP_value(prc
, i
);
996 if (suitable_rid(pollRep
->certReqId
, rid
))
1000 ERR_raise_data(ERR_LIB_CMP
, CMP_R_CERTRESPONSE_NOT_FOUND
,
1001 "expected certReqId = %d", rid
);
1006 * returns a pointer to the CertResponse with the given CertReqId
1007 * (or the first one in case -1) inside a CertRepMessage
1008 * returns NULL on error or if no suitable CertResponse available
1010 OSSL_CMP_CERTRESPONSE
*
1011 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE
*crm
,
1014 OSSL_CMP_CERTRESPONSE
*crep
= NULL
;
1017 if (!ossl_assert(crm
!= NULL
&& crm
->response
!= NULL
))
1020 for (i
= 0; i
< sk_OSSL_CMP_CERTRESPONSE_num(crm
->response
); i
++) {
1021 crep
= sk_OSSL_CMP_CERTRESPONSE_value(crm
->response
, i
);
1022 if (suitable_rid(crep
->certReqId
, rid
))
1026 ERR_raise_data(ERR_LIB_CMP
, CMP_R_CERTRESPONSE_NOT_FOUND
,
1027 "expected certReqId = %d", rid
);
1032 * Retrieve the newly enrolled certificate from the given certResponse crep.
1033 * In case of indirect POPO uses the libctx and propq from ctx and private key.
1034 * Returns a pointer to a copy of the found certificate, or NULL if not found.
1036 X509
*ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE
*crep
,
1037 const OSSL_CMP_CTX
*ctx
, EVP_PKEY
*pkey
)
1039 OSSL_CMP_CERTORENCCERT
*coec
;
1042 if (!ossl_assert(crep
!= NULL
&& ctx
!= NULL
))
1045 if (crep
->certifiedKeyPair
1046 && (coec
= crep
->certifiedKeyPair
->certOrEncCert
) != NULL
) {
1047 switch (coec
->type
) {
1048 case OSSL_CMP_CERTORENCCERT_CERTIFICATE
:
1049 crt
= X509_dup(coec
->value
.certificate
);
1051 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT
:
1052 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
1054 ERR_raise(ERR_LIB_CMP
, CMP_R_MISSING_PRIVATE_KEY
);
1058 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec
->value
.encryptedCert
,
1059 ctx
->libctx
, ctx
->propq
,
1063 ERR_raise(ERR_LIB_CMP
, CMP_R_UNKNOWN_CERT_TYPE
);
1068 ERR_raise(ERR_LIB_CMP
, CMP_R_CERTIFICATE_NOT_FOUND
);
1070 (void)ossl_x509_set0_libctx(crt
, ctx
->libctx
, ctx
->propq
);
1074 int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX
*ctx
, OSSL_CMP_MSG
*msg
)
1076 if (ctx
== NULL
|| msg
== NULL
) {
1077 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
1080 if (!ossl_cmp_hdr_set_transactionID(ctx
, msg
->header
))
1082 return msg
->header
->protectionAlg
== NULL
1083 || ossl_cmp_msg_protect(ctx
, msg
);
1086 OSSL_CMP_MSG
*OSSL_CMP_MSG_read(const char *file
, OSSL_LIB_CTX
*libctx
,
1093 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
1097 msg
= OSSL_CMP_MSG_new(libctx
, propq
);
1099 ERR_raise(ERR_LIB_CMP
, ERR_R_MALLOC_FAILURE
);
1103 if ((bio
= BIO_new_file(file
, "rb")) == NULL
)
1105 if (d2i_OSSL_CMP_MSG_bio(bio
, &msg
) == NULL
) {
1106 OSSL_CMP_MSG_free(msg
);
1113 int OSSL_CMP_MSG_write(const char *file
, const OSSL_CMP_MSG
*msg
)
1118 if (file
== NULL
|| msg
== NULL
) {
1119 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
1123 bio
= BIO_new_file(file
, "wb");
1126 res
= i2d_OSSL_CMP_MSG_bio(bio
, msg
);
1131 OSSL_CMP_MSG
*d2i_OSSL_CMP_MSG(OSSL_CMP_MSG
**msg
, const unsigned char **in
,
1134 OSSL_LIB_CTX
*libctx
= NULL
;
1135 const char *propq
= NULL
;
1137 if (msg
!= NULL
&& *msg
!= NULL
) {
1138 libctx
= (*msg
)->libctx
;
1139 propq
= (*msg
)->propq
;
1142 return (OSSL_CMP_MSG
*)ASN1_item_d2i_ex((ASN1_VALUE
**)msg
, in
, len
,
1143 ASN1_ITEM_rptr(OSSL_CMP_MSG
),
1147 int i2d_OSSL_CMP_MSG(const OSSL_CMP_MSG
*msg
, unsigned char **out
)
1149 return ASN1_item_i2d((const ASN1_VALUE
*)msg
, out
,
1150 ASN1_ITEM_rptr(OSSL_CMP_MSG
));
1153 OSSL_CMP_MSG
*d2i_OSSL_CMP_MSG_bio(BIO
*bio
, OSSL_CMP_MSG
**msg
)
1155 OSSL_LIB_CTX
*libctx
= NULL
;
1156 const char *propq
= NULL
;
1158 if (msg
!= NULL
&& *msg
!= NULL
) {
1159 libctx
= (*msg
)->libctx
;
1160 propq
= (*msg
)->propq
;
1163 return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG
), bio
, msg
, libctx
,
1167 int i2d_OSSL_CMP_MSG_bio(BIO
*bio
, const OSSL_CMP_MSG
*msg
)
1169 return ASN1_i2d_bio_of(OSSL_CMP_MSG
, i2d_OSSL_CMP_MSG
, bio
, msg
);