[tor-commits] [tor/release-0.3.0] Merge branch 'maint-0.2.9' into maint-0.3.0

nickm at torproject.org nickm at torproject.org
Mon Jun 5 19:52:53 UTC 2017


commit d1c1dc229e189cbf4e463b82751af007801a02eb
Merge: 7c54d2f 9fea009
Author: Nick Mathewson <nickm at 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;





More information about the tor-commits mailing list