diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2020-09-04 09:29:01 +0200 |
---|---|---|
committer | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2020-09-05 18:10:03 +0200 |
commit | 39082af2fa6549c3d92c917ea5a423bca57c7b42 (patch) | |
tree | 2e42a3bafd12963a1e55f039361d28dc9320374f /apps/cmp.c | |
parent | 09e76c5dd34515f9df42b2f1deed5166ba6b31fa (diff) |
Add OSSL_CMP_CTX_get1_newChain() and related CLI option -chainout
Also simplify certificate saving in apps/cmp.c
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12790)
Diffstat (limited to 'apps/cmp.c')
-rw-r--r-- | apps/cmp.c | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/apps/cmp.c b/apps/cmp.c index 4d6acdd499..1af27f7881 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -129,6 +129,7 @@ static char *opt_out_trusted = NULL; static int opt_implicit_confirm = 0; static int opt_disable_confirm = 0; static char *opt_certout = NULL; +static char *opt_chainout = NULL; /* certificate enrollment and revocation */ static char *opt_oldcert = NULL; @@ -205,7 +206,7 @@ typedef enum OPTION_choice { OPT_POLICIES, OPT_POLICY_OIDS, OPT_POLICY_OIDS_CRITICAL, OPT_POPO, OPT_CSR, OPT_OUT_TRUSTED, OPT_IMPLICIT_CONFIRM, OPT_DISABLE_CONFIRM, - OPT_CERTOUT, + OPT_CERTOUT, OPT_CHAINOUT, OPT_OLDCERT, OPT_REVREASON, @@ -314,6 +315,8 @@ const OPTIONS cmp_options[] = { "confirmation. WARNING: This leads to behavior violating RFC 4210"}, {"certout", OPT_CERTOUT, 's', "File to save newly enrolled certificate"}, + {"chainout", OPT_CHAINOUT, 's', + "File to save the chain of newly enrolled certificate"}, OPT_SECTION("Certificate enrollment and revocation"), @@ -521,7 +524,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {(char **)&opt_popo}, {&opt_csr}, {&opt_out_trusted}, {(char **)&opt_implicit_confirm}, {(char **)&opt_disable_confirm}, - {&opt_certout}, + {&opt_certout}, {&opt_chainout}, {&opt_oldcert}, {(char **)&opt_revreason}, @@ -2066,18 +2069,21 @@ static int write_cert(BIO *bio, X509 *cert) } /* - * writes out a stack of certs to the given file. + * If destFile != NULL writes out a stack of certs to the given file. + * In any case frees the certs. * Depending on options use either PEM or DER format, * where DER does not make much sense for writing more than one cert! - * Returns number of written certificates on success, 0 on error. + * Returns number of written certificates on success, -1 on error. */ -static int save_certs(OSSL_CMP_CTX *ctx, - STACK_OF(X509) *certs, char *destFile, char *desc) +static int save_free_certs(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *certs, char *destFile, char *desc) { BIO *bio = NULL; int i; int n = sk_X509_num(certs); + if (destFile == NULL) + goto end; CMP_info3("received %d %s certificate(s), saving to file '%s'", n, desc, destFile); if (n > 1 && opt_certform != FORMAT_PEM) @@ -2087,19 +2093,20 @@ static int save_certs(OSSL_CMP_CTX *ctx, || !BIO_write_filename(bio, (char *)destFile)) { CMP_err1("could not open file '%s' for writing", destFile); n = -1; - goto err; + goto end; } for (i = 0; i < n; i++) { if (!write_cert(bio, sk_X509_value(certs, i))) { CMP_err1("cannot write certificate to file '%s'", destFile); n = -1; - goto err; + goto end; } } - err: + end: BIO_free(bio); + sk_X509_pop_free(certs, X509_free); return n; } @@ -2511,6 +2518,9 @@ static int get_opts(int argc, char **argv) case OPT_CERTOUT: opt_certout = opt_str("certout"); break; + case OPT_CHAINOUT: + opt_chainout = opt_str("chainout"); + break; case OPT_OLDCERT: opt_oldcert = opt_str("oldcert"); break; @@ -2935,39 +2945,26 @@ int cmp_main(int argc, char **argv) OPENSSL_free(buf); } - if (opt_cacertsout != NULL) { - STACK_OF(X509) *certs = OSSL_CMP_CTX_get1_caPubs(cmp_ctx); - - if (sk_X509_num(certs) > 0 - && save_certs(cmp_ctx, certs, opt_cacertsout, "CA") < 0) { - sk_X509_pop_free(certs, X509_free); - goto err; - } - sk_X509_pop_free(certs, X509_free); - } - - if (opt_extracertsout != NULL) { - STACK_OF(X509) *certs = OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx); - if (sk_X509_num(certs) > 0 - && save_certs(cmp_ctx, certs, opt_extracertsout, - "extra") < 0) { - sk_X509_pop_free(certs, X509_free); - goto err; - } - sk_X509_pop_free(certs, X509_free); - } - - if (opt_certout != NULL && newcert != NULL) { + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_caPubs(cmp_ctx), + opt_cacertsout, "CA") < 0) + goto err; + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx), + opt_extracertsout, "extra") < 0) + goto err; + if (newcert != NULL) { STACK_OF(X509) *certs = sk_X509_new_null(); - if (certs == NULL || !sk_X509_push(certs, newcert) - || save_certs(cmp_ctx, certs, opt_certout, - "enrolled") < 0) { + if (!X509_add_cert(certs, newcert, X509_ADD_FLAG_UP_REF)) { sk_X509_free(certs); goto err; } - sk_X509_free(certs); + if (save_free_certs(cmp_ctx, certs, opt_certout, "enrolled") < 0) + goto err; } + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_newChain(cmp_ctx), + opt_chainout, "chain") < 0) + goto err; + if (!OSSL_CMP_CTX_reinit(cmp_ctx)) goto err; } |