diff options
author | Nick Mathewson <nickm@torproject.org> | 2015-06-19 09:09:49 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-11-03 08:39:28 -0400 |
commit | b4a5c779014b35d60f4a2ddcec31e7075ad52995 (patch) | |
tree | a844a09789e2a78be68fdc4e47d082d0d92918c1 /src/or/channeltls.c | |
parent | 99b3e54691f451b766556391cba6e26120ad7d84 (diff) | |
download | tor-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.c | 90 |
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 } |