summaryrefslogtreecommitdiff
path: root/src/or/channeltls.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-06-19 09:09:49 -0400
committerNick Mathewson <nickm@torproject.org>2016-11-03 08:39:28 -0400
commitb4a5c779014b35d60f4a2ddcec31e7075ad52995 (patch)
treea844a09789e2a78be68fdc4e47d082d0d92918c1 /src/or/channeltls.c
parent99b3e54691f451b766556391cba6e26120ad7d84 (diff)
downloadtor-b4a5c779014b35d60f4a2ddcec31e7075ad52995.tar.gz
tor-b4a5c779014b35d60f4a2ddcec31e7075ad52995.zip
Verify ed25519 link handshake certificates
This code stores the ed certs as appropriate, and tries to check them. The Ed25519 result is not yet used, and (because of its behavior) this will break RSA authenticate cells. That will get fixed as we go, however. This should implement 19157, but it needs tests, and it needs to get wired in.
Diffstat (limited to 'src/or/channeltls.c')
-rw-r--r--src/or/channeltls.c90
1 files changed, 56 insertions, 34 deletions
diff --git a/src/or/channeltls.c b/src/or/channeltls.c
index d1fae926d5..6de3bd4732 100644
--- a/src/or/channeltls.c
+++ b/src/or/channeltls.c
@@ -1788,8 +1788,9 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
* of ed/x509 */
tor_x509_cert_t *x509_certs[MAX_CERT_TYPE_WANTED + 1];
tor_cert_t *ed_certs[MAX_CERT_TYPE_WANTED + 1];
+ uint8_t *rsa_ed_cc_cert = NULL;
+ size_t rsa_ed_cc_cert_len = 0;
- rsa_ed_crosscert_t *rsa_crosscert = NULL;
int n_certs, i;
certs_cell_t *cc = NULL;
@@ -1879,38 +1880,45 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
}
break;
}
+
case CERT_ENCODING_RSA_CROSSCERT: {
- rsa_ed_crosscert_t *cc_cert = NULL;
- ssize_t n = rsa_ed_crosscert_parse(&cc_cert, cert_body, cert_len);
- if (n != cert_len) {
- log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Received unparseable RS1024-Ed25519 crosscert "
- " in CERTS cell from %s:%d",
- safe_str(chan->conn->base_.address),
- chan->conn->base_.port);
+ if (rsa_ed_cc_cert) {
+ ERR("Duplicate RSA->Ed25519 crosscert");
} else {
- if (rsa_crosscert) {
- rsa_ed_crosscert_free(cc_cert);
- ERR("Duplicate RSA->Ed25519 crosscert");
- } else {
- rsa_crosscert = cc_cert;
- }
+ rsa_ed_cc_cert = tor_memdup(cert_body, cert_len);
+ rsa_ed_cc_cert_len = cert_len;
}
break;
}
}
}
- tor_x509_cert_t *id_cert = x509_certs[OR_CERT_TYPE_ID_1024];
- tor_x509_cert_t *auth_cert = x509_certs[OR_CERT_TYPE_AUTH_1024];
- tor_x509_cert_t *link_cert = x509_certs[OR_CERT_TYPE_TLS_LINK];
-
+ /* Move the certificates we (might) want into the handshake_state->certs
+ * structure. */
+ tor_x509_cert_t *id_cert = x509_certs[CERTTYPE_RSA1024_ID_ID];
+ tor_x509_cert_t *auth_cert = x509_certs[CERTTYPE_RSA1024_ID_AUTH];
+ tor_x509_cert_t *link_cert = x509_certs[CERTTYPE_RSA1024_ID_LINK];
chan->conn->handshake_state->certs->auth_cert = auth_cert;
chan->conn->handshake_state->certs->link_cert = link_cert;
chan->conn->handshake_state->certs->id_cert = id_cert;
- x509_certs[OR_CERT_TYPE_ID_1024] =
- x509_certs[OR_CERT_TYPE_AUTH_1024] =
- x509_certs[OR_CERT_TYPE_TLS_LINK] = NULL;
+ x509_certs[CERTTYPE_RSA1024_ID_ID] =
+ x509_certs[CERTTYPE_RSA1024_ID_AUTH] =
+ x509_certs[CERTTYPE_RSA1024_ID_LINK] = NULL;
+
+ tor_cert_t *ed_id_sign = ed_certs[CERTTYPE_ED_ID_SIGN];
+ tor_cert_t *ed_sign_link = ed_certs[CERTTYPE_ED_SIGN_LINK];
+ tor_cert_t *ed_sign_auth = ed_certs[CERTTYPE_ED_SIGN_AUTH];
+ chan->conn->handshake_state->certs->ed_id_sign = ed_id_sign;
+ chan->conn->handshake_state->certs->ed_sign_link = ed_sign_link;
+ chan->conn->handshake_state->certs->ed_sign_auth = ed_sign_auth;
+ ed_certs[CERTTYPE_ED_ID_SIGN] =
+ ed_certs[CERTTYPE_ED_SIGN_LINK] =
+ ed_certs[CERTTYPE_ED_SIGN_AUTH] = NULL;
+
+ chan->conn->handshake_state->certs->ed_rsa_crosscert = rsa_ed_cc_cert;
+ chan->conn->handshake_state->certs->ed_rsa_crosscert_len =
+ rsa_ed_cc_cert_len;
+ rsa_ed_cc_cert = NULL;
int severity;
/* Note that this warns more loudly about time and validity if we were
@@ -1922,11 +1930,17 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
else
severity = LOG_PROTOCOL_WARN;
- if (! or_handshake_certs_rsa_ok(severity,
- chan->conn->handshake_state->certs,
- chan->conn->tls,
- time(NULL)))
- ERR("Invalid RSA certificates!");
+ const ed25519_public_key_t *checked_ed_id = NULL;
+ const common_digests_t *checked_rsa_id = NULL;
+ or_handshake_certs_check_both(severity,
+ chan->conn->handshake_state->certs,
+ chan->conn->tls,
+ time(NULL),
+ &checked_ed_id,
+ &checked_rsa_id);
+
+ if (!checked_rsa_id)
+ ERR("Invalid certificate chain!");
if (chan->conn->handshake_state->started_here) {
/* No more information is needed. */
@@ -1934,8 +1948,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
chan->conn->handshake_state->authenticated = 1;
chan->conn->handshake_state->authenticated_rsa = 1;
{
- const common_digests_t *id_digests =
- tor_x509_cert_get_id_digests(id_cert);
+ const common_digests_t *id_digests = checked_rsa_id;
crypto_pk_t *identity_rcvd;
if (!id_digests)
ERR("Couldn't compute digests for key in ID cert");
@@ -1950,14 +1963,22 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
crypto_pk_free(identity_rcvd);
}
+ if (checked_ed_id) {
+ chan->conn->handshake_state->authenticated_ed25519 = 1;
+ memcpy(&chan->conn->handshake_state->authenticated_ed25519_peer_id,
+ checked_ed_id, sizeof(ed25519_public_key_t));
+ }
+
if (connection_or_client_learned_peer_id(chan->conn,
chan->conn->handshake_state->authenticated_rsa_peer_id,
- NULL) < 0)
+ checked_ed_id) < 0)
ERR("Problem setting or checking peer id");
log_info(LD_OR,
- "Got some good certificates from %s:%d: Authenticated it.",
- safe_str(chan->conn->base_.address), chan->conn->base_.port);
+ "Got some good certificates from %s:%d: Authenticated it with "
+ "RSA%s",
+ safe_str(chan->conn->base_.address), chan->conn->base_.port,
+ checked_ed_id ? " and Ed25519" : "");
if (!public_server_mode(get_options())) {
/* If we initiated the connection and we are not a public server, we
@@ -1968,8 +1989,9 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
} else {
/* We can't call it authenticated till we see an AUTHENTICATE cell. */
log_info(LD_OR,
- "Got some good certificates from %s:%d: "
+ "Got some good RSA%s certificates from %s:%d. "
"Waiting for AUTHENTICATE.",
+ checked_ed_id ? " and Ed25519" : "",
safe_str(chan->conn->base_.address),
chan->conn->base_.port);
/* XXXX check more stuff? */
@@ -1992,7 +2014,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
for (unsigned u = 0; u < ARRAY_LENGTH(ed_certs); ++u) {
tor_cert_free(ed_certs[u]);
}
- rsa_ed_crosscert_free(rsa_crosscert);
+ tor_free(rsa_ed_cc_cert);
certs_cell_free(cc);
#undef ERR
}