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
,
209 int rid
, EVP_PKEY
*rkey
)
211 OSSL_CRMF_MSG
*crm
= NULL
;
212 X509
*refcert
= ctx
->oldCert
!= NULL
? ctx
->oldCert
: ctx
->clCert
;
213 /* refcert defaults to current client cert */
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 || (bodytype
== OSSL_CMP_PKIBODY_KUR
&& refcert
== NULL
)) {
222 CMPerr(0, CMP_R_INVALID_ARGS
);
225 if ((crm
= OSSL_CRMF_MSG_new()) == NULL
)
227 if (!OSSL_CRMF_MSG_set_certReqId(crm
, rid
)
229 * fill certTemplate, corresponding to CertificationRequestInfo
230 * of PKCS#10. The rkey param cannot be NULL so far -
231 * it could be NULL if centralized key creation was supported
233 || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm
), rkey
,
234 subject
, ctx
->issuer
,
237 if (ctx
->days
!= 0) {
238 time_t notBefore
, notAfter
;
240 notBefore
= time(NULL
);
241 notAfter
= notBefore
+ 60 * 60 * 24 * ctx
->days
;
242 if (!OSSL_CRMF_MSG_set_validity(crm
, notBefore
, notAfter
))
247 if (refcert
!= NULL
&& !ctx
->SubjectAltName_nodefault
)
248 default_sans
= X509V3_get_d2i(X509_get0_extensions(refcert
),
249 NID_subject_alt_name
, NULL
, NULL
);
250 /* exts are copied from ctx to allow reuse */
251 if (ctx
->reqExtensions
!= NULL
) {
252 exts
= sk_X509_EXTENSION_deep_copy(ctx
->reqExtensions
,
254 X509_EXTENSION_free
);
258 if (sk_GENERAL_NAME_num(ctx
->subjectAltNames
) > 0
259 && !add1_extension(&exts
, NID_subject_alt_name
,
260 crit
, ctx
->subjectAltNames
))
262 if (!HAS_SAN(ctx
) && default_sans
!= NULL
263 && !add1_extension(&exts
, NID_subject_alt_name
, crit
, default_sans
))
265 if (ctx
->policies
!= NULL
266 && !add1_extension(&exts
, NID_certificate_policies
,
267 ctx
->setPoliciesCritical
, ctx
->policies
))
269 if (!OSSL_CRMF_MSG_set0_extensions(crm
, exts
))
272 /* end fill certTemplate, now set any controls */
274 /* for KUR, set OldCertId according to D.6 */
275 if (bodytype
== OSSL_CMP_PKIBODY_KUR
) {
276 OSSL_CRMF_CERTID
*cid
=
277 OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert
),
278 X509_get_serialNumber(refcert
));
283 ret
= OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm
, cid
);
284 OSSL_CRMF_CERTID_free(cid
);
292 OSSL_CRMF_MSG_free(crm
);
296 sk_X509_EXTENSION_pop_free(exts
, X509_EXTENSION_free
);
297 sk_GENERAL_NAME_pop_free(default_sans
, GENERAL_NAME_free
);
301 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 rkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 0);
314 privkey
= OSSL_CMP_CTX_get0_newPkey(ctx
, 1);
316 if (type
!= OSSL_CMP_PKIBODY_IR
&& type
!= OSSL_CMP_PKIBODY_CR
317 && type
!= OSSL_CMP_PKIBODY_KUR
&& type
!= OSSL_CMP_PKIBODY_P10CR
) {
318 CMPerr(0, CMP_R_INVALID_ARGS
);
322 if ((msg
= ossl_cmp_msg_create(ctx
, type
)) == NULL
)
326 if (ctx
->implicitConfirm
&& !ossl_cmp_hdr_set_implicitConfirm(msg
->header
))
330 /* For P10CR the content has already been set in OSSL_CMP_MSG_create */
331 if (type
!= OSSL_CMP_PKIBODY_P10CR
) {
332 if (ctx
->popoMethod
== OSSL_CRMF_POPO_SIGNATURE
&& privkey
== NULL
) {
333 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
336 if ((crm
= crm_new(ctx
, type
, OSSL_CMP_CERTREQID
, rkey
)) == NULL
337 || !OSSL_CRMF_MSG_create_popo(crm
, privkey
, ctx
->digest
,
339 /* value.ir is same for cr and kur */
340 || !sk_OSSL_CRMF_MSG_push(msg
->body
->value
.ir
, crm
))
343 /* TODO: here optional 2nd certreqmsg could be pushed to the stack */
346 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_pkistatus(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_pkistatus(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_pkistatus(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 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
, int body_type
, int err_code
)
588 OSSL_CMP_MSG
*msg
= NULL
;
590 if (!ossl_assert(ctx
!= NULL
))
593 if ((msg
= ossl_cmp_msg_create(ctx
, body_type
)) == NULL
)
596 if (ctx
->genm_ITAVs
!= NULL
597 && !ossl_cmp_msg_gen_push1_ITAVs(msg
, ctx
->genm_ITAVs
))
600 if (!ossl_cmp_msg_protect(ctx
, msg
))
607 OSSL_CMP_MSG_free(msg
);
611 OSSL_CMP_MSG
*ossl_cmp_genm_new(OSSL_CMP_CTX
*ctx
)
613 return gen_new(ctx
, OSSL_CMP_PKIBODY_GENM
, CMP_R_ERROR_CREATING_GENM
);
616 OSSL_CMP_MSG
*ossl_cmp_genp_new(OSSL_CMP_CTX
*ctx
)
618 return gen_new(ctx
, OSSL_CMP_PKIBODY_GENP
, CMP_R_ERROR_CREATING_GENP
);
621 OSSL_CMP_MSG
*ossl_cmp_error_new(OSSL_CMP_CTX
*ctx
, OSSL_CMP_PKISI
*si
,
623 OSSL_CMP_PKIFREETEXT
*errorDetails
,
626 OSSL_CMP_MSG
*msg
= NULL
;
628 if (!ossl_assert(ctx
!= NULL
&& si
!= NULL
))
631 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_ERROR
)) == NULL
)
634 OSSL_CMP_PKISI_free(msg
->body
->value
.error
->pKIStatusInfo
);
635 if ((msg
->body
->value
.error
->pKIStatusInfo
= OSSL_CMP_PKISI_dup(si
))
638 if (errorCode
>= 0) {
639 if ((msg
->body
->value
.error
->errorCode
= ASN1_INTEGER_new()) == NULL
)
641 if (!ASN1_INTEGER_set(msg
->body
->value
.error
->errorCode
, errorCode
))
644 if (errorDetails
!= NULL
)
645 if ((msg
->body
->value
.error
->errorDetails
=
646 sk_ASN1_UTF8STRING_deep_copy(errorDetails
, ASN1_STRING_dup
,
647 ASN1_STRING_free
)) == NULL
)
650 if (!unprotected
&& !ossl_cmp_msg_protect(ctx
, msg
))
655 CMPerr(0, CMP_R_ERROR_CREATING_ERROR
);
656 OSSL_CMP_MSG_free(msg
);
661 * OSSL_CMP_CERTSTATUS_set_certHash() calculates a hash of the certificate,
662 * using the same hash algorithm as is used to create and verify the
663 * certificate signature, and places the hash into the certHash field of a
664 * OSSL_CMP_CERTSTATUS structure. This is used in the certConf message,
665 * for example, to confirm that the certificate was received successfully.
667 int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS
*certStatus
,
671 unsigned char hash
[EVP_MAX_MD_SIZE
];
673 const EVP_MD
*md
= NULL
;
675 if (!ossl_assert(certStatus
!= NULL
&& cert
!= NULL
))
679 * select hash algorithm, as stated in Appendix F. Compilable ASN.1 defs:
680 * the hash of the certificate, using the same hash algorithm
681 * as is used to create and verify the certificate signature
683 if (OBJ_find_sigid_algs(X509_get_signature_nid(cert
), &md_NID
, NULL
)
684 && (md
= EVP_get_digestbynid(md_NID
)) != NULL
) {
685 if (!X509_digest(cert
, md
, hash
, &len
))
687 if (!ossl_cmp_asn1_octet_string_set1_bytes(&certStatus
->certHash
, hash
,
691 CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM
);
697 CMPerr(0, CMP_R_ERROR_SETTING_CERTHASH
);
702 * TODO: handle potential 2nd certificate when signing and encrypting
703 * certificates have been requested/received
705 OSSL_CMP_MSG
*ossl_cmp_certConf_new(OSSL_CMP_CTX
*ctx
, int fail_info
,
708 OSSL_CMP_MSG
*msg
= NULL
;
709 OSSL_CMP_CERTSTATUS
*certStatus
= NULL
;
710 OSSL_CMP_PKISI
*sinfo
;
712 if (!ossl_assert(ctx
!= NULL
&& ctx
->newCert
!= NULL
))
715 if ((unsigned)fail_info
> OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN
) {
716 CMPerr(0, CMP_R_FAIL_INFO_OUT_OF_RANGE
);
720 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_CERTCONF
)) == NULL
)
723 if ((certStatus
= OSSL_CMP_CERTSTATUS_new()) == NULL
)
725 /* consume certStatus into msg right away so it gets deallocated with msg */
726 if (!sk_OSSL_CMP_CERTSTATUS_push(msg
->body
->value
.certConf
, certStatus
))
728 /* set the ID of the certReq */
729 if (!ASN1_INTEGER_set(certStatus
->certReqId
, OSSL_CMP_CERTREQID
))
732 * the hash of the certificate, using the same hash algorithm
733 * as is used to create and verify the certificate signature
735 if (!ossl_cmp_certstatus_set_certHash(certStatus
, ctx
->newCert
))
738 * For any particular CertStatus, omission of the statusInfo field
739 * indicates ACCEPTANCE of the specified certificate. Alternatively,
740 * explicit status details (with respect to acceptance or rejection) MAY
741 * be provided in the statusInfo field, perhaps for auditing purposes at
744 sinfo
= fail_info
!= 0 ?
745 ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_rejection
, fail_info
, text
) :
746 ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_accepted
, 0, text
);
749 certStatus
->statusInfo
= sinfo
;
751 if (!ossl_cmp_msg_protect(ctx
, msg
))
757 CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF
);
758 OSSL_CMP_MSG_free(msg
);
762 OSSL_CMP_MSG
*ossl_cmp_pollReq_new(OSSL_CMP_CTX
*ctx
, int crid
)
764 OSSL_CMP_MSG
*msg
= NULL
;
765 OSSL_CMP_POLLREQ
*preq
= NULL
;
767 if (!ossl_assert(ctx
!= NULL
))
770 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREQ
)) == NULL
)
773 /* TODO: support multiple cert request IDs to poll */
774 if ((preq
= OSSL_CMP_POLLREQ_new()) == NULL
775 || !ASN1_INTEGER_set(preq
->certReqId
, crid
)
776 || !sk_OSSL_CMP_POLLREQ_push(msg
->body
->value
.pollReq
, preq
))
780 if (!ossl_cmp_msg_protect(ctx
, msg
))
786 CMPerr(0, CMP_R_ERROR_CREATING_POLLREQ
);
787 OSSL_CMP_POLLREQ_free(preq
);
788 OSSL_CMP_MSG_free(msg
);
792 OSSL_CMP_MSG
*ossl_cmp_pollRep_new(OSSL_CMP_CTX
*ctx
, int crid
,
796 OSSL_CMP_POLLREP
*prep
;
798 if (!ossl_assert(ctx
!= NULL
))
801 if ((msg
= ossl_cmp_msg_create(ctx
, OSSL_CMP_PKIBODY_POLLREP
)) == NULL
)
803 if ((prep
= OSSL_CMP_POLLREP_new()) == NULL
)
805 if (!sk_OSSL_CMP_POLLREP_push(msg
->body
->value
.pollRep
, prep
))
807 if (!ASN1_INTEGER_set(prep
->certReqId
, crid
))
809 if (!ASN1_INTEGER_set_int64(prep
->checkAfter
, poll_after
))
812 if (!ossl_cmp_msg_protect(ctx
, msg
))
817 CMPerr(0, CMP_R_ERROR_CREATING_POLLREP
);
818 OSSL_CMP_MSG_free(msg
);
823 * returns the status field of the RevRepContent with the given
824 * request/sequence id inside a revocation response.
825 * RevRepContent has the revocation statuses in same order as they were sent in
827 * returns NULL on error
830 ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
832 OSSL_CMP_PKISI
*status
;
834 if (!ossl_assert(rrep
!= NULL
))
837 if ((status
= sk_OSSL_CMP_PKISI_value(rrep
->status
, rsid
)) != NULL
)
840 CMPerr(0, CMP_R_PKISTATUSINFO_NOT_FOUND
);
845 * returns the CertId field in the revCerts part of the RevRepContent
846 * with the given request/sequence id inside a revocation response.
847 * RevRepContent has the CertIds in same order as they were sent in
849 * returns NULL on error
852 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT
*rrep
, int rsid
)
854 OSSL_CRMF_CERTID
*cid
= NULL
;
856 if (!ossl_assert(rrep
!= NULL
))
859 if ((cid
= sk_OSSL_CRMF_CERTID_value(rrep
->revCerts
, rsid
)) != NULL
)
862 CMPerr(0, CMP_R_CERTID_NOT_FOUND
);
866 static int suitable_rid(const ASN1_INTEGER
*certReqId
, int rid
)
873 trid
= ossl_cmp_asn1_get_int(certReqId
);
876 CMPerr(0, CMP_R_BAD_REQUEST_ID
);
882 static void add_expected_rid(int rid
)
884 char str
[DECIMAL_SIZE(rid
) + 1];
886 BIO_snprintf(str
, sizeof(str
), "%d", rid
);
887 ERR_add_error_data(2, "expected certReqId = ", str
);
891 * returns a pointer to the PollResponse with the given CertReqId
892 * (or the first one in case -1) inside a PollRepContent
893 * returns NULL on error or if no suitable PollResponse available
896 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT
*prc
,
899 OSSL_CMP_POLLREP
*pollRep
= NULL
;
902 if (!ossl_assert(prc
!= NULL
))
905 for (i
= 0; i
< sk_OSSL_CMP_POLLREP_num(prc
); i
++) {
906 pollRep
= sk_OSSL_CMP_POLLREP_value(prc
, i
);
907 if (suitable_rid(pollRep
->certReqId
, rid
))
911 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
912 add_expected_rid(rid
);
917 * returns a pointer to the CertResponse with the given CertReqId
918 * (or the first one in case -1) inside a CertRepMessage
919 * returns NULL on error or if no suitable CertResponse available
921 OSSL_CMP_CERTRESPONSE
*
922 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE
*crm
,
925 OSSL_CMP_CERTRESPONSE
*crep
= NULL
;
928 if (!ossl_assert(crm
!= NULL
&& crm
->response
!= NULL
))
931 for (i
= 0; i
< sk_OSSL_CMP_CERTRESPONSE_num(crm
->response
); i
++) {
932 crep
= sk_OSSL_CMP_CERTRESPONSE_value(crm
->response
, i
);
933 if (suitable_rid(crep
->certReqId
, rid
))
937 CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND
);
938 add_expected_rid(rid
);
943 * CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned
944 * certificate from the given certResponse B<crep>.
945 * Uses the privkey in case of indirect POP from B<ctx>.
946 * Returns a pointer to a copy of the found certificate, or NULL if not found.
948 X509
*ossl_cmp_certresponse_get1_certificate(EVP_PKEY
*privkey
,
949 const OSSL_CMP_CERTRESPONSE
*crep
)
951 OSSL_CMP_CERTORENCCERT
*coec
;
954 if (!ossl_assert(crep
!= NULL
))
957 if (crep
->certifiedKeyPair
958 && (coec
= crep
->certifiedKeyPair
->certOrEncCert
) != NULL
) {
959 switch (coec
->type
) {
960 case OSSL_CMP_CERTORENCCERT_CERTIFICATE
:
961 crt
= X509_dup(coec
->value
.certificate
);
963 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT
:
964 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
965 if (privkey
== NULL
) {
966 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY
);
970 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec
->value
.encryptedCert
,
974 CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE
);
979 CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND
);
983 OSSL_CMP_MSG
*ossl_cmp_msg_load(const char *file
)
985 OSSL_CMP_MSG
*msg
= NULL
;
988 if (!ossl_assert(file
!= NULL
))
991 if ((bio
= BIO_new_file(file
, "rb")) == NULL
)
993 msg
= OSSL_d2i_CMP_MSG_bio(bio
, NULL
);