diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-06-01 09:26:24 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-06-01 09:26:24 -0400 |
commit | 34a6755b94015fcbc838b46b54667899c238ac04 (patch) | |
tree | 5e904e93310020615cb0e0351e4effe05ab3d7f8 /src/or/connection_or.c | |
parent | a9be768959c189846178723d5fe44d3b59b0d983 (diff) | |
download | tor-34a6755b94015fcbc838b46b54667899c238ac04.tar.gz tor-34a6755b94015fcbc838b46b54667899c238ac04.zip |
Fix ed25519 link certificate race on tls context rotation
Whenever we rotate our TLS context, we change our Ed25519
Signing->Link certificate. But if we've already started a TLS
connection, then we've already sent the old X509 link certificate,
so the new Ed25519 Signing->Link certificate won't match it.
To fix this, we now store a copy of the Signing->Link certificate
when we initialize the handshake state, and send that certificate
as part of our CERTS cell.
Fixes one case of bug22460; bugfix on 0.3.0.1-alpha.
Diffstat (limited to 'src/or/connection_or.c')
-rw-r--r-- | src/or/connection_or.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/or/connection_or.c b/src/or/connection_or.c index cefe42c4db..0966ec8acb 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -1855,6 +1855,9 @@ connection_init_or_handshake_state(or_connection_t *conn, int started_here) s->started_here = started_here ? 1 : 0; s->digest_sent_data = 1; s->digest_received_data = 1; + if (! started_here && get_current_link_cert_cert()) { + s->own_link_cert = tor_cert_dup(get_current_link_cert_cert()); + } s->certs = or_handshake_certs_new(); s->certs->started_here = s->started_here; return 0; @@ -1869,6 +1872,7 @@ or_handshake_state_free(or_handshake_state_t *state) crypto_digest_free(state->digest_sent); crypto_digest_free(state->digest_received); or_handshake_certs_free(state->certs); + tor_cert_free(state->own_link_cert); memwipe(state, 0xBE, sizeof(or_handshake_state_t)); tor_free(state); } @@ -2311,7 +2315,7 @@ connection_or_send_certs_cell(or_connection_t *conn) if (conn_in_server_mode) { add_ed25519_cert(certs_cell, CERTTYPE_ED_SIGN_LINK, - get_current_link_cert_cert()); + conn->handshake_state->own_link_cert); } else { add_ed25519_cert(certs_cell, CERTTYPE_ED_SIGN_AUTH, |