hx509: Add hxtool cc --no-root-certs, --no-private-keys, and --append options

This commit is contained in:
Nicolas Williams
2022-12-19 16:26:03 -06:00
parent 6def4750bc
commit d24b7fd8b2
2 changed files with 65 additions and 7 deletions

View File

@@ -363,6 +363,21 @@ command = {
argument = "password"
help = "password, prompter, or environment"
}
option = {
long = "append"
type = "flag"
help = "append source to destination"
}
option = {
long = "root-certs"
type = "-flag"
help = "do not copy root certificates"
}
option = {
long = "private-keys"
type = "-flag"
help = "do not copy private keys"
}
min_args="2"
argument="in-certificates-1 ... out-certificate"
help = "Copy in certificates stores into out certificate store"

View File

@@ -861,11 +861,26 @@ certificate_copy(struct certificate_copy_options *opt, int argc, char **argv)
hx509_certs certs;
hx509_lock inlock, outlock = NULL;
char *sn;
int flags = 0;
int store_flags = 0;
int ret;
hx509_lock_init(context, &inlock);
lock_strings(inlock, &opt->in_pass_strings);
if (!opt->root_certs_flag)
/*
* We're probably copying an EE cert, its issuer, and all intermediates
* up to and excluding the root.
*/
store_flags |= HX509_CERTS_STORE_NO_ROOTS;
if (!opt->private_keys_flag) {
/* Neither read nor store private keys */
store_flags |= HX509_CERTS_NO_PRIVATE_KEYS;
flags |= HX509_CERTS_NO_PRIVATE_KEYS;
}
if (opt->out_pass_string) {
hx509_lock_init(context, &outlock);
ret = hx509_lock_command_string(outlock, opt->out_pass_string);
@@ -874,25 +889,53 @@ certificate_copy(struct certificate_copy_options *opt, int argc, char **argv)
opt->out_pass_string, ret);
}
if (argc < 2)
errx(1, "hxtool copy-certificate requires at least two positional "
"arguments");
/*
* The _last_ positional argument is the destination store. Because we use
* HX509_CERTS_CREATE we'll ignore its contents and then truncate to write
* it (well, if it's a file; see key store plugins).
*
* But note that the truncation doesn't happen until we call
* hx509_certs_store(), which means we still have a chance to _read_ this
* store. That means that one can write this:
*
* hxtool cc FILE:b FILE:a FILE:b
*
* to notionally append FILE:a to FILE:b. Still, we'll have an option to
* do the append anyways:
*
* hxtool cc --append FILE:a FILE:b
*/
sn = fix_store_name(context, argv[argc - 1], "FILE");
ret = hx509_certs_init(context, sn,
HX509_CERTS_CREATE, inlock, &certs);
HX509_CERTS_CREATE | flags, inlock, &certs);
if (ret)
hx509_err(context, 1, ret, "hx509_certs_init %s", sn);
if (opt->append_flag) {
/* Append == read the certs in the dst prior to doing anything else */
ret = hx509_certs_append(context, certs, inlock, sn);
if (ret)
hx509_err(context, 1, ret, "hx509_certs_append %s", sn);
}
free(sn);
/*
* Read all the certificate stores in all but the last positional argument.
*/
while(argc-- > 1) {
int retx;
sn = fix_store_name(context, argv[0], "FILE");
retx = hx509_certs_append(context, certs, inlock, sn);
if (retx)
hx509_err(context, 1, retx, "hx509_certs_append %s", sn);
ret = hx509_certs_append(context, certs, inlock, sn);
if (ret)
hx509_err(context, 1, ret, "hx509_certs_append %s", sn);
free(sn);
argv++;
}
ret = hx509_certs_store(context, certs, 0, outlock);
ret = hx509_certs_store(context, certs, store_flags, outlock);
if (ret)
hx509_err(context, 1, ret, "hx509_certs_store");