commit d1c1dc229e189cbf4e463b82751af007801a02eb Merge: 7c54d2f 9fea009 Author: Nick Mathewson nickm@torproject.org Date: Mon Jun 5 15:44:12 2017 -0400
Merge branch 'maint-0.2.9' into maint-0.3.0
changes/bug22460_case2 | 8 ++++++++ src/common/tortls.c | 27 ++++++++++++++++++++++++--- src/common/tortls.h | 1 + src/or/connection_or.c | 32 ++++++++++++++++++-------------- src/test/test_link_handshake.c | 30 +++++++++++++++++++++++++++++- 5 files changed, 80 insertions(+), 18 deletions(-)
diff --cc src/common/tortls.c index 1594f3b,d61cc2e..e3e8830 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@@ -2058,10 -2031,27 +2061,28 @@@ tor_tls_get_peer_cert,(tor_tls_t *tls) return tor_x509_cert_new(cert); }
+ /** Return a newly allocated copy of the cerficate we used on the connection, + * or NULL if somehow we didn't use one. */ + MOCK_IMPL(tor_x509_cert_t *, + tor_tls_get_own_cert,(tor_tls_t *tls)) + { + X509 *cert = SSL_get_certificate(tls->ssl); + tls_log_errors(tls, LOG_WARN, LD_HANDSHAKE, + "getting own-connection certificate"); + if (!cert) + return NULL; + /* Fun inconsistency: SSL_get_peer_certificate increments the reference + * count, but SSL_get_certificate does not. */ + X509 *duplicate = X509_dup(cert); + if (BUG(duplicate == NULL)) + return NULL; + return tor_x509_cert_new(duplicate); + } + /** Warn that a certificate lifetime extends through a certain range. */ static void -log_cert_lifetime(int severity, const X509 *cert, const char *problem) +log_cert_lifetime(int severity, const X509 *cert, const char *problem, + time_t now) { BIO *bio = NULL; BUF_MEM *buf; diff --cc src/common/tortls.h index 6510fdb,f018c45..bb7701c --- a/src/common/tortls.h +++ b/src/common/tortls.h @@@ -198,11 -197,12 +198,12 @@@ void tor_tls_set_renegotiate_callback(t int tor_tls_is_server(tor_tls_t *tls); void tor_tls_free(tor_tls_t *tls); int tor_tls_peer_has_cert(tor_tls_t *tls); -tor_x509_cert_t *tor_x509_cert_dup(const tor_x509_cert_t *cert); MOCK_DECL(tor_x509_cert_t *,tor_tls_get_peer_cert,(tor_tls_t *tls)); + MOCK_DECL(tor_x509_cert_t *,tor_tls_get_own_cert,(tor_tls_t *tls)); int tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity); int tor_tls_check_lifetime(int severity, - tor_tls_t *tls, int past_tolerance, + tor_tls_t *tls, time_t now, + int past_tolerance, int future_tolerance); MOCK_DECL(int, tor_tls_read, (tor_tls_t *tls, char *cp, size_t len)); int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n); diff --cc src/or/connection_or.c index cefe42c,3b35d5e..b9ac9b2 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@@ -2270,80 -2137,57 +2270,87 @@@ add_ed25519_cert(certs_cell_t *certs_ce int connection_or_send_certs_cell(or_connection_t *conn) { - const tor_x509_cert_t *link_cert = NULL, *id_cert = NULL; - const tor_x509_cert_t *global_link_cert = NULL, *id_cert = NULL, - *using_link_cert = NULL; ++ const tor_x509_cert_t *global_link_cert = NULL, *id_cert = NULL; + tor_x509_cert_t *own_link_cert = NULL; - const uint8_t *link_encoded = NULL, *id_encoded = NULL; - size_t link_len, id_len; var_cell_t *cell; - size_t cell_len; - ssize_t pos; + + certs_cell_t *certs_cell = NULL;
tor_assert(conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3);
if (! conn->handshake_state) return -1; + const int conn_in_server_mode = ! conn->handshake_state->started_here; + + /* Get the encoded values of the X509 certificates */ - if (tor_tls_get_my_certs(conn_in_server_mode, &link_cert, &id_cert) < 0) + if (tor_tls_get_my_certs(conn_in_server_mode, + &global_link_cert, &id_cert) < 0) return -1; + - tor_assert(link_cert); ++ if (conn_in_server_mode) { ++ own_link_cert = tor_tls_get_own_cert(conn->tls); ++ } + tor_assert(id_cert); + + certs_cell = certs_cell_new(); + + /* Start adding certs. First the link cert or auth1024 cert. */ if (conn_in_server_mode) { - using_link_cert = own_link_cert = tor_tls_get_own_cert(conn->tls); ++ tor_assert_nonfatal(own_link_cert); + add_x509_cert(certs_cell, - OR_CERT_TYPE_TLS_LINK, link_cert); ++ OR_CERT_TYPE_TLS_LINK, own_link_cert); } else { - using_link_cert = global_link_cert; ++ tor_assert(global_link_cert); + add_x509_cert(certs_cell, - OR_CERT_TYPE_AUTH_1024, link_cert); ++ OR_CERT_TYPE_AUTH_1024, global_link_cert); } - tor_x509_cert_get_der(using_link_cert, &link_encoded, &link_len); - tor_x509_cert_get_der(id_cert, &id_encoded, &id_len);
- cell_len = 1 /* 1 byte: num certs in cell */ + - 2 * ( 1 + 2 ) /* For each cert: 1 byte for type, 2 for length */ + - link_len + id_len; - cell = var_cell_new(cell_len); - cell->command = CELL_CERTS; - cell->payload[0] = 2; - pos = 1; + /* Next the RSA->RSA ID cert */ + add_x509_cert(certs_cell, + OR_CERT_TYPE_ID_1024, id_cert);
- if (conn_in_server_mode) - cell->payload[pos] = OR_CERT_TYPE_TLS_LINK; /* Link cert */ - else - cell->payload[pos] = OR_CERT_TYPE_AUTH_1024; /* client authentication */ - set_uint16(&cell->payload[pos+1], htons(link_len)); - memcpy(&cell->payload[pos+3], link_encoded, link_len); - pos += 3 + link_len; + /* Next the Ed25519 certs */ + add_ed25519_cert(certs_cell, + CERTTYPE_ED_ID_SIGN, + get_master_signing_key_cert()); + if (conn_in_server_mode) { + add_ed25519_cert(certs_cell, + CERTTYPE_ED_SIGN_LINK, + get_current_link_cert_cert()); + } else { + add_ed25519_cert(certs_cell, + CERTTYPE_ED_SIGN_AUTH, + get_current_auth_key_cert()); + } + + /* And finally the crosscert. */ + { + const uint8_t *crosscert=NULL; + size_t crosscert_len; + get_master_rsa_crosscert(&crosscert, &crosscert_len); + if (crosscert) { + add_certs_cell_cert_helper(certs_cell, + CERTTYPE_RSA1024_ID_EDID, + crosscert, crosscert_len); + } + }
- cell->payload[pos] = OR_CERT_TYPE_ID_1024; /* ID cert */ - set_uint16(&cell->payload[pos+1], htons(id_len)); - memcpy(&cell->payload[pos+3], id_encoded, id_len); - pos += 3 + id_len; + /* We've added all the certs; make the cell. */ + certs_cell->n_certs = certs_cell_getlen_certs(certs_cell);
- tor_assert(pos == (int)cell_len); /* Otherwise we just smashed the heap */ + ssize_t alloc_len = certs_cell_encoded_len(certs_cell); + tor_assert(alloc_len >= 0 && alloc_len <= UINT16_MAX); + cell = var_cell_new(alloc_len); + cell->command = CELL_CERTS; + ssize_t enc_len = certs_cell_encode(cell->payload, alloc_len, certs_cell); + tor_assert(enc_len > 0 && enc_len <= alloc_len); + cell->payload_len = enc_len;
connection_or_write_var_cell_to_buf(cell, conn); var_cell_free(cell); + certs_cell_free(certs_cell); + tor_x509_cert_free(own_link_cert);
return 0; } @@@ -2453,41 -2255,22 +2460,41 @@@ connection_or_compute_authenticate_cell { auth1_t *auth = NULL; auth_ctx_t *ctx = auth_ctx_new(); - int result; + var_cell_t *result = NULL; + int old_tlssecrets_algorithm = 0; + const char *authtype_str = NULL;
- /* assert state is reasonable XXXX */ + int is_ed = 0;
- ctx->is_ed = 0; + /* assert state is reasonable XXXX */ + switch (authtype) { + case AUTHTYPE_RSA_SHA256_TLSSECRET: + authtype_str = "AUTH0001"; + old_tlssecrets_algorithm = 1; + break; + case AUTHTYPE_RSA_SHA256_RFC5705: + authtype_str = "AUTH0002"; + break; + case AUTHTYPE_ED25519_SHA256_RFC5705: + authtype_str = "AUTH0003"; + is_ed = 1; + break; + default: + tor_assert(0); + break; + }
auth = auth1_new(); + ctx->is_ed = is_ed;
/* Type: 8 bytes. */ - memcpy(auth1_getarray_type(auth), "AUTH0001", 8); + memcpy(auth1_getarray_type(auth), authtype_str, 8);
{ - const tor_x509_cert_t *id_cert=NULL, *link_cert=NULL; + const tor_x509_cert_t *id_cert=NULL; const common_digests_t *my_digests, *their_digests; const uint8_t *my_id, *their_id, *client_id, *server_id; - if (tor_tls_get_my_certs(server, &link_cert, &id_cert)) + if (tor_tls_get_my_certs(server, NULL, &id_cert)) goto err; my_digests = tor_x509_cert_get_id_digests(id_cert); their_digests = @@@ -2542,17 -2309,14 +2549,15 @@@
{ /* Digest of cert used on TLS link : 32 octets. */ - const tor_x509_cert_t *cert = NULL; - tor_x509_cert_t *freecert = NULL; + tor_x509_cert_t *cert = NULL; if (server) { - tor_tls_get_my_certs(1, &cert, NULL); + cert = tor_tls_get_own_cert(conn->tls); } else { - freecert = tor_tls_get_peer_cert(conn->tls); - cert = freecert; + cert = tor_tls_get_peer_cert(conn->tls); } if (!cert) { - log_warn(LD_OR, "Unable to find cert when making AUTH1 data."); + log_warn(LD_OR, "Unable to find cert when making %s data.", + authtype_str); goto err; }
diff --cc src/test/test_link_handshake.c index 421f3aa,b979485..b3e854e --- a/src/test/test_link_handshake.c +++ b/src/test/test_link_handshake.c @@@ -51,16 -37,6 +51,16 @@@ mock_tls_cert_matches_key(const tor_tls (void) cert; // XXXX look at this. return 1; } +static tor_tls_t *mock_peer_cert_expect_tortls = NULL; +static tor_x509_cert_t *mock_peer_cert = NULL; +static tor_x509_cert_t * +mock_get_peer_cert(tor_tls_t *tls) +{ + if (mock_peer_cert_expect_tortls && + mock_peer_cert_expect_tortls != tls) + return NULL; - return mock_peer_cert; ++ return tor_x509_cert_dup(mock_peer_cert); +}
static int mock_send_netinfo_called = 0; static int @@@ -90,21 -65,15 +90,29 @@@ mock_send_authenticate(or_connection_t ++mock_send_authenticate_called;// XXX check_this return 0; } +static int +mock_export_key_material(tor_tls_t *tls, uint8_t *secrets_out, + const uint8_t *context, + size_t context_len, + const char *label) +{ + (void) tls; + (void)secrets_out; + (void)context; + (void)context_len; + (void)label; + memcpy(secrets_out, "int getRandomNumber(){return 4;}", 32); + return 0; +}
+ static tor_x509_cert_t *mock_own_cert = NULL; + static tor_x509_cert_t * + mock_get_own_cert(tor_tls_t *tls) + { + (void)tls; + return tor_x509_cert_dup(mock_own_cert); + } + /* Test good certs cells */ static void test_link_handshake_certs_ok(void *arg) @@@ -125,7 -92,7 +133,8 @@@ MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key); MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell); MOCK(connection_or_send_netinfo, mock_send_netinfo); + MOCK(tor_tls_get_peer_cert, mock_get_peer_cert); + MOCK(tor_tls_get_own_cert, mock_get_own_cert);
key1 = pk_generate(2); key2 = pk_generate(3); @@@ -136,13 -103,12 +145,19 @@@ tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER, key1, key2, 86400), ==, 0);
+ if (with_ed) { + /* If we're making a CERTS cell for an ed handshake, let's make sure we + * have some Ed25519 certificates and keys. */ + init_mock_ed_keys(key2); + } + + /* c1 has started_here == 1 */ + { + const tor_x509_cert_t *link = NULL; + tt_assert(!tor_tls_get_my_certs(1, &link, NULL)); + mock_own_cert = tor_x509_cert_dup(link); + } + c1->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3; c1->link_proto = 3; tt_int_op(connection_init_or_handshake_state(c1, 1), ==, 0); @@@ -284,7 -189,9 +299,10 @@@ UNMOCK(tor_tls_cert_matches_key); UNMOCK(connection_or_write_var_cell_to_buf); UNMOCK(connection_or_send_netinfo); + UNMOCK(tor_tls_get_peer_cert); + UNMOCK(tor_tls_get_own_cert); + tor_x509_cert_free(mock_own_cert); + mock_own_cert = NULL; memset(c1->identity_digest, 0, sizeof(c1->identity_digest)); memset(c2->identity_digest, 0, sizeof(c2->identity_digest)); connection_free_(TO_CONN(c1)); @@@ -321,7 -226,6 +339,8 @@@ recv_certs_cleanup(const struct testcas UNMOCK(tor_tls_cert_matches_key); UNMOCK(connection_or_send_netinfo); UNMOCK(connection_or_close_for_error); + UNMOCK(tor_tls_get_peer_cert); ++ UNMOCK(tor_tls_get_own_cert);
if (d) { tor_free(d->cell); @@@ -1226,15 -797,15 +1251,18 @@@ authenticate_data_setup(const struct te tor_x509_cert_get_der(link_cert, &der, &sz); mock_peer_cert = tor_x509_cert_decode(der, sz); tt_assert(mock_peer_cert); + + mock_own_cert = tor_x509_cert_decode(der, sz); + tt_assert(mock_own_cert); - tt_assert(! tor_tls_get_my_certs(0, &auth_cert, &id_cert)); - tor_x509_cert_get_der(auth_cert, &der, &sz); - d->c2->handshake_state->auth_cert = tor_x509_cert_decode(der, sz); + /* Make an authenticate cell ... */ - tt_int_op(0, ==, connection_or_send_authenticate_cell(d->c1, - AUTHTYPE_RSA_SHA256_TLSSECRET)); + int authtype; + if (is_ed) + authtype = AUTHTYPE_ED25519_SHA256_RFC5705; + else + authtype = AUTHTYPE_RSA_SHA256_TLSSECRET; + tt_int_op(0, ==, connection_or_send_authenticate_cell(d->c1, authtype)); + tt_assert(mock_got_var_cell); d->cell = mock_got_var_cell; mock_got_var_cell = NULL;
tor-commits@lists.torproject.org