hx509: Add hxtool cc --no-root-certs, --no-private-keys, and --append options
This commit is contained in:
@@ -363,6 +363,21 @@ command = {
|
|||||||
argument = "password"
|
argument = "password"
|
||||||
help = "password, prompter, or environment"
|
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"
|
min_args="2"
|
||||||
argument="in-certificates-1 ... out-certificate"
|
argument="in-certificates-1 ... out-certificate"
|
||||||
help = "Copy in certificates stores into out certificate store"
|
help = "Copy in certificates stores into out certificate store"
|
||||||
|
@@ -861,11 +861,26 @@ certificate_copy(struct certificate_copy_options *opt, int argc, char **argv)
|
|||||||
hx509_certs certs;
|
hx509_certs certs;
|
||||||
hx509_lock inlock, outlock = NULL;
|
hx509_lock inlock, outlock = NULL;
|
||||||
char *sn;
|
char *sn;
|
||||||
|
int flags = 0;
|
||||||
|
int store_flags = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
hx509_lock_init(context, &inlock);
|
hx509_lock_init(context, &inlock);
|
||||||
lock_strings(inlock, &opt->in_pass_strings);
|
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) {
|
if (opt->out_pass_string) {
|
||||||
hx509_lock_init(context, &outlock);
|
hx509_lock_init(context, &outlock);
|
||||||
ret = hx509_lock_command_string(outlock, opt->out_pass_string);
|
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);
|
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");
|
sn = fix_store_name(context, argv[argc - 1], "FILE");
|
||||||
ret = hx509_certs_init(context, sn,
|
ret = hx509_certs_init(context, sn,
|
||||||
HX509_CERTS_CREATE, inlock, &certs);
|
HX509_CERTS_CREATE | flags, inlock, &certs);
|
||||||
if (ret)
|
if (ret)
|
||||||
hx509_err(context, 1, ret, "hx509_certs_init %s", sn);
|
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);
|
free(sn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read all the certificate stores in all but the last positional argument.
|
||||||
|
*/
|
||||||
while(argc-- > 1) {
|
while(argc-- > 1) {
|
||||||
int retx;
|
|
||||||
|
|
||||||
sn = fix_store_name(context, argv[0], "FILE");
|
sn = fix_store_name(context, argv[0], "FILE");
|
||||||
retx = hx509_certs_append(context, certs, inlock, sn);
|
ret = hx509_certs_append(context, certs, inlock, sn);
|
||||||
if (retx)
|
if (ret)
|
||||||
hx509_err(context, 1, retx, "hx509_certs_append %s", sn);
|
hx509_err(context, 1, ret, "hx509_certs_append %s", sn);
|
||||||
free(sn);
|
free(sn);
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = hx509_certs_store(context, certs, 0, outlock);
|
ret = hx509_certs_store(context, certs, store_flags, outlock);
|
||||||
if (ret)
|
if (ret)
|
||||||
hx509_err(context, 1, ret, "hx509_certs_store");
|
hx509_err(context, 1, ret, "hx509_certs_store");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user