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 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 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
))
352 OSSL_CRMF_MSG_free(crm
);
353 OSSL_CMP_MSG_free(msg
);
357 OSSL_CMP_MSG
*ossl_cmp_certRep_new(OSSL_CMP_CTX
*ctx
, int bodytype
,
358 int certReqId
, OSSL_CMP_PKISI
*si
,
359 X509
*cert
, STACK_OF(X509
) *chain
,
360 STACK_OF(X509
) *caPubs
, int encrypted
,
361 int unprotectedErrors
)
363 OSSL_CMP_MSG
*msg
= NULL
;
364 OSSL_CMP_CERTREPMESSAGE
*repMsg
= NULL
;
365 OSSL_CMP_CERTRESPONSE
*resp
= NULL
;
368 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
371 if ((msg
= ossl_cmp_msg_create(ctx
, bodytype
)) == NULL
)
373 repMsg
= msg
->body
->value
.ip
; /* value.ip is same for cp and kup */
376 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
380 if ((resp
= OSSL_CMP_CERTRESPONSE_new()) == NULL
)
382 OSSL_CMP_PKISI_free(resp
->status
);
383 if ((resp
->status
= OSSL_CMP_PKISI_dup(si
)) == NULL
384 || !ASN1_INTEGER_set(resp
->certReqId
, certReqId
))
387 status
= ossl_cmp_pkisi_get_status(resp
->status
);
388 if (status
!= OSSL_CMP_PKISTATUS_rejection
389 && status
!= OSSL_CMP_PKISTATUS_waiting
&& cert
!= NULL
) {
391 CMPerr(0, CMP_R_INVALID_ARGS
);
395 if ((resp
->certifiedKeyPair
= OSSL_CMP_CERTIFIEDKEYPAIR_new())
398 resp
->certifiedKeyPair
->certOrEncCert
->type
=
399 OSSL_CMP_CERTORENCCERT_CERTIFICATE
;
400 if (!X509_up_ref(cert
))
402 resp
->certifiedKeyPair
->certOrEncCert
->value
.certificate
= cert
;
405 if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg
->response
, resp
))
408 /* TODO: here optional 2nd certrep could be pushed to the stack */
410 if (bodytype
== OSSL_CMP_PKIBODY_IP
&& caPubs
!= NULL
411 && (repMsg
->caPubs
= X509_chain_up_ref(caPubs
)) == NULL
)
414 && !ossl_cmp_sk_X509_add1_certs(msg
->extraCerts
, chain
, 0, 1, 0))
417 if (!unprotectedErrors
418 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
419 if (!ossl_cmp_msg_protect(ctx
, msg
))
425 CMPerr(0, CMP_R_ERROR_CREATING_CERTREP
);
426 OSSL_CMP_CERTRESPONSE_free(resp
);
427 OSSL_CMP_MSG_free(msg
);
431 OSSL_CMP_MSG
*ossl_cmp_rr_new(OSSL_CMP_CTX
*ctx
)
433 OSSL_CMP_MSG
*msg
= NULL
;
434 OSSL_CMP_REVDETAILS
*rd
;
436 if (!ossl_assert(ctx
!= NULL
&& ctx
->oldCert
!= NULL
))
439 if ((rd
= OSSL_CMP_REVDETAILS_new()) == NULL
)
442 /* Fill the template from the contents of the certificate to be revoked */
443 if (!OSSL_CRMF_CERTTEMPLATE_fill(rd
->certDetails
,
444 NULL
/* pubkey would be redundant */,
445 NULL
/* subject would be redundant */,
446 X509_get_issuer_name(ctx
->oldCert
),
447 X509_get_serialNumber(ctx
->oldCert
)))
450 /* revocation reason code is optional */
451 if (ctx
->revocationReason
!= CRL_REASON_NONE
452 && !add_crl_reason_extension(&rd
->crlEntryDetails
,
453 ctx
->revocationReason
))
456 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RR
)) == NULL
)
459 if (!sk_OSSL_CMP_REVDETAILS_push(msg
->body
->value
.rr
, rd
))
464 * TODO: the Revocation Passphrase according to section 5.3.19.9 could be
465 * set here if set in ctx
468 if (!ossl_cmp_msg_protect(ctx
, msg
))
474 CMPerr(0, CMP_R_ERROR_CREATING_RR
);
475 OSSL_CMP_MSG_free(msg
);
476 OSSL_CMP_REVDETAILS_free(rd
);
480 OSSL_CMP_MSG
*ossl_cmp_rp_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
481 OSSL_CRMF_CERTID
*cid
, int unprot_err
)
483 OSSL_CMP_REVREPCONTENT
*rep
= NULL
;
484 OSSL_CMP_PKISI
*si1
= NULL
;
485 OSSL_CRMF_CERTID
*cid_copy
= NULL
;
486 OSSL_CMP_MSG
*msg
= NULL
;
488 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
&& cid
!= NULL
))
491 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_RP
)) == NULL
)
493 rep
= msg
->body
->value
.rp
;
495 if ((si1
= OSSL_CMP_PKISI_dup(si
)) == NULL
)
498 if (!sk_OSSL_CMP_PKISI_push(rep
->status
, si1
)) {
499 OSSL_CMP_PKISI_free(si1
);
503 if ((rep
->revCerts
= sk_OSSL_CRMF_CERTID_new_null()) == NULL
)
505 if ((cid_copy
= OSSL_CRMF_CERTID_dup(cid
)) == NULL
)
507 if (!sk_OSSL_CRMF_CERTID_push(rep
->revCerts
, cid_copy
)) {
508 OSSL_CRMF_CERTID_free(cid_copy
);
513 || ossl_cmp_pkisi_get_status(si
) != OSSL_CMP_PKISTATUS_rejection
)
514 if (!ossl_cmp_msg_protect(ctx
, msg
))
520 CMPerr(0, CMP_R_ERROR_CREATING_RP
);
521 OSSL_CMP_MSG_free(msg
);
525 OSSL_CMP_MSG
*ossl_cmp_pkiconf_new(OSSL_CMP_CTX
*ctx
)
529 if (!ossl_assert(ctx
!= NULL
))
532 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_PKICONF
)) == NULL
)
534 if (ossl_cmp_msg_protect(ctx
, msg
))
538 CMPerr(0, CMP_R_ERROR_CREATING_PKICONF
);
539 OSSL_CMP_MSG_free(msg
);
543 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG
*msg
, OSSL_CMP_ITAV
*itav
)
547 if (!ossl_assert(msg
!= NULL
&& itav
!= NULL
))
550 bodytype
= ossl_cmp_msg_get_bodytype(msg
);
551 if (bodytype
!= OSSL_CMP_PKIBODY_GENM
552 && bodytype
!= OSSL_CMP_PKIBODY_GENP
) {
553 CMPerr(0, CMP_R_INVALID_ARGS
);
557 /* value.genp has the same structure, so this works for genp as well */
558 return OSSL_CMP_ITAV_push0_stack_item(&msg
->body
->value
.genm
, itav
);
561 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG
*msg
,
562 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
565 OSSL_CMP_ITAV
*itav
= NULL
;
567 if (!ossl_assert(msg
!= NULL
))
570 for (i
= 0; i
< sk_OSSL_CMP_ITAV_num(itavs
); i
++) {
571 if ((itav
= OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs
, i
))) == NULL
)
573 if (!ossl_cmp_msg_gen_push0_ITAV(msg
, itav
)) {
574 OSSL_CMP_ITAV_free(itav
);
582 * Creates a new General Message/Response with an empty itav stack
583 * returns a pointer to the PKIMessage on success, NULL on error
585 static OSSL_CMP_MSG
*gen_new(OSSL_CMP_CTX
*ctx
,
586 const STACK_OF(OSSL_CMP_ITAV
) *itavs
,
587 int body_type
, int err_code
)
589 OSSL_CMP_MSG
*msg
= NULL
;
591 if (!ossl_assert(ctx
!= NULL
))
594 if ((msg
= ossl_cmp_msg_create(ctx
, body_type
)) == NULL
)
597 if (ctx
->genm_ITAVs
!= NULL
598 && !ossl_cmp_msg_gen_push1_ITAVs(msg
, itavs
))
601 if (!ossl_cmp_msg_protect(ctx
, msg
))
608 OSSL_CMP_MSG_free(msg
);
612 OSSL_CMP_MSG
*ossl_cmp_genm_new(OSSL_CMP_CTX
*ctx
)
614 return gen_new(ctx
, ctx
->genm_ITAVs
,
615 OSSL_CMP_PKIBODY_GENM
, CMP_R_ERROR_CREATING_GENM
);
618 OSSL_CMP_MSG
*ossl_cmp_genp_new(OSSL_CMP_CTX
*ctx
,
619 const STACK_OF(OSSL_CMP_ITAV
) *itavs
)
621 return gen_new(ctx
, itavs
,
622 OSSL_CMP_PKIBODY_GENP
, CMP_R_ERROR_CREATING_GENP
);
625 OSSL_CMP_MSG
*ossl_cmp_error_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
627 const char *details
, int unprotected
)
629 OSSL_CMP_MSG
*msg
= NULL
;
630 OSSL_CMP_PKIFREETEXT
*ft
;
632 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
635 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_ERROR
)) == NULL
)
638 OSSL_CMP_PKISI_free(msg
->body
->value
.error
->pKIStatusInfo
);
639 if ((msg
->body
->value
.error
->pKIStatusInfo
= OSSL_CMP_PKISI_dup(si
))
642 if (errorCode
>= 0) {
643 if ((msg
->body
->value
.error
->errorCode
= ASN1_INTEGER_new()) == NULL
)
645 if (!ASN1_INTEGER_set(msg
->body
->value
.error
->errorCode
, errorCode
))
648 if (details
!= NULL
) {
649 if ((ft
= sk_ASN1_UTF8STRING_new_null()) == NULL
)
651 msg
->body
->value
.error
->errorDetails
= ft
;
652 if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft
, details
))
656 if (!unprotected
&& !ossl_cmp_msg_protect(ctx
, msg
))
661 CMPerr(0, CMP_R_ERROR_CREATING_ERROR
);
662 OSSL_CMP_MSG_free(msg
);
667 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
668 * This is used in the certConf message, for example,
669 * to confirm that the certificate was received successfully.
671 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS
*certStatus
,
672 ASN1_OCTET_STRING
*hash
)
674 if (!ossl_assert(certStatus
!= NULL
))
676 ASN1_OCTET_STRING_free(certStatus
->certHash
);
677 certStatus
->certHash
= hash
;
682 * TODO: handle potential 2nd certificate when signing and encrypting
683 * certificates have been requested/received
685 OSSL_CMP_MSG
*ossl_cmp_certConf_new(OSSL_CMP_CTX
*ctx
, int fail_info
,
688 OSSL_CMP_MSG
*msg
= NULL
;
689 OSSL_CMP_CERTSTATUS
*certStatus
= NULL
;
690 ASN1_OCTET_STRING
*certHash
= NULL
;
691 OSSL_CMP_PKISI
*sinfo
;
693 if (!ossl_assert(ctx
!= NULL
&& ctx
->newCert
!= NULL
))
696 if ((unsigned)fail_info
> OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN
) {
697 CMPerr(0, CMP_R_FAIL_INFO_OUT_OF_RANGE
);
701 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_CERTCONF
)) == NULL
)
704 if ((certStatus
= OSSL_CMP_CERTSTATUS_new()) == NULL
)
706 /* consume certStatus into msg right away so it gets deallocated with msg */
707 if (!sk_OSSL_CMP_CERTSTATUS_push(msg
->body
->value
.certConf
, certStatus
))
709 /* set the ID of the certReq */
710 if (!ASN1_INTEGER_set(certStatus
->certReqId
, OSSL_CMP_CERTREQID
))
713 * the hash of the certificate, using the same hash algorithm
714 * as is used to create and verify the certificate signature
716 if ((certHash
= X509_digest_sig(ctx
->newCert
)) == NULL
)
719 if (!ossl_cmp_certstatus_set0_certHash(certStatus
, certHash
))
723 * For any particular CertStatus, omission of the statusInfo field
724 * indicates ACCEPTANCE of the specified certificate. Alternatively,
725 * explicit status details (with respect to acceptance or rejection) MAY
726 * be provided in the statusInfo field, perhaps for auditing purposes at
729 sinfo
= fail_info
!= 0 ?
730 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection
, fail_info
, text
) :
731 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted
, 0, text
);
734 certStatus
->statusInfo
= sinfo
;
736 if (!ossl_cmp_msg_protect(ctx
, msg
))
742 CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF
);
743 OSSL_CMP_MSG_free(msg
);
744 ASN1_OCTET_STRING_free(certHash
);
748 OSSL_CMP_MSG
*ossl_cmp_pollReq_new(OSSL_CMP_CTX
*ctx
, int crid
)
750 OSSL_CMP_MSG
*msg
= NULL
;
751 OSSL_CMP_POLLREQ
*preq
= NULL
;
753 if (!ossl_assert(ctx
!= NULL
))
756 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREQ
)) == NULL
)
759 /* TODO: support multiple cert request IDs to poll */
760 if ((preq
= OSSL_CMP_POLLREQ_new()) == NULL
761 || !ASN1_INTEGER_set(preq
->certReqId
, crid
)
762 || !sk_OSSL_CMP_POLLREQ_push(msg
->body
->value
.pollReq
, preq
))
766 if (!ossl_cmp_msg_protect(ctx
, msg
))
772 CMPerr(0, CMP_R_ERROR_CREATING_POLLREQ
);
773 OSSL_CMP_POLLREQ_free(preq
);
774 OSSL_CMP_MSG_free(msg
);
778 OSSL_CMP_MSG
*ossl_cmp_pollRep_new(OSSL_CMP_CTX
*ctx
, int crid
,
782 OSSL_CMP_POLLREP
*prep
;
784 if (!ossl_assert(ctx
!= NULL
))
787 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREP
)) == NULL
)
789 if ((prep
= OSSL_CMP_POLLREP_new()) == NULL
)
791 if (!sk_OSSL_CMP_POLLREP_push(msg
->body
->value
.pollRep
, prep
))
793 if (!ASN1_INTEGER_set(prep
->certReqId
, crid
))
795 if (!ASN1_INTEGER_set_int64(prep
->checkAfter
, poll_after
))
798 if (!ossl_cmp_msg_protect(ctx
, msg
))
803 CMPerr(0, CMP_R_ERROR_CREATING_POLLREP
);
804 OSSL_CMP_MSG_free(msg
);
809 * returns the status field of the RevRepContent with the given
810 * request/sequence id inside a revocation response.
811 * RevRepContent has the revocation statuses in same order as they were sent in
813 * returns NULL on error
816 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
818 OSSL_CMP_PKISI
*status
;
820 if (!ossl_assert(rrep
!= NULL
))
823 if ((status
= sk_OSSL_CMP_PKISI_value(rrep
->status
, rsid
)) != NULL
)
826 CMPerr(0, CMP_R_PKISTATUSINFO_NOT_FOUND
);
831 * returns the CertId field in the revCerts part of the RevRepContent
832 * with the given request/sequence id inside a revocation response.
833 * RevRepContent has the CertIds in same order as they were sent in
835 * returns NULL on error
838 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
840 OSSL_CRMF_CERTID
*cid
= NULL
;
842 if (!ossl_assert(rrep
!= NULL
))
845 if ((cid
= sk_OSSL_CRMF_CERTID_value(rrep
->revCerts
, rsid
)) != NULL
)
848 CMPerr(0, CMP_R_CERTID_NOT_FOUND
);
852 static int suitable_rid(const ASN1_INTEGER
*certReqId
, int rid
)
859 trid
= ossl_cmp_asn1_get_int(certReqId
);
862 CMPerr(0, CMP_R_BAD_REQUEST_ID
);
868 static void add_expected_rid(int rid
)
870 char str
[DECIMAL_SIZE(rid
) + 1];
872 BIO_snprintf(str
, sizeof(str
), "%d", rid
);
873 ERR_add_error_data(2, "expected certReqId = ", str
);
877 * returns a pointer to the PollResponse with the given CertReqId
878 * (or the first one in case -1) inside a PollRepContent
879 * returns NULL on error or if no suitable PollResponse available
882 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT
*prc
,
885 OSSL_CMP_POLLREP
*pollRep
= NULL
;
888 if (!ossl_assert(prc
!= NULL
))
891 for (i
= 0; i
< sk_OSSL_CMP_POLLREP_num(prc
); i
++) {
892 pollRep
= sk_OSSL_CMP_POLLREP_value(prc
, i
);
893 if (suitable_rid(pollRep
->certReqId
, rid
))
897 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
898 add_expected_rid(rid
);
903 * returns a pointer to the CertResponse with the given CertReqId
904 * (or the first one in case -1) inside a CertRepMessage
905 * returns NULL on error or if no suitable CertResponse available
907 OSSL_CMP_CERTRESPONSE
*
908 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE
*crm
,
911 OSSL_CMP_CERTRESPONSE
*crep
= NULL
;
914 if (!ossl_assert(crm
!= NULL
&& crm
->response
!= NULL
))
917 for (i
= 0; i
< sk_OSSL_CMP_CERTRESPONSE_num(crm
->response
); i
++) {
918 crep
= sk_OSSL_CMP_CERTRESPONSE_value(crm
->response
, i
);
919 if (suitable_rid(crep
->certReqId
, rid
))
923 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
924 add_expected_rid(rid
);
929 * CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned
930 * certificate from the given certResponse B<crep>.
931 * Uses the privkey in case of indirect POP from B<ctx>.
932 * Returns a pointer to a copy of the found certificate, or NULL if not found.
934 X509
*ossl_cmp_certresponse_get1_certificate(EVP_PKEY
*privkey
,
935 const OSSL_CMP_CERTRESPONSE
*crep
)
937 OSSL_CMP_CERTORENCCERT
*coec
;
940 if (!ossl_assert(crep
!= NULL
))
943 if (crep
->certifiedKeyPair
944 && (coec
= crep
->certifiedKeyPair
->certOrEncCert
) != NULL
) {
945 switch (coec
->type
) {
946 case OSSL_CMP_CERTORENCCERT_CERTIFICATE
:
947 crt
= X509_dup(coec
->value
.certificate
);
949 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT
:
950 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
951 if (privkey
== NULL
) {
952 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
956 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec
->value
.encryptedCert
,
960 CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE
);
965 CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND
);
969 OSSL_CMP_MSG
*ossl_cmp_msg_load(const char *file
)
971 OSSL_CMP_MSG
*msg
= NULL
;
974 if (!ossl_assert(file
!= NULL
))
977 if ((bio
= BIO_new_file(file
, "rb")) == NULL
)
979 msg
= OSSL_d2i_CMP_MSG_bio(bio
, NULL
);
984 OSSL_CMP_MSG
*OSSL_d2i_CMP_MSG_bio(BIO
*bio
, OSSL_CMP_MSG
**msg
)
986 return ASN1_d2i_bio_of(OSSL_CMP_MSG
, OSSL_CMP_MSG_new
,
987 d2i_OSSL_CMP_MSG
, bio
, msg
);
990 int OSSL_i2d_CMP_MSG_bio(BIO
*bio
, const OSSL_CMP_MSG
*msg
)
992 return ASN1_i2d_bio_of(OSSL_CMP_MSG
, i2d_OSSL_CMP_MSG
, bio
, msg
);