Add --format argument to --key-expiration option. #30045

This commit is contained in:
Daniel Pinto 2020-08-01 00:03:06 +01:00
parent 700e8a8bb0
commit 1474ab3395
7 changed files with 147 additions and 15 deletions

6
changes/feature30045 Normal file
View File

@ -0,0 +1,6 @@
o Minor features (admin tools):
- Add new --format argument to -key-expiration option to allow
specifying the time format of expiration date. Adds Unix
timestamp format support. Patch by Daniel Pinto. Closes
ticket 30045.

View File

@ -174,16 +174,22 @@ The following options in this section are only recognized on the
If the file descriptor is not specified, the passphrase is read If the file descriptor is not specified, the passphrase is read
from the terminal by default. from the terminal by default.
[[opt-key-expiration]] **`--key-expiration`** [__purpose__]:: [[opt-key-expiration]] **`--key-expiration`** [__purpose__] [**`--format`** **`iso8601`**|**`timestamp`**]::
The __purpose__ specifies which type of key certificate to determine The __purpose__ specifies which type of key certificate to determine
the expiration of. The only currently recognised __purpose__ is the expiration of. The only currently recognised __purpose__ is
"sign". + "sign". +
+ +
Running **`tor --key-expiration sign`** will attempt to find your Running **`tor --key-expiration sign`** will attempt to find your
signing key certificate and will output, both in the logs as well signing key certificate and will output, both in the logs as well
as to stdout, the signing key certificate's expiration time in as to stdout. The optional **`--format`** argument lets you specify
ISO-8601 format. For example, the output sent to stdout will be the time format. Currently, **`iso8601`** and **`timestamp`** are
of the form: "signing-cert-expiry: 2017-07-25 08:30:15 UTC" supported. If **`--format`** is not specified, the signing key
certificate's expiration time will be in ISO-8601 format. For example,
the output sent to stdout will be of the form:
"signing-cert-expiry: 2017-07-25 08:30:15 UTC". If **`--format`** **`timestamp`**
is specified, the signing key certificate's expiration time will be in
Unix timestamp format. For example, the output sent to stdout will be of the form:
"signing-cert-expiry: 1500971415".
[[opt-dbg]] **--dbg-**...:: [[opt-dbg]] **--dbg-**...::
Tor may support other options beginning with the string "dbg". These Tor may support other options beginning with the string "dbg". These

View File

@ -37,7 +37,7 @@ problem file-size /src/app/config/config.c 7525
problem include-count /src/app/config/config.c 81 problem include-count /src/app/config/config.c 81
problem function-size /src/app/config/config.c:options_act() 381 problem function-size /src/app/config/config.c:options_act() 381
problem function-size /src/app/config/config.c:options_validate_cb() 794 problem function-size /src/app/config/config.c:options_validate_cb() 794
problem function-size /src/app/config/config.c:options_init_from_torrc() 198 problem function-size /src/app/config/config.c:options_init_from_torrc() 231
problem function-size /src/app/config/config.c:options_init_from_string() 103 problem function-size /src/app/config/config.c:options_init_from_string() 103
problem function-size /src/app/config/config.c:options_init_logs() 125 problem function-size /src/app/config/config.c:options_init_logs() 125
problem function-size /src/app/config/config.c:parse_bridge_line() 104 problem function-size /src/app/config/config.c:parse_bridge_line() 104
@ -47,7 +47,7 @@ problem function-size /src/app/config/config.c:parse_dir_fallback_line() 101
problem function-size /src/app/config/config.c:port_parse_config() 435 problem function-size /src/app/config/config.c:port_parse_config() 435
problem function-size /src/app/config/config.c:parse_ports() 132 problem function-size /src/app/config/config.c:parse_ports() 132
problem function-size /src/app/config/resolve_addr.c:resolve_my_address_v4() 197 problem function-size /src/app/config/resolve_addr.c:resolve_my_address_v4() 197
problem file-size /src/app/config/or_options_st.h 1050 problem file-size /src/app/config/or_options_st.h 1069
problem include-count /src/app/main/main.c 71 problem include-count /src/app/main/main.c 71
problem function-size /src/app/main/main.c:dumpstats() 102 problem function-size /src/app/main/main.c:dumpstats() 102
problem function-size /src/app/main/main.c:tor_init() 109 problem function-size /src/app/main/main.c:tor_init() 109

View File

