2 * Copyright 2007-2020 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>
22 #include "crypto/x509.h" /* for x509_set0_libctx() */
24 DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS
)
25 DEFINE_STACK_OF(OSSL_CMP_ITAV
)
26 DEFINE_STACK_OF(OSSL_CMP_PKISI
)
27 DEFINE_STACK_OF(OSSL_CRMF_MSG
)
28 DEFINE_STACK_OF(OSSL_CMP_CERTRESPONSE
)
29 DEFINE_STACK_OF(OSSL_CRMF_CERTID
)
30 DEFINE_STACK_OF(ASN1_UTF8STRING
)
32 OSSL_CMP_PKIHEADER
*OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG
*msg
)
35 CMPerr(0, CMP_R_NULL_ARGUMENT
);
41 const char *ossl_cmp_bodytype_to_string(int type
)
43 static const char *type_names
[] = {
44 "IR", "IP", "CR", "CP", "P10CR",
45 "POPDECC", "POPDECR", "KUR", "KUP",
46 "KRR", "KRP", "RR", "RP", "CCR", "CCP",
47 "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
48 "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
51 if (type
< 0 || type
> OSSL_CMP_PKIBODY_TYPE_MAX
)
52 return "illegal body type";
53 return type_names
[type
];
56 int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG
*msg
, int type
)
58 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
61 msg
->body
->type
= type
;
65 int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG
*msg
)
67 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
70 return msg
->body
->type
;
73 /* Add an extension to the referenced extension stack, which may be NULL */
74 static int add1_extension(X509_EXTENSIONS
**pexts
, int nid
, int crit
, void *ex
)
79 if (!ossl_assert(pexts
!= NULL
)) /* pointer to var must not be NULL */
82 if ((ext
= X509V3_EXT_i2d(nid
, crit
, ex
)) == NULL
)
85 res
= X509v3_add_ext(pexts
, ext
, 0) != NULL
;
86 X509_EXTENSION_free(ext
);
90 /* Add a CRL revocation reason code to extension stack, which may be NULL */
91 static int add_crl_reason_extension(X509_EXTENSIONS
**pexts
, int reason_code
)
93 ASN1_ENUMERATED
*val
= ASN1_ENUMERATED_new();
96 if (val
!= NULL
&& ASN1_ENUMERATED_set(val
, reason_code
))
97 res
= add1_extension(pexts
, NID_crl_reason
, 0 /* non-critical */, val
);
98 ASN1_ENUMERATED_free(val
);
102 OSSL_CMP_MSG
*ossl_cmp_msg_create(OSSL_CMP_CTX
*ctx
, int bodytype
)
104 OSSL_CMP_MSG
*msg
= NULL
;
106 if (!ossl_assert(ctx
!= NULL
))
109 if ((msg
= OSSL_CMP_MSG_new()) == NULL
)
111 if (!ossl_cmp_hdr_init(ctx
, msg
->header
)
112 || !ossl_cmp_msg_set_bodytype(msg
, bodytype
))
114 if (ctx
->geninfo_ITAVs
!= NULL
115 && !ossl_cmp_hdr_generalInfo_push1_items(msg
->header
,
120 case OSSL_CMP_PKIBODY_IR
:
121 case OSSL_CMP_PKIBODY_CR
:
122 case OSSL_CMP_PKIBODY_KUR
:
123 if ((msg
->body
->value
.ir
= OSSL_CRMF_MSGS_new()) == NULL
)
127 case OSSL_CMP_PKIBODY_P10CR
:
128 if (ctx
->p10CSR
== NULL
) {
129 CMPerr(0, CMP_R_MISSING_P10CSR
);
132 if ((msg
->body
->value
.p10cr
= X509_REQ_dup(ctx
->p10CSR
)) == NULL
)
136 case OSSL_CMP_PKIBODY_IP
:
137 case OSSL_CMP_PKIBODY_CP
:
138 case OSSL_CMP_PKIBODY_KUP
:
139 if ((msg
->body
->value
.ip
= OSSL_CMP_CERTREPMESSAGE_new()) == NULL
)
143 case OSSL_CMP_PKIBODY_RR
:
144 if ((msg
->body
->value
.rr
= sk_OSSL_CMP_REVDETAILS_new_null()) == NULL
)
147 case OSSL_CMP_PKIBODY_RP
:
148 if ((msg
->body
->value
.rp
= OSSL_CMP_REVREPCONTENT_new()) == NULL
)
152 case OSSL_CMP_PKIBODY_CERTCONF
:
153 if ((msg
->body
->value
.certConf
=
154 sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL
)
157 case OSSL_CMP_PKIBODY_PKICONF
:
158 if ((msg
->body
->value
.pkiconf
= ASN1_TYPE_new()) == NULL
)
160 ASN1_TYPE_set(msg
->body
->value
.pkiconf
, V_ASN1_NULL
, NULL
);
163 case OSSL_CMP_PKIBODY_POLLREQ
:
164 if ((msg
->body
->value
.pollReq
= sk_OSSL_CMP_POLLREQ_new_null()) == NULL
)
167 case OSSL_CMP_PKIBODY_POLLREP
:
168 if ((msg
->body
->value
.pollRep
= sk_OSSL_CMP_POLLREP_new_null()) == NULL
)
172 case OSSL_CMP_PKIBODY_GENM
:
173 case OSSL_CMP_PKIBODY_GENP
:
174 if ((msg
->body
->value
.genm
= sk_OSSL_CMP_ITAV_new_null()) == NULL
)
178 case OSSL_CMP_PKIBODY_ERROR
:
179 if ((msg
->body
->value
.error
= OSSL_CMP_ERRORMSGCONTENT_new()) == NULL
)
184 CMPerr(0, CMP_R_UNEXPECTED_PKIBODY
);
189 OSSL_CMP_MSG_free(msg
);
193 #define HAS_SAN(ctx) \
194 (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
195 || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
197 static const X509_NAME
*determine_subj(OSSL_CMP_CTX
*ctx
, X509
*refcert
,
200 if (ctx
->subjectName
!= NULL
)
201 return ctx
->subjectName
;
203 if (refcert
!= NULL
&& (for_KUR
|| !HAS_SAN(ctx
)))
205 * For KUR, copy subjectName from reference certificate.
206 * For IR or CR, do the same only if there is no subjectAltName.
208 return X509_get_subject_name(refcert
);
212 OSSL_CRMF_MSG
*OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX
*ctx
, int for_KUR
, int rid
)
214 OSSL_CRMF_MSG
*crm
= NULL
;
215 X509
*refcert
= ctx
->oldCert
!= NULL
? ctx
->oldCert
: ctx
->cert
;
216 /* refcert defaults to current client cert */
217 EVP_PKEY
*rkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 0);
218 STACK_OF(GENERAL_NAME
) *default_sans
= NULL
;
219 const X509_NAME
*subject
= determine_subj(ctx
, refcert
, for_KUR
);
220 int crit
= ctx
->setSubjectAltNameCritical
|| subject
== NULL
;
221 /* RFC5280: subjectAltName MUST be critical if subject is null */
222 X509_EXTENSIONS
*exts
= NULL
;
225 rkey
= ctx
->pkey
; /* default is independent of ctx->oldCert */
227 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
228 CMPerr(0, CMP_R_NULL_ARGUMENT
);
232 if (for_KUR
&& refcert
== NULL
) {
233 CMPerr(0, CMP_R_MISSING_REFERENCE_CERT
);
236 if ((crm
= OSSL_CRMF_MSG_new()) == NULL
)
238 if (!OSSL_CRMF_MSG_set_certReqId(crm
, rid
)
240 * fill certTemplate, corresponding to CertificationRequestInfo
241 * of PKCS#10. The rkey param cannot be NULL so far -
242 * it could be NULL if centralized key creation was supported
244 || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm
), rkey
,
245 subject
, ctx
->issuer
,
248 if (ctx
->days
!= 0) {
249 time_t now
= time(NULL
);
250 ASN1_TIME
*notBefore
= ASN1_TIME_adj(NULL
, now
, 0, 0);
251 ASN1_TIME
*notAfter
= ASN1_TIME_adj(NULL
, now
, ctx
->days
, 0);
253 if (notBefore
== NULL
255 || !OSSL_CRMF_MSG_set0_validity(crm
, notBefore
, notAfter
)) {
256 ASN1_TIME_free(notBefore
);
257 ASN1_TIME_free(notAfter
);
263 if (refcert
!= NULL
&& !ctx
->SubjectAltName_nodefault
)
264 default_sans
= X509V3_get_d2i(X509_get0_extensions(refcert
),
265 NID_subject_alt_name
, NULL
, NULL
);
266 /* exts are copied from ctx to allow reuse */
267 if (ctx
->reqExtensions
!= NULL
) {
268 exts
= sk_X509_EXTENSION_deep_copy(ctx
->reqExtensions
,
270 X509_EXTENSION_free
);
274 if (sk_GENERAL_NAME_num(ctx
->subjectAltNames
) > 0
275 && !add1_extension(&exts
, NID_subject_alt_name
,
276 crit
, ctx
->subjectAltNames
))
278 if (!HAS_SAN(ctx
) && default_sans
!= NULL
279 && !add1_extension(&exts
, NID_subject_alt_name
, crit
, default_sans
))
281 if (ctx
->policies
!= NULL
282 && !add1_extension(&exts
, NID_certificate_policies
,
283 ctx
->setPoliciesCritical
, ctx
->policies
))
285 if (!OSSL_CRMF_MSG_set0_extensions(crm
, exts
))
288 /* end fill certTemplate, now set any controls */
290 /* for KUR, set OldCertId according to D.6 */
292 OSSL_CRMF_CERTID
*cid
=
293 OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert
),
294 X509_get0_serialNumber(refcert
));
299 ret
= OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm
, cid
);
300 OSSL_CRMF_CERTID_free(cid
);
308 OSSL_CRMF_MSG_free(crm
);
312 sk_X509_EXTENSION_pop_free(exts
, X509_EXTENSION_free
);
313 sk_GENERAL_NAME_pop_free(default_sans
, GENERAL_NAME_free
);
317 OSSL_CMP_MSG
*ossl_cmp_certreq_new(OSSL_CMP_CTX
*ctx
, int type
,
318 const OSSL_CRMF_MSG
*crm
)
321 OSSL_CRMF_MSG
*local_crm
= NULL
;
323 if (!ossl_assert(ctx
!= NULL
))
326 if (type
!= OSSL_CMP_PKIBODY_IR
&& type
!= OSSL_CMP_PKIBODY_CR
327 && type
!= OSSL_CMP_PKIBODY_KUR
&& type
!= OSSL_CMP_PKIBODY_P10CR
) {
328 CMPerr(0, CMP_R_INVALID_ARGS
);
332 if ((msg
= ossl_cmp_msg_create(ctx
, type
)) == NULL
)
336 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
340 /* For P10CR the content has already been set in OSSL_CMP_MSG_create */
341 if (type
!= OSSL_CMP_PKIBODY_P10CR
) {
342 EVP_PKEY
*privkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 1);
345 privkey
= ctx
->pkey
; /* default is independent of ctx->oldCert */
346 if (ctx
->popoMethod
== OSSL_CRMF_POPO_SIGNATURE
&& privkey
== NULL
) {
347 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
351 local_crm
= OSSL_CMP_CTX_setup_CRM(ctx
,
352 type
== OSSL_CMP_PKIBODY_KUR
,
354 if (local_crm
== NULL
355 || !OSSL_CRMF_MSG_create_popo(ctx
->popoMethod
, local_crm
,
356 privkey
, ctx
->digest
,
357 ctx
->libctx
, ctx
->propq
))
360 if ((local_crm
= OSSL_CRMF_MSG_dup(crm
)) == NULL
)
364 /* value.ir is same for cr and kur */
365 if (!sk_OSSL_CRMF_MSG_push(msg
->body
->value
.ir
, local_crm
))
368 /* TODO: here optional 2nd certreqmsg could be pushed to the stack */
371 if (!ossl_cmp_msg_protect(ctx
, msg
))
377 CMPerr(0, CMP_R_ERROR_CREATING_CERTREQ
);
378 OSSL_CRMF_MSG_free(local_crm
);
379 OSSL_CMP_MSG_free(msg
);
383 OSSL_CMP_MSG
*ossl_cmp_certrep_new(OSSL_CMP_CTX
*ctx
, int bodytype
,
384 int certReqId
, OSSL_CMP_PKISI
*si
,
385 X509
*cert
, STACK_OF(X509
) *chain
,
386 STACK_OF(X509
) *caPubs
, int encrypted
,
387 int unprotectedErrors
)
389 OSSL_CMP_MSG
*msg
= NULL
;
390 OSSL_CMP_CERTREPMESSAGE
*repMsg
= NULL
;
391 OSSL_CMP_CERTRESPONSE
*resp
= NULL
;
394 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
397 if ((msg
= ossl_cmp_msg_create(ctx
, bodytype
)) == NULL
)
399 repMsg
= msg
->body
->value
.ip
; /* value.ip is same for cp and kup */
402 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
406 if ((resp
= OSSL_CMP_CERTRESPONSE_new()) == NULL
)
408 OSSL_CMP_PKISI_free(resp
->status
);
409 if ((resp
->status
= OSSL_CMP_PKISI_dup(si
)) == NULL
410 || !ASN1_INTEGER_set(resp
->certReqId
, certReqId
))
413 status
= ossl_cmp_pkisi_get_status(resp
->status
);
414 if (status
!= OSSL_CMP_PKISTATUS_rejection
415 && status
!= OSSL_CMP_PKISTATUS_waiting
&& cert
!= NULL
) {
417 CMPerr(0, CMP_R_INVALID_ARGS
);
421 if ((resp
->certifiedKeyPair
= OSSL_CMP_CERTIFIEDKEYPAIR_new())
424 resp
->certifiedKeyPair
->certOrEncCert
->type
=
425 OSSL_CMP_CERTORENCCERT_CERTIFICATE
;
426 if (!X509_up_ref(cert
))
428 resp
->certifiedKeyPair
->certOrEncCert
->value
.certificate
= cert
;
431 if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg
->response
, resp
))
434 /* TODO: here optional 2nd certrep could be pushed to the stack */
436 if (bodytype
== OSSL_CMP_PKIBODY_IP
&& caPubs
!= NULL
437 && (repMsg
->caPubs
= X509_chain_up_ref(caPubs
)) == NULL
)
439 if (sk_X509_num(chain
) > 0) {
440 msg
->extraCerts
= sk_X509_new_reserve(NULL
, sk_X509_num(chain
));
441 if (msg
->extraCerts
== NULL
442 || !X509_add_certs(msg
->extraCerts
, chain
,
443 X509_ADD_FLAG_UP_REF
| X509_ADD_FLAG_NO_DUP
))
447 if (!unprotectedErrors
448 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
449 if (!ossl_cmp_msg_protect(ctx
, msg
))
455 CMPerr(0, CMP_R_ERROR_CREATING_CERTREP
);
456 OSSL_CMP_CERTRESPONSE_free(resp
);
457 OSSL_CMP_MSG_free(msg
);
461 OSSL_CMP_MSG
*ossl_cmp_rr_new(OSSL_CMP_CTX
*ctx
)
463 OSSL_CMP_MSG
*msg
= NULL
;
464 OSSL_CMP_REVDETAILS
*rd
;
466 if (!ossl_assert(ctx
!= NULL
&& ctx
->oldCert
!= NULL
))
469 if ((rd
= OSSL_CMP_REVDETAILS_new()) == NULL
)
472 /* Fill the template from the contents of the certificate to be revoked */
473 if (!OSSL_CRMF_CERTTEMPLATE_fill(rd
->certDetails
,
474 NULL
/* pubkey would be redundant */,
475 NULL
/* subject would be redundant */,
476 X509_get_issuer_name(ctx
->oldCert
),
477 X509_get0_serialNumber(ctx
->oldCert
)))
480 /* revocation reason code is optional */
481 if (ctx
->revocationReason
!= CRL_REASON_NONE
482 && !add_crl_reason_extension(&rd
->crlEntryDetails
,
483 ctx
->revocationReason
))
486 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RR
)) == NULL
)
489 if (!sk_OSSL_CMP_REVDETAILS_push(msg
->body
->value
.rr
, rd
))
494 * TODO: the Revocation Passphrase according to section 5.3.19.9 could be
495 * set here if set in ctx
498 if (!ossl_cmp_msg_protect(ctx
, msg
))
504 CMPerr(0, CMP_R_ERROR_CREATING_RR
);
505 OSSL_CMP_MSG_free(msg
);
506 OSSL_CMP_REVDETAILS_free(rd
);
510 OSSL_CMP_MSG
*ossl_cmp_rp_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
511 OSSL_CRMF_CERTID
*cid
, int unprot_err
)
513 OSSL_CMP_REVREPCONTENT
*rep
= NULL
;
514 OSSL_CMP_PKISI
*si1
= NULL
;
515 OSSL_CRMF_CERTID
*cid_copy
= NULL
;
516 OSSL_CMP_MSG
*msg
= NULL
;
518 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
&& cid
!= NULL
))
521 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RP
)) == NULL
)
523 rep
= msg
->body
->value
.rp
;
525 if ((si1
= OSSL_CMP_PKISI_dup(si
)) == NULL
)
528 if (!sk_OSSL_CMP_PKISI_push(rep
->status
, si1
)) {
529 OSSL_CMP_PKISI_free(si1
);
533 if ((rep
->revCerts
= sk_OSSL_CRMF_CERTID_new_null()) == NULL
)
535 if ((cid_copy
= OSSL_CRMF_CERTID_dup(cid
)) == NULL
)
537 if (!sk_OSSL_CRMF_CERTID_push(rep
->revCerts
, cid_copy
)) {
538 OSSL_CRMF_CERTID_free(cid_copy
);
543 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
544 if (!ossl_cmp_msg_protect(ctx
, msg
))
550 CMPerr(0, CMP_R_ERROR_CREATING_RP
);
551 OSSL_CMP_MSG_free(msg
);
555 OSSL_CMP_MSG
*ossl_cmp_pkiconf_new(OSSL_CMP_CTX
*ctx
)
559 if (!ossl_assert(ctx
!= NULL
))
562 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_PKICONF
)) == NULL
)
564 if (ossl_cmp_msg_protect(ctx
, msg
))
568 CMPerr(0, CMP_R_ERROR_CREATING_PKICONF
);
569 OSSL_CMP_MSG_free(msg
);
573 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG
*msg
, OSSL_CMP_ITAV
*itav
)
577 if (!ossl_assert(msg
!= NULL
&& itav
!= NULL
))
580 bodytype
= ossl_cmp_msg_get_bodytype(msg
);
581 if (bodytype
!= OSSL_CMP_PKIBODY_GENM
582 && bodytype
!= OSSL_CMP_PKIBODY_GENP
) {
583 CMPerr(0, CMP_R_INVALID_ARGS
);
587 /* value.genp has the same structure, so this works for genp as well */
588 return OSSL_CMP_ITAV_push0_stack_item(&msg
->body
->value
.genm
, itav
);
591 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG
*msg
,
592 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
595 OSSL_CMP_ITAV
*itav
= NULL
;
597 if (!ossl_assert(msg
!= NULL
))
600 for (i
= 0; i
< sk_OSSL_CMP_ITAV_num(itavs
); i
++) {
601 itav
= OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs
, i
));
603 || !ossl_cmp_msg_gen_push0_ITAV(msg
, itav
)) {
604 OSSL_CMP_ITAV_free(itav
);
612 * Creates a new General Message/Response with an empty itav stack
613 * returns a pointer to the PKIMessage on success, NULL on error
615 static OSSL_CMP_MSG
*gen_new(OSSL_CMP_CTX
*ctx
,
616 const STACK_OF(OSSL_CMP_ITAV
) *itavs
,
617 int body_type
, int err_code
)
619 OSSL_CMP_MSG
*msg
= NULL
;
621 if (!ossl_assert(ctx
!= NULL
))
624 if ((msg
= ossl_cmp_msg_create(ctx
, body_type
)) == NULL
)
627 if (ctx
->genm_ITAVs
!= NULL
628 && !ossl_cmp_msg_gen_push1_ITAVs(msg
, itavs
))
631 if (!ossl_cmp_msg_protect(ctx
, msg
))
638 OSSL_CMP_MSG_free(msg
);
642 OSSL_CMP_MSG
*ossl_cmp_genm_new(OSSL_CMP_CTX
*ctx
)
644 return gen_new(ctx
, ctx
->genm_ITAVs
,
645 OSSL_CMP_PKIBODY_GENM
, CMP_R_ERROR_CREATING_GENM
);
648 OSSL_CMP_MSG
*ossl_cmp_genp_new(OSSL_CMP_CTX
*ctx
,
649 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
651 return gen_new(ctx
, itavs
,
652 OSSL_CMP_PKIBODY_GENP
, CMP_R_ERROR_CREATING_GENP
);
655 OSSL_CMP_MSG
*ossl_cmp_error_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
657 const char *details
, int unprotected
)
659 OSSL_CMP_MSG
*msg
= NULL
;
660 OSSL_CMP_PKIFREETEXT
*ft
;
662 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
665 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_ERROR
)) == NULL
)
668 OSSL_CMP_PKISI_free(msg
->body
->value
.error
->pKIStatusInfo
);
669 if ((msg
->body
->value
.error
->pKIStatusInfo
= OSSL_CMP_PKISI_dup(si
))
672 if (errorCode
>= 0) {
673 if ((msg
->body
->value
.error
->errorCode
= ASN1_INTEGER_new()) == NULL
)
675 if (!ASN1_INTEGER_set(msg
->body
->value
.error
->errorCode
, errorCode
))
678 if (details
!= NULL
) {
679 if ((ft
= sk_ASN1_UTF8STRING_new_null()) == NULL
)
681 msg
->body
->value
.error
->errorDetails
= ft
;
682 if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, details
))
686 if (!unprotected
&& !ossl_cmp_msg_protect(ctx
, msg
))
691 CMPerr(0, CMP_R_ERROR_CREATING_ERROR
);
692 OSSL_CMP_MSG_free(msg
);
697 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
698 * This is used in the certConf message, for example,
699 * to confirm that the certificate was received successfully.
701 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS
*certStatus
,
702 ASN1_OCTET_STRING
*hash
)
704 if (!ossl_assert(certStatus
!= NULL
))
706 ASN1_OCTET_STRING_free(certStatus
->certHash
);
707 certStatus
->certHash
= hash
;
712 * TODO: handle potential 2nd certificate when signing and encrypting
713 * certificates have been requested/received
715 OSSL_CMP_MSG
*ossl_cmp_certConf_new(OSSL_CMP_CTX
*ctx
, int fail_info
,
718 OSSL_CMP_MSG
*msg
= NULL
;
719 OSSL_CMP_CERTSTATUS
*certStatus
= NULL
;
720 ASN1_OCTET_STRING
*certHash
= NULL
;
721 OSSL_CMP_PKISI
*sinfo
;
723 if (!ossl_assert(ctx
!= NULL
&& ctx
->newCert
!= NULL
))
726 if ((unsigned)fail_info
> OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN
) {
727 CMPerr(0, CMP_R_FAIL_INFO_OUT_OF_RANGE
);
731 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_CERTCONF
)) == NULL
)
734 if ((certStatus
= OSSL_CMP_CERTSTATUS_new()) == NULL
)
736 /* consume certStatus into msg right away so it gets deallocated with msg */
737 if (!sk_OSSL_CMP_CERTSTATUS_push(msg
->body
->value
.certConf
, certStatus
))
739 /* set the ID of the certReq */
740 if (!ASN1_INTEGER_set(certStatus
->certReqId
, OSSL_CMP_CERTREQID
))
743 * the hash of the certificate, using the same hash algorithm
744 * as is used to create and verify the certificate signature
746 if ((certHash
= X509_digest_sig(ctx
->newCert
)) == NULL
)
749 if (!ossl_cmp_certstatus_set0_certHash(certStatus
, certHash
))
753 * For any particular CertStatus, omission of the statusInfo field
754 * indicates ACCEPTANCE of the specified certificate. Alternatively,
755 * explicit status details (with respect to acceptance or rejection) MAY
756 * be provided in the statusInfo field, perhaps for auditing purposes at
759 sinfo
= fail_info
!= 0 ?
760 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection
, fail_info
, text
) :
761 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted
, 0, text
);
764 certStatus
->statusInfo
= sinfo
;
766 if (!ossl_cmp_msg_protect(ctx
, msg
))
772 CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF
);
773 OSSL_CMP_MSG_free(msg
);
774 ASN1_OCTET_STRING_free(certHash
);
778 OSSL_CMP_MSG
*ossl_cmp_pollReq_new(OSSL_CMP_CTX
*ctx
, int crid
)
780 OSSL_CMP_MSG
*msg
= NULL
;
781 OSSL_CMP_POLLREQ
*preq
= NULL
;
783 if (!ossl_assert(ctx
!= NULL
))
786 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREQ
)) == NULL
)
789 /* TODO: support multiple cert request IDs to poll */
790 if ((preq
= OSSL_CMP_POLLREQ_new()) == NULL
791 || !ASN1_INTEGER_set(preq
->certReqId
, crid
)
792 || !sk_OSSL_CMP_POLLREQ_push(msg
->body
->value
.pollReq
, preq
))
796 if (!ossl_cmp_msg_protect(ctx
, msg
))
802 CMPerr(0, CMP_R_ERROR_CREATING_POLLREQ
);
803 OSSL_CMP_POLLREQ_free(preq
);
804 OSSL_CMP_MSG_free(msg
);
808 OSSL_CMP_MSG
*ossl_cmp_pollRep_new(OSSL_CMP_CTX
*ctx
, int crid
,
812 OSSL_CMP_POLLREP
*prep
;
814 if (!ossl_assert(ctx
!= NULL
))
817 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREP
)) == NULL
)
819 if ((prep
= OSSL_CMP_POLLREP_new()) == NULL
)
821 if (!sk_OSSL_CMP_POLLREP_push(msg
->body
->value
.pollRep
, prep
))
823 if (!ASN1_INTEGER_set(prep
->certReqId
, crid
))
825 if (!ASN1_INTEGER_set_int64(prep
->checkAfter
, poll_after
))
828 if (!ossl_cmp_msg_protect(ctx
, msg
))
833 CMPerr(0, CMP_R_ERROR_CREATING_POLLREP
);
834 OSSL_CMP_MSG_free(msg
);
839 * returns the status field of the RevRepContent with the given
840 * request/sequence id inside a revocation response.
841 * RevRepContent has the revocation statuses in same order as they were sent in
843 * returns NULL on error
846 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
848 OSSL_CMP_PKISI
*status
;
850 if (!ossl_assert(rrep
!= NULL
))
853 if ((status
= sk_OSSL_CMP_PKISI_value(rrep
->status
, rsid
)) != NULL
)
856 CMPerr(0, CMP_R_PKISTATUSINFO_NOT_FOUND
);
861 * returns the CertId field in the revCerts part of the RevRepContent
862 * with the given request/sequence id inside a revocation response.
863 * RevRepContent has the CertIds in same order as they were sent in
865 * returns NULL on error
868 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
870 OSSL_CRMF_CERTID
*cid
= NULL
;
872 if (!ossl_assert(rrep
!= NULL
))
875 if ((cid
= sk_OSSL_CRMF_CERTID_value(rrep
->revCerts
, rsid
)) != NULL
)
878 CMPerr(0, CMP_R_CERTID_NOT_FOUND
);
882 static int suitable_rid(const ASN1_INTEGER
*certReqId
, int rid
)
889 trid
= ossl_cmp_asn1_get_int(certReqId
);
892 CMPerr(0, CMP_R_BAD_REQUEST_ID
);
898 static void add_expected_rid(int rid
)
900 char str
[DECIMAL_SIZE(rid
) + 1];
902 BIO_snprintf(str
, sizeof(str
), "%d", rid
);
903 ERR_add_error_data(2, "expected certReqId = ", str
);
907 * returns a pointer to the PollResponse with the given CertReqId
908 * (or the first one in case -1) inside a PollRepContent
909 * returns NULL on error or if no suitable PollResponse available
912 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT
*prc
,
915 OSSL_CMP_POLLREP
*pollRep
= NULL
;
918 if (!ossl_assert(prc
!= NULL
))
921 for (i
= 0; i
< sk_OSSL_CMP_POLLREP_num(prc
); i
++) {
922 pollRep
= sk_OSSL_CMP_POLLREP_value(prc
, i
);
923 if (suitable_rid(pollRep
->certReqId
, rid
))
927 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
928 add_expected_rid(rid
);
933 * returns a pointer to the CertResponse with the given CertReqId
934 * (or the first one in case -1) inside a CertRepMessage
935 * returns NULL on error or if no suitable CertResponse available
937 OSSL_CMP_CERTRESPONSE
*
938 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE
*crm
,
941 OSSL_CMP_CERTRESPONSE
*crep
= NULL
;
944 if (!ossl_assert(crm
!= NULL
&& crm
->response
!= NULL
))
947 for (i
= 0; i
< sk_OSSL_CMP_CERTRESPONSE_num(crm
->response
); i
++) {
948 crep
= sk_OSSL_CMP_CERTRESPONSE_value(crm
->response
, i
);
949 if (suitable_rid(crep
->certReqId
, rid
))
953 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
954 add_expected_rid(rid
);
959 * Retrieve the newly enrolled certificate from the given certResponse crep.
960 * In case of indirect POPO uses the libctx and propq from ctx and private key.
961 * Returns a pointer to a copy of the found certificate, or NULL if not found.
963 X509
*ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE
*crep
,
964 const OSSL_CMP_CTX
*ctx
, EVP_PKEY
*pkey
)
966 OSSL_CMP_CERTORENCCERT
*coec
;
969 if (!ossl_assert(crep
!= NULL
&& ctx
!= NULL
))
972 if (crep
->certifiedKeyPair
973 && (coec
= crep
->certifiedKeyPair
->certOrEncCert
) != NULL
) {
974 switch (coec
->type
) {
975 case OSSL_CMP_CERTORENCCERT_CERTIFICATE
:
976 crt
= X509_dup(coec
->value
.certificate
);
978 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT
:
979 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
981 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
985 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec
->value
.encryptedCert
,
986 ctx
->libctx
, ctx
->propq
,
990 CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE
);
995 CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND
);
997 (void)x509_set0_libctx(crt
, ctx
->libctx
, ctx
->propq
);
1001 int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX
*ctx
, OSSL_CMP_MSG
*msg
)
1003 if (ctx
== NULL
|| msg
== NULL
) {
1004 CMPerr(0, CMP_R_NULL_ARGUMENT
);
1007 if (!ossl_cmp_hdr_set_transactionID(ctx
, msg
->header
))
1009 return msg
->header
->protectionAlg
== NULL
1010 || ossl_cmp_msg_protect(ctx
, msg
);
1013 OSSL_CMP_MSG
*OSSL_CMP_MSG_read(const char *file
)
1015 OSSL_CMP_MSG
*msg
= NULL
;
1019 CMPerr(0, CMP_R_NULL_ARGUMENT
);
1023 if ((bio
= BIO_new_file(file
, "rb")) == NULL
)
1025 msg
= d2i_OSSL_CMP_MSG_bio(bio
, NULL
);
1030 int OSSL_CMP_MSG_write(const char *file
, const OSSL_CMP_MSG
*msg
)
1035 if (file
== NULL
|| msg
== NULL
) {
1036 CMPerr(0, CMP_R_NULL_ARGUMENT
);
1040 bio
= BIO_new_file(file
, "wb");
1043 res
= i2d_OSSL_CMP_MSG_bio(bio
, msg
);
1048 OSSL_CMP_MSG
*d2i_OSSL_CMP_MSG_bio(BIO
*bio
, OSSL_CMP_MSG
**msg
)
1050 return ASN1_d2i_bio_of(OSSL_CMP_MSG
, OSSL_CMP_MSG_new
,
1051 d2i_OSSL_CMP_MSG
, bio
, msg
);
1054 int i2d_OSSL_CMP_MSG_bio(BIO
*bio
, const OSSL_CMP_MSG
*msg
)
1056 return ASN1_i2d_bio_of(OSSL_CMP_MSG
, i2d_OSSL_CMP_MSG
, bio
, msg
);