Beispiel #1
0
static const routerinfo_t*
NS(router_get_my_routerinfo)(void)
{
  crypto_pk_t* ident_key;
  crypto_pk_t* tap_key;
  time_t now;

  if (!mock_routerinfo) {
    /* Mock the published timestamp, otherwise router_dump_router_to_string()
     * will poop its pants. */
    time(&now);

    /* We'll need keys, or router_dump_router_to_string() would return NULL. */
    ident_key = pk_generate(0);
    tap_key = pk_generate(0);

    tor_assert(ident_key != NULL);
    tor_assert(tap_key != NULL);

    mock_routerinfo = tor_malloc_zero(sizeof(routerinfo_t));
    mock_routerinfo->nickname = tor_strdup("ConlonNancarrow");
    mock_routerinfo->addr = 123456789;
    mock_routerinfo->or_port = 443;
    mock_routerinfo->platform = tor_strdup("unittest");
    mock_routerinfo->cache_info.published_on = now;
    mock_routerinfo->identity_pkey = crypto_pk_dup_key(ident_key);
    router_set_rsa_onion_pkey(tap_key, &mock_routerinfo->onion_pkey,
                              &mock_routerinfo->onion_pkey_len);
    mock_routerinfo->bandwidthrate = 9001;
    mock_routerinfo->bandwidthburst = 9002;
    crypto_pk_free(ident_key);
    crypto_pk_free(tap_key);
  }

  return mock_routerinfo;
}
Beispiel #2
0
static void
test_routerkeys_write_fingerprint(void *arg)
{
  crypto_pk_t *key = pk_generate(2);
  or_options_t *options = get_options_mutable();
  const char *ddir = get_fname("write_fingerprint");
  char *cp = NULL, *cp2 = NULL;
  char fp[FINGERPRINT_LEN+1];

  (void)arg;

  tt_assert(key);

  options->ORPort_set = 1; /* So that we can get the server ID key */
  tor_free(options->DataDirectory);
  options->DataDirectory = tor_strdup(ddir);
  options->Nickname = tor_strdup("haflinger");
  set_server_identity_key(key);
  set_client_identity_key(crypto_pk_dup_key(key));

  tt_int_op(0, OP_EQ, check_private_dir(ddir, CPD_CREATE, NULL));
  tt_int_op(crypto_pk_cmp_keys(get_server_identity_key(),key),OP_EQ,0);

  /* Write fingerprint file */
  tt_int_op(0, OP_EQ, router_write_fingerprint(0));
  cp = read_file_to_str(get_fname("write_fingerprint/fingerprint"),
                        0, NULL);
  crypto_pk_get_fingerprint(key, fp, 0);
  tor_asprintf(&cp2, "haflinger %s\n", fp);
  tt_str_op(cp, OP_EQ, cp2);
  tor_free(cp);
  tor_free(cp2);

  /* Write hashed-fingerprint file */
  tt_int_op(0, OP_EQ, router_write_fingerprint(1));
  cp = read_file_to_str(get_fname("write_fingerprint/hashed-fingerprint"),
                        0, NULL);
  crypto_pk_get_hashed_fingerprint(key, fp);
  tor_asprintf(&cp2, "haflinger %s\n", fp);
  tt_str_op(cp, OP_EQ, cp2);
  tor_free(cp);
  tor_free(cp2);

  /* Replace outdated file */
  write_str_to_file(get_fname("write_fingerprint/hashed-fingerprint"),
                    "junk goes here", 0);
  tt_int_op(0, OP_EQ, router_write_fingerprint(1));
  cp = read_file_to_str(get_fname("write_fingerprint/hashed-fingerprint"),
                        0, NULL);
  crypto_pk_get_hashed_fingerprint(key, fp);
  tor_asprintf(&cp2, "haflinger %s\n", fp);
  tt_str_op(cp, OP_EQ, cp2);
  tor_free(cp);
  tor_free(cp2);

 done:
  crypto_pk_free(key);
  set_client_identity_key(NULL);
  tor_free(cp);
  tor_free(cp2);
}
Beispiel #3
0
/** Create a new TLS context for use with Tor TLS handshakes.
 * <b>identity</b> should be set to the identity key used to sign the
 * certificate, and <b>nickname</b> set to the nickname to use.
 *
 * You can call this function multiple times.  Each time you call it,
 * it generates new certificates; all new connections will use
 * the new SSL context.
 */
