|
@@ -105,20 +105,51 @@ connection_or_clear_identity_map(void)
|
|
}
|
|
}
|
|
|
|
|
|
/** Change conn->identity_digest to digest, and add conn into
|
|
/** Change conn->identity_digest to digest, and add conn into
|
|
- * orconn_digest_map. */
|
|
|
|
|
|
+ * the appropriate digest maps.
|
|
|
|
+ *
|
|
|
|
+ * NOTE that this function only allows two kinds of transitions: from
|
|
|
|
+ * unset identity to set identity, and from idempotent re-settings
|
|
|
|
+ * of the same identity. It's not allowed to clear an identity or to
|
|
|
|
+ * change an identity. Return 0 on success, and -1 if the transition
|
|
|
|
+ * is not allowed.
|
|
|
|
+ **/
|
|
static void
|
|
static void
|
|
connection_or_set_identity_digest(or_connection_t *conn,
|
|
connection_or_set_identity_digest(or_connection_t *conn,
|
|
const char *rsa_digest,
|
|
const char *rsa_digest,
|
|
const ed25519_public_key_t *ed_id)
|
|
const ed25519_public_key_t *ed_id)
|
|
{
|
|
{
|
|
|
|
+ channel_t *chan = NULL;
|
|
tor_assert(conn);
|
|
tor_assert(conn);
|
|
tor_assert(rsa_digest);
|
|
tor_assert(rsa_digest);
|
|
|
|
|
|
- if (tor_memeq(conn->identity_digest, rsa_digest, DIGEST_LEN))
|
|
|
|
|
|
+ if (conn->chan)
|
|
|
|
+ chan = TLS_CHAN_TO_BASE(conn->chan);
|
|
|
|
+
|
|
|
|
+ log_info(LD_HANDSHAKE, "Set identity digest for %p (%s): %s %s.",
|
|
|
|
+ conn,
|
|
|
|
+ escaped_safe_str(conn->base_.address),
|
|
|
|
+ hex_str(rsa_digest, DIGEST_LEN),
|
|
|
|
+ ed25519_fmt(ed_id));
|
|
|
|
+ log_info(LD_HANDSHAKE, " (Previously: %s %s)",
|
|
|
|
+ hex_str(conn->identity_digest, DIGEST_LEN),
|
|
|
|
+ chan ? ed25519_fmt(&chan->ed25519_identity) : "<null>");
|
|
|
|
+
|
|
|
|
+ const int rsa_id_was_set = ! tor_digest_is_zero(conn->identity_digest);
|
|
|
|
+ const int ed_id_was_set =
|
|
|
|
+ chan && !ed25519_public_key_is_zero(&chan->ed25519_identity);
|
|
|
|
+ const int rsa_changed =
|
|
|
|
+ tor_memneq(conn->identity_digest, rsa_digest, DIGEST_LEN);
|
|
|
|
+ const int ed_changed = ed_id_was_set &&
|
|
|
|
+ (!ed_id || !ed25519_pubkey_eq(ed_id, &chan->ed25519_identity));
|
|
|
|
+
|
|
|
|
+ tor_assert(!rsa_changed || !rsa_id_was_set);
|
|
|
|
+ tor_assert(!ed_changed || !ed_id_was_set);
|
|
|
|
+
|
|
|
|
+ if (!rsa_changed && !ed_changed)
|
|
return;
|
|
return;
|
|
|
|
|
|
/* If the identity was set previously, remove the old mapping. */
|
|
/* If the identity was set previously, remove the old mapping. */
|
|
- if (! tor_digest_is_zero(conn->identity_digest)) {
|
|
|
|
|
|
+ if (rsa_id_was_set) {
|
|
connection_or_clear_identity(conn);
|
|
connection_or_clear_identity(conn);
|
|
if (conn->chan)
|
|
if (conn->chan)
|
|
channel_clear_identity_digest(TLS_CHAN_TO_BASE(conn->chan));
|
|
channel_clear_identity_digest(TLS_CHAN_TO_BASE(conn->chan));
|
|
@@ -126,8 +157,9 @@ connection_or_set_identity_digest(or_connection_t *conn,
|
|
|
|
|
|
memcpy(conn->identity_digest, rsa_digest, DIGEST_LEN);
|
|
memcpy(conn->identity_digest, rsa_digest, DIGEST_LEN);
|
|
|
|
|
|
- /* If we're setting the ID to zero, don't add a mapping. */
|
|
|
|
- if (tor_digest_is_zero(rsa_digest))
|
|
|
|
|
|
+ /* If we're initializing the IDs to zero, don't add a mapping yet. */
|
|
|
|
+ if (tor_digest_is_zero(rsa_digest) &&
|
|
|
|
+ (!ed_id || ed25519_public_key_is_zero(ed_id)))
|
|
return;
|
|
return;
|
|
|
|
|
|
/* Deal with channels */
|
|
/* Deal with channels */
|