2 * Copyright 2007-2019 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_PKIHEADER
*OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG
*msg
)
26 CMPerr(0, CMP_R_NULL_ARGUMENT
);
32 const char *ossl_cmp_bodytype_to_string(int type
)
34 static const char *type_names
[] = {
35 "IR", "IP", "CR", "CP", "P10CR",
36 "POPDECC", "POPDECR", "KUR", "KUP",
37 "KRR", "KRP", "RR", "RP", "CCR", "CCP",
38 "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
39 "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
42 if (type
< 0 || type
> OSSL_CMP_PKIBODY_TYPE_MAX
)
43 return "illegal body type";
44 return type_names
[type
];
47 int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG
*msg
, int type
)
49 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
52 msg
->body
->type
= type
;
56 int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG
*msg
)
58 if (!ossl_assert(msg
!= NULL
&& msg
->body
!= NULL
))
61 return msg
->body
->type
;
64 /* Add an extension to the referenced extension stack, which may be NULL */
65 static int add1_extension(X509_EXTENSIONS
**pexts
, int nid
, int crit
, void *ex
)
70 if (!ossl_assert(pexts
!= NULL
)) /* pointer to var must not be NULL */
73 if ((ext
= X509V3_EXT_i2d(nid
, crit
, ex
)) == NULL
)
76 res
= X509v3_add_ext(pexts
, ext
, 0) != NULL
;
77 X509_EXTENSION_free(ext
);
81 /* Add a CRL revocation reason code to extension stack, which may be NULL */
82 static int add_crl_reason_extension(X509_EXTENSIONS
**pexts
, int reason_code
)
84 ASN1_ENUMERATED
*val
= ASN1_ENUMERATED_new();
87 if (val
!= NULL
&& ASN1_ENUMERATED_set(val
, reason_code
))
88 res
= add1_extension(pexts
, NID_crl_reason
, 0 /* non-critical */, val
);
89 ASN1_ENUMERATED_free(val
);
93 OSSL_CMP_MSG
*ossl_cmp_msg_create(OSSL_CMP_CTX
*ctx
, int bodytype
)
95 OSSL_CMP_MSG
*msg
= NULL
;
97 if (!ossl_assert(ctx
!= NULL
))
100 if ((msg
= OSSL_CMP_MSG_new()) == NULL
)
102 if (!ossl_cmp_hdr_init(ctx
, msg
->header
)
103 || !ossl_cmp_msg_set_bodytype(msg
, bodytype
))
105 if (ctx
->geninfo_ITAVs
!= NULL
106 && !ossl_cmp_hdr_generalInfo_push1_items(msg
->header
,
111 case OSSL_CMP_PKIBODY_IR
:
112 case OSSL_CMP_PKIBODY_CR
:
113 case OSSL_CMP_PKIBODY_KUR
:
114 if ((msg
->body
->value
.ir
= OSSL_CRMF_MSGS_new()) == NULL
)
118 case OSSL_CMP_PKIBODY_P10CR
:
119 if (ctx
->p10CSR
== NULL
) {
120 CMPerr(0, CMP_R_ERROR_CREATING_P10CR
);
123 if ((msg
->body
->value
.p10cr
= X509_REQ_dup(ctx
->p10CSR
)) == NULL
)
127 case OSSL_CMP_PKIBODY_IP
:
128 case OSSL_CMP_PKIBODY_CP
:
129 case OSSL_CMP_PKIBODY_KUP
:
130 if ((msg
->body
->value
.ip
= OSSL_CMP_CERTREPMESSAGE_new()) == NULL
)
134 case OSSL_CMP_PKIBODY_RR
:
135 if ((msg
->body
->value
.rr
= sk_OSSL_CMP_REVDETAILS_new_null()) == NULL
)
138 case OSSL_CMP_PKIBODY_RP
:
139 if ((msg
->body
->value
.rp
= OSSL_CMP_REVREPCONTENT_new()) == NULL
)
143 case OSSL_CMP_PKIBODY_CERTCONF
:
144 if ((msg
->body
->value
.certConf
=
145 sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL
)
148 case OSSL_CMP_PKIBODY_PKICONF
:
149 if ((msg
->body
->value
.pkiconf
= ASN1_TYPE_new()) == NULL
)
151 ASN1_TYPE_set(msg
->body
->value
.pkiconf
, V_ASN1_NULL
, NULL
);
154 case OSSL_CMP_PKIBODY_POLLREQ
:
155 if ((msg
->body
->value
.pollReq
= sk_OSSL_CMP_POLLREQ_new_null()) == NULL
)
158 case OSSL_CMP_PKIBODY_POLLREP
:
159 if ((msg
->body
->value
.pollRep
= sk_OSSL_CMP_POLLREP_new_null()) == NULL
)
163 case OSSL_CMP_PKIBODY_GENM
:
164 case OSSL_CMP_PKIBODY_GENP
:
165 if ((msg
->body
->value
.genm
= sk_OSSL_CMP_ITAV_new_null()) == NULL
)
169 case OSSL_CMP_PKIBODY_ERROR
:
170 if ((msg
->body
->value
.error
= OSSL_CMP_ERRORMSGCONTENT_new()) == NULL
)
175 CMPerr(0, CMP_R_UNEXPECTED_PKIBODY
);
180 OSSL_CMP_MSG_free(msg
);
184 #define HAS_SAN(ctx) \
185 (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
186 || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
188 static const X509_NAME
*determine_subj(OSSL_CMP_CTX
*ctx
, X509
*refcert
,
191 if (ctx
->subjectName
!= NULL
)
192 return ctx
->subjectName
;
195 && (bodytype
== OSSL_CMP_PKIBODY_KUR
|| !HAS_SAN(ctx
)))
197 * For KUR, copy subjectName from reference certificate.
198 * For IR or CR, do the same only if there is no subjectAltName.
200 return X509_get_subject_name(refcert
);
205 * Create CRMF certificate request message for IR/CR/KUR
206 * returns a pointer to the OSSL_CRMF_MSG on success, NULL on error
208 static OSSL_CRMF_MSG
*crm_new(OSSL_CMP_CTX
*ctx
, int bodytype
, int rid
)
210 OSSL_CRMF_MSG
*crm
= NULL
;
211 X509
*refcert
= ctx
->oldCert
!= NULL
? ctx
->oldCert
: ctx
->clCert
;
212 /* refcert defaults to current client cert */
213 EVP_PKEY
*rkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 0);
214 STACK_OF(GENERAL_NAME
) *default_sans
= NULL
;
215 const X509_NAME
*subject
= determine_subj(ctx
, refcert
, bodytype
);
216 int crit
= ctx
->setSubjectAltNameCritical
|| subject
== NULL
;
217 /* RFC5280: subjectAltName MUST be critical if subject is null */
218 X509_EXTENSIONS
*exts
= NULL
;
221 rkey
= ctx
->pkey
; /* default is independent of ctx->oldClCert */
223 || (bodytype
== OSSL_CMP_PKIBODY_KUR
&& refcert
== NULL
)) {
224 CMPerr(0, CMP_R_INVALID_ARGS
);
227 if ((crm
= OSSL_CRMF_MSG_new()) == NULL
)
229 if (!OSSL_CRMF_MSG_set_certReqId(crm
, rid
)
231 * fill certTemplate, corresponding to CertificationRequestInfo
232 * of PKCS#10. The rkey param cannot be NULL so far -
233 * it could be NULL if centralized key creation was supported
235 || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm
), rkey
,
236 subject
, ctx
->issuer
,
239 if (ctx
->days
!= 0) {
240 time_t notBefore
, notAfter
;
242 notBefore
= time(NULL
);
243 notAfter
= notBefore
+ 60 * 60 * 24 * ctx
->days
;
244 if (!OSSL_CRMF_MSG_set_validity(crm
, notBefore
, notAfter
))
249 if (refcert
!= NULL
&& !ctx
->SubjectAltName_nodefault
)
250 default_sans
= X509V3_get_d2i(X509_get0_extensions(refcert
),
251 NID_subject_alt_name
, NULL
, NULL
);
252 /* exts are copied from ctx to allow reuse */
253 if (ctx
->reqExtensions
!= NULL
) {
254 exts
= sk_X509_EXTENSION_deep_copy(ctx
->reqExtensions
,
256 X509_EXTENSION_free
);
260 if (sk_GENERAL_NAME_num(ctx
->subjectAltNames
) > 0
261 && !add1_extension(&exts
, NID_subject_alt_name
,
262 crit
, ctx
->subjectAltNames
))
264 if (!HAS_SAN(ctx
) && default_sans
!= NULL
265 && !add1_extension(&exts
, NID_subject_alt_name
, crit
, default_sans
))
267 if (ctx
->policies
!= NULL
268 && !add1_extension(&exts
, NID_certificate_policies
,
269 ctx
->setPoliciesCritical
, ctx
->policies
))
271 if (!OSSL_CRMF_MSG_set0_extensions(crm
, exts
))
274 /* end fill certTemplate, now set any controls */
276 /* for KUR, set OldCertId according to D.6 */
277 if (bodytype
== OSSL_CMP_PKIBODY_KUR
) {
278 OSSL_CRMF_CERTID
*cid
=
279 OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert
),
280 X509_get_serialNumber(refcert
));
285 ret
= OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm
, cid
);
286 OSSL_CRMF_CERTID_free(cid
);
294 OSSL_CRMF_MSG_free(crm
);
298 sk_X509_EXTENSION_pop_free(exts
, X509_EXTENSION_free
);
299 sk_GENERAL_NAME_pop_free(default_sans
, GENERAL_NAME_free
);
303 OSSL_CMP_MSG
*ossl_cmp_certReq_new(OSSL_CMP_CTX
*ctx
, int type
, int err_code
)
306 OSSL_CRMF_MSG
*crm
= NULL
;
308 if (!ossl_assert(ctx
!= NULL
))
311 if (type
!= OSSL_CMP_PKIBODY_IR
&& type
!= OSSL_CMP_PKIBODY_CR
312 && type
!= OSSL_CMP_PKIBODY_KUR
&& type
!= OSSL_CMP_PKIBODY_P10CR
) {
313 CMPerr(0, CMP_R_INVALID_ARGS
);
317 if ((msg
= ossl_cmp_msg_create(ctx
, type
)) == NULL
)
321 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
325 /* For P10CR the content has already been set in OSSL_CMP_MSG_create */
326 if (type
!= OSSL_CMP_PKIBODY_P10CR
) {
327 EVP_PKEY
*privkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 1);
330 privkey
= ctx
->pkey
; /* default is independent of ctx->oldCert */
331 if (ctx
->popoMethod
== OSSL_CRMF_POPO_SIGNATURE
&& privkey
== NULL
) {
332 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
335 if ((crm
= crm_new(ctx
, type
, OSSL_CMP_CERTREQID
)) == NULL
336 || !OSSL_CRMF_MSG_create_popo(crm
, privkey
, ctx
->digest
,
338 /* value.ir is same for cr and kur */
339 || !sk_OSSL_CRMF_MSG_push(msg
->body
->value
.ir
, crm
))
342 /* TODO: here optional 2nd certreqmsg could be pushed to the stack */
345 if (!ossl_cmp_msg_protect(ctx
, msg
))
353 OSSL_CRMF_MSG_free(crm
);
354 OSSL_CMP_MSG_free(msg
);
358 OSSL_CMP_MSG
*ossl_cmp_certRep_new(OSSL_CMP_CTX
*ctx
, int bodytype
,
359 int certReqId
, OSSL_CMP_PKISI
*si
,
360 X509
*cert
, STACK_OF(X509
) *chain
,
361 STACK_OF(X509
) *caPubs
, int encrypted
,
362 int unprotectedErrors
)
364 OSSL_CMP_MSG
*msg
= NULL
;
365 OSSL_CMP_CERTREPMESSAGE
*repMsg
= NULL
;
366 OSSL_CMP_CERTRESPONSE
*resp
= NULL
;
369 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
372 if ((msg
= ossl_cmp_msg_create(ctx
, bodytype
)) == NULL
)
374 repMsg
= msg
->body
->value
.ip
; /* value.ip is same for cp and kup */
377 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
381 if ((resp
= OSSL_CMP_CERTRESPONSE_new()) == NULL
)
383 OSSL_CMP_PKISI_free(resp
->status
);
384 if ((resp
->status
= OSSL_CMP_PKISI_dup(si
)) == NULL
385 || !ASN1_INTEGER_set(resp
->certReqId
, certReqId
))
388 status
= ossl_cmp_pkisi_get_status(resp
->status
);
389 if (status
!= OSSL_CMP_PKISTATUS_rejection
390 && status
!= OSSL_CMP_PKISTATUS_waiting
&& cert
!= NULL
) {
392 CMPerr(0, CMP_R_INVALID_ARGS
);
396 if ((resp
->certifiedKeyPair
= OSSL_CMP_CERTIFIEDKEYPAIR_new())
399 resp
->certifiedKeyPair
->certOrEncCert
->type
=
400 OSSL_CMP_CERTORENCCERT_CERTIFICATE
;
401 if (!X509_up_ref(cert
))
403 resp
->certifiedKeyPair
->certOrEncCert
->value
.certificate
= cert
;
406 if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg
->response
, resp
))
409 /* TODO: here optional 2nd certrep could be pushed to the stack */
411 if (bodytype
== OSSL_CMP_PKIBODY_IP
&& caPubs
!= NULL
412 && (repMsg
->caPubs
= X509_chain_up_ref(caPubs
)) == NULL
)
415 && !ossl_cmp_sk_X509_add1_certs(msg
->extraCerts
, chain
, 0, 1, 0))
418 if (!unprotectedErrors
419 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
420 if (!ossl_cmp_msg_protect(ctx
, msg
))
426 CMPerr(0, CMP_R_ERROR_CREATING_CERTREP
);
427 OSSL_CMP_CERTRESPONSE_free(resp
);
428 OSSL_CMP_MSG_free(msg
);
432 OSSL_CMP_MSG
*ossl_cmp_rr_new(OSSL_CMP_CTX
*ctx
)
434 OSSL_CMP_MSG
*msg
= NULL
;
435 OSSL_CMP_REVDETAILS
*rd
;
437 if (!ossl_assert(ctx
!= NULL
&& ctx
->oldCert
!= NULL
))
440 if ((rd
= OSSL_CMP_REVDETAILS_new()) == NULL
)
443 /* Fill the template from the contents of the certificate to be revoked */
444 if (!OSSL_CRMF_CERTTEMPLATE_fill(rd
->certDetails
,
445 NULL
/* pubkey would be redundant */,
446 NULL
/* subject would be redundant */,
447 X509_get_issuer_name(ctx
->oldCert
),
448 X509_get_serialNumber(ctx
->oldCert
)))
451 /* revocation reason code is optional */
452 if (ctx
->revocationReason
!= CRL_REASON_NONE
453 && !add_crl_reason_extension(&rd
->crlEntryDetails
,
454 ctx
->revocationReason
))
457 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RR
)) == NULL
)
460 if (!sk_OSSL_CMP_REVDETAILS_push(msg
->body
->value
.rr
, rd
))
465 * TODO: the Revocation Passphrase according to section 5.3.19.9 could be
466 * set here if set in ctx
469 if (!ossl_cmp_msg_protect(ctx
, msg
))
475 CMPerr(0, CMP_R_ERROR_CREATING_RR
);
476 OSSL_CMP_MSG_free(msg
);
477 OSSL_CMP_REVDETAILS_free(rd
);
481 OSSL_CMP_MSG
*ossl_cmp_rp_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
482 OSSL_CRMF_CERTID
*cid
, int unprot_err
)
484 OSSL_CMP_REVREPCONTENT
*rep
= NULL
;
485 OSSL_CMP_PKISI
*si1
= NULL
;
486 OSSL_CRMF_CERTID
*cid_copy
= NULL
;
487 OSSL_CMP_MSG
*msg
= NULL
;
489 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
&& cid
!= NULL
))
492 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RP
)) == NULL
)
494 rep
= msg
->body
->value
.rp
;
496 if ((si1
= OSSL_CMP_PKISI_dup(si
)) == NULL
)
499 if (!sk_OSSL_CMP_PKISI_push(rep
->status
, si1
)) {
500 OSSL_CMP_PKISI_free(si1
);
504 if ((rep
->revCerts
= sk_OSSL_CRMF_CERTID_new_null()) == NULL
)
506 if ((cid_copy
= OSSL_CRMF_CERTID_dup(cid
)) == NULL
)
508 if (!sk_OSSL_CRMF_CERTID_push(rep
->revCerts
, cid_copy
)) {
509 OSSL_CRMF_CERTID_free(cid_copy
);
514 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
515 if (!ossl_cmp_msg_protect(ctx
, msg
))
521 CMPerr(0, CMP_R_ERROR_CREATING_RP
);
522 OSSL_CMP_MSG_free(msg
);
526 OSSL_CMP_MSG
*ossl_cmp_pkiconf_new(OSSL_CMP_CTX
*ctx
)
530 if (!ossl_assert(ctx
!= NULL
))
533 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_PKICONF
)) == NULL
)
535 if (ossl_cmp_msg_protect(ctx
, msg
))
539 CMPerr(0, CMP_R_ERROR_CREATING_PKICONF
);
540 OSSL_CMP_MSG_free(msg
);
544 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG
*msg
, OSSL_CMP_ITAV
*itav
)
548 if (!ossl_assert(msg
!= NULL
&& itav
!= NULL
))
551 bodytype
= ossl_cmp_msg_get_bodytype(msg
);
552 if (bodytype
!= OSSL_CMP_PKIBODY_GENM
553 && bodytype
!= OSSL_CMP_PKIBODY_GENP
) {
554 CMPerr(0, CMP_R_INVALID_ARGS
);
558 /* value.genp has the same structure, so this works for genp as well */
559 return OSSL_CMP_ITAV_push0_stack_item(&msg
->body
->value
.genm
, itav
);
562 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG
*msg
,
563 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
566 OSSL_CMP_ITAV
*itav
= NULL
;
568 if (!ossl_assert(msg
!= NULL
))
571 for (i
= 0; i
< sk_OSSL_CMP_ITAV_num(itavs
); i
++) {
572 if ((itav
= OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs
, i
))) == NULL
)
574 if (!ossl_cmp_msg_gen_push0_ITAV(msg
, itav
)) {
575 OSSL_CMP_ITAV_free(itav
);
583 * Creates a new General Message/Response with an empty itav stack
584 * returns a pointer to the PKIMessage on success, NULL on error
586 static OSSL_CMP_MSG
*gen_new(OSSL_CMP_CTX
*ctx
,
587 const STACK_OF(OSSL_CMP_ITAV
) *itavs
,
588 int body_type
, int err_code
)
590 OSSL_CMP_MSG
*msg
= NULL
;
592 if (!ossl_assert(ctx
!= NULL
))
595 if ((msg
= ossl_cmp_msg_create(ctx
, body_type
)) == NULL
)
598 if (ctx
->genm_ITAVs
!= NULL
599 && !ossl_cmp_msg_gen_push1_ITAVs(msg
, itavs
))
602 if (!ossl_cmp_msg_protect(ctx
, msg
))
609 OSSL_CMP_MSG_free(msg
);
613 OSSL_CMP_MSG
*ossl_cmp_genm_new(OSSL_CMP_CTX
*ctx
)
615 return gen_new(ctx
, ctx
->genm_ITAVs
,
616 OSSL_CMP_PKIBODY_GENM
, CMP_R_ERROR_CREATING_GENM
);
619 OSSL_CMP_MSG
*ossl_cmp_genp_new(OSSL_CMP_CTX
*ctx
,
620 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
622 return gen_new(ctx
, itavs
,
623 OSSL_CMP_PKIBODY_GENP
, CMP_R_ERROR_CREATING_GENP
);
626 OSSL_CMP_MSG
*ossl_cmp_error_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
628 const char *details
, int unprotected
)
630 OSSL_CMP_MSG
*msg
= NULL
;
631 OSSL_CMP_PKIFREETEXT
*ft
;
633 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
636 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_ERROR
)) == NULL
)
639 OSSL_CMP_PKISI_free(msg
->body
->value
.error
->pKIStatusInfo
);
640 if ((msg
->body
->value
.error
->pKIStatusInfo
= OSSL_CMP_PKISI_dup(si
))
643 if (errorCode
>= 0) {
644 if ((msg
->body
->value
.error
->errorCode
= ASN1_INTEGER_new()) == NULL
)
646 if (!ASN1_INTEGER_set(msg
->body
->value
.error
->errorCode
, errorCode
))
649 if (details
!= NULL
) {
650 if ((ft
= sk_ASN1_UTF8STRING_new_null()) == NULL
)
652 msg
->body
->value
.error
->errorDetails
= ft
;
653 if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, details
))
657 if (!unprotected
&& !ossl_cmp_msg_protect(ctx
, msg
))
662 CMPerr(0, CMP_R_ERROR_CREATING_ERROR
);
663 OSSL_CMP_MSG_free(msg
);
668 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
669 * This is used in the certConf message, for example,
670 * to confirm that the certificate was received successfully.
672 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS
*certStatus
,
673 ASN1_OCTET_STRING
*hash
)
675 if (!ossl_assert(certStatus
!= NULL
))
677 ASN1_OCTET_STRING_free(certStatus
->certHash
);
678 certStatus
->certHash
= hash
;
683 * TODO: handle potential 2nd certificate when signing and encrypting
684 * certificates have been requested/received
686 OSSL_CMP_MSG
*ossl_cmp_certConf_new(OSSL_CMP_CTX
*ctx
, int fail_info
,
689 OSSL_CMP_MSG
*msg
= NULL
;
690 OSSL_CMP_CERTSTATUS
*certStatus
= NULL
;
691 ASN1_OCTET_STRING
*certHash
= NULL
;
692 OSSL_CMP_PKISI
*sinfo
;
694 if (!ossl_assert(ctx
!= NULL
&& ctx
->newCert
!= NULL
))
697 if ((unsigned)fail_info
> OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN
) {
698 CMPerr(0, CMP_R_FAIL_INFO_OUT_OF_RANGE
);
702 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_CERTCONF
)) == NULL
)
705 if ((certStatus
= OSSL_CMP_CERTSTATUS_new()) == NULL
)
707 /* consume certStatus into msg right away so it gets deallocated with msg */
708 if (!sk_OSSL_CMP_CERTSTATUS_push(msg
->body
->value
.certConf
, certStatus
))
710 /* set the ID of the certReq */
711 if (!ASN1_INTEGER_set(certStatus
->certReqId
, OSSL_CMP_CERTREQID
))
714 * the hash of the certificate, using the same hash algorithm
715 * as is used to create and verify the certificate signature
717 if ((certHash
= X509_digest_sig(ctx
->newCert
)) == NULL
)
720 if (!ossl_cmp_certstatus_set0_certHash(certStatus
, certHash
))
724 * For any particular CertStatus, omission of the statusInfo field
725 * indicates ACCEPTANCE of the specified certificate. Alternatively,
726 * explicit status details (with respect to acceptance or rejection) MAY
727 * be provided in the statusInfo field, perhaps for auditing purposes at
730 sinfo
= fail_info
!= 0 ?
731 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection
, fail_info
, text
) :
732 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted
, 0, text
);
735 certStatus
->statusInfo
= sinfo
;
737 if (!ossl_cmp_msg_protect(ctx
, msg
))
743 CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF
);
744 OSSL_CMP_MSG_free(msg
);
745 ASN1_OCTET_STRING_free(certHash
);
749 OSSL_CMP_MSG
*ossl_cmp_pollReq_new(OSSL_CMP_CTX
*ctx
, int crid
)
751 OSSL_CMP_MSG
*msg
= NULL
;
752 OSSL_CMP_POLLREQ
*preq
= NULL
;
754 if (!ossl_assert(ctx
!= NULL
))
757 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREQ
)) == NULL
)
760 /* TODO: support multiple cert request IDs to poll */
761 if ((preq
= OSSL_CMP_POLLREQ_new()) == NULL
762 || !ASN1_INTEGER_set(preq
->certReqId
, crid
)
763 || !sk_OSSL_CMP_POLLREQ_push(msg
->body
->value
.pollReq
, preq
))
767 if (!ossl_cmp_msg_protect(ctx
, msg
))
773 CMPerr(0, CMP_R_ERROR_CREATING_POLLREQ
);
774 OSSL_CMP_POLLREQ_free(preq
);
775 OSSL_CMP_MSG_free(msg
);
779 OSSL_CMP_MSG
*ossl_cmp_pollRep_new(OSSL_CMP_CTX
*ctx
, int crid
,
783 OSSL_CMP_POLLREP
*prep
;
785 if (!ossl_assert(ctx
!= NULL
))
788 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREP
)) == NULL
)
790 if ((prep
= OSSL_CMP_POLLREP_new()) == NULL
)
792 if (!sk_OSSL_CMP_POLLREP_push(msg
->body
->value
.pollRep
, prep
))
794 if (!ASN1_INTEGER_set(prep
->certReqId
, crid
))
796 if (!ASN1_INTEGER_set_int64(prep
->checkAfter
, poll_after
))
799 if (!ossl_cmp_msg_protect(ctx
, msg
))
804 CMPerr(0, CMP_R_ERROR_CREATING_POLLREP
);
805 OSSL_CMP_MSG_free(msg
);
810 * returns the status field of the RevRepContent with the given
811 * request/sequence id inside a revocation response.
812 * RevRepContent has the revocation statuses in same order as they were sent in
814 * returns NULL on error
817 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
819 OSSL_CMP_PKISI
*status
;
821 if (!ossl_assert(rrep
!= NULL
))
824 if ((status
= sk_OSSL_CMP_PKISI_value(rrep
->status
, rsid
)) != NULL
)
827 CMPerr(0, CMP_R_PKISTATUSINFO_NOT_FOUND
);
832 * returns the CertId field in the revCerts part of the RevRepContent
833 * with the given request/sequence id inside a revocation response.
834 * RevRepContent has the CertIds in same order as they were sent in
836 * returns NULL on error
839 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
841 OSSL_CRMF_CERTID
*cid
= NULL
;
843 if (!ossl_assert(rrep
!= NULL
))
846 if ((cid
= sk_OSSL_CRMF_CERTID_value(rrep
->revCerts
, rsid
)) != NULL
)
849 CMPerr(0, CMP_R_CERTID_NOT_FOUND
);
853 static int suitable_rid(const ASN1_INTEGER
*certReqId
, int rid
)
860 trid
= ossl_cmp_asn1_get_int(certReqId
);
863 CMPerr(0, CMP_R_BAD_REQUEST_ID
);
869 static void add_expected_rid(int rid
)
871 char str
[DECIMAL_SIZE(rid
) + 1];
873 BIO_snprintf(str
, sizeof(str
), "%d", rid
);
874 ERR_add_error_data(2, "expected certReqId = ", str
);
878 * returns a pointer to the PollResponse with the given CertReqId
879 * (or the first one in case -1) inside a PollRepContent
880 * returns NULL on error or if no suitable PollResponse available
883 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT
*prc
,
886 OSSL_CMP_POLLREP
*pollRep
= NULL
;
889 if (!ossl_assert(prc
!= NULL
))
892 for (i
= 0; i
< sk_OSSL_CMP_POLLREP_num(prc
); i
++) {
893 pollRep
= sk_OSSL_CMP_POLLREP_value(prc
, i
);
894 if (suitable_rid(pollRep
->certReqId
, rid
))
898 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
899 add_expected_rid(rid
);
904 * returns a pointer to the CertResponse with the given CertReqId
905 * (or the first one in case -1) inside a CertRepMessage
906 * returns NULL on error or if no suitable CertResponse available
908 OSSL_CMP_CERTRESPONSE
*
909 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE
*crm
,
912 OSSL_CMP_CERTRESPONSE
*crep
= NULL
;
915 if (!ossl_assert(crm
!= NULL
&& crm
->response
!= NULL
))
918 for (i
= 0; i
< sk_OSSL_CMP_CERTRESPONSE_num(crm
->response
); i
++) {
919 crep
= sk_OSSL_CMP_CERTRESPONSE_value(crm
->response
, i
);
920 if (suitable_rid(crep
->certReqId
, rid
))
924 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
925 add_expected_rid(rid
);
930 * CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned
931 * certificate from the given certResponse B<crep>.
932 * Uses the privkey in case of indirect POP from B<ctx>.
933 * Returns a pointer to a copy of the found certificate, or NULL if not found.
935 X509
*ossl_cmp_certresponse_get1_certificate(EVP_PKEY
*privkey
,
936 const OSSL_CMP_CERTRESPONSE
*crep
)
938 OSSL_CMP_CERTORENCCERT
*coec
;
941 if (!ossl_assert(crep
!= NULL
))
944 if (crep
->certifiedKeyPair
945 && (coec
= crep
->certifiedKeyPair
->certOrEncCert
) != NULL
) {
946 switch (coec
->type
) {
947 case OSSL_CMP_CERTORENCCERT_CERTIFICATE
:
948 crt
= X509_dup(coec
->value
.certificate
);
950 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT
:
951 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
952 if (privkey
== NULL
) {
953 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
957 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec
->value
.encryptedCert
,
961 CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE
);
966 CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND
);
970 OSSL_CMP_MSG
*ossl_cmp_msg_load(const char *file
)
972 OSSL_CMP_MSG
*msg
= NULL
;
975 if (!ossl_assert(file
!= NULL
))
978 if ((bio
= BIO_new_file(file
, "rb")) == NULL
)
980 msg
= d2i_OSSL_CMP_MSG_bio(bio
, NULL
);
985 OSSL_CMP_MSG
*d2i_OSSL_CMP_MSG_bio(BIO
*bio
, OSSL_CMP_MSG
**msg
)
987 return ASN1_d2i_bio_of(OSSL_CMP_MSG
, OSSL_CMP_MSG_new
,
988 d2i_OSSL_CMP_MSG
, bio
, msg
);
991 int i2d_OSSL_CMP_MSG_bio(BIO
*bio
, const OSSL_CMP_MSG
*msg
)
993 return ASN1_i2d_bio_of(OSSL_CMP_MSG
, i2d_OSSL_CMP_MSG
, bio
, msg
);