summaryrefslogtreecommitdiffstats
path: root/apps/cmp.c
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2020-09-04 09:29:01 +0200
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>2020-09-05 18:10:03 +0200
commit39082af2fa6549c3d92c917ea5a423bca57c7b42 (patch)
tree2e42a3bafd12963a1e55f039361d28dc9320374f /apps/cmp.c
parent09e76c5dd34515f9df42b2f1deed5166ba6b31fa (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.c69
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;
}