int
tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
{
  crypto_pk_env_t *rsa = NULL;
  EVP_PKEY *pkey = NULL;
  tor_tls_context_t *result = NULL;
  X509 *cert = NULL, *idcert = NULL;
  char *nickname = NULL, *nn2 = NULL;

  tor_tls_init();
  nickname = crypto_random_hostname(8, 20, "www.", ".net");
  nn2 = crypto_random_hostname(8, 20, "www.", ".net");

  /* Generate short-term RSA key. */
  if (!(rsa = crypto_new_pk_env()))
    goto error;
  if (crypto_pk_generate_key(rsa)<0)
    goto error;
  /* Create certificate signed by identity key. */
  cert = tor_tls_create_certificate(rsa, identity, nickname, nn2,
                                    key_lifetime);
  /* Create self-signed certificate for identity key. */
  idcert = tor_tls_create_certificate(identity, identity, nn2, nn2,
                                      IDENTITY_CERT_LIFETIME);
  if (!cert || !idcert) {
    log(LOG_WARN, LD_CRYPTO, "Error creating certificate");
    goto error;
  }

  result = tor_malloc_zero(sizeof(tor_tls_context_t));
  result->refcnt = 1;
  result->my_cert = X509_dup(cert);
  result->my_id_cert = X509_dup(idcert);
  result->key = crypto_pk_dup_key(rsa);

#ifdef EVERYONE_HAS_AES
  /* Tell OpenSSL to only use TLS1 */
  if (!(result->ctx = SSL_CTX_new(TLSv1_method())))
    goto error;
#else
  /* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */
  if (!(result->ctx = SSL_CTX_new(SSLv23_method())))
    goto error;
  SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2);
#endif
  SSL_CTX_set_options(result->ctx, SSL_OP_SINGLE_DH_USE);

#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
  SSL_CTX_set_options(result->ctx,
                      SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
  /* Yes, we know what we are doing here.  No, we do not treat a renegotiation
   * as authenticating any earlier-received data.
   */
  if (use_unsafe_renegotiation_op) {
    SSL_CTX_set_options(result->ctx,
                        SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
  }
  /* Don't actually allow compression; it uses ram and time, but the data
   * we transmit is all encrypted anyway. */
  if (result->ctx->comp_methods)
    result->ctx->comp_methods = NULL;
#ifdef SSL_MODE_RELEASE_BUFFERS
  SSL_CTX_set_mode(result->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
  if (cert && !SSL_CTX_use_certificate(result->ctx,cert))
    goto error;
  X509_free(cert); /* We just added a reference to cert. */
  cert=NULL;
  if (idcert) {
    X509_STORE *s = SSL_CTX_get_cert_store(result->ctx);
    tor_assert(s);
    X509_STORE_add_cert(s, idcert);
    X509_free(idcert); /* The context now owns the reference to idcert */
    idcert = NULL;
  }
  SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
  tor_assert(rsa);
  if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
    goto error;
  if (!SSL_CTX_use_PrivateKey(result->ctx, pkey))
    goto error;
  EVP_PKEY_free(pkey);
  pkey = NULL;
  if (!SSL_CTX_check_private_key(result->ctx))
    goto error;
  {
    crypto_dh_env_t *dh = crypto_dh_new();
    SSL_CTX_set_tmp_dh(result->ctx, _crypto_dh_env_get_dh(dh));
    crypto_dh_free(dh);
  }
  SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER,
                     always_accept_verify_cb);
  /* let us realloc bufs that we're writing from */
  SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  /* Free the old context if one exists. */
  if (global_tls_context) {
    /* This is safe even if there are open connections: OpenSSL does
     * reference counting with SSL and SSL_CTX objects. */
    tor_tls_context_decref(global_tls_context);
  }
  global_tls_context = result;
  if (rsa)
    crypto_free_pk_env(rsa);
  tor_free(nickname);
  tor_free(nn2);
  return 0;

 error:
  tls_log_errors(NULL, LOG_WARN, "creating TLS context");
  tor_free(nickname);
  tor_free(nn2);
  if (pkey)
    EVP_PKEY_free(pkey);
  if (rsa)
    crypto_free_pk_env(rsa);
  if (result)
    tor_tls_context_decref(result);
  if (cert)
    X509_free(cert);
  if (idcert)
    X509_free(idcert);
  return -1;
}