tor-commits
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2018
- 17 participants
- 3230 discussions

[tor/master] Move key-loading and crosscert-checking out of feature/relay
by nickm@torproject.org 26 Sep '18
by nickm@torproject.org 26 Sep '18
26 Sep '18
commit 934859cf80902e6a16fb69d884fadc8ea831779f
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Sep 25 14:19:48 2018 -0400
Move key-loading and crosscert-checking out of feature/relay
This is also used by onion services, so it needs to go in another
module.
---
src/core/include.am | 3 +
src/feature/hs/hs_service.c | 3 +-
src/feature/keymgt/loadkey.c | 755 ++++++++++++++++++++++++++++++++++++++++
src/feature/keymgt/loadkey.h | 55 +++
src/feature/nodelist/torcert.c | 37 ++
src/feature/nodelist/torcert.h | 6 +
src/feature/relay/router.c | 91 +----
src/feature/relay/router.h | 2 -
src/feature/relay/routerkeys.c | 682 +-----------------------------------
src/feature/relay/routerkeys.h | 41 ---
src/feature/rend/rendservice.c | 5 +-
src/test/fuzz/fuzz_descriptor.c | 4 +-
src/test/test_routerkeys.c | 1 +
13 files changed, 874 insertions(+), 811 deletions(-)
diff --git a/src/core/include.am b/src/core/include.am
index 0bd4626c4..954b3bb55 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -86,6 +86,8 @@ LIBTOR_APP_A_SOURCES = \
src/feature/hs/hs_stats.c \
src/feature/hs_common/replaycache.c \
src/feature/hs_common/shared_random_client.c \
+ src/feature/keymgt/loadkey.c \
+ src/feature/dirauth/keypin.c \
src/feature/nodelist/authcert.c \
src/feature/nodelist/dirlist.c \
src/feature/nodelist/microdesc.c \
@@ -289,6 +291,7 @@ noinst_HEADERS += \
src/feature/hs/hsdir_index_st.h \
src/feature/hs_common/replaycache.h \
src/feature/hs_common/shared_random_client.h \
+ src/feature/keymgt/loadkey.h \
src/feature/nodelist/authcert.h \
src/feature/nodelist/authority_cert_st.h \
src/feature/nodelist/desc_store_st.h \
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index dc7bb41ee..aa031bd70 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -27,7 +27,8 @@
#include "core/or/relay.h"
#include "feature/rend/rendservice.h"
#include "feature/relay/router.h"
-#include "feature/relay/routerkeys.h"
+#include "feature/keymgt/loadkey.h"
+//#include "feature/relay/routerkeys.h"
#include "feature/nodelist/node_select.h"
#include "feature/hs_common/shared_random_client.h"
#include "app/config/statefile.h"
diff --git a/src/feature/keymgt/loadkey.c b/src/feature/keymgt/loadkey.c
new file mode 100644
index 000000000..4621e39c5
--- /dev/null
+++ b/src/feature/keymgt/loadkey.c
@@ -0,0 +1,755 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file loadkey.c
+ * \brief Read keys from disk, creating as needed
+ *
+ * This code is shared by relays and onion services, which both need
+ * this functionality.
+ **/
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "app/main/main.h"
+#include "feature/keymgt/loadkey.h"
+#include "feature/nodelist/torcert.h"
+
+#include "lib/crypt_ops/crypto_pwbox.h"
+#include "lib/crypt_ops/crypto_util.h"
+#include "lib/term/getpass.h"
+#include "lib/crypt_ops/crypto_format.h"
+
+#define ENC_KEY_HEADER "Boxed Ed25519 key"
+#define ENC_KEY_TAG "master"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist
+ * and <b>generate</b> is true, create a new RSA key and save it in
+ * <b>fname</b>. Return the read/created key, or NULL on error. Log all
+ * errors at level <b>severity</b>. If <b>created_out/b> is non-NULL and a
+ * new key was created, set *<b>created_out</b> to true.
+ */
+crypto_pk_t *
+init_key_from_file(const char *fname, int generate, int severity,
+ bool *created_out)
+{
+ crypto_pk_t *prkey = NULL;
+
+ if (created_out) {
+ *created_out = false;
+ }
+
+ if (!(prkey = crypto_pk_new())) {
+ tor_log(severity, LD_GENERAL,"Error constructing key");
+ goto error;
+ }
+
+ switch (file_status(fname)) {
+ case FN_DIR:
+ case FN_ERROR:
+ tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname);
+ goto error;
+ /* treat empty key files as if the file doesn't exist, and,
+ * if generate is set, replace the empty file in
+ * crypto_pk_write_private_key_to_filename() */
+ case FN_NOENT:
+ case FN_EMPTY:
+ if (generate) {
+ if (!have_lockfile()) {
+ if (try_locking(get_options(), 0)<0) {
+ /* Make sure that --list-fingerprint only creates new keys
+ * if there is no possibility for a deadlock. */
+ tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". "
+ "Not writing any new keys.", fname);
+ /*XXXX The 'other process' might make a key in a second or two;
+ * maybe we should wait for it. */
+ goto error;
+ }
+ }
+ log_info(LD_GENERAL, "No key found in \"%s\"; generating fresh key.",
+ fname);
+ if (crypto_pk_generate_key(prkey)) {
+ tor_log(severity, LD_GENERAL,"Error generating onion key");
+ goto error;
+ }
+ if (! crypto_pk_is_valid_private_key(prkey)) {
+ tor_log(severity, LD_GENERAL,"Generated key seems invalid");
+ goto error;
+ }
+ log_info(LD_GENERAL, "Generated key seems valid");
+ if (created_out) {
+ *created_out = true;
+ }
+ if (crypto_pk_write_private_key_to_filename(prkey, fname)) {
+ tor_log(severity, LD_FS,
+ "Couldn't write generated key to \"%s\".", fname);
+ goto error;
+ }
+ } else {
+ tor_log(severity, LD_GENERAL, "No key found in \"%s\"", fname);
+ goto error;
+ }
+ return prkey;
+ case FN_FILE:
+ if (crypto_pk_read_private_key_from_filename(prkey, fname)) {
+ tor_log(severity, LD_GENERAL,"Error loading private key.");
+ goto error;
+ }
+ return prkey;
+ default:
+ tor_assert(0);
+ }
+
+ error:
+ if (prkey)
+ crypto_pk_free(prkey);
+ return NULL;
+}
+
+/* DOCDOC */
+static ssize_t
+do_getpass(const char *prompt, char *buf, size_t buflen,
+ int twice, const or_options_t *options)
+{
+ if (options->keygen_force_passphrase == FORCE_PASSPHRASE_OFF) {
+ tor_assert(buflen);
+ buf[0] = 0;
+ return 0;
+ }
+
+ char *prompt2 = NULL;
+ char *buf2 = NULL;
+ int fd = -1;
+ ssize_t length = -1;
+
+ if (options->use_keygen_passphrase_fd) {
+ twice = 0;
+ fd = options->keygen_passphrase_fd;
+ length = read_all_from_fd(fd, buf, buflen-1);
+ if (length >= 0)
+ buf[length] = 0;
+ goto done_reading;
+ }
+
+ if (twice) {
+ const char msg[] = "One more time:";
+ size_t p2len = strlen(prompt) + 1;
+ if (p2len < sizeof(msg))
+ p2len = sizeof(msg);
+ prompt2 = tor_malloc(p2len);
+ memset(prompt2, ' ', p2len);
+ memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg));
+
+ buf2 = tor_malloc_zero(buflen);
+ }
+
+ while (1) {
+ length = tor_getpass(prompt, buf, buflen);
+ if (length < 0)
+ goto done_reading;
+
+ if (! twice)
+ break;
+
+ ssize_t length2 = tor_getpass(prompt2, buf2, buflen);
+
+ if (length != length2 || tor_memneq(buf, buf2, length)) {
+ fprintf(stderr, "That didn't match.\n");
+ } else {
+ break;
+ }
+ }
+
+ done_reading:
+ if (twice) {
+ tor_free(prompt2);
+ memwipe(buf2, 0, buflen);
+ tor_free(buf2);
+ }
+
+ if (options->keygen_force_passphrase == FORCE_PASSPHRASE_ON && length == 0)
+ return -1;
+
+ return length;
+}
+
+/* DOCDOC */
+int
+read_encrypted_secret_key(ed25519_secret_key_t *out,
+ const char *fname)
+{
+ int r = -1;
+ uint8_t *secret = NULL;
+ size_t secret_len = 0;
+ char pwbuf[256];
+ uint8_t encrypted_key[256];
+ char *tag = NULL;
+ int saved_errno = 0;
+
+ ssize_t encrypted_len = crypto_read_tagged_contents_from_file(fname,
+ ENC_KEY_HEADER,
+ &tag,
+ encrypted_key,
+ sizeof(encrypted_key));
+ if (encrypted_len < 0) {
+ saved_errno = errno;
+ log_info(LD_OR, "%s is missing", fname);
+ r = 0;
+ goto done;
+ }
+ if (strcmp(tag, ENC_KEY_TAG)) {
+ saved_errno = EINVAL;
+ goto done;
+ }
+
+ while (1) {
+ ssize_t pwlen =
+ do_getpass("Enter passphrase for master key:", pwbuf, sizeof(pwbuf), 0,
+ get_options());
+ if (pwlen < 0) {
+ saved_errno = EINVAL;
+ goto done;
+ }
+ const int r_unbox = crypto_unpwbox(&secret, &secret_len,
+ encrypted_key, encrypted_len,
+ pwbuf, pwlen);
+ if (r_unbox == UNPWBOX_CORRUPTED) {
+ log_err(LD_OR, "%s is corrupted.", fname);
+ saved_errno = EINVAL;
+ goto done;
+ } else if (r_unbox == UNPWBOX_OKAY) {
+ break;
+ }
+
+ /* Otherwise, passphrase is bad, so try again till user does ctrl-c or gets
+ * it right. */
+ }
+
+ if (secret_len != ED25519_SECKEY_LEN) {
+ log_err(LD_OR, "%s is corrupted.", fname);
+ saved_errno = EINVAL;
+ goto done;
+ }
+ memcpy(out->seckey, secret, ED25519_SECKEY_LEN);
+ r = 1;
+
+ done:
+ memwipe(encrypted_key, 0, sizeof(encrypted_key));
+ memwipe(pwbuf, 0, sizeof(pwbuf));
+ tor_free(tag);
+ if (secret) {
+ memwipe(secret, 0, secret_len);
+ tor_free(secret);
+ }
+ if (saved_errno)
+ errno = saved_errno;
+ return r;
+}
+
+/* DOCDOC */
+int
+write_encrypted_secret_key(const ed25519_secret_key_t *key,
+ const char *fname)
+{
+ int r = -1;
+ char pwbuf0[256];
+ uint8_t *encrypted_key = NULL;
+ size_t encrypted_len = 0;
+
+ if (do_getpass("Enter new passphrase:", pwbuf0, sizeof(pwbuf0), 1,
+ get_options()) < 0) {
+ log_warn(LD_OR, "NO/failed passphrase");
+ return -1;
+ }
+
+ if (strlen(pwbuf0) == 0) {
+ if (get_options()->keygen_force_passphrase == FORCE_PASSPHRASE_ON)
+ return -1;
+ else
+ return 0;
+ }
+
+ if (crypto_pwbox(&encrypted_key, &encrypted_len,
+ key->seckey, sizeof(key->seckey),
+ pwbuf0, strlen(pwbuf0), 0) < 0) {
+ log_warn(LD_OR, "crypto_pwbox failed!?");
+ goto done;
+ }
+ if (crypto_write_tagged_contents_to_file(fname,
+ ENC_KEY_HEADER,
+ ENC_KEY_TAG,
+ encrypted_key, encrypted_len) < 0)
+ goto done;
+ r = 1;
+ done:
+ if (encrypted_key) {
+ memwipe(encrypted_key, 0, encrypted_len);
+ tor_free(encrypted_key);
+ }
+ memwipe(pwbuf0, 0, sizeof(pwbuf0));
+ return r;
+}
+
+/* DOCDOC */
+static int
+write_secret_key(const ed25519_secret_key_t *key, int encrypted,
+ const char *fname,
+ const char *fname_tag,
+ const char *encrypted_fname)
+{
+ if (encrypted) {
+ int r = write_encrypted_secret_key(key, encrypted_fname);
+ if (r == 1) {
+ /* Success! */
+
+ /* Try to unlink the unencrypted key, if any existed before */
+ if (strcmp(fname, encrypted_fname))
+ unlink(fname);
+ return r;
+ } else if (r != 0) {
+ /* Unrecoverable failure! */
+ return r;
+ }
+
+ fprintf(stderr, "Not encrypting the secret key.\n");
+ }
+ return ed25519_seckey_write_to_file(key, fname, fname_tag);
+}
+
+/**
+ * Read an ed25519 key and associated certificates from files beginning with
+ * <b>fname</b>, with certificate type <b>cert_type</b>. On failure, return
+ * NULL; on success return the keypair.
+ *
+ * The <b>options</b> is used to look at the change_key_passphrase value when
+ * writing to disk a secret key. It is safe to be NULL even in that case.
+ *
+ * If INIT_ED_KEY_CREATE is set in <b>flags</b>, then create the key (and
+ * certificate if requested) if it doesn't exist, and save it to disk.
+ *
+ * If INIT_ED_KEY_NEEDCERT is set in <b>flags</b>, load/create a certificate
+ * too and store it in *<b>cert_out</b>. Fail if the cert can't be
+ * found/created. To create a certificate, <b>signing_key</b> must be set to
+ * the key that should sign it; <b>now</b> to the current time, and
+ * <b>lifetime</b> to the lifetime of the key.
+ *
+ * If INIT_ED_KEY_REPLACE is set in <b>flags</b>, then create and save new key
+ * whether we can read the old one or not.
+ *
+ * If INIT_ED_KEY_EXTRA_STRONG is set in <b>flags</b>, set the extra_strong
+ * flag when creating the secret key.
+ *
+ * If INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT is set in <b>flags</b>, and
+ * we create a new certificate, create it with the signing key embedded.
+ *
+ * If INIT_ED_KEY_SPLIT is set in <b>flags</b>, and we create a new key,
+ * store the public key in a separate file from the secret key.
+ *
+ * If INIT_ED_KEY_MISSING_SECRET_OK is set in <b>flags</b>, and we find a
+ * public key file but no secret key file, return successfully anyway.
+ *
+ * If INIT_ED_KEY_OMIT_SECRET is set in <b>flags</b>, do not try to load a
+ * secret key unless no public key is found. Do not return a secret key. (but
+ * create and save one if needed).
+ *
+ * If INIT_ED_KEY_TRY_ENCRYPTED is set, we look for an encrypted secret key
+ * and consider encrypting any new secret key.
+ *
+ * If INIT_ED_KEY_NO_REPAIR is set, and there is any issue loading the keys
+ * from disk _other than their absence_ (full or partial), we do not try to
+ * replace them.
+ *
+ * If INIT_ED_KEY_SUGGEST_KEYGEN is set, have log messages about failures
+ * refer to the --keygen option.
+ *
+ * If INIT_ED_KEY_EXPLICIT_FNAME is set, use the provided file name for the
+ * secret key file, encrypted or not.
+ *
+ * If INIT_ED_KEY_OFFLINE_SECRET is set, we won't try to load the master
+ * secret key and we log a message at <b>severity</b> that we've done so.
+ */
+ed25519_keypair_t *
+ed_key_init_from_file(const char *fname, uint32_t flags,
+ int severity,
+ const ed25519_keypair_t *signing_key,
+ time_t now,
+ time_t lifetime,
+ uint8_t cert_type,
+ struct tor_cert_st **cert_out,
+ const or_options_t *options)
+{
+ char *secret_fname = NULL;
+ char *encrypted_secret_fname = NULL;
+ char *public_fname = NULL;
+ char *cert_fname = NULL;
+ const char *loaded_secret_fname = NULL;
+ int created_pk = 0, created_sk = 0, created_cert = 0;
+ const int try_to_load = ! (flags & INIT_ED_KEY_REPLACE);
+ const int encrypt_key = !! (flags & INIT_ED_KEY_TRY_ENCRYPTED);
+ const int norepair = !! (flags & INIT_ED_KEY_NO_REPAIR);
+ const int split = !! (flags & INIT_ED_KEY_SPLIT);
+ const int omit_secret = !! (flags & INIT_ED_KEY_OMIT_SECRET);
+ const int offline_secret = !! (flags & INIT_ED_KEY_OFFLINE_SECRET);
+ const int explicit_fname = !! (flags & INIT_ED_KEY_EXPLICIT_FNAME);
+
+ /* we don't support setting both of these flags at once. */
+ tor_assert((flags & (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)) !=
+ (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT));
+
+ char tag[8];
+ tor_snprintf(tag, sizeof(tag), "type%d", (int)cert_type);
+
+ tor_cert_t *cert = NULL;
+ char *got_tag = NULL;
+ ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t));
+
+ if (explicit_fname) {
+ secret_fname = tor_strdup(fname);
+ encrypted_secret_fname = tor_strdup(fname);
+ } else {
+ tor_asprintf(&secret_fname, "%s_secret_key", fname);
+ tor_asprintf(&encrypted_secret_fname, "%s_secret_key_encrypted", fname);
+ }
+ tor_asprintf(&public_fname, "%s_public_key", fname);
+ tor_asprintf(&cert_fname, "%s_cert", fname);
+
+ /* Try to read the secret key. */
+ int have_secret = 0;
+ int load_secret = try_to_load &&
+ !offline_secret &&
+ (!omit_secret || file_status(public_fname)==FN_NOENT);
+ if (load_secret) {
+ int rv = ed25519_seckey_read_from_file(&keypair->seckey,
+ &got_tag, secret_fname);
+ if (rv == 0) {
+ have_secret = 1;
+ loaded_secret_fname = secret_fname;
+ tor_assert(got_tag);
+ } else {
+ if (errno != ENOENT && norepair) {
+ tor_log(severity, LD_OR, "Unable to read %s: %s", secret_fname,
+ strerror(errno));
+ goto err;
+ }
+ }
+ }
+
+ /* Should we try for an encrypted key? */
+ int have_encrypted_secret_file = 0;
+ if (!have_secret && try_to_load && encrypt_key) {
+ int r = read_encrypted_secret_key(&keypair->seckey,
+ encrypted_secret_fname);
+ if (r > 0) {
+ have_secret = 1;
+ have_encrypted_secret_file = 1;
+ tor_free(got_tag); /* convince coverity we aren't leaking */
+ got_tag = tor_strdup(tag);
+ loaded_secret_fname = encrypted_secret_fname;
+ } else if (errno != ENOENT && norepair) {
+ tor_log(severity, LD_OR, "Unable to read %s: %s",
+ encrypted_secret_fname, strerror(errno));
+ goto err;
+ }
+ } else {
+ if (try_to_load) {
+ /* Check if it's there anyway, so we don't replace it. */
+ if (file_status(encrypted_secret_fname) != FN_NOENT)
+ have_encrypted_secret_file = 1;
+ }
+ }
+
+ if (have_secret) {
+ if (strcmp(got_tag, tag)) {
+ tor_log(severity, LD_OR, "%s has wrong tag", loaded_secret_fname);
+ goto err;
+ }
+ /* Derive the public key */
+ if (ed25519_public_key_generate(&keypair->pubkey, &keypair->seckey)<0) {
+ tor_log(severity, LD_OR, "%s can't produce a public key",
+ loaded_secret_fname);
+ goto err;
+ }
+ }
+
+ /* If we do split keys here, try to read the pubkey. */
+ int found_public = 0;
+ if (try_to_load && (!have_secret || split)) {
+ ed25519_public_key_t pubkey_tmp;
+ tor_free(got_tag);
+ found_public = ed25519_pubkey_read_from_file(&pubkey_tmp,
+ &got_tag, public_fname) == 0;
+ if (!found_public && errno != ENOENT && norepair) {
+ tor_log(severity, LD_OR, "Unable to read %s: %s", public_fname,
+ strerror(errno));
+ goto err;
+ }
+ if (found_public && strcmp(got_tag, tag)) {
+ tor_log(severity, LD_OR, "%s has wrong tag", public_fname);
+ goto err;
+ }
+ if (found_public) {
+ if (have_secret) {
+ /* If we have a secret key and we're reloading the public key,
+ * the key must match! */
+ if (! ed25519_pubkey_eq(&keypair->pubkey, &pubkey_tmp)) {
+ tor_log(severity, LD_OR, "%s does not match %s! If you are trying "
+ "to restore from backup, make sure you didn't mix up the "
+ "key files. If you are absolutely sure that %s is the right "
+ "key for this relay, delete %s or move it out of the way.",
+ public_fname, loaded_secret_fname,
+ loaded_secret_fname, public_fname);
+ goto err;
+ }
+ } else {
+ /* We only have the public key; better use that. */
+ tor_assert(split);
+ memcpy(&keypair->pubkey, &pubkey_tmp, sizeof(pubkey_tmp));
+ }
+ } else {
+ /* We have no public key file, but we do have a secret key, make the
+ * public key file! */
+ if (have_secret) {
+ if (ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag)
+ < 0) {
+ tor_log(severity, LD_OR, "Couldn't repair %s", public_fname);
+ goto err;
+ } else {
+ tor_log(LOG_NOTICE, LD_OR,
+ "Found secret key but not %s. Regenerating.",
+ public_fname);
+ }
+ }
+ }
+ }
+
+ /* If the secret key is absent and it's not allowed to be, fail. */
+ if (!have_secret && found_public &&
+ !(flags & INIT_ED_KEY_MISSING_SECRET_OK)) {
+ if (have_encrypted_secret_file) {
+ tor_log(severity, LD_OR, "We needed to load a secret key from %s, "
+ "but it was encrypted. Try 'tor --keygen' instead, so you "
+ "can enter the passphrase.",
+ secret_fname);
+ } else if (offline_secret) {
+ tor_log(severity, LD_OR, "We wanted to load a secret key from %s, "
+ "but you're keeping it offline. (OfflineMasterKey is set.)",
+ secret_fname);
+ } else {
+ tor_log(severity, LD_OR, "We needed to load a secret key from %s, "
+ "but couldn't find it. %s", secret_fname,
+ (flags & INIT_ED_KEY_SUGGEST_KEYGEN) ?
+ "If you're keeping your master secret key offline, you will "
+ "need to run 'tor --keygen' to generate new signing keys." :
+ "Did you forget to copy it over when you copied the rest of the "
+ "signing key material?");
+ }
+ goto err;
+ }
+
+ /* If it's absent, and we're not supposed to make a new keypair, fail. */
+ if (!have_secret && !found_public && !(flags & INIT_ED_KEY_CREATE)) {
+ if (split) {
+ tor_log(severity, LD_OR, "No key found in %s or %s.",
+ secret_fname, public_fname);
+ } else {
+ tor_log(severity, LD_OR, "No key found in %s.", secret_fname);
+ }
+ goto err;
+ }
+
+ /* If the secret key is absent, but the encrypted key would be present,
+ * that's an error */
+ if (!have_secret && !found_public && have_encrypted_secret_file) {
+ tor_assert(!encrypt_key);
+ tor_log(severity, LD_OR, "Found an encrypted secret key, "
+ "but not public key file %s!", public_fname);
+ goto err;
+ }
+
+ /* if it's absent, make a new keypair... */
+ if (!have_secret && !found_public) {
+ tor_free(keypair);
+ keypair = ed_key_new(signing_key, flags, now, lifetime,
+ cert_type, &cert);
+ if (!keypair) {
+ tor_log(severity, LD_OR, "Couldn't create keypair");
+ goto err;
+ }
+ created_pk = created_sk = created_cert = 1;
+ }
+
+ /* Write it to disk if we're supposed to do with a new passphrase, or if
+ * we just created it. */
+ if (created_sk || (have_secret && options != NULL &&
+ options->change_key_passphrase)) {
+ if (write_secret_key(&keypair->seckey,
+ encrypt_key,
+ secret_fname, tag, encrypted_secret_fname) < 0
+ ||
+ (split &&
+ ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) < 0)
+ ||
+ (cert &&
+ crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert",
+ tag, cert->encoded, cert->encoded_len) < 0)) {
+ tor_log(severity, LD_OR, "Couldn't write keys or cert to file.");
+ goto err;
+ }
+ goto done;
+ }
+
+ /* If we're not supposed to get a cert, we're done. */
+ if (! (flags & INIT_ED_KEY_NEEDCERT))
+ goto done;
+
+ /* Read a cert. */
+ tor_free(got_tag);
+ uint8_t certbuf[256];
+ ssize_t cert_body_len = crypto_read_tagged_contents_from_file(
+ cert_fname, "ed25519v1-cert",
+ &got_tag, certbuf, sizeof(certbuf));
+ if (cert_body_len >= 0 && !strcmp(got_tag, tag))
+ cert = tor_cert_parse(certbuf, cert_body_len);
+
+ /* If we got it, check it to the extent we can. */
+ int bad_cert = 0;
+
+ if (! cert) {
+ tor_log(severity, LD_OR, "Cert was unparseable");
+ bad_cert = 1;
+ } else if (!tor_memeq(cert->signed_key.pubkey, keypair->pubkey.pubkey,
+ ED25519_PUBKEY_LEN)) {
+ tor_log(severity, LD_OR, "Cert was for wrong key");
+ bad_cert = 1;
+ } else if (signing_key &&
+ tor_cert_checksig(cert, &signing_key->pubkey, now) < 0) {
+ tor_log(severity, LD_OR, "Can't check certificate: %s",
+ tor_cert_describe_signature_status(cert));
+ bad_cert = 1;
+ } else if (cert->cert_expired) {
+ tor_log(severity, LD_OR, "Certificate is expired");
+ bad_cert = 1;
+ } else if (signing_key && cert->signing_key_included &&
+ ! ed25519_pubkey_eq(&signing_key->pubkey, &cert->signing_key)) {
+ tor_log(severity, LD_OR, "Certificate signed by unexpectd key!");
+ bad_cert = 1;
+ }
+
+ if (bad_cert) {
+ tor_cert_free(cert);
+ cert = NULL;
+ }
+
+ /* If we got a cert, we're done. */
+ if (cert)
+ goto done;
+
+ /* If we didn't get a cert, and we're not supposed to make one, fail. */
+ if (!signing_key || !(flags & INIT_ED_KEY_CREATE)) {
+ tor_log(severity, LD_OR, "Without signing key, can't create certificate");
+ goto err;
+ }
+
+ /* We have keys but not a certificate, so make one. */
+ uint32_t cert_flags = 0;
+ if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT)
+ cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY;
+ cert = tor_cert_create(signing_key, cert_type,
+ &keypair->pubkey,
+ now, lifetime,
+ cert_flags);
+
+ if (! cert) {
+ tor_log(severity, LD_OR, "Couldn't create certificate");
+ goto err;
+ }
+
+ /* Write it to disk. */
+ created_cert = 1;
+ if (crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert",
+ tag, cert->encoded, cert->encoded_len) < 0) {
+ tor_log(severity, LD_OR, "Couldn't write cert to disk.");
+ goto err;
+ }
+
+ done:
+ if (cert_out)
+ *cert_out = cert;
+ else
+ tor_cert_free(cert);
+
+ goto cleanup;
+
+ err:
+ if (keypair)
+ memwipe(keypair, 0, sizeof(*keypair));
+ tor_free(keypair);
+ tor_cert_free(cert);
+ if (cert_out)
+ *cert_out = NULL;
+ if (created_sk)
+ unlink(secret_fname);
+ if (created_pk)
+ unlink(public_fname);
+ if (created_cert)
+ unlink(cert_fname);
+
+ cleanup:
+ tor_free(encrypted_secret_fname);
+ tor_free(secret_fname);
+ tor_free(public_fname);
+ tor_free(cert_fname);
+ tor_free(got_tag);
+
+ return keypair;
+}
+
+/**
+ * Create a new signing key and (optionally) certficiate; do not read or write
+ * from disk. See ed_key_init_from_file() for more information.
+ */
+ed25519_keypair_t *
+ed_key_new(const ed25519_keypair_t *signing_key,
+ uint32_t flags,
+ time_t now,
+ time_t lifetime,
+ uint8_t cert_type,
+ struct tor_cert_st **cert_out)
+{
+ if (cert_out)
+ *cert_out = NULL;
+
+ const int extra_strong = !! (flags & INIT_ED_KEY_EXTRA_STRONG);
+ ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t));
+ if (ed25519_keypair_generate(keypair, extra_strong) < 0)
+ goto err;
+
+ if (! (flags & INIT_ED_KEY_NEEDCERT))
+ return keypair;
+
+ tor_assert(signing_key);
+ tor_assert(cert_out);
+ uint32_t cert_flags = 0;
+ if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT)
+ cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY;
+ tor_cert_t *cert = tor_cert_create(signing_key, cert_type,
+ &keypair->pubkey,
+ now, lifetime,
+ cert_flags);
+ if (! cert)
+ goto err;
+
+ *cert_out = cert;
+ return keypair;
+
+ err:
+ tor_free(keypair);
+ return NULL;
+}
diff --git a/src/feature/keymgt/loadkey.h b/src/feature/keymgt/loadkey.h
new file mode 100644
index 000000000..7717bda29
--- /dev/null
+++ b/src/feature/keymgt/loadkey.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file loadkey.h
+ * \brief Header file for loadkey.c
+ **/
+
+#ifndef TOR_LOADKEY_H
+#define TOR_LOADKEY_H
+
+#include "lib/crypt_ops/crypto_ed25519.h"
+
+crypto_pk_t *init_key_from_file(const char *fname, int generate,
+ int severity, bool *created_out);
+
+#define INIT_ED_KEY_CREATE (1u<<0)
+#define INIT_ED_KEY_REPLACE (1u<<1)
+#define INIT_ED_KEY_SPLIT (1u<<2)
+#define INIT_ED_KEY_MISSING_SECRET_OK (1u<<3)
+#define INIT_ED_KEY_NEEDCERT (1u<<4)
+#define INIT_ED_KEY_EXTRA_STRONG (1u<<5)
+#define INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT (1u<<6)
+#define INIT_ED_KEY_OMIT_SECRET (1u<<7)
+#define INIT_ED_KEY_TRY_ENCRYPTED (1u<<8)
+#define INIT_ED_KEY_NO_REPAIR (1u<<9)
+#define INIT_ED_KEY_SUGGEST_KEYGEN (1u<<10)
+#define INIT_ED_KEY_OFFLINE_SECRET (1u<<11)
+#define INIT_ED_KEY_EXPLICIT_FNAME (1u<<12)
+
+struct tor_cert_st;
+ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags,
+ int severity,
+ const ed25519_keypair_t *signing_key,
+ time_t now,
+ time_t lifetime,
+ uint8_t cert_type,
+ struct tor_cert_st **cert_out,
+ const or_options_t *options);
+ed25519_keypair_t *ed_key_new(const ed25519_keypair_t *signing_key,
+ uint32_t flags,
+ time_t now,
+ time_t lifetime,
+ uint8_t cert_type,
+ struct tor_cert_st **cert_out);
+
+int read_encrypted_secret_key(ed25519_secret_key_t *out,
+ const char *fname);
+int write_encrypted_secret_key(const ed25519_secret_key_t *out,
+ const char *fname);
+
+#endif
diff --git a/src/feature/nodelist/torcert.c b/src/feature/nodelist/torcert.c
index fe67e5640..675d5c97b 100644
--- a/src/feature/nodelist/torcert.c
+++ b/src/feature/nodelist/torcert.c
@@ -638,6 +638,43 @@ or_handshake_certs_ed25519_ok(int severity,
return 1;
}
+/** Check whether an RSA-TAP cross-certification is correct. Return 0 if it
+ * is, -1 if it isn't. */
+MOCK_IMPL(int,
+check_tap_onion_key_crosscert,(const uint8_t *crosscert,
+ int crosscert_len,
+ const crypto_pk_t *onion_pkey,
+ const ed25519_public_key_t *master_id_pkey,
+ const uint8_t *rsa_id_digest))
+{
+ uint8_t *cc = tor_malloc(crypto_pk_keysize(onion_pkey));
+ int cc_len =
+ crypto_pk_public_checksig(onion_pkey,
+ (char*)cc,
+ crypto_pk_keysize(onion_pkey),
+ (const char*)crosscert,
+ crosscert_len);
+ if (cc_len < 0) {
+ goto err;
+ }
+ if (cc_len < DIGEST_LEN + ED25519_PUBKEY_LEN) {
+ log_warn(LD_DIR, "Short signature on cross-certification with TAP key");
+ goto err;
+ }
+ if (tor_memneq(cc, rsa_id_digest, DIGEST_LEN) ||
+ tor_memneq(cc + DIGEST_LEN, master_id_pkey->pubkey,
+ ED25519_PUBKEY_LEN)) {
+ log_warn(LD_DIR, "Incorrect cross-certification with TAP key");
+ goto err;
+ }
+
+ tor_free(cc);
+ return 0;
+ err:
+ tor_free(cc);
+ return -1;
+}
+
/**
* Check the Ed certificates and/or the RSA certificates, as appropriate. If
* we obtained an Ed25519 identity, set *ed_id_out. If we obtained an RSA
diff --git a/src/feature/nodelist/torcert.h b/src/feature/nodelist/torcert.h
index 5fa97679d..cb5e23cc3 100644
--- a/src/feature/nodelist/torcert.h
+++ b/src/feature/nodelist/torcert.h
@@ -107,4 +107,10 @@ void or_handshake_certs_check_both(int severity,
int tor_cert_encode_ed22519(const tor_cert_t *cert, char **cert_str_out);
+MOCK_DECL(int, check_tap_onion_key_crosscert,(const uint8_t *crosscert,
+ int crosscert_len,
+ const crypto_pk_t *onion_pkey,
+ const ed25519_public_key_t *master_id_pkey,
+ const uint8_t *rsa_id_digest));
+
#endif /* !defined(TORCERT_H_INCLUDED) */
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 622cfeb86..7f72c7f35 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -30,6 +30,7 @@
#include "core/or/policies.h"
#include "core/or/protover.h"
#include "core/or/relay.h"
+#include "feature/keymgt/loadkey.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
@@ -540,85 +541,6 @@ log_new_relay_greeting(void)
already_logged = 1;
}
-/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist
- * and <b>generate</b> is true, create a new RSA key and save it in
- * <b>fname</b>. Return the read/created key, or NULL on error. Log all
- * errors at level <b>severity</b>. If <b>log_greeting</b> is non-zero and a
- * new key was created, log_new_relay_greeting() is called.
- */
-crypto_pk_t *
-init_key_from_file(const char *fname, int generate, int severity,
- int log_greeting)
-{
- crypto_pk_t *prkey = NULL;
-
- if (!(prkey = crypto_pk_new())) {
- tor_log(severity, LD_GENERAL,"Error constructing key");
- goto error;
- }
-
- switch (file_status(fname)) {
- case FN_DIR:
- case FN_ERROR:
- tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname);
- goto error;
- /* treat empty key files as if the file doesn't exist, and,
- * if generate is set, replace the empty file in
- * crypto_pk_write_private_key_to_filename() */
- case FN_NOENT:
- case FN_EMPTY:
- if (generate) {
- if (!have_lockfile()) {
- if (try_locking(get_options(), 0)<0) {
- /* Make sure that --list-fingerprint only creates new keys
- * if there is no possibility for a deadlock. */
- tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". "
- "Not writing any new keys.", fname);
- /*XXXX The 'other process' might make a key in a second or two;
- * maybe we should wait for it. */
- goto error;
- }
- }
- log_info(LD_GENERAL, "No key found in \"%s\"; generating fresh key.",
- fname);
- if (crypto_pk_generate_key(prkey)) {
- tor_log(severity, LD_GENERAL,"Error generating onion key");
- goto error;
- }
- if (! crypto_pk_is_valid_private_key(prkey)) {
- tor_log(severity, LD_GENERAL,"Generated key seems invalid");
- goto error;
- }
- log_info(LD_GENERAL, "Generated key seems valid");
- if (log_greeting) {
- log_new_relay_greeting();
- }
- if (crypto_pk_write_private_key_to_filename(prkey, fname)) {
- tor_log(severity, LD_FS,
- "Couldn't write generated key to \"%s\".", fname);
- goto error;
- }
- } else {
- tor_log(severity, LD_GENERAL, "No key found in \"%s\"", fname);
- goto error;
- }
- return prkey;
- case FN_FILE:
- if (crypto_pk_read_private_key_from_filename(prkey, fname)) {
- tor_log(severity, LD_GENERAL,"Error loading private key.");
- goto error;
- }
- return prkey;
- default:
- tor_assert(0);
- }
-
- error:
- if (prkey)
- crypto_pk_free(prkey);
- return NULL;
-}
-
/** Load a curve25519 keypair from the file <b>fname</b>, writing it into
* <b>keys_out</b>. If the file isn't found, or is empty, and <b>generate</b>
* is true, create a new keypair and write it into the file. If there are
@@ -708,7 +630,7 @@ load_authority_keyset(int legacy, crypto_pk_t **key_out,
fname = get_keydir_fname(
legacy ? "legacy_signing_key" : "authority_signing_key");
- signing_key = init_key_from_file(fname, 0, LOG_ERR, 0);
+ signing_key = init_key_from_file(fname, 0, LOG_ERR, NULL);
if (!signing_key) {
log_warn(LD_DIR, "No version 3 directory key found in %s", fname);
goto done;
@@ -1042,9 +964,12 @@ init_keys(void)
/* 1b. Read identity key. Make it if none is found. */
keydir = get_keydir_fname("secret_id_key");
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
- prkey = init_key_from_file(keydir, 1, LOG_ERR, 1);
+ bool created = false;
+ prkey = init_key_from_file(keydir, 1, LOG_ERR, &created);
tor_free(keydir);
if (!prkey) return -1;
+ if (created)
+ log_new_relay_greeting();
set_server_identity_key(prkey);
/* 1c. If we are configured as a bridge, generate a client key;
@@ -1070,7 +995,9 @@ init_keys(void)
/* 2. Read onion key. Make it if none is found. */
keydir = get_keydir_fname("secret_onion_key");
log_info(LD_GENERAL,"Reading/making onion key \"%s\"...",keydir);
- prkey = init_key_from_file(keydir, 1, LOG_ERR, 1);
+ prkey = init_key_from_file(keydir, 1, LOG_ERR, &created);
+ if (created)
+ log_new_relay_greeting();
tor_free(keydir);
if (!prkey) return -1;
set_onion_key(prkey);
diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h
index cf0d27a45..e6a163973 100644
--- a/src/feature/relay/router.h
+++ b/src/feature/relay/router.h
@@ -39,8 +39,6 @@ crypto_pk_t *get_my_v3_legacy_signing_key(void);
void dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last);
void expire_old_onion_keys(void);
void rotate_onion_key(void);
-crypto_pk_t *init_key_from_file(const char *fname, int generate,
- int severity, int log_greeting);
void v3_authority_check_key_expiry(void);
int get_onion_key_lifetime(void);
int get_onion_key_grace_period(void);
diff --git a/src/feature/relay/routerkeys.c b/src/feature/relay/routerkeys.c
index 47af0f812..c13359795 100644
--- a/src/feature/relay/routerkeys.c
+++ b/src/feature/relay/routerkeys.c
@@ -18,14 +18,12 @@
#include "app/config/config.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
+#include "feature/keymgt/loadkey.h"
#include "feature/nodelist/torcert.h"
-#include "lib/crypt_ops/crypto_pwbox.h"
#include "lib/crypt_ops/crypto_util.h"
-#include "lib/term/getpass.h"
#include "lib/tls/tortls.h"
#include "lib/tls/x509.h"
-#include "lib/crypt_ops/crypto_format.h"
#define ENC_KEY_HEADER "Boxed Ed25519 key"
#define ENC_KEY_TAG "master"
@@ -34,647 +32,6 @@
#include <unistd.h>
#endif
-/* DOCDOC */
-static ssize_t
-do_getpass(const char *prompt, char *buf, size_t buflen,
- int twice, const or_options_t *options)
-{
- if (options->keygen_force_passphrase == FORCE_PASSPHRASE_OFF) {
- tor_assert(buflen);
- buf[0] = 0;
- return 0;
- }
-
- char *prompt2 = NULL;
- char *buf2 = NULL;
- int fd = -1;
- ssize_t length = -1;
-
- if (options->use_keygen_passphrase_fd) {
- twice = 0;
- fd = options->keygen_passphrase_fd;
- length = read_all_from_fd(fd, buf, buflen-1);
- if (length >= 0)
- buf[length] = 0;
- goto done_reading;
- }
-
- if (twice) {
- const char msg[] = "One more time:";
- size_t p2len = strlen(prompt) + 1;
- if (p2len < sizeof(msg))
- p2len = sizeof(msg);
- prompt2 = tor_malloc(p2len);
- memset(prompt2, ' ', p2len);
- memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg));
-
- buf2 = tor_malloc_zero(buflen);
- }
-
- while (1) {
- length = tor_getpass(prompt, buf, buflen);
- if (length < 0)
- goto done_reading;
-
- if (! twice)
- break;
-
- ssize_t length2 = tor_getpass(prompt2, buf2, buflen);
-
- if (length != length2 || tor_memneq(buf, buf2, length)) {
- fprintf(stderr, "That didn't match.\n");
- } else {
- break;
- }
- }
-
- done_reading:
- if (twice) {
- tor_free(prompt2);
- memwipe(buf2, 0, buflen);
- tor_free(buf2);
- }
-
- if (options->keygen_force_passphrase == FORCE_PASSPHRASE_ON && length == 0)
- return -1;
-
- return length;
-}
-
-/* DOCDOC */
-int
-read_encrypted_secret_key(ed25519_secret_key_t *out,
- const char *fname)
-{
- int r = -1;
- uint8_t *secret = NULL;
- size_t secret_len = 0;
- char pwbuf[256];
- uint8_t encrypted_key[256];
- char *tag = NULL;
- int saved_errno = 0;
-
- ssize_t encrypted_len = crypto_read_tagged_contents_from_file(fname,
- ENC_KEY_HEADER,
- &tag,
- encrypted_key,
- sizeof(encrypted_key));
- if (encrypted_len < 0) {
- saved_errno = errno;
- log_info(LD_OR, "%s is missing", fname);
- r = 0;
- goto done;
- }
- if (strcmp(tag, ENC_KEY_TAG)) {
- saved_errno = EINVAL;
- goto done;
- }
-
- while (1) {
- ssize_t pwlen =
- do_getpass("Enter passphrase for master key:", pwbuf, sizeof(pwbuf), 0,
- get_options());
- if (pwlen < 0) {
- saved_errno = EINVAL;
- goto done;
- }
- const int r_unbox = crypto_unpwbox(&secret, &secret_len,
- encrypted_key, encrypted_len,
- pwbuf, pwlen);
- if (r_unbox == UNPWBOX_CORRUPTED) {
- log_err(LD_OR, "%s is corrupted.", fname);
- saved_errno = EINVAL;
- goto done;
- } else if (r_unbox == UNPWBOX_OKAY) {
- break;
- }
-
- /* Otherwise, passphrase is bad, so try again till user does ctrl-c or gets
- * it right. */
- }
-
- if (secret_len != ED25519_SECKEY_LEN) {
- log_err(LD_OR, "%s is corrupted.", fname);
- saved_errno = EINVAL;
- goto done;
- }
- memcpy(out->seckey, secret, ED25519_SECKEY_LEN);
- r = 1;
-
- done:
- memwipe(encrypted_key, 0, sizeof(encrypted_key));
- memwipe(pwbuf, 0, sizeof(pwbuf));
- tor_free(tag);
- if (secret) {
- memwipe(secret, 0, secret_len);
- tor_free(secret);
- }
- if (saved_errno)
- errno = saved_errno;
- return r;
-}
-
-/* DOCDOC */
-int
-write_encrypted_secret_key(const ed25519_secret_key_t *key,
- const char *fname)
-{
- int r = -1;
- char pwbuf0[256];
- uint8_t *encrypted_key = NULL;
- size_t encrypted_len = 0;
-
- if (do_getpass("Enter new passphrase:", pwbuf0, sizeof(pwbuf0), 1,
- get_options()) < 0) {
- log_warn(LD_OR, "NO/failed passphrase");
- return -1;
- }
-
- if (strlen(pwbuf0) == 0) {
- if (get_options()->keygen_force_passphrase == FORCE_PASSPHRASE_ON)
- return -1;
- else
- return 0;
- }
-
- if (crypto_pwbox(&encrypted_key, &encrypted_len,
- key->seckey, sizeof(key->seckey),
- pwbuf0, strlen(pwbuf0), 0) < 0) {
- log_warn(LD_OR, "crypto_pwbox failed!?");
- goto done;
- }
- if (crypto_write_tagged_contents_to_file(fname,
- ENC_KEY_HEADER,
- ENC_KEY_TAG,
- encrypted_key, encrypted_len) < 0)
- goto done;
- r = 1;
- done:
- if (encrypted_key) {
- memwipe(encrypted_key, 0, encrypted_len);
- tor_free(encrypted_key);
- }
- memwipe(pwbuf0, 0, sizeof(pwbuf0));
- return r;
-}
-
-/* DOCDOC */
-static int
-write_secret_key(const ed25519_secret_key_t *key, int encrypted,
- const char *fname,
- const char *fname_tag,
- const char *encrypted_fname)
-{
- if (encrypted) {
- int r = write_encrypted_secret_key(key, encrypted_fname);
- if (r == 1) {
- /* Success! */
-
- /* Try to unlink the unencrypted key, if any existed before */
- if (strcmp(fname, encrypted_fname))
- unlink(fname);
- return r;
- } else if (r != 0) {
- /* Unrecoverable failure! */
- return r;
- }
-
- fprintf(stderr, "Not encrypting the secret key.\n");
- }
- return ed25519_seckey_write_to_file(key, fname, fname_tag);
-}
-
-/**
- * Read an ed25519 key and associated certificates from files beginning with
- * <b>fname</b>, with certificate type <b>cert_type</b>. On failure, return
- * NULL; on success return the keypair.
- *
- * The <b>options</b> is used to look at the change_key_passphrase value when
- * writing to disk a secret key. It is safe to be NULL even in that case.
- *
- * If INIT_ED_KEY_CREATE is set in <b>flags</b>, then create the key (and
- * certificate if requested) if it doesn't exist, and save it to disk.
- *
- * If INIT_ED_KEY_NEEDCERT is set in <b>flags</b>, load/create a certificate
- * too and store it in *<b>cert_out</b>. Fail if the cert can't be
- * found/created. To create a certificate, <b>signing_key</b> must be set to
- * the key that should sign it; <b>now</b> to the current time, and
- * <b>lifetime</b> to the lifetime of the key.
- *
- * If INIT_ED_KEY_REPLACE is set in <b>flags</b>, then create and save new key
- * whether we can read the old one or not.
- *
- * If INIT_ED_KEY_EXTRA_STRONG is set in <b>flags</b>, set the extra_strong
- * flag when creating the secret key.
- *
- * If INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT is set in <b>flags</b>, and
- * we create a new certificate, create it with the signing key embedded.
- *
- * If INIT_ED_KEY_SPLIT is set in <b>flags</b>, and we create a new key,
- * store the public key in a separate file from the secret key.
- *
- * If INIT_ED_KEY_MISSING_SECRET_OK is set in <b>flags</b>, and we find a
- * public key file but no secret key file, return successfully anyway.
- *
- * If INIT_ED_KEY_OMIT_SECRET is set in <b>flags</b>, do not try to load a
- * secret key unless no public key is found. Do not return a secret key. (but
- * create and save one if needed).
- *
- * If INIT_ED_KEY_TRY_ENCRYPTED is set, we look for an encrypted secret key
- * and consider encrypting any new secret key.
- *
- * If INIT_ED_KEY_NO_REPAIR is set, and there is any issue loading the keys
- * from disk _other than their absence_ (full or partial), we do not try to
- * replace them.
- *
- * If INIT_ED_KEY_SUGGEST_KEYGEN is set, have log messages about failures
- * refer to the --keygen option.
- *
- * If INIT_ED_KEY_EXPLICIT_FNAME is set, use the provided file name for the
- * secret key file, encrypted or not.
- *
- * If INIT_ED_KEY_OFFLINE_SECRET is set, we won't try to load the master
- * secret key and we log a message at <b>severity</b> that we've done so.
- */
-ed25519_keypair_t *
-ed_key_init_from_file(const char *fname, uint32_t flags,
- int severity,
- const ed25519_keypair_t *signing_key,
- time_t now,
- time_t lifetime,
- uint8_t cert_type,
- struct tor_cert_st **cert_out,
- const or_options_t *options)
-{
- char *secret_fname = NULL;
- char *encrypted_secret_fname = NULL;
- char *public_fname = NULL;
- char *cert_fname = NULL;
- const char *loaded_secret_fname = NULL;
- int created_pk = 0, created_sk = 0, created_cert = 0;
- const int try_to_load = ! (flags & INIT_ED_KEY_REPLACE);
- const int encrypt_key = !! (flags & INIT_ED_KEY_TRY_ENCRYPTED);
- const int norepair = !! (flags & INIT_ED_KEY_NO_REPAIR);
- const int split = !! (flags & INIT_ED_KEY_SPLIT);
- const int omit_secret = !! (flags & INIT_ED_KEY_OMIT_SECRET);
- const int offline_secret = !! (flags & INIT_ED_KEY_OFFLINE_SECRET);
- const int explicit_fname = !! (flags & INIT_ED_KEY_EXPLICIT_FNAME);
-
- /* we don't support setting both of these flags at once. */
- tor_assert((flags & (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)) !=
- (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT));
-
- char tag[8];
- tor_snprintf(tag, sizeof(tag), "type%d", (int)cert_type);
-
- tor_cert_t *cert = NULL;
- char *got_tag = NULL;
- ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t));
-
- if (explicit_fname) {
- secret_fname = tor_strdup(fname);
- encrypted_secret_fname = tor_strdup(fname);
- } else {
- tor_asprintf(&secret_fname, "%s_secret_key", fname);
- tor_asprintf(&encrypted_secret_fname, "%s_secret_key_encrypted", fname);
- }
- tor_asprintf(&public_fname, "%s_public_key", fname);
- tor_asprintf(&cert_fname, "%s_cert", fname);
-
- /* Try to read the secret key. */
- int have_secret = 0;
- int load_secret = try_to_load &&
- !offline_secret &&
- (!omit_secret || file_status(public_fname)==FN_NOENT);
- if (load_secret) {
- int rv = ed25519_seckey_read_from_file(&keypair->seckey,
- &got_tag, secret_fname);
- if (rv == 0) {
- have_secret = 1;
- loaded_secret_fname = secret_fname;
- tor_assert(got_tag);
- } else {
- if (errno != ENOENT && norepair) {
- tor_log(severity, LD_OR, "Unable to read %s: %s", secret_fname,
- strerror(errno));
- goto err;
- }
- }
- }
-
- /* Should we try for an encrypted key? */
- int have_encrypted_secret_file = 0;
- if (!have_secret && try_to_load && encrypt_key) {
- int r = read_encrypted_secret_key(&keypair->seckey,
- encrypted_secret_fname);
- if (r > 0) {
- have_secret = 1;
- have_encrypted_secret_file = 1;
- tor_free(got_tag); /* convince coverity we aren't leaking */
- got_tag = tor_strdup(tag);
- loaded_secret_fname = encrypted_secret_fname;
- } else if (errno != ENOENT && norepair) {
- tor_log(severity, LD_OR, "Unable to read %s: %s",
- encrypted_secret_fname, strerror(errno));
- goto err;
- }
- } else {
- if (try_to_load) {
- /* Check if it's there anyway, so we don't replace it. */
- if (file_status(encrypted_secret_fname) != FN_NOENT)
- have_encrypted_secret_file = 1;
- }
- }
-
- if (have_secret) {
- if (strcmp(got_tag, tag)) {
- tor_log(severity, LD_OR, "%s has wrong tag", loaded_secret_fname);
- goto err;
- }
- /* Derive the public key */
- if (ed25519_public_key_generate(&keypair->pubkey, &keypair->seckey)<0) {
- tor_log(severity, LD_OR, "%s can't produce a public key",
- loaded_secret_fname);
- goto err;
- }
- }
-
- /* If we do split keys here, try to read the pubkey. */
- int found_public = 0;
- if (try_to_load && (!have_secret || split)) {
- ed25519_public_key_t pubkey_tmp;
- tor_free(got_tag);
- found_public = ed25519_pubkey_read_from_file(&pubkey_tmp,
- &got_tag, public_fname) == 0;
- if (!found_public && errno != ENOENT && norepair) {
- tor_log(severity, LD_OR, "Unable to read %s: %s", public_fname,
- strerror(errno));
- goto err;
- }
- if (found_public && strcmp(got_tag, tag)) {
- tor_log(severity, LD_OR, "%s has wrong tag", public_fname);
- goto err;
- }
- if (found_public) {
- if (have_secret) {
- /* If we have a secret key and we're reloading the public key,
- * the key must match! */
- if (! ed25519_pubkey_eq(&keypair->pubkey, &pubkey_tmp)) {
- tor_log(severity, LD_OR, "%s does not match %s! If you are trying "
- "to restore from backup, make sure you didn't mix up the "
- "key files. If you are absolutely sure that %s is the right "
- "key for this relay, delete %s or move it out of the way.",
- public_fname, loaded_secret_fname,
- loaded_secret_fname, public_fname);
- goto err;
- }
- } else {
- /* We only have the public key; better use that. */
- tor_assert(split);
- memcpy(&keypair->pubkey, &pubkey_tmp, sizeof(pubkey_tmp));
- }
- } else {
- /* We have no public key file, but we do have a secret key, make the
- * public key file! */
- if (have_secret) {
- if (ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag)
- < 0) {
- tor_log(severity, LD_OR, "Couldn't repair %s", public_fname);
- goto err;
- } else {
- tor_log(LOG_NOTICE, LD_OR,
- "Found secret key but not %s. Regenerating.",
- public_fname);
- }
- }
- }
- }
-
- /* If the secret key is absent and it's not allowed to be, fail. */
- if (!have_secret && found_public &&
- !(flags & INIT_ED_KEY_MISSING_SECRET_OK)) {
- if (have_encrypted_secret_file) {
- tor_log(severity, LD_OR, "We needed to load a secret key from %s, "
- "but it was encrypted. Try 'tor --keygen' instead, so you "
- "can enter the passphrase.",
- secret_fname);
- } else if (offline_secret) {
- tor_log(severity, LD_OR, "We wanted to load a secret key from %s, "
- "but you're keeping it offline. (OfflineMasterKey is set.)",
- secret_fname);
- } else {
- tor_log(severity, LD_OR, "We needed to load a secret key from %s, "
- "but couldn't find it. %s", secret_fname,
- (flags & INIT_ED_KEY_SUGGEST_KEYGEN) ?
- "If you're keeping your master secret key offline, you will "
- "need to run 'tor --keygen' to generate new signing keys." :
- "Did you forget to copy it over when you copied the rest of the "
- "signing key material?");
- }
- goto err;
- }
-
- /* If it's absent, and we're not supposed to make a new keypair, fail. */
- if (!have_secret && !found_public && !(flags & INIT_ED_KEY_CREATE)) {
- if (split) {
- tor_log(severity, LD_OR, "No key found in %s or %s.",
- secret_fname, public_fname);
- } else {
- tor_log(severity, LD_OR, "No key found in %s.", secret_fname);
- }
- goto err;
- }
-
- /* If the secret key is absent, but the encrypted key would be present,
- * that's an error */
- if (!have_secret && !found_public && have_encrypted_secret_file) {
- tor_assert(!encrypt_key);
- tor_log(severity, LD_OR, "Found an encrypted secret key, "
- "but not public key file %s!", public_fname);
- goto err;
- }
-
- /* if it's absent, make a new keypair... */
- if (!have_secret && !found_public) {
- tor_free(keypair);
- keypair = ed_key_new(signing_key, flags, now, lifetime,
- cert_type, &cert);
- if (!keypair) {
- tor_log(severity, LD_OR, "Couldn't create keypair");
- goto err;
- }
- created_pk = created_sk = created_cert = 1;
- }
-
- /* Write it to disk if we're supposed to do with a new passphrase, or if
- * we just created it. */
- if (created_sk || (have_secret && options != NULL &&
- options->change_key_passphrase)) {
- if (write_secret_key(&keypair->seckey,
- encrypt_key,
- secret_fname, tag, encrypted_secret_fname) < 0
- ||
- (split &&
- ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) < 0)
- ||
- (cert &&
- crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert",
- tag, cert->encoded, cert->encoded_len) < 0)) {
- tor_log(severity, LD_OR, "Couldn't write keys or cert to file.");
- goto err;
- }
- goto done;
- }
-
- /* If we're not supposed to get a cert, we're done. */
- if (! (flags & INIT_ED_KEY_NEEDCERT))
- goto done;
-
- /* Read a cert. */
- tor_free(got_tag);
- uint8_t certbuf[256];
- ssize_t cert_body_len = crypto_read_tagged_contents_from_file(
- cert_fname, "ed25519v1-cert",
- &got_tag, certbuf, sizeof(certbuf));
- if (cert_body_len >= 0 && !strcmp(got_tag, tag))
- cert = tor_cert_parse(certbuf, cert_body_len);
-
- /* If we got it, check it to the extent we can. */
- int bad_cert = 0;
-
- if (! cert) {
- tor_log(severity, LD_OR, "Cert was unparseable");
- bad_cert = 1;
- } else if (!tor_memeq(cert->signed_key.pubkey, keypair->pubkey.pubkey,
- ED25519_PUBKEY_LEN)) {
- tor_log(severity, LD_OR, "Cert was for wrong key");
- bad_cert = 1;
- } else if (signing_key &&
- tor_cert_checksig(cert, &signing_key->pubkey, now) < 0) {
- tor_log(severity, LD_OR, "Can't check certificate: %s",
- tor_cert_describe_signature_status(cert));
- bad_cert = 1;
- } else if (cert->cert_expired) {
- tor_log(severity, LD_OR, "Certificate is expired");
- bad_cert = 1;
- } else if (signing_key && cert->signing_key_included &&
- ! ed25519_pubkey_eq(&signing_key->pubkey, &cert->signing_key)) {
- tor_log(severity, LD_OR, "Certificate signed by unexpectd key!");
- bad_cert = 1;
- }
-
- if (bad_cert) {
- tor_cert_free(cert);
- cert = NULL;
- }
-
- /* If we got a cert, we're done. */
- if (cert)
- goto done;
-
- /* If we didn't get a cert, and we're not supposed to make one, fail. */
- if (!signing_key || !(flags & INIT_ED_KEY_CREATE)) {
- tor_log(severity, LD_OR, "Without signing key, can't create certificate");
- goto err;
- }
-
- /* We have keys but not a certificate, so make one. */
- uint32_t cert_flags = 0;
- if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT)
- cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY;
- cert = tor_cert_create(signing_key, cert_type,
- &keypair->pubkey,
- now, lifetime,
- cert_flags);
-
- if (! cert) {
- tor_log(severity, LD_OR, "Couldn't create certificate");
- goto err;
- }
-
- /* Write it to disk. */
- created_cert = 1;
- if (crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert",
- tag, cert->encoded, cert->encoded_len) < 0) {
- tor_log(severity, LD_OR, "Couldn't write cert to disk.");
- goto err;
- }
-
- done:
- if (cert_out)
- *cert_out = cert;
- else
- tor_cert_free(cert);
-
- goto cleanup;
-
- err:
- if (keypair)
- memwipe(keypair, 0, sizeof(*keypair));
- tor_free(keypair);
- tor_cert_free(cert);
- if (cert_out)
- *cert_out = NULL;
- if (created_sk)
- unlink(secret_fname);
- if (created_pk)
- unlink(public_fname);
- if (created_cert)
- unlink(cert_fname);
-
- cleanup:
- tor_free(encrypted_secret_fname);
- tor_free(secret_fname);
- tor_free(public_fname);
- tor_free(cert_fname);
- tor_free(got_tag);
-
- return keypair;
-}
-
-/**
- * Create a new signing key and (optionally) certficiate; do not read or write
- * from disk. See ed_key_init_from_file() for more information.
- */
-ed25519_keypair_t *
-ed_key_new(const ed25519_keypair_t *signing_key,
- uint32_t flags,
- time_t now,
- time_t lifetime,
- uint8_t cert_type,
- struct tor_cert_st **cert_out)
-{
- if (cert_out)
- *cert_out = NULL;
-
- const int extra_strong = !! (flags & INIT_ED_KEY_EXTRA_STRONG);
- ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t));
- if (ed25519_keypair_generate(keypair, extra_strong) < 0)
- goto err;
-
- if (! (flags & INIT_ED_KEY_NEEDCERT))
- return keypair;
-
- tor_assert(signing_key);
- tor_assert(cert_out);
- uint32_t cert_flags = 0;
- if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT)
- cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY;
- tor_cert_t *cert = tor_cert_create(signing_key, cert_type,
- &keypair->pubkey,
- now, lifetime,
- cert_flags);
- if (! cert)
- goto err;
-
- *cert_out = cert;
- return keypair;
-
- err:
- tor_free(keypair);
- return NULL;
-}
-
static ed25519_keypair_t *master_identity_key = NULL;
static ed25519_keypair_t *master_signing_key = NULL;
static ed25519_keypair_t *current_auth_key = NULL;
@@ -1363,43 +720,6 @@ make_tap_onion_key_crosscert(const crypto_pk_t *onion_key,
return tor_memdup(signature, r);
}
-/** Check whether an RSA-TAP cross-certification is correct. Return 0 if it
- * is, -1 if it isn't. */
-MOCK_IMPL(int,
-check_tap_onion_key_crosscert,(const uint8_t *crosscert,
- int crosscert_len,
- const crypto_pk_t *onion_pkey,
- const ed25519_public_key_t *master_id_pkey,
- const uint8_t *rsa_id_digest))
-{
- uint8_t *cc = tor_malloc(crypto_pk_keysize(onion_pkey));
- int cc_len =
- crypto_pk_public_checksig(onion_pkey,
- (char*)cc,
- crypto_pk_keysize(onion_pkey),
- (const char*)crosscert,
- crosscert_len);
- if (cc_len < 0) {
- goto err;
- }
- if (cc_len < DIGEST_LEN + ED25519_PUBKEY_LEN) {
- log_warn(LD_DIR, "Short signature on cross-certification with TAP key");
- goto err;
- }
- if (tor_memneq(cc, rsa_id_digest, DIGEST_LEN) ||
- tor_memneq(cc + DIGEST_LEN, master_id_pkey->pubkey,
- ED25519_PUBKEY_LEN)) {
- log_warn(LD_DIR, "Incorrect cross-certification with TAP key");
- goto err;
- }
-
- tor_free(cc);
- return 0;
- err:
- tor_free(cc);
- return -1;
-}
-
void
routerkeys_free_all(void)
{
diff --git a/src/feature/relay/routerkeys.h b/src/feature/relay/routerkeys.h
index f52ed0f30..c5a58e553 100644
--- a/src/feature/relay/routerkeys.h
+++ b/src/feature/relay/routerkeys.h
@@ -6,35 +6,6 @@
#include "lib/crypt_ops/crypto_ed25519.h"
-#define INIT_ED_KEY_CREATE (1u<<0)
-#define INIT_ED_KEY_REPLACE (1u<<1)
-#define INIT_ED_KEY_SPLIT (1u<<2)
-#define INIT_ED_KEY_MISSING_SECRET_OK (1u<<3)
-#define INIT_ED_KEY_NEEDCERT (1u<<4)
-#define INIT_ED_KEY_EXTRA_STRONG (1u<<5)
-#define INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT (1u<<6)
-#define INIT_ED_KEY_OMIT_SECRET (1u<<7)
-#define INIT_ED_KEY_TRY_ENCRYPTED (1u<<8)
-#define INIT_ED_KEY_NO_REPAIR (1u<<9)
-#define INIT_ED_KEY_SUGGEST_KEYGEN (1u<<10)
-#define INIT_ED_KEY_OFFLINE_SECRET (1u<<11)
-#define INIT_ED_KEY_EXPLICIT_FNAME (1u<<12)
-
-struct tor_cert_st;
-ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags,
- int severity,
- const ed25519_keypair_t *signing_key,
- time_t now,
- time_t lifetime,
- uint8_t cert_type,
- struct tor_cert_st **cert_out,
- const or_options_t *options);
-ed25519_keypair_t *ed_key_new(const ed25519_keypair_t *signing_key,
- uint32_t flags,
- time_t now,
- time_t lifetime,
- uint8_t cert_type,
- struct tor_cert_st **cert_out);
const ed25519_public_key_t *get_master_identity_key(void);
const ed25519_keypair_t *get_master_signing_keypair(void);
const struct tor_cert_st *get_master_signing_key_cert(void);
@@ -58,23 +29,12 @@ uint8_t *make_tap_onion_key_crosscert(const crypto_pk_t *onion_key,
const crypto_pk_t *rsa_id_key,
int *len_out);
-MOCK_DECL(int, check_tap_onion_key_crosscert,(const uint8_t *crosscert,
- int crosscert_len,
- const crypto_pk_t *onion_pkey,
- const ed25519_public_key_t *master_id_pkey,
- const uint8_t *rsa_id_digest));
-
int log_cert_expiration(void);
int load_ed_keys(const or_options_t *options, time_t now);
int should_make_new_ed_keys(const or_options_t *options, const time_t now);
int generate_ed_link_cert(const or_options_t *options, time_t now, int force);
-int read_encrypted_secret_key(ed25519_secret_key_t *out,
- const char *fname);
-int write_encrypted_secret_key(const ed25519_secret_key_t *out,
- const char *fname);
-
void routerkeys_free_all(void);
#ifdef TOR_UNIT_TESTS
@@ -83,4 +43,3 @@ void init_mock_ed_keys(const crypto_pk_t *rsa_identity_key);
#endif
#endif /* !defined(TOR_ROUTERKEYS_H) */
-
diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c
index 7966ab846..b16574003 100644
--- a/src/feature/rend/rendservice.c
+++ b/src/feature/rend/rendservice.c
@@ -31,6 +31,7 @@
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendservice.h"
#include "feature/relay/router.h"
+#include "feature/keymgt/loadkey.h"
#include "core/or/relay.h"
#include "feature/stats/rephist.h"
#include "feature/hs_common/replaycache.h"
@@ -1363,7 +1364,7 @@ rend_service_key_on_disk(const char *directory_path)
/* Load key */
fname = hs_path_from_filename(directory_path, private_key_fname);
- pk = init_key_from_file(fname, 0, LOG_DEBUG, 0);
+ pk = init_key_from_file(fname, 0, LOG_DEBUG, NULL);
if (pk) {
ret = 1;
}
@@ -1535,7 +1536,7 @@ rend_service_load_keys(rend_service_t *s)
/* Load key */
fname = rend_service_path(s, private_key_fname);
- s->private_key = init_key_from_file(fname, 1, LOG_ERR, 0);
+ s->private_key = init_key_from_file(fname, 1, LOG_ERR, NULL);
if (!s->private_key)
goto err;
diff --git a/src/test/fuzz/fuzz_descriptor.c b/src/test/fuzz/fuzz_descriptor.c
index 5a56f4081..2babdce4b 100644
--- a/src/test/fuzz/fuzz_descriptor.c
+++ b/src/test/fuzz/fuzz_descriptor.c
@@ -4,7 +4,8 @@
#include "core/or/or.h"
#include "feature/nodelist/routerparse.h"
#include "feature/nodelist/routerlist.h"
-#include "feature/relay/routerkeys.h"
+#include "feature/nodelist/torcert.h"
+#include "feature/keymgt/loadkey.h"
#include "test/fuzz/fuzzing.h"
static int
@@ -76,4 +77,3 @@ fuzz_main(const uint8_t *data, size_t sz)
}
return 0;
}
-
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index b62aea113..f05401ba0 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -11,6 +11,7 @@
#include "feature/relay/routerkeys.h"
#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_format.h"
+#include "feature/keymgt/loadkey.h"
#include "feature/nodelist/torcert.h"
#include "test/test.h"
1
0