@ -2468,6 +2468,8 @@ static const struct {
{ .name="--key-expiration", { .name="--key-expiration",
.takes_argument=ARGUMENT_OPTIONAL, .takes_argument=ARGUMENT_OPTIONAL,
.command=CMD_KEY_EXPIRATION }, .command=CMD_KEY_EXPIRATION },
{ .name="--format",
.takes_argument=ARGUMENT_NECESSARY },
{ .name="--newpass" }, { .name="--newpass" },
{ .name="--no-passphrase" }, { .name="--no-passphrase" },
{ .name="--passphrase-fd", { .name="--passphrase-fd",
@ -4425,6 +4427,39 @@ options_init_from_torrc(int argc, char **argv)
} }
} }
const config_line_t *format_line = config_line_find(cmdline_only_options,
"--format");
if (format_line) {
if (command == CMD_KEY_EXPIRATION) {
const char *v = format_line->value;
// keep the same order as enum key_expiration_format
const char *formats[] = { "iso8601", "timestamp" };
const int formats_len = sizeof(formats) / sizeof(formats[0]);
int format = -1;
for (int i = 0; i < formats_len; i++) {
if (!strcmp(v, formats[i])) {
format = i;
break;
}
}
if (format < 0) {
log_err(LD_CONFIG, "Invalid --format value %s", escaped(v));
retval = -1;
goto err;
} else {
get_options_mutable()->key_expiration_format = format;
}
} else {
log_err(LD_CONFIG, "--format specified without --key-expiration!");
retval = -1;
goto err;
}
} else {
get_options_mutable()->key_expiration_format =
KEY_EXPIRATION_FORMAT_ISO8601;
}
if (config_line_find(cmdline_only_options, "--newpass")) { if (config_line_find(cmdline_only_options, "--newpass")) {
if (command == CMD_KEYGEN) { if (command == CMD_KEYGEN) {
get_options_mutable()->change_key_passphrase = 1; get_options_mutable()->change_key_passphrase = 1;

View File

@ -944,6 +944,11 @@ struct or_options_t {
* ed25519 identity key except from tor --keygen */ * ed25519 identity key except from tor --keygen */
int OfflineMasterKey; int OfflineMasterKey;
enum {
KEY_EXPIRATION_FORMAT_ISO8601 = 0,
KEY_EXPIRATION_FORMAT_TIMESTAMP
} key_expiration_format;
enum { enum {
FORCE_PASSPHRASE_AUTO=0, FORCE_PASSPHRASE_AUTO=0,
FORCE_PASSPHRASE_ON, FORCE_PASSPHRASE_ON,

View File

@ -519,19 +519,34 @@ print_cert_expiration(const char *expiration,
/** /**
* Log when a certificate, <b>cert</b>, with some <b>description</b> and * Log when a certificate, <b>cert</b>, with some <b>description</b> and
* stored in a file named <b>fname</b>, is going to expire. * stored in a file named <b>fname</b>, is going to expire. Formats the expire
* time according to <b>time_format</b>. Valid time formats are in the
* key_expiration_format enum, in or_options_t.
*/ */
static void static void
log_ed_cert_expiration(const tor_cert_t *cert, log_ed_cert_expiration(const tor_cert_t *cert,
const char *description, const char *description,
const char *fname) { const char *fname,
char expiration[ISO_TIME_LEN+1]; int time_format) {
if (BUG(!cert)) { /* If the specified key hasn't been loaded */ if (BUG(!cert)) { /* If the specified key hasn't been loaded */
log_warn(LD_OR, "No %s key loaded; can't get certificate expiration.", log_warn(LD_OR, "No %s key loaded; can't get certificate expiration.",
description); description);
} else { } else {
format_local_iso_time(expiration, cert->valid_until); char expiration[ISO_TIME_LEN+1];
switch (time_format) {
case KEY_EXPIRATION_FORMAT_ISO8601:
format_local_iso_time(expiration, cert->valid_until);
break;
case KEY_EXPIRATION_FORMAT_TIMESTAMP:
tor_snprintf(expiration, sizeof(expiration), "%"PRId64,
(int64_t) cert->valid_until);
break;
default:
log_err(LD_BUG, "Unknown time format value: %d.", time_format);
return;
}
log_notice(LD_OR, "The %s certificate stored in %s is valid until %s.", log_notice(LD_OR, "The %s certificate stored in %s is valid until %s.",
description, fname, expiration); description, fname, expiration);
print_cert_expiration(expiration, description); print_cert_expiration(expiration, description);
@ -567,7 +582,8 @@ log_master_signing_key_cert_expiration(const or_options_t *options)
/* If we do have a signing key, log the expiration time. */ /* If we do have a signing key, log the expiration time. */
if (signing_key) { if (signing_key) {
log_ed_cert_expiration(signing_key, "signing", fn); int time_format = options->key_expiration_format;
log_ed_cert_expiration(signing_key, "signing", fn, time_format);
} else { } else {
log_warn(LD_OR, "Could not load signing key certificate from %s, so " \ log_warn(LD_OR, "Could not load signing key certificate from %s, so " \
"we couldn't learn anything about certificate expiration.", fn); "we couldn't learn anything about certificate expiration.", fn);

View File

@ -61,6 +61,11 @@ fi
CASE1=$dflt CASE1=$dflt
CASE2=$dflt CASE2=$dflt
CASE3=$dflt CASE3=$dflt
CASE4=$dflt
CASE5=$dflt
CASE6=$dflt
CASE7=$dflt
CASE8=$dflt
if [ $# -ge 1 ]; then if [ $# -ge 1 ]; then
eval "CASE${1}"=1 eval "CASE${1}"=1
@ -125,16 +130,17 @@ if [ "$CASE1" = 1 ]; then
${TOR} ${QUIETLY} --key-expiration 2>"$FN" || true ${TOR} ${QUIETLY} --key-expiration 2>"$FN" || true
grep "No valid argument to --key-expiration found!" "$FN" >/dev/null || \ grep "No valid argument to --key-expiration found!" "$FN" >/dev/null || \
die "Tor didn't mention supported --key-expiration argmuents" die "Tor didn't mention supported --key-expiration arguments"
echo "==== Case 1: ok" echo "==== Case 1: ok"
fi fi
if [ "$CASE2" = 1 ]; then if [ "$CASE2" = 1 ]; then
echo "==== Case 2: Start Tor with --key-expiration 'sign' and make sure it prints an expiration." echo "==== Case 2: Start Tor with --key-expiration 'sign' and make sure it"
echo " prints an expiration using ISO8601 date format."
${TOR} ${QUIETLY} --key-expiration sign 2>"$FN" ${TOR} ${QUIETLY} --key-expiration sign 2>"$FN"
grep "signing-cert-expiry:" "$FN" >/dev/null || \ grep "signing-cert-expiry: [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}" "$FN" >/dev/null || \
die "Tor didn't print an expiration" die "Tor didn't print an expiration"
echo "==== Case 2: ok" echo "==== Case 2: ok"
@ -160,3 +166,61 @@ if [ "$CASE3" = 1 ]; then
echo "==== Case 3: ok" echo "==== Case 3: ok"
fi fi
if [ "$CASE4" = 1 ]; then
echo "==== Case 4: Start Tor with --format iso8601 and make sure it prints an"
echo " error message due to missing --key-expiration argument."
${TOR} --format iso8601 > "$FN" 2>&1 || true
grep -- "--format specified without --key-expiration!" "$FN" >/dev/null || \
die "Tor didn't print a missing --key-expiration error message"
echo "==== Case 4: ok"
fi
if [ "$CASE5" = 1 ]; then
echo "==== Case 5: Start Tor with --key-expiration 'sign' --format '' and"
echo " make sure it prints an error message due to missing value."
${TOR} --key-expiration sign --format > "$FN" 2>&1 || true
grep "Command-line option '--format' with no value. Failing." "$FN" >/dev/null || \
die "Tor didn't print a missing format value error message"
echo "==== Case 5: ok"
fi
if [ "$CASE6" = 1 ]; then
echo "==== Case 6: Start Tor with --key-expiration 'sign' --format 'invalid'"
echo " and make sure it prints an error message due to invalid"
echo " value."
${TOR} --key-expiration sign --format invalid > "$FN" 2>&1 || true
grep "Invalid --format value" "$FN" >/dev/null || \
die "Tor didn't print an invalid format value error message"
echo "==== Case 6: ok"
fi
if [ "$CASE7" = 1 ]; then
echo "==== Case 7: Start Tor with --key-expiration 'sign' --format 'iso8601'"
echo " and make sure it prints an expiration using ISO8601 date"
echo " format."
${TOR} ${QUIETLY} --key-expiration sign --format iso8601 2>"$FN"
grep "signing-cert-expiry: [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}" "$FN" >/dev/null || \
die "Tor didn't print an expiration"
echo "==== Case 7: ok"
fi
if [ "$CASE8" = 1 ]; then
echo "==== Case 8: Start Tor with --key-expiration 'sign' --format 'timestamp'"
echo " and make sure it prints an expiration using timestamp date"
echo " format."
${TOR} ${QUIETLY} --key-expiration sign --format timestamp 2>"$FN"
grep "signing-cert-expiry: [0-9]\{5,\}" "$FN" >/dev/null || \
die "Tor didn't print an expiration"
echo "==== Case 8: ok"
fi