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
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 expiration of. The only currently recognised __purpose__ is
"sign". +
+
Running **`tor --key-expiration sign`** will attempt to find your
signing key certificate and will output, both in the logs as well
as to stdout, the signing key certificate's expiration time 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"
as to stdout. The optional **`--format`** argument lets you specify
the time format. Currently, **`iso8601`** and **`timestamp`** are
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-**...::
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 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_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_logs() 125
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:parse_ports() 132
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 function-size /src/app/main/main.c:dumpstats() 102
problem function-size /src/app/main/main.c:tor_init() 109

View File

@ -2468,6 +2468,8 @@ static const struct {
{ .name="--key-expiration",
.takes_argument=ARGUMENT_OPTIONAL,
.command=CMD_KEY_EXPIRATION },
{ .name="--format",
.takes_argument=ARGUMENT_NECESSARY },
{ .name="--newpass" },
{ .name="--no-passphrase" },
{ .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 (command == CMD_KEYGEN) {
get_options_mutable()->change_key_passphrase = 1;

View File

@ -944,6 +944,11 @@ struct or_options_t {
* ed25519 identity key except from tor --keygen */
int OfflineMasterKey;
enum {
KEY_EXPIRATION_FORMAT_ISO8601 = 0,
KEY_EXPIRATION_FORMAT_TIMESTAMP
} key_expiration_format;
enum {
FORCE_PASSPHRASE_AUTO=0,
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
* 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
log_ed_cert_expiration(const tor_cert_t *cert,
const char *description,
const char *fname) {
char expiration[ISO_TIME_LEN+1];
const char *fname,
int time_format) {
if (BUG(!cert)) { /* If the specified key hasn't been loaded */
log_warn(LD_OR, "No %s key loaded; can't get certificate expiration.",
description);
} 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.",
description, fname, expiration);
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 (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 {
log_warn(LD_OR, "Could not load signing key certificate from %s, so " \
"we couldn't learn anything about certificate expiration.", fn);

View File

@ -61,6 +61,11 @@ fi
CASE1=$dflt
CASE2=$dflt
CASE3=$dflt
CASE4=$dflt
CASE5=$dflt
CASE6=$dflt
CASE7=$dflt
CASE8=$dflt
if [ $# -ge 1 ]; then
eval "CASE${1}"=1
@ -125,16 +130,17 @@ if [ "$CASE1" = 1 ]; then
${TOR} ${QUIETLY} --key-expiration 2>"$FN" || true
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"
fi
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"
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"
echo "==== Case 2: ok"
@ -160,3 +166,61 @@ if [ "$CASE3" = 1 ]; then
echo "==== Case 3: ok"
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