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>
23 DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS
)
24 DEFINE_STACK_OF(OSSL_CMP_ITAV
)
25 DEFINE_STACK_OF(GENERAL_NAME
)
27 DEFINE_STACK_OF(X509_EXTENSION
)
28 DEFINE_STACK_OF(OSSL_CMP_PKISI
)
29 DEFINE_STACK_OF(OSSL_CRMF_MSG
)
30 DEFINE_STACK_OF(OSSL_CMP_CERTRESPONSE
)
31 DEFINE_STACK_OF(OSSL_CRMF_CERTID
)
32 DEFINE_STACK_OF(ASN1_UTF8STRING
)
34 OSSL_CMP_PKIHEADER
*OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG
*msg
)
37 CMPerr(0, CMP_R_NULL_ARGUMENT
);
43 const char *ossl_cmp_bodytype_to_string(int type
)
45 static const char *type_names
[] = {
46 "IR", "IP", "CR", "CP", "P10CR",
47 "POPDECC", "POPDECR", "KUR", "KUP",
48 "KRR", "KRP", "RR", "RP", "CCR", "CCP",
49 "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
50 "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
53 if (type
< 0 || type
> OSSL_CMP_PKIBODY_TYPE_MAX
)
54 return "illegal body type";
55 return type_names
[type
];
58 int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG
*msg
, int type
)
60 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
63 msg
->body
->type
= type
;
67 int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG
*msg
)
69 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
72 return msg
->body
->type
;
75 /* Add an extension to the referenced extension stack, which may be NULL */
76 static int add1_extension(X509_EXTENSIONS
**pexts
, int nid
, int crit
, void *ex
)
81 if (!ossl_assert(pexts
!= NULL
)) /* pointer to var must not be NULL */
84 if ((ext
= X509V3_EXT_i2d(nid
, crit
, ex
)) == NULL
)
87 res
= X509v3_add_ext(pexts
, ext
, 0) != NULL
;
88 X509_EXTENSION_free(ext
);
92 /* Add a CRL revocation reason code to extension stack, which may be NULL */
93 static int add_crl_reason_extension(X509_EXTENSIONS
**pexts
, int reason_code
)
95 ASN1_ENUMERATED
*val
= ASN1_ENUMERATED_new();
98 if (val
!= NULL
&& ASN1_ENUMERATED_set(val
, reason_code
))
99 res
= add1_extension(pexts
, NID_crl_reason
, 0 /* non-critical */, val
);
100 ASN1_ENUMERATED_free(val
);
104 OSSL_CMP_MSG
*ossl_cmp_msg_create(OSSL_CMP_CTX
*ctx
, int bodytype
)
106 OSSL_CMP_MSG
*msg
= NULL
;
108 if (!ossl_assert(ctx
!= NULL
))
111 if ((msg
= OSSL_CMP_MSG_new()) == NULL
)
113 if (!ossl_cmp_hdr_init(ctx
, msg
->header
)
114 || !ossl_cmp_msg_set_bodytype(msg
, bodytype
))
116 if (ctx
->geninfo_ITAVs
!= NULL
117 && !ossl_cmp_hdr_generalInfo_push1_items(msg
->header
,
122 case OSSL_CMP_PKIBODY_IR
:
123 case OSSL_CMP_PKIBODY_CR
:
124 case OSSL_CMP_PKIBODY_KUR
:
125 if ((msg
->body
->value
.ir
= OSSL_CRMF_MSGS_new()) == NULL
)
129 case OSSL_CMP_PKIBODY_P10CR
:
130 if (ctx
->p10CSR
== NULL
) {
131 CMPerr(0, CMP_R_ERROR_CREATING_P10CR
);
134 if ((msg
->body
->value
.p10cr
= X509_REQ_dup(ctx
->p10CSR
)) == NULL
)
138 case OSSL_CMP_PKIBODY_IP
:
139 case OSSL_CMP_PKIBODY_CP
:
140 case OSSL_CMP_PKIBODY_KUP
:
141 if ((msg
->body
->value
.ip
= OSSL_CMP_CERTREPMESSAGE_new()) == NULL
)
145 case OSSL_CMP_PKIBODY_RR
:
146 if ((msg
->body
->value
.rr
= sk_OSSL_CMP_REVDETAILS_new_null()) == NULL
)
149 case OSSL_CMP_PKIBODY_RP
:
150 if ((msg
->body
->value
.rp
= OSSL_CMP_REVREPCONTENT_new()) == NULL
)
154 case OSSL_CMP_PKIBODY_CERTCONF
:
155 if ((msg
->body
->value
.certConf
=
156 sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL
)
159 case OSSL_CMP_PKIBODY_PKICONF
:
160 if ((msg
->body
->value
.pkiconf
= ASN1_TYPE_new()) == NULL
)
162 ASN1_TYPE_set(msg
->body
->value
.pkiconf
, V_ASN1_NULL
, NULL
);
165 case OSSL_CMP_PKIBODY_POLLREQ
:
166 if ((msg
->body
->value
.pollReq
= sk_OSSL_CMP_POLLREQ_new_null()) == NULL
)
169 case OSSL_CMP_PKIBODY_POLLREP
:
170 if ((msg
->body
->value
.pollRep
= sk_OSSL_CMP_POLLREP_new_null()) == NULL
)
174 case OSSL_CMP_PKIBODY_GENM
:
175 case OSSL_CMP_PKIBODY_GENP
:
176 if ((msg
->body
->value
.genm
= sk_OSSL_CMP_ITAV_new_null()) == NULL
)
180 case OSSL_CMP_PKIBODY_ERROR
:
181 if ((msg
->body
->value
.error
= OSSL_CMP_ERRORMSGCONTENT_new()) == NULL
)
186 CMPerr(0, CMP_R_UNEXPECTED_PKIBODY
);
191 OSSL_CMP_MSG_free(msg
);
195 #define HAS_SAN(ctx) \
196 (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
197 || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
199 static const X509_NAME
*determine_subj(OSSL_CMP_CTX
*ctx
, X509
*refcert
,
202 if (ctx
->subjectName
!= NULL
)
203 return ctx
->subjectName
;
206 && (bodytype
== OSSL_CMP_PKIBODY_KUR
|| !HAS_SAN(ctx
)))
208 * For KUR, copy subjectName from reference certificate.
209 * For IR or CR, do the same only if there is no subjectAltName.
211 return X509_get_subject_name(refcert
);
216 * Create CRMF certificate request message for IR/CR/KUR
217 * returns a pointer to the OSSL_CRMF_MSG on success, NULL on error
219 static OSSL_CRMF_MSG
*crm_new(OSSL_CMP_CTX
*ctx
, int bodytype
, int rid
)
221 OSSL_CRMF_MSG
*crm
= NULL
;
222 X509
*refcert
= ctx
->oldCert
!= NULL
? ctx
->oldCert
: ctx
->cert
;
223 /* refcert defaults to current client cert */
224 EVP_PKEY
*rkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 0);
225 STACK_OF(GENERAL_NAME
) *default_sans
= NULL
;
226 const X509_NAME
*subject
= determine_subj(ctx
, refcert
, bodytype
);
227 int crit
= ctx
->setSubjectAltNameCritical
|| subject
== NULL
;
228 /* RFC5280: subjectAltName MUST be critical if subject is null */
229 X509_EXTENSIONS
*exts
= NULL
;
232 rkey
= ctx
->pkey
; /* default is independent of ctx->oldCert */
234 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
235 CMPerr(0, CMP_R_NULL_ARGUMENT
);
239 if (bodytype
== OSSL_CMP_PKIBODY_KUR
&& refcert
== NULL
) {
240 CMPerr(0, CMP_R_MISSING_REFERENCE_CERT
);
243 if ((crm
= OSSL_CRMF_MSG_new()) == NULL
)
245 if (!OSSL_CRMF_MSG_set_certReqId(crm
, rid
)
247 * fill certTemplate, corresponding to CertificationRequestInfo
248 * of PKCS#10. The rkey param cannot be NULL so far -
249 * it could be NULL if centralized key creation was supported
251 || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm
), rkey
,
252 subject
, ctx
->issuer
,
255 if (ctx
->days
!= 0) {
256 time_t now
= time(NULL
);
257 ASN1_TIME
*notBefore
= ASN1_TIME_adj(NULL
, now
, 0, 0);
258 ASN1_TIME
*notAfter
= ASN1_TIME_adj(NULL
, now
, ctx
->days
, 0);
260 if (notBefore
== NULL
262 || !OSSL_CRMF_MSG_set0_validity(crm
, notBefore
, notAfter
)) {
263 ASN1_TIME_free(notBefore
);
264 ASN1_TIME_free(notAfter
);
270 if (refcert
!= NULL
&& !ctx
->SubjectAltName_nodefault
)
271 default_sans
= X509V3_get_d2i(X509_get0_extensions(refcert
),
272 NID_subject_alt_name
, NULL
, NULL
);
273 /* exts are copied from ctx to allow reuse */
274 if (ctx
->reqExtensions
!= NULL
) {
275 exts
= sk_X509_EXTENSION_deep_copy(ctx
->reqExtensions
,
277 X509_EXTENSION_free
);
281 if (sk_GENERAL_NAME_num(ctx
->subjectAltNames
) > 0
282 && !add1_extension(&exts
, NID_subject_alt_name
,
283 crit
, ctx
->subjectAltNames
))
285 if (!HAS_SAN(ctx
) && default_sans
!= NULL
286 && !add1_extension(&exts
, NID_subject_alt_name
, crit
, default_sans
))
288 if (ctx
->policies
!= NULL
289 && !add1_extension(&exts
, NID_certificate_policies
,
290 ctx
->setPoliciesCritical
, ctx
->policies
))
292 if (!OSSL_CRMF_MSG_set0_extensions(crm
, exts
))
295 /* end fill certTemplate, now set any controls */
297 /* for KUR, set OldCertId according to D.6 */
298 if (bodytype
== OSSL_CMP_PKIBODY_KUR
) {
299 OSSL_CRMF_CERTID
*cid
=
300 OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert
),
301 X509_get0_serialNumber(refcert
));
306 ret
= OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm
, cid
);
307 OSSL_CRMF_CERTID_free(cid
);
315 OSSL_CRMF_MSG_free(crm
);
319 sk_X509_EXTENSION_pop_free(exts
, X509_EXTENSION_free
);
320 sk_GENERAL_NAME_pop_free(default_sans
, GENERAL_NAME_free
);
324 OSSL_CMP_MSG
*ossl_cmp_certReq_new(OSSL_CMP_CTX
*ctx
, int type
, int err_code
)
327 OSSL_CRMF_MSG
*crm
= NULL
;
329 if (!ossl_assert(ctx
!= NULL
))
332 if (type
!= OSSL_CMP_PKIBODY_IR
&& type
!= OSSL_CMP_PKIBODY_CR
333 && type
!= OSSL_CMP_PKIBODY_KUR
&& type
!= OSSL_CMP_PKIBODY_P10CR
) {
334 CMPerr(0, CMP_R_INVALID_ARGS
);
338 if ((msg
= ossl_cmp_msg_create(ctx
, type
)) == NULL
)
342 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
346 /* For P10CR the content has already been set in OSSL_CMP_MSG_create */
347 if (type
!= OSSL_CMP_PKIBODY_P10CR
) {
348 EVP_PKEY
*privkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 1);
351 privkey
= ctx
->pkey
; /* default is independent of ctx->oldCert */
352 if (ctx
->popoMethod
== OSSL_CRMF_POPO_SIGNATURE
&& privkey
== NULL
) {
353 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
356 if ((crm
= crm_new(ctx
, type
, OSSL_CMP_CERTREQID
)) == NULL
357 || !OSSL_CRMF_MSG_create_popo(crm
, privkey
, ctx
->digest
,
359 /* value.ir is same for cr and kur */
360 || !sk_OSSL_CRMF_MSG_push(msg
->body
->value
.ir
, crm
))
363 /* TODO: here optional 2nd certreqmsg could be pushed to the stack */
366 if (!ossl_cmp_msg_protect(ctx
, msg
))
374 OSSL_CRMF_MSG_free(crm
);
375 OSSL_CMP_MSG_free(msg
);
379 OSSL_CMP_MSG
*ossl_cmp_certRep_new(OSSL_CMP_CTX
*ctx
, int bodytype
,
380 int certReqId
, OSSL_CMP_PKISI
*si
,
381 X509
*cert
, STACK_OF(X509
) *chain
,
382 STACK_OF(X509
) *caPubs
, int encrypted
,
383 int unprotectedErrors
)
385 OSSL_CMP_MSG
*msg
= NULL
;
386 OSSL_CMP_CERTREPMESSAGE
*repMsg
= NULL
;
387 OSSL_CMP_CERTRESPONSE
*resp
= NULL
;
390 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
393 if ((msg
= ossl_cmp_msg_create(ctx
, bodytype
)) == NULL
)
395 repMsg
= msg
->body
->value
.ip
; /* value.ip is same for cp and kup */
398 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
402 if ((resp
= OSSL_CMP_CERTRESPONSE_new()) == NULL
)
404 OSSL_CMP_PKISI_free(resp
->status
);
405 if ((resp
->status
= OSSL_CMP_PKISI_dup(si
)) == NULL
406 || !ASN1_INTEGER_set(resp
->certReqId
, certReqId
))
409 status
= ossl_cmp_pkisi_get_status(resp
->status
);
410 if (status
!= OSSL_CMP_PKISTATUS_rejection
411 && status
!= OSSL_CMP_PKISTATUS_waiting
&& cert
!= NULL
) {
413 CMPerr(0, CMP_R_INVALID_ARGS
);
417 if ((resp
->certifiedKeyPair
= OSSL_CMP_CERTIFIEDKEYPAIR_new())
420 resp
->certifiedKeyPair
->certOrEncCert
->type
=
421 OSSL_CMP_CERTORENCCERT_CERTIFICATE
;
422 if (!X509_up_ref(cert
))
424 resp
->certifiedKeyPair
->certOrEncCert
->value
.certificate
= cert
;
427 if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg
->response
, resp
))
430 /* TODO: here optional 2nd certrep could be pushed to the stack */
432 if (bodytype
== OSSL_CMP_PKIBODY_IP
&& caPubs
!= NULL
433 && (repMsg
->caPubs
= X509_chain_up_ref(caPubs
)) == NULL
)
435 if (sk_X509_num(chain
) > 0) {
436 msg
->extraCerts
= sk_X509_new_reserve(NULL
, sk_X509_num(chain
));
437 if (msg
->extraCerts
== NULL
438 || !ossl_cmp_sk_X509_add1_certs(msg
->extraCerts
, chain
, 0, 1, 0))
442 if (!unprotectedErrors
443 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
444 if (!ossl_cmp_msg_protect(ctx
, msg
))
450 CMPerr(0, CMP_R_ERROR_CREATING_CERTREP
);
451 OSSL_CMP_CERTRESPONSE_free(resp
);
452 OSSL_CMP_MSG_free(msg
);
456 OSSL_CMP_MSG
*ossl_cmp_rr_new(OSSL_CMP_CTX
*ctx
)
458 OSSL_CMP_MSG
*msg
= NULL
;
459 OSSL_CMP_REVDETAILS
*rd
;
461 if (!ossl_assert(ctx
!= NULL
&& ctx
->oldCert
!= NULL
))
464 if ((rd
= OSSL_CMP_REVDETAILS_new()) == NULL
)
467 /* Fill the template from the contents of the certificate to be revoked */
468 if (!OSSL_CRMF_CERTTEMPLATE_fill(rd
->certDetails
,
469 NULL
/* pubkey would be redundant */,
470 NULL
/* subject would be redundant */,
471 X509_get_issuer_name(ctx
->oldCert
),
472 X509_get0_serialNumber(ctx
->oldCert
)))
475 /* revocation reason code is optional */
476 if (ctx
->revocationReason
!= CRL_REASON_NONE
477 && !add_crl_reason_extension(&rd
->crlEntryDetails
,
478 ctx
->revocationReason
))
481 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RR
)) == NULL
)
484 if (!sk_OSSL_CMP_REVDETAILS_push(msg
->body
->value
.rr
, rd
))
489 * TODO: the Revocation Passphrase according to section 5.3.19.9 could be
490 * set here if set in ctx
493 if (!ossl_cmp_msg_protect(ctx
, msg
))
499 CMPerr(0, CMP_R_ERROR_CREATING_RR
);
500 OSSL_CMP_MSG_free(msg
);
501 OSSL_CMP_REVDETAILS_free(rd
);
505 OSSL_CMP_MSG
*ossl_cmp_rp_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
506 OSSL_CRMF_CERTID
*cid
, int unprot_err
)
508 OSSL_CMP_REVREPCONTENT
*rep
= NULL
;
509 OSSL_CMP_PKISI
*si1
= NULL
;
510 OSSL_CRMF_CERTID
*cid_copy
= NULL
;
511 OSSL_CMP_MSG
*msg
= NULL
;
513 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
&& cid
!= NULL
))
516 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RP
)) == NULL
)
518 rep
= msg
->body
->value
.rp
;
520 if ((si1
= OSSL_CMP_PKISI_dup(si
)) == NULL
)
523 if (!sk_OSSL_CMP_PKISI_push(rep
->status
, si1
)) {
524 OSSL_CMP_PKISI_free(si1
);
528 if ((rep
->revCerts
= sk_OSSL_CRMF_CERTID_new_null()) == NULL
)
530 if ((cid_copy
= OSSL_CRMF_CERTID_dup(cid
)) == NULL
)
532 if (!sk_OSSL_CRMF_CERTID_push(rep
->revCerts
, cid_copy
)) {
533 OSSL_CRMF_CERTID_free(cid_copy
);
538 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
539 if (!ossl_cmp_msg_protect(ctx
, msg
))
545 CMPerr(0, CMP_R_ERROR_CREATING_RP
);
546 OSSL_CMP_MSG_free(msg
);
550 OSSL_CMP_MSG
*ossl_cmp_pkiconf_new(OSSL_CMP_CTX
*ctx
)
554 if (!ossl_assert(ctx
!= NULL
))
557 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_PKICONF
)) == NULL
)
559 if (ossl_cmp_msg_protect(ctx
, msg
))
563 CMPerr(0, CMP_R_ERROR_CREATING_PKICONF
);
564 OSSL_CMP_MSG_free(msg
);
568 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG
*msg
, OSSL_CMP_ITAV
*itav
)
572 if (!ossl_assert(msg
!= NULL
&& itav
!= NULL
))
575 bodytype
= ossl_cmp_msg_get_bodytype(msg
);
576 if (bodytype
!= OSSL_CMP_PKIBODY_GENM
577 && bodytype
!= OSSL_CMP_PKIBODY_GENP
) {
578 CMPerr(0, CMP_R_INVALID_ARGS
);
582 /* value.genp has the same structure, so this works for genp as well */
583 return OSSL_CMP_ITAV_push0_stack_item(&msg
->body
->value
.genm
, itav
);
586 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG
*msg
,
587 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
590 OSSL_CMP_ITAV
*itav
= NULL
;
592 if (!ossl_assert(msg
!= NULL
))
595 for (i
= 0; i
< sk_OSSL_CMP_ITAV_num(itavs
); i
++) {
596 itav
= OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs
, i
));
598 || !ossl_cmp_msg_gen_push0_ITAV(msg
, itav
)) {
599 OSSL_CMP_ITAV_free(itav
);
607 * Creates a new General Message/Response with an empty itav stack
608 * returns a pointer to the PKIMessage on success, NULL on error
610 static OSSL_CMP_MSG
*gen_new(OSSL_CMP_CTX
*ctx
,
611 const STACK_OF(OSSL_CMP_ITAV
) *itavs
,
612 int body_type
, int err_code
)
614 OSSL_CMP_MSG
*msg
= NULL
;
616 if (!ossl_assert(ctx
!= NULL
))
619 if ((msg
= ossl_cmp_msg_create(ctx
, body_type
)) == NULL
)
622 if (ctx
->genm_ITAVs
!= NULL
623 && !ossl_cmp_msg_gen_push1_ITAVs(msg
, itavs
))
626 if (!ossl_cmp_msg_protect(ctx
, msg
))
633 OSSL_CMP_MSG_free(msg
);
637 OSSL_CMP_MSG
*ossl_cmp_genm_new(OSSL_CMP_CTX
*ctx
)
639 return gen_new(ctx
, ctx
->genm_ITAVs
,
640 OSSL_CMP_PKIBODY_GENM
, CMP_R_ERROR_CREATING_GENM
);
643 OSSL_CMP_MSG
*ossl_cmp_genp_new(OSSL_CMP_CTX
*ctx
,
644 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
646 return gen_new(ctx
, itavs
,
647 OSSL_CMP_PKIBODY_GENP
, CMP_R_ERROR_CREATING_GENP
);
650 OSSL_CMP_MSG
*ossl_cmp_error_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
652 const char *details
, int unprotected
)
654 OSSL_CMP_MSG
*msg
= NULL
;
655 OSSL_CMP_PKIFREETEXT
*ft
;
657 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
660 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_ERROR
)) == NULL
)
663 OSSL_CMP_PKISI_free(msg
->body
->value
.error
->pKIStatusInfo
);
664 if ((msg
->body
->value
.error
->pKIStatusInfo
= OSSL_CMP_PKISI_dup(si
))
667 if (errorCode
>= 0) {
668 if ((msg
->body
->value
.error
->errorCode
= ASN1_INTEGER_new()) == NULL
)
670 if (!ASN1_INTEGER_set(msg
->body
->value
.error
->errorCode
, errorCode
))
673 if (details
!= NULL
) {
674 if ((ft
= sk_ASN1_UTF8STRING_new_null()) == NULL
)
676 msg
->body
->value
.error
->errorDetails
= ft
;
677 if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, details
))
681 if (!unprotected
&& !ossl_cmp_msg_protect(ctx
, msg
))
686 CMPerr(0, CMP_R_ERROR_CREATING_ERROR
);
687 OSSL_CMP_MSG_free(msg
);
692 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
693 * This is used in the certConf message, for example,
694 * to confirm that the certificate was received successfully.
696 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS
*certStatus
,
697 ASN1_OCTET_STRING
*hash
)
699 if (!ossl_assert(certStatus
!= NULL
))
701 ASN1_OCTET_STRING_free(certStatus
->certHash
);
702 certStatus
->certHash
= hash
;
707 * TODO: handle potential 2nd certificate when signing and encrypting
708 * certificates have been requested/received
710 OSSL_CMP_MSG
*ossl_cmp_certConf_new(OSSL_CMP_CTX
*ctx
, int fail_info
,
713 OSSL_CMP_MSG
*msg
= NULL
;
714 OSSL_CMP_CERTSTATUS
*certStatus
= NULL
;
715 ASN1_OCTET_STRING
*certHash
= NULL
;
716 OSSL_CMP_PKISI
*sinfo
;
718 if (!ossl_assert(ctx
!= NULL
&& ctx
->newCert
!= NULL
))
721 if ((unsigned)fail_info
> OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN
) {
722 CMPerr(0, CMP_R_FAIL_INFO_OUT_OF_RANGE
);
726 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_CERTCONF
)) == NULL
)
729 if ((certStatus
= OSSL_CMP_CERTSTATUS_new()) == NULL
)
731 /* consume certStatus into msg right away so it gets deallocated with msg */
732 if (!sk_OSSL_CMP_CERTSTATUS_push(msg
->body
->value
.certConf
, certStatus
))
734 /* set the ID of the certReq */
735 if (!ASN1_INTEGER_set(certStatus
->certReqId
, OSSL_CMP_CERTREQID
))
738 * the hash of the certificate, using the same hash algorithm
739 * as is used to create and verify the certificate signature
741 if ((certHash
= X509_digest_sig(ctx
->newCert
)) == NULL
)
744 if (!ossl_cmp_certstatus_set0_certHash(certStatus
, certHash
))
748 * For any particular CertStatus, omission of the statusInfo field
749 * indicates ACCEPTANCE of the specified certificate. Alternatively,
750 * explicit status details (with respect to acceptance or rejection) MAY
751 * be provided in the statusInfo field, perhaps for auditing purposes at
754 sinfo
= fail_info
!= 0 ?
755 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection
, fail_info
, text
) :
756 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted
, 0, text
);
759 certStatus
->statusInfo
= sinfo
;
761 if (!ossl_cmp_msg_protect(ctx
, msg
))
767 CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF
);
768 OSSL_CMP_MSG_free(msg
);
769 ASN1_OCTET_STRING_free(certHash
);
773 OSSL_CMP_MSG
*ossl_cmp_pollReq_new(OSSL_CMP_CTX
*ctx
, int crid
)
775 OSSL_CMP_MSG
*msg
= NULL
;
776 OSSL_CMP_POLLREQ
*preq
= NULL
;
778 if (!ossl_assert(ctx
!= NULL
))
781 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREQ
)) == NULL
)
784 /* TODO: support multiple cert request IDs to poll */
785 if ((preq
= OSSL_CMP_POLLREQ_new()) == NULL
786 || !ASN1_INTEGER_set(preq
->certReqId
, crid
)
787 || !sk_OSSL_CMP_POLLREQ_push(msg
->body
->value
.pollReq
, preq
))
791 if (!ossl_cmp_msg_protect(ctx
, msg
))
797 CMPerr(0, CMP_R_ERROR_CREATING_POLLREQ
);
798 OSSL_CMP_POLLREQ_free(preq
);
799 OSSL_CMP_MSG_free(msg
);
803 OSSL_CMP_MSG
*ossl_cmp_pollRep_new(OSSL_CMP_CTX
*ctx
, int crid
,
807 OSSL_CMP_POLLREP
*prep
;
809 if (!ossl_assert(ctx
!= NULL
))
812 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREP
)) == NULL
)
814 if ((prep
= OSSL_CMP_POLLREP_new()) == NULL
)
816 if (!sk_OSSL_CMP_POLLREP_push(msg
->body
->value
.pollRep
, prep
))
818 if (!ASN1_INTEGER_set(prep
->certReqId
, crid
))
820 if (!ASN1_INTEGER_set_int64(prep
->checkAfter
, poll_after
))
823 if (!ossl_cmp_msg_protect(ctx
, msg
))
828 CMPerr(0, CMP_R_ERROR_CREATING_POLLREP
);
829 OSSL_CMP_MSG_free(msg
);
834 * returns the status field of the RevRepContent with the given
835 * request/sequence id inside a revocation response.
836 * RevRepContent has the revocation statuses in same order as they were sent in
838 * returns NULL on error
841 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
843 OSSL_CMP_PKISI
*status
;
845 if (!ossl_assert(rrep
!= NULL
))
848 if ((status
= sk_OSSL_CMP_PKISI_value(rrep
->status
, rsid
)) != NULL
)
851 CMPerr(0, CMP_R_PKISTATUSINFO_NOT_FOUND
);
856 * returns the CertId field in the revCerts part of the RevRepContent
857 * with the given request/sequence id inside a revocation response.
858 * RevRepContent has the CertIds in same order as they were sent in
860 * returns NULL on error
863 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
865 OSSL_CRMF_CERTID
*cid
= NULL
;
867 if (!ossl_assert(rrep
!= NULL
))
870 if ((cid
= sk_OSSL_CRMF_CERTID_value(rrep
->revCerts
, rsid
)) != NULL
)
873 CMPerr(0, CMP_R_CERTID_NOT_FOUND
);
877 static int suitable_rid(const ASN1_INTEGER
*certReqId
, int rid
)
884 trid
= ossl_cmp_asn1_get_int(certReqId
);
887 CMPerr(0, CMP_R_BAD_REQUEST_ID
);
893 static void add_expected_rid(int rid
)
895 char str
[DECIMAL_SIZE(rid
) + 1];
897 BIO_snprintf(str
, sizeof(str
), "%d", rid
);
898 ERR_add_error_data(2, "expected certReqId = ", str
);
902 * returns a pointer to the PollResponse with the given CertReqId
903 * (or the first one in case -1) inside a PollRepContent
904 * returns NULL on error or if no suitable PollResponse available
907 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT
*prc
,
910 OSSL_CMP_POLLREP
*pollRep
= NULL
;
913 if (!ossl_assert(prc
!= NULL
))
916 for (i
= 0; i
< sk_OSSL_CMP_POLLREP_num(prc
); i
++) {
917 pollRep
= sk_OSSL_CMP_POLLREP_value(prc
, i
);
918 if (suitable_rid(pollRep
->certReqId
, rid
))
922 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
923 add_expected_rid(rid
);
928 * returns a pointer to the CertResponse with the given CertReqId
929 * (or the first one in case -1) inside a CertRepMessage
930 * returns NULL on error or if no suitable CertResponse available
932 OSSL_CMP_CERTRESPONSE
*
933 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE
*crm
,
936 OSSL_CMP_CERTRESPONSE
*crep
= NULL
;
939 if (!ossl_assert(crm
!= NULL
&& crm
->response
!= NULL
))
942 for (i
= 0; i
< sk_OSSL_CMP_CERTRESPONSE_num(crm
->response
); i
++) {
943 crep
= sk_OSSL_CMP_CERTRESPONSE_value(crm
->response
, i
);
944 if (suitable_rid(crep
->certReqId
, rid
))
948 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
949 add_expected_rid(rid
);
954 * CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned
955 * certificate from the given certResponse B<crep>.
956 * Uses the privkey in case of indirect POP from B<ctx>.
957 * Returns a pointer to a copy of the found certificate, or NULL if not found.
959 X509
*ossl_cmp_certresponse_get1_certificate(EVP_PKEY
*privkey
,
960 const OSSL_CMP_CERTRESPONSE
*crep
)
962 OSSL_CMP_CERTORENCCERT
*coec
;
965 if (!ossl_assert(crep
!= NULL
))
968 if (crep
->certifiedKeyPair
969 && (coec
= crep
->certifiedKeyPair
->certOrEncCert
) != NULL
) {
970 switch (coec
->type
) {
971 case OSSL_CMP_CERTORENCCERT_CERTIFICATE
:
972 crt
= X509_dup(coec
->value
.certificate
);
974 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT
:
975 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
976 if (privkey
== NULL
) {
977 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
981 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec
->value
.encryptedCert
,
985 CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE
);
990 CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND
);
994 int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX
*ctx
, OSSL_CMP_MSG
*msg
)
996 if (ctx
== NULL
|| msg
== NULL
) {
997 CMPerr(0, CMP_R_NULL_ARGUMENT
);
1000 if (!ossl_cmp_hdr_set_transactionID(ctx
, msg
->header
))
1002 return msg
->header
->protectionAlg
== NULL
1003 || ossl_cmp_msg_protect(ctx
, msg
);
1006 OSSL_CMP_MSG
*ossl_cmp_msg_load(const char *file
)
1008 OSSL_CMP_MSG
*msg
= NULL
;
1011 if (!ossl_assert(file
!= NULL
))
1014 if ((bio
= BIO_new_file(file
, "rb")) == NULL
)
1016 msg
= d2i_OSSL_CMP_MSG_bio(bio
, NULL
);
1021 OSSL_CMP_MSG
*d2i_OSSL_CMP_MSG_bio(BIO
*bio
, OSSL_CMP_MSG
**msg
)
1023 return ASN1_d2i_bio_of(OSSL_CMP_MSG
, OSSL_CMP_MSG_new
,
1024 d2i_OSSL_CMP_MSG
, bio
, msg
);
1027 int i2d_OSSL_CMP_MSG_bio(BIO
*bio
, const OSSL_CMP_MSG
*msg
)
1029 return ASN1_i2d_bio_of(OSSL_CMP_MSG
, i2d_OSSL_CMP_MSG
, bio
, msg
);