From 1e7bec7dc30031f465ce95c3b8464ec7b470a97a Mon Sep 17 00:00:00 2001 From: "Dr. David von Oheimb" Date: Thu, 25 Apr 2024 20:05:22 +0200 Subject: [PATCH] CMP app: fix combination of -certout and -chainout with equal filename argument --- apps/cmp.c | 27 +++++++++++++++++++++------ doc/man1/openssl-cmp.pod.in | 6 ++++++ doc/man3/OSSL_CMP_CTX_new.pod | 2 ++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/apps/cmp.c b/apps/cmp.c index 213596f723107..10a477dace22c 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -3435,13 +3435,28 @@ int cmp_main(int argc, char **argv) opt_extracertsout, "extra") < 0) goto err; if (newcert != NULL && (opt_cmd == CMP_IR || opt_cmd == CMP_CR - || opt_cmd == CMP_KUR || opt_cmd == CMP_P10CR)) - if (!save_cert_or_delete(newcert, opt_certout, "newly enrolled") - || save_free_certs(OSSL_CMP_CTX_get1_newChain(cmp_ctx), - opt_chainout, "chain") < 0 - || save_free_certs(OSSL_CMP_CTX_get1_caPubs(cmp_ctx), - opt_cacertsout, "CA") < 0) + || opt_cmd == CMP_KUR || opt_cmd == CMP_P10CR)) { + STACK_OF(X509) *newchain = OSSL_CMP_CTX_get1_newChain(cmp_ctx); + + if (newcert != NULL && newchain != NULL /* NULL is on error only */ + && opt_certout != NULL && opt_chainout != NULL + && strcmp(opt_certout, opt_chainout) == 0) { + if (!X509_add_cert(newchain, newcert, X509_ADD_FLAG_PREPEND + | X509_ADD_FLAG_UP_REF)) { + sk_X509_pop_free(newchain, X509_free); + goto err; + } + if (!save_free_certs(newchain, opt_chainout, "newly enrolled cert and chain")) + goto err; + } else { + if (save_free_certs(newchain, opt_chainout, "chain") < 0 + || !save_cert_or_delete(newcert, opt_certout, "newly enrolled")) + goto err; + } + if (save_free_certs(OSSL_CMP_CTX_get1_caPubs(cmp_ctx), + opt_cacertsout, "CA") < 0) goto err; + } if (!OSSL_CMP_CTX_reinit(cmp_ctx)) goto err; } diff --git a/doc/man1/openssl-cmp.pod.in b/doc/man1/openssl-cmp.pod.in index f9f33db569f73..4f7840270c0b6 100644 --- a/doc/man1/openssl-cmp.pod.in +++ b/doc/man1/openssl-cmp.pod.in @@ -414,6 +414,12 @@ The file where any newly enrolled certificate should be saved. =item B<-chainout> I The file where the chain of any newly enrolled certificate should be saved. +This chain excludes the leaf certificate, i.e., the newly enrolled certificate. +Also the trust anchor (the root certificate) is not included. + +If the B<-certout> option is given, too, with equal I argument, +then the file produced contains both outputs concatenated: +the newly enrolled certificate followed by its chain. =back diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod index 9d117e204a913..eecc67f171c26 100644 --- a/doc/man3/OSSL_CMP_CTX_new.pod +++ b/doc/man3/OSSL_CMP_CTX_new.pod @@ -642,6 +642,8 @@ If the callback argument is NULL the function tries building an approximate chain as far as possible using the same untrusted certificates from the I, and if this fails it takes the received extraCerts as fallback. The resulting cert chain can be retrieved using OSSL_CMP_CTX_get1_newChain(). +This chain excludes the leaf certificate, i.e., the newly enrolled certificate. +Also the trust anchor (the root certificate) is not included. OSSL_CMP_CTX_set_certConf_cb() sets the callback used for evaluating the newly enrolled certificate before the library sends, depending on its result,