26 Sep '18
commit 70539e3d5e357521616a083a69712605b7b98c23
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Sep 25 15:39:24 2018 -0400
Move all authdir_mode_*() functions into authmode.h
---
src/core/include.am | 1 +
src/core/mainloop/connection.c | 1 +
src/core/mainloop/mainloop.c | 1 +
src/core/or/circuitstats.c | 1 +
src/core/or/connection_or.c | 1 +
src/feature/control/fmt_serverstatus.c | 1 +
src/feature/dirauth/authmode.c | 70 ++++++++++++++++++++++++++++++++++
src/feature/dirauth/authmode.h | 28 ++++++++------
src/feature/dirauth/reachability.c | 1 +
src/feature/nodelist/authcert.c | 1 +
src/feature/nodelist/dirlist.c | 1 +
src/feature/relay/router.c | 51 -------------------------
src/feature/relay/router.h | 6 ---
src/feature/stats/rephist.c | 1 +
14 files changed, 96 insertions(+), 69 deletions(-)
diff --git a/src/core/include.am b/src/core/include.am
index 5e6e95da1..abbf89f69 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -138,6 +138,7 @@ LIBTOR_APP_TESTING_A_SOURCES = $(LIBTOR_APP_A_SOURCES)
# The Directory Authority module.
MODULE_DIRAUTH_SOURCES = \
+ src/feature/dirauth/authmode.c \
src/feature/dirauth/dircollate.c \
src/feature/dirauth/dirvote.c \
src/feature/dirauth/shared_random.c \
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 4231bec01..b858b94cd 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -77,6 +77,7 @@
#include "core/or/connection_or.h"
#include "feature/control/control.h"
#include "lib/crypt_ops/crypto_util.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dircommon/directory.h"
#include "feature/dircache/dirserv.h"
#include "feature/relay/dns.h"
diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c
index 105638ffa..6d60b779b 100644
--- a/src/core/mainloop/mainloop.c
+++ b/src/core/mainloop/mainloop.c
@@ -70,6 +70,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/dircommon/directory.h"
#include "feature/dircache/dirserv.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dirauth/reachability.h"
#include "feature/relay/dns.h"
#include "feature/client/dnsserv.h"
diff --git a/src/core/or/circuitstats.c b/src/core/or/circuitstats.c
index 2f37cdfa1..0429f2c86 100644
--- a/src/core/or/circuitstats.c
+++ b/src/core/or/circuitstats.c
@@ -43,6 +43,7 @@
#include "lib/math/fp.h"
#include "lib/time/tvdiff.h"
#include "lib/encoding/confline.h"
+#include "feature/dirauth/authmode.h"
#include "core/or/crypt_path_st.h"
#include "core/or/origin_circuit_st.h"
diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c
index ca69fa00d..7902b6c59 100644
--- a/src/core/or/connection_or.c
+++ b/src/core/or/connection_or.c
@@ -62,6 +62,7 @@
#include "core/or/scheduler.h"
#include "feature/nodelist/torcert.h"
#include "core/or/channelpadding.h"
+#include "feature/dirauth/authmode.h"
#include "core/or/cell_st.h"
#include "core/or/cell_queue_st.h"
diff --git a/src/feature/control/fmt_serverstatus.c b/src/feature/control/fmt_serverstatus.c
index f150832ce..ed9f14ab3 100644
--- a/src/feature/control/fmt_serverstatus.c
+++ b/src/feature/control/fmt_serverstatus.c
@@ -7,6 +7,7 @@
#include "feature/control/fmt_serverstatus.h"
#include "app/config/config.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dirauth/voteflags.h"// XXXX remove
#include "feature/nodelist/nodelist.h"
#include "feature/relay/router.h"
diff --git a/src/feature/dirauth/authmode.c b/src/feature/dirauth/authmode.c
new file mode 100644
index 000000000..7c900ea7b
--- /dev/null
+++ b/src/feature/dirauth/authmode.c
@@ -0,0 +1,70 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file authmode.c
+ * \brief What kind of directory authority are we?
+ *
+ * If we're not an authority, these functions are all replaced with 0 in
+ * authmode.h.
+ **/
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "feature/dirauth/authmode.h"
+
+#include "feature/nodelist/routerinfo_st.h"
+
+/** Return true iff we believe ourselves to be an authoritative
+ * directory server.
+ */
+int
+authdir_mode(const or_options_t *options)
+{
+ return options->AuthoritativeDir != 0;
+}
+/** Return true iff we are an authoritative directory server that is
+ * authoritative about receiving and serving descriptors of type
+ * <b>purpose</b> on its dirport.
+ */
+int
+authdir_mode_handles_descs(const or_options_t *options, int purpose)
+{
+ if (BUG(purpose < 0)) /* Deprecated. */
+ return authdir_mode(options);
+ else if (purpose == ROUTER_PURPOSE_GENERAL)
+ return authdir_mode_v3(options);
+ else if (purpose == ROUTER_PURPOSE_BRIDGE)
+ return authdir_mode_bridge(options);
+ else
+ return 0;
+}
+/** Return true iff we are an authoritative directory server that
+ * publishes its own network statuses.
+ */
+int
+authdir_mode_publishes_statuses(const or_options_t *options)
+{
+ if (authdir_mode_bridge(options))
+ return 0;
+ return authdir_mode(options);
+}
+/** Return true iff we are an authoritative directory server that
+ * tests reachability of the descriptors it learns about.
+ */
+int
+authdir_mode_tests_reachability(const or_options_t *options)
+{
+ return authdir_mode(options);
+}
+/** Return true iff we believe ourselves to be a bridge authoritative
+ * directory server.
+ */
+int
+authdir_mode_bridge(const or_options_t *options)
+{
+ return authdir_mode(options) && options->BridgeAuthoritativeDir != 0;
+}
diff --git a/src/feature/dirauth/authmode.h b/src/feature/dirauth/authmode.h
index 8bb961dff..3ca127b82 100644
--- a/src/feature/dirauth/authmode.h
+++ b/src/feature/dirauth/authmode.h
@@ -2,16 +2,22 @@
/* See LICENSE for licensing information */
/**
- * \file mode.h
- * \brief Standalone header file for directory authority mode.
+ * \file authmode.h
+ * \brief Header file for directory authority mode.
**/
#ifndef TOR_DIRAUTH_MODE_H
#define TOR_DIRAUTH_MODE_H
+#include "feature/relay/router.h"
+
#ifdef HAVE_MODULE_DIRAUTH
-#include "feature/relay/router.h"
+int authdir_mode(const or_options_t *options);
+int authdir_mode_handles_descs(const or_options_t *options, int purpose);
+int authdir_mode_publishes_statuses(const or_options_t *options);
+int authdir_mode_tests_reachability(const or_options_t *options);
+int authdir_mode_bridge(const or_options_t *options);
/* Return true iff we believe ourselves to be a v3 authoritative directory
* server. */
@@ -23,16 +29,14 @@ authdir_mode_v3(const or_options_t *options)
#else /* HAVE_MODULE_DIRAUTH */
-/* Without the dirauth module, we can't be a v3 directory authority, ever. */
-
-static inline int
-authdir_mode_v3(const or_options_t *options)
-{
- (void) options;
- return 0;
-}
+#define authdir_mode(options) (((void)(options)),0)
+#define authdir_mode_handles_descs(options,purpose) \
+ (((void)(options)),((void)(purpose)),0)
+#define authdir_mode_publishes_statuses(options) (((void)(options)),0)
+#define authdir_mode_tests_reachability(options) (((void)(options)),0)
+#define authdir_mode_bridge(options) (((void)(options)),0)
+#define authdir_mode_v3(options) (((void)(options)),0)
#endif /* HAVE_MODULE_DIRAUTH */
#endif /* TOR_MODE_H */
-
diff --git a/src/feature/dirauth/reachability.c b/src/feature/dirauth/reachability.c
index abc7249b6..79c98d3ee 100644
--- a/src/feature/dirauth/reachability.c
+++ b/src/feature/dirauth/reachability.c
@@ -16,6 +16,7 @@
#include "core/or/channel.h"
#include "core/or/channeltls.h"
#include "core/or/command.h"
+#include "feature/dirauth/authmode.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/torcert.h"
diff --git a/src/feature/nodelist/authcert.c b/src/feature/nodelist/authcert.c
index e070cb142..665105e60 100644
--- a/src/feature/nodelist/authcert.c
+++ b/src/feature/nodelist/authcert.c
@@ -23,6 +23,7 @@
#include "core/mainloop/mainloop.h"
#include "core/or/policies.h"
#include "feature/client/bridges.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dircommon/directory.h"
#include "feature/dirclient/dirclient.h"
#include "feature/dirclient/dlstatus.h"
diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c
index 0935145d8..c14d7df0f 100644
--- a/src/feature/nodelist/dirlist.c
+++ b/src/feature/nodelist/dirlist.c
@@ -29,6 +29,7 @@
#include "app/config/config.h"
#include "core/or/policies.h"
#include "feature/control/control.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dircommon/directory.h"
#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/networkstatus.h"
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 3e19c7b61..cc5c424fe 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -1348,57 +1348,6 @@ net_is_completely_disabled(void)
return get_options()->DisableNetwork || we_are_fully_hibernating();
}
-/** Return true iff we believe ourselves to be an authoritative
- * directory server.
- */
-int
-authdir_mode(const or_options_t *options)
-{
- return options->AuthoritativeDir != 0;
-}
-/** Return true iff we are an authoritative directory server that is
- * authoritative about receiving and serving descriptors of type
- * <b>purpose</b> on its dirport.
- */
-int
-authdir_mode_handles_descs(const or_options_t *options, int purpose)
-{
- if (BUG(purpose < 0)) /* Deprecated. */
- return authdir_mode(options);
- else if (purpose == ROUTER_PURPOSE_GENERAL)
- return authdir_mode_v3(options);
- else if (purpose == ROUTER_PURPOSE_BRIDGE)
- return authdir_mode_bridge(options);
- else
- return 0;
-}
-/** Return true iff we are an authoritative directory server that
- * publishes its own network statuses.
- */
-int
-authdir_mode_publishes_statuses(const or_options_t *options)
-{
- if (authdir_mode_bridge(options))
- return 0;
- return authdir_mode(options);
-}
-/** Return true iff we are an authoritative directory server that
- * tests reachability of the descriptors it learns about.
- */
-int
-authdir_mode_tests_reachability(const or_options_t *options)
-{
- return authdir_mode(options);
-}
-/** Return true iff we believe ourselves to be a bridge authoritative
- * directory server.
- */
-int
-authdir_mode_bridge(const or_options_t *options)
-{
- return authdir_mode(options) && options->BridgeAuthoritativeDir != 0;
-}
-
/** Return true iff we are trying to be a server.
*/
MOCK_IMPL(int,
diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h
index 52c4ac0bd..7b33069aa 100644
--- a/src/feature/relay/router.h
+++ b/src/feature/relay/router.h
@@ -61,12 +61,6 @@ int dir_server_mode(const or_options_t *options);
int net_is_disabled(void);
int net_is_completely_disabled(void);
-int authdir_mode(const or_options_t *options);
-int authdir_mode_handles_descs(const or_options_t *options, int purpose);
-int authdir_mode_publishes_statuses(const or_options_t *options);
-int authdir_mode_tests_reachability(const or_options_t *options);
-int authdir_mode_bridge(const or_options_t *options);
-
uint16_t router_get_active_listener_port_by_type_af(int listener_type,
sa_family_t family);
uint16_t router_get_advertised_or_port(const or_options_t *options);
diff --git a/src/feature/stats/rephist.c b/src/feature/stats/rephist.c
index 24c73554b..210576b9e 100644
--- a/src/feature/stats/rephist.c
+++ b/src/feature/stats/rephist.c
@@ -90,6 +90,7 @@
#include "core/or/channelpadding.h"
#include "core/or/connection_or.h"
#include "app/config/statefile.h"
+#include "feature/dirauth/authmode.h"
#include "feature/nodelist/networkstatus_st.h"
#include "core/or/or_circuit_st.h"
1
0

[translation/torbutton-aboutdialogdtd] Update translations for torbutton-aboutdialogdtd
by translation@torproject.org 26 Sep '18
by translation@torproject.org 26 Sep '18
26 Sep '18
commit 14416c2f4e001145e93ff5f14ad6114b6033c436
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed Sep 26 13:48:18 2018 +0000
Update translations for torbutton-aboutdialogdtd
---
br/aboutdialog.dtd | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/br/aboutdialog.dtd b/br/aboutdialog.dtd
index 5099ad74b..d0a84339e 100644
--- a/br/aboutdialog.dtd
+++ b/br/aboutdialog.dtd
@@ -5,7 +5,7 @@
<!ENTITY help.start "Want to help? ">
<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en -->
-<!ENTITY help.donateLink "Donate">
+<!ENTITY help.donateLink "Reiñ arc'hant">
<!ENTITY help.or " or ">
<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en -->
<!ENTITY help.getInvolvedLink "get involved">
1
0
commit a06cb1e308e247b8db1c08592f49b8b2c183eafb
Author: hiro <hiro(a)torproject.org>
Date: Wed Sep 26 15:45:02 2018 +0200
Sync local changes
---
.../we-gave-tor-browser-ux-overhaul/contents.lr | 76 +++++++++++-----------
databags/footer+en.json | 14 ++++
databags/menu+en.json | 18 +++++
3 files changed, 70 insertions(+), 38 deletions(-)
diff --git a/content/archive/we-gave-tor-browser-ux-overhaul/contents.lr b/content/archive/we-gave-tor-browser-ux-overhaul/contents.lr
index f5e0dfd..b3dd80b 100644
--- a/content/archive/we-gave-tor-browser-ux-overhaul/contents.lr
+++ b/content/archive/we-gave-tor-browser-ux-overhaul/contents.lr
@@ -35,68 +35,68 @@ html_body:
<td style="padding:0 15px 15px 15px;">
<hr />
<h1><span class="quickedit-field" data-quickedit-field-id="node/1578/title/en/full" property="schema:name">We Gave Tor Browser a UX Overhaul </span></h1>
-\
+
<p><a href="https://blog.torproject.org/new-alpha-release-tor-browser-android"><img alt="Tor Browser for Android " src="https://blog.torproject.org/sites/default/files/styles/full_width/public/im…" style="width: 560px; height: 280px;" /></a></p>
-\
+
<p>For the past year, we have been collecting feedback on how we can make Tor Browser work better for you.</p>
-\
+
<p>Tor Browser 8.0, our first stable release based on Firefox 60 ESR, <a href="https://www.torproject.org/download/download-easy.html">is now available</a>. <em>This release is all about users first.</em></p>
-\
+
<p>Tor Browser 8.0 comes with a series of user experience improvements that address a set of long-term Tor Browser issues you’ve told us about. To meet our users' needs, Tor Browser has a new user onboarding experience; an updated landing page that follows our <a href="https://styleguide.torproject.org/">styleguide</a>; support for 9 new languages; and new behaviors for bridge fetching, displaying a circuit, and visiting .onion sites.</p>
-\
+
<h2>New User Onboarding</h2>
-\
+
<p><a href="https://blog.torproject.org/new-release-tor-browser-80"><img alt="user-onboarding" src="https://extra.torproject.org/blog/2018-09-05-tor-browser-80/tb8-onboarding-…" style="width: 560px; height: 489px;" /></a></p>
-\
+
<p>For the most part, using Tor is like using any other browser (and it is based on Firefox), but there are some usage differences and cool things happening behind the scenes that users should be aware of. Our new onboarding experience aims to better let you know about unique aspects of Tor Browser and how to maximize those for your best browsing experience.</p>
-\
+
<h2>Improved Bridge Fetching</h2>
-\
+
<p>For users where Tor is blocked, we have previously offered a handful of bridges in the browser to bypass censorship. But to receive additional bridges, you had to send an email or visit a website, which posed a set of problems. To simplify how you request bridges, we now have a new bridge configuration flow when you when you launch Tor. Now all you have to do is solve a captcha in Tor Launcher, and you’ll get a bridge IP. We hope this simplification will allow more people to bypass censorship and browse the internet freely and privately.</p>
-\
+
<h2>Better Language Support</h2>
-\
+
<p>Millions of people around the world use Tor, but not everyone has been able to use Tor in their language. In Tor Browser 8, we’ve added resources and support for nine previously unsupported languages: Catalan, Irish, Indonesian, Icelandic, Norwegian, Danish, Hebrew, Swedish, and Traditional Chinese.</p>
-\
+
<h2>Collaboration Was Key</h2>
-\
+
<p>Providing this many improvements for our users could only be possible with collaboration between the Tor Browser team and Tor's UX team, Community team, Services Admin team, and our volunteers. We would like to thank everyone for working hard over the past year to bring all these new features to our users.</p>
-\
+
<p><a href="https://blog.torproject.org/new-alpha-release-tor-browser-android">Learn more about the release</a>.</p>
-\
+
<p><a href="https://www.torproject.org/download/download-easy.html">Try it out</a>.</p>
-\
+
<hr />
<h1>Volunteer Spotlight: <span class="quickedit-field" data-quickedit-field-id="node/1595/title/en/full" property="schema:name">Sina Rabbani Helps Activists Avoid Government Censorship</span></h1>
-\
+
<p><a href="https://blog.torproject.org/volunteer-spotlight-sina-rabbani-helps-activist…"><img alt="Tor Volunteers" src="https://blog.torproject.org/sites/default/files/styles/full_width/public/im…" style="width: 560px; height: 280px;" /></a></p>
-\
+
<p>Tor is a labor of love built by a small group of committed individuals. We’re grateful to have the support of a dedicated volunteer base who help us to make Tor the strongest privacy tool out there, and we’re highlighting their work in this series. We want to thank Sina Rabbani, one of the co-founders (and former CTO) of <a href="https://accessnow.org/">Access Now</a>, a nonprofit dedicated to defending users’ digital rights, for his years of support to Tor and to the internet freedom movement.</p>
-\
+
<p>Sina runs<a href="https://metrics.torproject.org/rs.html#details/CF6D0AAFB385BE71B8E111FC5CFF…"> Faravahar</a>, one of nine Tor directory authorities. These <a href="https://blog.torproject.org/introducing-bastet-our-new-directory-authority">dedicated servers</a> tell the millions of Tor clients which relays make up the Tor network. A talented and passionate engineer, Sina has been involved with digital rights activism for almost a decade. Today, he’s a Systems Engineer with Team Cymru, an internet security company which analyzes threat intelligence.</p>
-\
+
<p><a href="https://blog.torproject.org/volunteer-spotlight-sina-rabbani-helps-activist…"><img alt="Sina " src="https://blog.torproject.org/sites/default/files/inline-images/sina-tor-volu…" style="width: 560px; height: 280px;" /></a></p>
-\
+
<p>Free speech is something Sina doesn’t take for granted. “I was born in a country where you can be sentenced to death because of your speech,” he said. “Freedom of speech in the digital age is a basic human right. Tyranny will start by taking our ability to speak up first, then the rest of our rights.”</p>
-\>
+>
<p>“Tor gives me a chance to resist tyranny in a non-violent manner, and I feel blessed and grateful for the opportunity. The hope is to one day move Faravahar to one of Iran’s universities. Until that day, <em>Ma Hastim va Ma Bishomarim</em> — we are, and we are countless.”</p>
-\
+
<p><a href="https://blog.torproject.org/volunteer-spotlight-sina-rabbani-helps-activist…">Learn more about Sina's work and how he became involved with Tor. </a></p>
-\
+
<hr />
<h1>More New Releases</h1>
-\
+
<h2 class="title"><span class="quickedit-field" data-quickedit-field-id="node/1533/title/en/full" property="schema:name">Tor Browser 8.0a10</span></h2>
-\
+
<p><a href="https://blog.torproject.org/new-release-tor-browser-80a10">Tor Browser 8.0a10</a> is the second alpha release based on Firefox ESR 60 and contains a number of improvements and bug fixes. It includes major updates to the user experience, and there are more to come. The stable version is slated for release next week!</p>
-\
+
<h2>Tor 0.3.4.7-rc</h2>
-\
+
<p><a href="https://blog.torproject.org/new-release-tor-0347-rc">Tor 0.3.4.7-rc </a>fixes several small compilation, portability, and correctness issues in previous versions of Tor. This version is a release candidate: if no serious bugs are found, we expect that the stable 0.3.4 release will be (almost) the same as this release.</p>
-\
+
<hr />
<h1>Upcoming Events with Tor</h1>
-\
+
<ul>
<li>
<p><a href="https://blog.torproject.org/events/tor-meetup-ciudad-de-mexico">Tor Meetup Ciudad de México</a>. Mexico City. September 27, 2018.</p>
@@ -105,16 +105,16 @@ html_body:
<p><a href="https://blog.torproject.org/events/tors-open-hack-days-mexico-city">Tor's Open Hack Days</a>. Mexico City. October 2-3, 2018.</p>
</li>
</ul>
-\
+
<hr />
<h1>Join Our Community</h1>
-\
+
<p>Getting involved with Tor is easy. <a href="https://trac.torproject.org/projects/tor/wiki/TorRelayGuide">Run a relay</a> to make the network faster and more decentralized.</p>
-\
+
<p>Learn about each of our <a href="https://trac.torproject.org/projects/tor/wiki/WikiStart#Teams">teams </a>and start collaborating.</p>
-\
+
<p><a href="https://donate.torproject.org">Donate today</a> to help keep Tor fast, strong, and secure.</p>
-\
+
<div style="background-color: #68b030; padding: 6px 8px 6px 8px;\
-webkit-border-radius:3px; border-radius:3px; margin: 0 auto; width:200px; text-align: center;"><a href="https://donate.torproject.org" style="font-size: 24px; font-family: Source sans pro, Helvetica, Arial, sans-serif; font-weight: bold; color: #ffffff; text-decoration: none; display:inline-block;" target="_blank">DONATE</a></div>
</td>
@@ -122,10 +122,10 @@ html_body:
<tr>
<td style="padding:0 15px;">
<p>The Tor Project is a US 501(c)(3) non-profit organization advancing human rights and freedoms by creating and deploying free and open-source anonymity and privacy technologies, supporting their unrestricted availability and use, and furthering their scientific and popular understanding.</p>
-\
+
<hr />
<p><a href="https://facebook.com/torproject"><img alt="" src="https://blog.torproject.org/sites/default/files/inline-images/tor-facebook.…" style="width: 25px; height: 25px; margin: 3px;" /></a><a href="https://twitter.com/torproject"> <img alt="tor-twitter" src="https://blog.torproject.org/sites/default/files/inline-images/tor-twitter.p…" style="width: 25px; height: 25px; margin: 3px;" /></a><a href="https://instagram.com/torproject"> <img alt="tor-insta" src="https://blog.torproject.org/sites/default/files/inline-images/instagram-tor…" style="width: 25px; height: 25px; margin: 3px;" /></a></p>
-\
+
<br />
<a href="https://torproject.org">torproject.org</a></small></p>
</td>
@@ -144,7 +144,7 @@ html_body:
</tr>
</tbody>
</table>
-\
+
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" id="backgroundTable" st-sortable="left-image" width="100%">
<tbody>
<tr>
diff --git a/databags/footer+en.json b/databags/footer+en.json
new file mode 100644
index 0000000..2d4d1da
--- /dev/null
+++ b/databags/footer+en.json
@@ -0,0 +1,14 @@
+{
+ "about": {
+ "path": "https://www.torproject.org/",
+ "label": "The Tor Project"
+ },
+ "rss": {
+ "path": "https://newsletter.torproject.org/rss/index.xml",
+ "label": "RSS"
+ },
+ "donate":{
+ "path": "https://donate.torproject.org/",
+ "label": "Donate"
+ }
+}
diff --git a/databags/menu+en.json b/databags/menu+en.json
new file mode 100644
index 0000000..d167ebd
--- /dev/null
+++ b/databags/menu+en.json
@@ -0,0 +1,18 @@
+{
+ "archive": {
+ "path": "/archive",
+ "label": "Archive"
+ },
+ "about": {
+ "path": "https://www.torproject.org/",
+ "label": "About Tor"
+ },
+ "donate":{
+ "path": "https://donate.torproject.org/",
+ "label": "Donate"
+ },
+ "RSS":{
+ "path": "/rss",
+ "label": "RSS"
+ }
+}
1
0
commit 4612036a734bdfff542e8e74207661e91b49ed1d
Author: traumschule <traumschuleriebau(a)riseup.net>
Date: Sun Sep 23 18:18:04 2018 +0200
intro: remove name fields (#27830)
---
templates/intro.html | 70 +++++++++++++++++-----------------------------------
1 file changed, 23 insertions(+), 47 deletions(-)
diff --git a/templates/intro.html b/templates/intro.html
index e93a3b6..1b30716 100644
--- a/templates/intro.html
+++ b/templates/intro.html
@@ -2,59 +2,35 @@
{% block title %}{{ this.title }}{% endblock %}
{% block body %}
{{ this.body }}
-<div class="row mx-auto">
- <div class="col-10">
- <p class="text-center">
+<div class="row mb-1">
+ <div class="col-12">
+ <h6>
Sign Up For Tor News
- </p>
- <p class="text-center">
- Get updates and opportunities from across the organization and community
- </p>
+ </h6>
+ <h2>
+ Get updates and opportunities from across the organization and community.
+ </h2>
</div>
</div>
-<div class="row mx-auto">
- <div class="col-10 text-center">
- <h2 class="newsletter-title">Your Info</h2>
- </div>
-</div>
-<div class="row mx-auto">
- <div class="col-10 text-center">
- <p class="required-field">
- * required fields
+<div class="row mb-1">
+ <div class="col-12">
+ <p>
+ The information you provide here will only be used to send you updates
+ and opportunities from Tor. You can unsubscribe at any time. We will not
+ publish, sell, trade, share, or rent any information about you. Never.
</p>
</div>
</div>
-<div class="row mx-auto">
- <div class="col-10">
- <form action="https://donate.torproject.org/subscription-request" method="POST">
- <div class="form-group row">
- <div class="col">
- <input class="form-control form-control-lg" id="firstName" name="firstName" placeholder="First Name" value="" type="text">
- </div>
- <div class="col">
- <input class="form-control form-control-lg" id="lastName" name="lastName" placeholder="Last Name" value="" type="text">
- </div>
- </div>
- <div class="form-group row">
- <div class="col">
- <input class="form-control form-control-lg form-required" id="email" name="email" placeholder="* Email Address" value="" type="email">
- </div>
- </div>
- <div class="row">
- <div class="col">
- <p class="text-justify">
- The information you provide here will only be used to send you updates and opportunities from Tor. You can unsubscribe at any time. We will not publish, sell, trade, share, or rent any information about you.
- </p>
- </div>
- </div>
- <div class="row">
- <div class="col-4"></div>
- <div class="col-4">
- <input class="donate btn btn-lg btn-success btn-block" value="Join" type="submit">
- </div>
- <div class="col-4"></div>
- </div>
- </form>
+<div class="row mb-1">
+ <form action="https://donate.torproject.org/subscription-request" method="POST">
+ <div class="col-8">
+ <input class="form-control form-control-lg form-required" id="email"
+ name="email" placeholder="* Email Address" value="" type="email" />
+ </div>
+ <div class="col-4">
+ <input class="donate btn btn-lg btn-success btn-block" value="Join"
+ type="submit" />
</div>
+ </form>
</div>
{% endblock %}
1
0
commit 9036d6c788fb210733c0c68b5964bc1cd5b4a6aa
Merge: a06cb1e 4612036
Author: hiro <hiro(a)torproject.org>
Date: Wed Sep 26 15:45:30 2018 +0200
Merge branch 'noname'
templates/intro.html | 70 +++++++++++++++++-----------------------------------
1 file changed, 23 insertions(+), 47 deletions(-)
1
0
commit 37c1fe2d4bf3f486f79222bc2aced932bca6bc87
Author: hiro <hiro(a)torproject.org>
Date: Thu Sep 6 16:30:22 2018 +0200
Add sept newsletter
---
.gitignore | 2 +-
.../we-gave-tor-browser-ux-overhaul/contents.lr | 171 +++++++++++++++++++++
.../text/contents.lr | 78 ++++++++++
3 files changed, 250 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index bdd9d96..5a76bd0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
node_modules
i18n
configs
-
+venv
.sass-cache
.DS_Store
diff --git a/content/archive/we-gave-tor-browser-ux-overhaul/contents.lr b/content/archive/we-gave-tor-browser-ux-overhaul/contents.lr
new file mode 100644
index 0000000..f5e0dfd
--- /dev/null
+++ b/content/archive/we-gave-tor-browser-ux-overhaul/contents.lr
@@ -0,0 +1,171 @@
+_model: post
+---
+_template: newsletter.html
+---
+author: steph(a)torproject.org
+---
+pub_date: 2018-09-06
+---
+title: We Gave Tor Browser a UX Overhaul
+---
+html_body:
+
+<table align="center" border="0" cellpadding="0" cellspacing="0" class="devicewidth" width="650">
+ <tbody>
+ <tr>
+ <td width="100%">
+ <table align="center" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" class="devicewidth" width="650">
+ <tbody><!-- Spacing -->
+ <tr>
+ <td height="20" width="100%"><a href="https://newsletter.torproject.org"><img alt="tor-news-logo" src="https://blog.torproject.org/sites/default/files/inline-images/tor-news-logo…" style="width: 250px; height: 75px;" /></a></td>
+ </tr>
+ <tr>
+ <td>
+ <table align="center" border="0" cellpadding="0" cellspacing="0" class="devicewidth" width="650">
+ <tbody>
+ <tr>
+ <td width="100%">
+ <table align="center" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" class="devicewidth" width="650">
+ <tbody><!-- /Spacing --><!-- Spacing -->
+ <tr>
+ <td height="15" style="font-size:1px; line-height:1px; mso-line-height-rule: exactly;" width="100%"> </td>
+ </tr>
+ <!-- /Spacing --><!-- content -->
+ <tr>
+ <td style="padding:0 15px 15px 15px;">
+ <hr />
+ <h1><span class="quickedit-field" data-quickedit-field-id="node/1578/title/en/full" property="schema:name">We Gave Tor Browser a UX Overhaul </span></h1>
+\
+ <p><a href="https://blog.torproject.org/new-alpha-release-tor-browser-android"><img alt="Tor Browser for Android " src="https://blog.torproject.org/sites/default/files/styles/full_width/public/im…" style="width: 560px; height: 280px;" /></a></p>
+\
+ <p>For the past year, we have been collecting feedback on how we can make Tor Browser work better for you.</p>
+\
+ <p>Tor Browser 8.0, our first stable release based on Firefox 60 ESR, <a href="https://www.torproject.org/download/download-easy.html">is now available</a>. <em>This release is all about users first.</em></p>
+\
+ <p>Tor Browser 8.0 comes with a series of user experience improvements that address a set of long-term Tor Browser issues you’ve told us about. To meet our users' needs, Tor Browser has a new user onboarding experience; an updated landing page that follows our <a href="https://styleguide.torproject.org/">styleguide</a>; support for 9 new languages; and new behaviors for bridge fetching, displaying a circuit, and visiting .onion sites.</p>
+\
+ <h2>New User Onboarding</h2>
+\
+ <p><a href="https://blog.torproject.org/new-release-tor-browser-80"><img alt="user-onboarding" src="https://extra.torproject.org/blog/2018-09-05-tor-browser-80/tb8-onboarding-…" style="width: 560px; height: 489px;" /></a></p>
+\
+ <p>For the most part, using Tor is like using any other browser (and it is based on Firefox), but there are some usage differences and cool things happening behind the scenes that users should be aware of. Our new onboarding experience aims to better let you know about unique aspects of Tor Browser and how to maximize those for your best browsing experience.</p>
+\
+ <h2>Improved Bridge Fetching</h2>
+\
+ <p>For users where Tor is blocked, we have previously offered a handful of bridges in the browser to bypass censorship. But to receive additional bridges, you had to send an email or visit a website, which posed a set of problems. To simplify how you request bridges, we now have a new bridge configuration flow when you when you launch Tor. Now all you have to do is solve a captcha in Tor Launcher, and you’ll get a bridge IP. We hope this simplification will allow more people to bypass censorship and browse the internet freely and privately.</p>
+\
+ <h2>Better Language Support</h2>
+\
+ <p>Millions of people around the world use Tor, but not everyone has been able to use Tor in their language. In Tor Browser 8, we’ve added resources and support for nine previously unsupported languages: Catalan, Irish, Indonesian, Icelandic, Norwegian, Danish, Hebrew, Swedish, and Traditional Chinese.</p>
+\
+ <h2>Collaboration Was Key</h2>
+\
+ <p>Providing this many improvements for our users could only be possible with collaboration between the Tor Browser team and Tor's UX team, Community team, Services Admin team, and our volunteers. We would like to thank everyone for working hard over the past year to bring all these new features to our users.</p>
+\
+ <p><a href="https://blog.torproject.org/new-alpha-release-tor-browser-android">Learn more about the release</a>.</p>
+\
+ <p><a href="https://www.torproject.org/download/download-easy.html">Try it out</a>.</p>
+\
+ <hr />
+ <h1>Volunteer Spotlight: <span class="quickedit-field" data-quickedit-field-id="node/1595/title/en/full" property="schema:name">Sina Rabbani Helps Activists Avoid Government Censorship</span></h1>
+\
+ <p><a href="https://blog.torproject.org/volunteer-spotlight-sina-rabbani-helps-activist…"><img alt="Tor Volunteers" src="https://blog.torproject.org/sites/default/files/styles/full_width/public/im…" style="width: 560px; height: 280px;" /></a></p>
+\
+ <p>Tor is a labor of love built by a small group of committed individuals. We’re grateful to have the support of a dedicated volunteer base who help us to make Tor the strongest privacy tool out there, and we’re highlighting their work in this series. We want to thank Sina Rabbani, one of the co-founders (and former CTO) of <a href="https://accessnow.org/">Access Now</a>, a nonprofit dedicated to defending users’ digital rights, for his years of support to Tor and to the internet freedom movement.</p>
+\
+ <p>Sina runs<a href="https://metrics.torproject.org/rs.html#details/CF6D0AAFB385BE71B8E111FC5CFF…"> Faravahar</a>, one of nine Tor directory authorities. These <a href="https://blog.torproject.org/introducing-bastet-our-new-directory-authority">dedicated servers</a> tell the millions of Tor clients which relays make up the Tor network. A talented and passionate engineer, Sina has been involved with digital rights activism for almost a decade. Today, he’s a Systems Engineer with Team Cymru, an internet security company which analyzes threat intelligence.</p>
+\
+ <p><a href="https://blog.torproject.org/volunteer-spotlight-sina-rabbani-helps-activist…"><img alt="Sina " src="https://blog.torproject.org/sites/default/files/inline-images/sina-tor-volu…" style="width: 560px; height: 280px;" /></a></p>
+\
+ <p>Free speech is something Sina doesn’t take for granted. “I was born in a country where you can be sentenced to death because of your speech,” he said. “Freedom of speech in the digital age is a basic human right. Tyranny will start by taking our ability to speak up first, then the rest of our rights.”</p>
+\>
+ <p>“Tor gives me a chance to resist tyranny in a non-violent manner, and I feel blessed and grateful for the opportunity. The hope is to one day move Faravahar to one of Iran’s universities. Until that day, <em>Ma Hastim va Ma Bishomarim</em> — we are, and we are countless.”</p>
+\
+ <p><a href="https://blog.torproject.org/volunteer-spotlight-sina-rabbani-helps-activist…">Learn more about Sina's work and how he became involved with Tor. </a></p>
+\
+ <hr />
+ <h1>More New Releases</h1>
+\
+ <h2 class="title"><span class="quickedit-field" data-quickedit-field-id="node/1533/title/en/full" property="schema:name">Tor Browser 8.0a10</span></h2>
+\
+ <p><a href="https://blog.torproject.org/new-release-tor-browser-80a10">Tor Browser 8.0a10</a> is the second alpha release based on Firefox ESR 60 and contains a number of improvements and bug fixes. It includes major updates to the user experience, and there are more to come. The stable version is slated for release next week!</p>
+\
+ <h2>Tor 0.3.4.7-rc</h2>
+\
+ <p><a href="https://blog.torproject.org/new-release-tor-0347-rc">Tor 0.3.4.7-rc </a>fixes several small compilation, portability, and correctness issues in previous versions of Tor. This version is a release candidate: if no serious bugs are found, we expect that the stable 0.3.4 release will be (almost) the same as this release.</p>
+\
+ <hr />
+ <h1>Upcoming Events with Tor</h1>
+\
+ <ul>
+ <li>
+ <p><a href="https://blog.torproject.org/events/tor-meetup-ciudad-de-mexico">Tor Meetup Ciudad de México</a>. Mexico City. September 27, 2018.</p>
+ </li>
+ <li>
+ <p><a href="https://blog.torproject.org/events/tors-open-hack-days-mexico-city">Tor's Open Hack Days</a>. Mexico City. October 2-3, 2018.</p>
+ </li>
+ </ul>
+\
+ <hr />
+ <h1>Join Our Community</h1>
+\
+ <p>Getting involved with Tor is easy. <a href="https://trac.torproject.org/projects/tor/wiki/TorRelayGuide">Run a relay</a> to make the network faster and more decentralized.</p>
+\
+ <p>Learn about each of our <a href="https://trac.torproject.org/projects/tor/wiki/WikiStart#Teams">teams </a>and start collaborating.</p>
+\
+ <p><a href="https://donate.torproject.org">Donate today</a> to help keep Tor fast, strong, and secure.</p>
+\
+ <div style="background-color: #68b030; padding: 6px 8px 6px 8px;\
+-webkit-border-radius:3px; border-radius:3px; margin: 0 auto; width:200px; text-align: center;"><a href="https://donate.torproject.org" style="font-size: 24px; font-family: Source sans pro, Helvetica, Arial, sans-serif; font-weight: bold; color: #ffffff; text-decoration: none; display:inline-block;" target="_blank">DONATE</a></div>
+ </td>
+ </tr>
+ <tr>
+ <td style="padding:0 15px;">
+ <p>The Tor Project is a US 501(c)(3) non-profit organization advancing human rights and freedoms by creating and deploying free and open-source anonymity and privacy technologies, supporting their unrestricted availability and use, and furthering their scientific and popular understanding.</p>
+\
+ <hr />
+ <p><a href="https://facebook.com/torproject"><img alt="" src="https://blog.torproject.org/sites/default/files/inline-images/tor-facebook.…" style="width: 25px; height: 25px; margin: 3px;" /></a><a href="https://twitter.com/torproject"> <img alt="tor-twitter" src="https://blog.torproject.org/sites/default/files/inline-images/tor-twitter.p…" style="width: 25px; height: 25px; margin: 3px;" /></a><a href="https://instagram.com/torproject"> <img alt="tor-insta" src="https://blog.torproject.org/sites/default/files/inline-images/instagram-tor…" style="width: 25px; height: 25px; margin: 3px;" /></a></p>
+\
+ <br />
+ <a href="https://torproject.org">torproject.org</a></small></p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+</table>
+\
+<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" id="backgroundTable" st-sortable="left-image" width="100%">
+ <tbody>
+ <tr>
+ <td>
+ <table align="center" border="0" cellpadding="0" cellspacing="0" class="devicewidth" width="650">
+ <tbody>
+ <tr>
+ <td width="100%">
+ <table align="center" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" class="devicewidth" width="650">
+ <tbody><!-- Spacing -->
+ <tr>
+ <td> </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<!-- Spacing -->
diff --git a/content/archive/we-gave-tor-browser-ux-overhaul/text/contents.lr b/content/archive/we-gave-tor-browser-ux-overhaul/text/contents.lr
new file mode 100644
index 0000000..51cca91
--- /dev/null
+++ b/content/archive/we-gave-tor-browser-ux-overhaul/text/contents.lr
@@ -0,0 +1,78 @@
+_model: post
+---
+_template: post.html
+---
+author: steph(a)torproject.org
+---
+pub_date: 2018-09-06
+---
+title: We Gave Tor Browser a UX Overhaul
+---
+body:
+
+// We Gave Tor Browser a UX Overhaul //
+
+For the past year, we have been collecting feedback on how we can make Tor Browser work better for you.
+
+Tor Browser 8.0, our first stable release based on Firefox 60 ESR, is now available. This release is all about users first.
+
+Tor Browser 8.0 comes with a series of user experience improvements that address a set of long-term Tor Browser issues you’ve told us about. To meet our users' needs, Tor Browser has a new user onboarding experience; an updated landing page that follows our styleguide; additional language support; and new behaviors for bridge fetching, displaying a circuit, and visiting .onion sites.
+
+For the most part, using Tor is like using any other browser (and it is based on Firefox), but there are some usage differences and cool things happening behind the scenes that users should be aware of. Our new onboarding experience aims to better let you know about unique aspects of Tor Browser and how to maximize those for your best browsing experience.
+
+Improved Bridge Fetching
+
+For users where Tor is blocked, we have previously offered a handful of bridges in the browser to bypass censorship. But to receive additional bridges, you had to send an email or visit a website, which posed a set of problems. To simplify how you request bridges, we now have a new bridge configuration flow when you when you launch Tor. Now all you have to do is solve a captcha in Tor Launcher, and you’ll get a bridge IP. We hope this simplification will allow more people to bypass censorship and browse the internet freely and privately.
+
+Better Language Support
+
+Millions of people around the world use Tor, but not everyone has been able to use Tor in their language. In Tor Browser 8, we’ve added resources and support for nine previously unsupported languages: Catalan, Irish, Indonesian, Icelandic, Norwegian, Danish, Hebrew, Swedish, and Traditional Chinese.
+
+Collaboration Was Key
+
+Providing this many improvements for our users could only be possible with collaboration between the Tor Browser team and Tor's UX team, Community team, Services Admin team, and our volunteers. We would like to thank everyone for working hard over the past year to bring all these new features to our users.
+
+Learn more about it: https://blog.torproject.org/new-alpha-release-tor-browser-android
+Try it out: https://www.torproject.org/download/download-easy.html
+
+// Volunteer Spotlight: Sina Rabbani Helps Activists Avoid Government Censorship //
+
+Tor is a labor of love built by a small group of committed individuals. We’re grateful to have the support of a dedicated volunteer base who help us to make Tor the strongest privacy tool out there, and we’re highlighting their work in this series. We want to thank Sina Rabbani, one of the co-founders (and former CTO) of Access Now, a nonprofit dedicated to defending users’ digital rights, for his years of support to Tor and to the internet freedom movement.
+
+Sina runs Faravahar, one of nine Tor directory authorities. These dedicated servers tell the millions of Tor clients which relays make up the Tor network. A talented and passionate engineer, Sina has been involved with digital rights activism for almost a decade. Today, he’s a Systems Engineer with Team Cymru, an internet security company which analyzes threat intelligence.
+
+Free speech is something Sina doesn’t take for granted. “I was born in a country where you can be sentenced to death because of your speech,” he said. “Freedom of speech in the digital age is a basic human right. Tyranny will start by taking our ability to speak up first, then the rest of our rights.”
+
+“Tor gives me a chance to resist tyranny in a non-violent manner, and I feel blessed and grateful for the opportunity. The hope is to one day move Faravahar to one of Iran’s universities. Until that day, Ma Hastim va Ma Bishomarim — we are, and we are countless.”
+
+Learn more about Sina's work and how he became involved with Tor: https://blog.torproject.org/volunteer-spotlight-sina-rabbani-helps-activist…
+
+// More New Releases //
+
+Tor Browser 8.0a10
+Tor Browser 8.0a10 is the second alpha release based on Firefox ESR 60 and contains a number of improvements and bug fixes. It includes major updates to the user experience, and there are more to come. The stable version is slated for release next week! Full changelog: https://blog.torproject.org/new-release-tor-browser-80a10
+
+Tor 0.3.4.7-rc
+Tor 0.3.4.7-rc fixes several small compilation, portability, and correctness issues in previous versions of Tor. This version is a release candidate: if no serious bugs are found, we expect that the stable 0.3.4 release will be (almost) the same as this release. Full changelog: https://blog.torproject.org/new-release-tor-0347-rc
+
+// Upcoming Events with Tor //
+
+- Tor Meetup Ciudad de México. Mexico City. September 27, 2018. https://blog.torproject.org/events/tor-meetup-ciudad-de-mexico
+
+- Tor's Open Hack Days. Mexico City. October 2-3, 2018. https://blog.torproject.org/events/tors-open-hack-days-mexico-city
+
+
+// Join Our Community //
+
+Getting involved with Tor is easy. Run a relay to make the network faster and more decentralized: https://trac.torproject.org/projects/tor/wiki/TorRelayGuide
+
+Learn about each of our teams and start collaborating: https://trac.torproject.org/projects/tor/wiki/WikiStart#Teams
+
+Donate to help keep Tor fast, strong, and secure: https://donate.torproject.org
+
+--
+
+The Tor Project is a US 501(c)(3) non-profit organization advancing human rights and freedoms by creating and deploying free and open-source anonymity and privacy technologies, supporting their unrestricted availability and use, and furthering their scientific and popular understanding.
+
+Twitter: https://twitter.com/torproject
+Facebook: https://facebook.com/torproject
1
0

[tor/master] hs-v3: Silence some logging for client authorization
by nickm@torproject.org 26 Sep '18
by nickm@torproject.org 26 Sep '18
26 Sep '18
commit 672620901b43ee7f895ef2a01f058eeb5dffe399
Author: David Goulet <dgoulet(a)torproject.org>
Date: Mon Sep 10 15:04:22 2018 -0400
hs-v3: Silence some logging for client authorization
If a tor client gets a descriptor that it can't decrypt, chances are that the
onion requires client authorization.
If a tor client is configured with client authorization for an onion but
decryption fails, it means that the configured keys aren't working anymore.
In both cases, we'll log notice the former and log warn the latter and the
rest of the decryption errors are now at info level.
Two logs statement have been removed because it was redundant and printing the
fetched descriptor in the logs when 80% of it is encrypted wat not helping.
Fixes #27550
Signed-off-by: David Goulet <dgoulet(a)torproject.org>
---
src/feature/dircache/directory.c | 2 +-
src/feature/hs/hs_client.c | 4 ----
src/feature/hs/hs_descriptor.c | 22 ++++++++++++++++++----
3 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/src/feature/dircache/directory.c b/src/feature/dircache/directory.c
index de0bcdbfa..1f33f38c9 100644
--- a/src/feature/dircache/directory.c
+++ b/src/feature/dircache/directory.c
@@ -3124,7 +3124,7 @@ handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
case 200:
/* We got something: Try storing it in the cache. */
if (hs_cache_store_as_client(body, &conn->hs_ident->identity_pk) < 0) {
- log_warn(LD_REND, "Failed to store hidden service descriptor");
+ log_info(LD_REND, "Failed to store hidden service descriptor");
/* Fire control port FAILED event. */
hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest,
"BAD_DESC");
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index 6f031eb3b..7002cafae 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -1258,10 +1258,6 @@ hs_client_decode_descriptor(const char *desc_str,
client_auht_sk, desc);
memwipe(subcredential, 0, sizeof(subcredential));
if (ret < 0) {
- log_warn(LD_GENERAL, "Could not parse received descriptor as client.");
- if (get_options()->SafeLogging_ == SAFELOG_SCRUB_NONE) {
- log_warn(LD_GENERAL, "%s", escaped(desc_str));
- }
goto err;
}
diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c
index d0cdffdf1..9c85a729e 100644
--- a/src/feature/hs/hs_descriptor.c
+++ b/src/feature/hs/hs_descriptor.c
@@ -1389,7 +1389,7 @@ encrypted_data_length_is_valid(size_t len)
/* Make sure there is enough data for the salt and the mac. The equality is
there to ensure that there is at least one byte of encrypted data. */
if (len <= HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN) {
- log_warn(LD_REND, "Length of descriptor's encrypted data is too small. "
+ log_info(LD_REND, "Length of descriptor's encrypted data is too small. "
"Got %lu but minimum value is %d",
(unsigned long)len, HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN);
goto err;
@@ -1540,7 +1540,7 @@ decrypt_desc_layer,(const hs_descriptor_t *desc,
* This is a critical check that is making sure the computed MAC matches the
* one in the descriptor. */
if (!tor_memeq(our_mac, desc_mac, sizeof(our_mac))) {
- log_warn(LD_REND, "Encrypted service descriptor MAC check failed");
+ log_info(LD_REND, "Encrypted service descriptor MAC check failed");
goto err;
}
@@ -1662,7 +1662,6 @@ desc_decrypt_encrypted(const hs_descriptor_t *desc,
desc->superencrypted_data.encrypted_blob_size,
descriptor_cookie, 0, &encrypted_plaintext);
if (!encrypted_len) {
- log_warn(LD_REND, "Decrypting encrypted desc failed.");
goto err;
}
tor_assert(encrypted_plaintext);
@@ -2272,7 +2271,22 @@ desc_decode_encrypted_v3(const hs_descriptor_t *desc,
* in the descriptor as a blob of bytes. */
message_len = desc_decrypt_encrypted(desc, client_auth_sk, &message);
if (!message_len) {
- log_warn(LD_REND, "Service descriptor decryption failed.");
+ /* Two possible situation here. Either we have a client authorization
+ * configured that didn't work or we do not have any configured for this
+ * onion address so likely the descriptor is for authorized client only,
+ * we are not. */
+ if (client_auth_sk) {
+ /* At warning level so the client can notice that its client
+ * authorization is failing. */
+ log_warn(LD_REND, "Client authorization for requested onion address "
+ "is invalid. Can't decrypt the descriptor.");
+ } else {
+ /* Inform at notice level that the onion address requested can't be
+ * reached without client authorization most likely. */
+ log_notice(LD_REND, "Fail to decrypt descriptor for requested onion "
+ "address. It is likely requiring client "
+ "authorization.");
+ }
goto err;
}
tor_assert(message);
1
0

[tor/master] Merge remote-tracking branch 'dgoulet/bug27550_035_01'
by nickm@torproject.org 26 Sep '18
by nickm@torproject.org 26 Sep '18
26 Sep '18
commit 5e5e019b31296b5a829afc4f7f3766697888b678
Merge: c82163dff 36be6f0d2
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Sep 26 08:36:09 2018 -0400
Merge remote-tracking branch 'dgoulet/bug27550_035_01'
changes/ticket27550 | 5 +++++
src/feature/dirclient/dirclient.c | 2 +-
src/feature/hs/hs_client.c | 4 ----
src/feature/hs/hs_descriptor.c | 20 +++++++++++++++++---
4 files changed, 23 insertions(+), 8 deletions(-)
1
0

[tor/master] fixup! hs-v3: Silence some logging for client authorization
by nickm@torproject.org 26 Sep '18
by nickm@torproject.org 26 Sep '18
26 Sep '18
commit 49e4bda50bdf723d6cdc8e7a0fb24619fded5f2c
Author: David Goulet <dgoulet(a)torproject.org>
Date: Fri Sep 21 08:52:47 2018 -0400
fixup! hs-v3: Silence some logging for client authorization
---
src/feature/hs/hs_descriptor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c
index 9c85a729e..b9a0c0ef1 100644
--- a/src/feature/hs/hs_descriptor.c
+++ b/src/feature/hs/hs_descriptor.c
@@ -1389,7 +1389,7 @@ encrypted_data_length_is_valid(size_t len)
/* Make sure there is enough data for the salt and the mac. The equality is
there to ensure that there is at least one byte of encrypted data. */
if (len <= HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN) {
- log_info(LD_REND, "Length of descriptor's encrypted data is too small. "
+ log_warn(LD_REND, "Length of descriptor's encrypted data is too small. "
"Got %lu but minimum value is %d",
(unsigned long)len, HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN);
goto err;
1
0