/** * Log when our master signing key certificate expires. Used when tor is given * the --key-expiration command-line option. * * Returns 0 on success and 1 on failure. */ static int log_master_signing_key_cert_expiration(const or_options_t *options) { const tor_cert_t *signing_key; char *fn = NULL; int failed = 0; time_t now = approx_time(); fn = options_get_keydir_fname(options, "ed25519_signing_cert"); /* Try to grab our cached copy of the key. */ signing_key = get_master_signing_key_cert(); tor_assert(server_identity_key_is_set()); /* Load our keys from disk, if necessary. */ if (!signing_key) { failed = load_ed_keys(options, now) < 0; signing_key = get_master_signing_key_cert(); } /* If we do have a signing key, log the expiration time. */ if (signing_key) { log_ed_cert_expiration(signing_key, "signing", fn); } else { log_warn(LD_OR, "Could not load signing key certificate from %s, so " \ "we couldn't learn anything about certificate expiration.", fn); } tor_free(fn); return failed; }
/** Based on our interval and our estimated bandwidth, choose a * deterministic (but random-ish) time to wake up. */ static void accounting_set_wakeup_time(void) { char digest[DIGEST_LEN]; crypto_digest_t *d_env; uint64_t time_to_exhaust_bw; int time_to_consider; if (! server_identity_key_is_set()) { if (init_keys() < 0) { log_err(LD_BUG, "Error initializing keys"); tor_assert(0); } } if (server_identity_key_is_set()) { char buf[ISO_TIME_LEN+1]; format_iso_time(buf, interval_start_time); crypto_pk_get_digest(get_server_identity_key(), digest); d_env = crypto_digest_new(); crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN); crypto_digest_add_bytes(d_env, digest, DIGEST_LEN); crypto_digest_get_digest(d_env, digest, DIGEST_LEN); crypto_digest_free(d_env); } else { crypto_rand(digest, DIGEST_LEN); } if (!expected_bandwidth_usage) { char buf1[ISO_TIME_LEN+1]; char buf2[ISO_TIME_LEN+1]; format_local_iso_time(buf1, interval_start_time); format_local_iso_time(buf2, interval_end_time); interval_wakeup_time = interval_start_time; log_notice(LD_ACCT, "Configured hibernation. This interval begins at %s " "and ends at %s. We have no prior estimate for bandwidth, so " "we will start out awake and hibernate when we exhaust our quota.", buf1, buf2); return; } time_to_exhaust_bw = (get_options()->AccountingMax/expected_bandwidth_usage)*60; if (time_to_exhaust_bw > INT_MAX) { time_to_exhaust_bw = INT_MAX; time_to_consider = 0; } else { time_to_consider = accounting_get_interval_length() - (int)time_to_exhaust_bw; } if (time_to_consider<=0) { interval_wakeup_time = interval_start_time; } else { /* XXX can we simplify this just by picking a random (non-deterministic) * time to be up? If we go down and come up, then we pick a new one. Is * that good enough? -RD */ /* This is not a perfectly unbiased conversion, but it is good enough: * in the worst case, the first half of the day is 0.06 percent likelier * to be chosen than the last half. */ interval_wakeup_time = interval_start_time + (get_uint32(digest) % time_to_consider); } { char buf1[ISO_TIME_LEN+1]; char buf2[ISO_TIME_LEN+1]; char buf3[ISO_TIME_LEN+1]; char buf4[ISO_TIME_LEN+1]; time_t down_time; if (interval_wakeup_time+time_to_exhaust_bw > TIME_MAX) down_time = TIME_MAX; else down_time = (time_t)(interval_wakeup_time+time_to_exhaust_bw); if (down_time>interval_end_time) down_time = interval_end_time; format_local_iso_time(buf1, interval_start_time); format_local_iso_time(buf2, interval_wakeup_time); format_local_iso_time(buf3, down_time); format_local_iso_time(buf4, interval_end_time); log_notice(LD_ACCT, "Configured hibernation. This interval began at %s; " "the scheduled wake-up time %s %s; " "we expect%s to exhaust our quota for this interval around %s; " "the next interval begins at %s (all times local)", buf1, time(NULL)<interval_wakeup_time?"is":"was", buf2, time(NULL)<down_time?"":"ed", buf3, buf4); } }