mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +01:00
cd741cc595
If a node can prove its Ed25519 identity, don't consider connections to it canonical unless they match both identities. Includes link handshake changes needed to avoid crashing with bug warnings, since the tests now reach more parts of the code. Closes ticket 20355
1553 lines
55 KiB
C
1553 lines
55 KiB
C
/* Copyright (c) 2014-2016, The Tor Project, Inc. */
|
|
/* See LICENSE for licensing information */
|
|
|
|
#include "orconfig.h"
|
|
|
|
#define CHANNELTLS_PRIVATE
|
|
#define CONNECTION_PRIVATE
|
|
#define TOR_CHANNEL_INTERNAL_
|
|
#define TORTLS_PRIVATE
|
|
|
|
#include "compat.h"
|
|
|
|
/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
|
|
* srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
|
|
DISABLE_GCC_WARNING(redundant-decls)
|
|
#include <openssl/x509.h>
|
|
#include <openssl/ssl.h>
|
|
ENABLE_GCC_WARNING(redundant-decls)
|
|
|
|
#include "or.h"
|
|
#include "config.h"
|
|
#include "connection.h"
|
|
#include "connection_or.h"
|
|
#include "channeltls.h"
|
|
#include "link_handshake.h"
|
|
#include "router.h"
|
|
#include "routerkeys.h"
|
|
#include "scheduler.h"
|
|
#include "torcert.h"
|
|
|
|
#include "test.h"
|
|
#include "log_test_helpers.h"
|
|
|
|
static var_cell_t *mock_got_var_cell = NULL;
|
|
|
|
static void
|
|
mock_write_var_cell(const var_cell_t *vc, or_connection_t *conn)
|
|
{
|
|
(void)conn;
|
|
|
|
var_cell_t *newcell = var_cell_new(vc->payload_len);
|
|
memcpy(newcell, vc, sizeof(var_cell_t));
|
|
memcpy(newcell->payload, vc->payload, vc->payload_len);
|
|
|
|
mock_got_var_cell = newcell;
|
|
}
|
|
static int
|
|
mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
|
|
{
|
|
(void) 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;
|
|
}
|
|
|
|
static int mock_send_netinfo_called = 0;
|
|
static int
|
|
mock_send_netinfo(or_connection_t *conn)
|
|
{
|
|
(void) conn;
|
|
++mock_send_netinfo_called;// XXX check_this
|
|
return 0;
|
|
}
|
|
|
|
static int mock_close_called = 0;
|
|
static void
|
|
mock_close_for_err(or_connection_t *orconn, int flush)
|
|
{
|
|
(void)orconn;
|
|
(void)flush;
|
|
++mock_close_called;
|
|
}
|
|
|
|
static int mock_send_authenticate_called = 0;
|
|
static int mock_send_authenticate_called_with_type = 0;
|
|
static int
|
|
mock_send_authenticate(or_connection_t *conn, int type)
|
|
{
|
|
(void) conn;
|
|
mock_send_authenticate_called_with_type = type;
|
|
++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;
|
|
}
|
|
|
|
/* Test good certs cells */
|
|
static void
|
|
test_link_handshake_certs_ok(void *arg)
|
|
{
|
|
or_connection_t *c1 = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
or_connection_t *c2 = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
var_cell_t *cell1 = NULL, *cell2 = NULL;
|
|
certs_cell_t *cc1 = NULL, *cc2 = NULL;
|
|
channel_tls_t *chan1 = NULL, *chan2 = NULL;
|
|
crypto_pk_t *key1 = NULL, *key2 = NULL;
|
|
const int with_ed = !strcmp((const char *)arg, "Ed25519");
|
|
|
|
tor_addr_from_ipv4h(&c1->base_.addr, 0x7f000001);
|
|
tor_addr_from_ipv4h(&c2->base_.addr, 0x7f000001);
|
|
|
|
scheduler_init();
|
|
|
|
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);
|
|
|
|
key1 = pk_generate(2);
|
|
key2 = pk_generate(3);
|
|
|
|
/* We need to make sure that our TLS certificates are set up before we can
|
|
* actually generate a CERTS cell.
|
|
*/
|
|
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 */
|
|
c1->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
|
|
c1->link_proto = 3;
|
|
tt_int_op(connection_init_or_handshake_state(c1, 1), ==, 0);
|
|
|
|
/* c2 has started_here == 0 */
|
|
c2->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
|
|
c2->link_proto = 3;
|
|
tt_int_op(connection_init_or_handshake_state(c2, 0), ==, 0);
|
|
|
|
tt_int_op(0, ==, connection_or_send_certs_cell(c1));
|
|
tt_assert(mock_got_var_cell);
|
|
cell1 = mock_got_var_cell;
|
|
|
|
tt_int_op(0, ==, connection_or_send_certs_cell(c2));
|
|
tt_assert(mock_got_var_cell);
|
|
cell2 = mock_got_var_cell;
|
|
|
|
tt_int_op(cell1->command, ==, CELL_CERTS);
|
|
tt_int_op(cell1->payload_len, >, 1);
|
|
|
|
tt_int_op(cell2->command, ==, CELL_CERTS);
|
|
tt_int_op(cell2->payload_len, >, 1);
|
|
|
|
tt_int_op(cell1->payload_len, ==,
|
|
certs_cell_parse(&cc1, cell1->payload, cell1->payload_len));
|
|
tt_int_op(cell2->payload_len, ==,
|
|
certs_cell_parse(&cc2, cell2->payload, cell2->payload_len));
|
|
|
|
if (with_ed) {
|
|
tt_int_op(5, ==, cc1->n_certs);
|
|
tt_int_op(5, ==, cc2->n_certs);
|
|
} else {
|
|
tt_int_op(2, ==, cc1->n_certs);
|
|
tt_int_op(2, ==, cc2->n_certs);
|
|
}
|
|
|
|
tt_int_op(certs_cell_get_certs(cc1, 0)->cert_type, ==,
|
|
CERTTYPE_RSA1024_ID_AUTH);
|
|
tt_int_op(certs_cell_get_certs(cc1, 1)->cert_type, ==,
|
|
CERTTYPE_RSA1024_ID_ID);
|
|
|
|
tt_int_op(certs_cell_get_certs(cc2, 0)->cert_type, ==,
|
|
CERTTYPE_RSA1024_ID_LINK);
|
|
tt_int_op(certs_cell_get_certs(cc2, 1)->cert_type, ==,
|
|
CERTTYPE_RSA1024_ID_ID);
|
|
|
|
if (with_ed) {
|
|
tt_int_op(certs_cell_get_certs(cc1, 2)->cert_type, ==,
|
|
CERTTYPE_ED_ID_SIGN);
|
|
tt_int_op(certs_cell_get_certs(cc1, 3)->cert_type, ==,
|
|
CERTTYPE_ED_SIGN_AUTH);
|
|
tt_int_op(certs_cell_get_certs(cc1, 4)->cert_type, ==,
|
|
CERTTYPE_RSA1024_ID_EDID);
|
|
|
|
tt_int_op(certs_cell_get_certs(cc2, 2)->cert_type, ==,
|
|
CERTTYPE_ED_ID_SIGN);
|
|
tt_int_op(certs_cell_get_certs(cc2, 3)->cert_type, ==,
|
|
CERTTYPE_ED_SIGN_LINK);
|
|
tt_int_op(certs_cell_get_certs(cc2, 4)->cert_type, ==,
|
|
CERTTYPE_RSA1024_ID_EDID);
|
|
}
|
|
|
|
chan1 = tor_malloc_zero(sizeof(*chan1));
|
|
channel_tls_common_init(chan1);
|
|
c1->chan = chan1;
|
|
chan1->conn = c1;
|
|
c1->base_.address = tor_strdup("C1");
|
|
c1->tls = tor_tls_new(-1, 0);
|
|
c1->link_proto = 4;
|
|
c1->base_.conn_array_index = -1;
|
|
crypto_pk_get_digest(key2, c1->identity_digest);
|
|
|
|
if (with_ed) {
|
|
const tor_x509_cert_t *linkc, *idc;
|
|
tor_tls_get_my_certs(1, &linkc, &idc);
|
|
mock_peer_cert_expect_tortls = c1->tls; /* We should see this tls... */
|
|
mock_peer_cert = tor_x509_cert_dup(linkc); /* and when we do, the peer's
|
|
* cert is this... */
|
|
}
|
|
channel_tls_process_certs_cell(cell2, chan1);
|
|
mock_peer_cert_expect_tortls = NULL;
|
|
mock_peer_cert = NULL;
|
|
|
|
tor_assert(c1->handshake_state->authenticated);
|
|
|
|
tt_assert(c1->handshake_state->received_certs_cell);
|
|
tt_assert(c1->handshake_state->certs->auth_cert == NULL);
|
|
tt_assert(c1->handshake_state->certs->ed_sign_auth == NULL);
|
|
tt_assert(c1->handshake_state->certs->id_cert);
|
|
if (with_ed) {
|
|
tt_assert(c1->handshake_state->certs->ed_sign_link);
|
|
tt_assert(c1->handshake_state->certs->ed_rsa_crosscert);
|
|
tt_assert(c1->handshake_state->certs->ed_id_sign);
|
|
tt_assert(c1->handshake_state->authenticated_rsa);
|
|
tt_assert(c1->handshake_state->authenticated_ed25519);
|
|
} else {
|
|
tt_assert(c1->handshake_state->certs->ed_sign_link == NULL);
|
|
tt_assert(c1->handshake_state->certs->ed_rsa_crosscert == NULL);
|
|
tt_assert(c1->handshake_state->certs->ed_id_sign == NULL);
|
|
tt_assert(c1->handshake_state->authenticated_rsa);
|
|
tt_assert(! c1->handshake_state->authenticated_ed25519);
|
|
}
|
|
tt_assert(! tor_mem_is_zero(
|
|
(char*)c1->handshake_state->authenticated_rsa_peer_id, 20));
|
|
|
|
chan2 = tor_malloc_zero(sizeof(*chan2));
|
|
channel_tls_common_init(chan2);
|
|
c2->chan = chan2;
|
|
chan2->conn = c2;
|
|
c2->base_.address = tor_strdup("C2");
|
|
c2->tls = tor_tls_new(-1, 1);
|
|
c2->link_proto = 4;
|
|
c2->base_.conn_array_index = -1;
|
|
crypto_pk_get_digest(key1, c2->identity_digest);
|
|
|
|
channel_tls_process_certs_cell(cell1, chan2);
|
|
|
|
tt_assert(c2->handshake_state->received_certs_cell);
|
|
if (with_ed) {
|
|
tt_assert(c2->handshake_state->certs->ed_sign_auth);
|
|
tt_assert(c2->handshake_state->certs->ed_rsa_crosscert);
|
|
tt_assert(c2->handshake_state->certs->ed_id_sign);
|
|
} else {
|
|
tt_assert(c2->handshake_state->certs->auth_cert);
|
|
tt_assert(c2->handshake_state->certs->ed_sign_auth == NULL);
|
|
tt_assert(c2->handshake_state->certs->ed_rsa_crosscert == NULL);
|
|
tt_assert(c2->handshake_state->certs->ed_id_sign == NULL);
|
|
}
|
|
tt_assert(c2->handshake_state->certs->id_cert);
|
|
tt_assert(tor_mem_is_zero(
|
|
(char*)c2->handshake_state->authenticated_rsa_peer_id, 20));
|
|
/* no authentication has happened yet, since we haen't gotten an AUTH cell.
|
|
*/
|
|
tt_assert(! c2->handshake_state->authenticated);
|
|
tt_assert(! c2->handshake_state->authenticated_rsa);
|
|
tt_assert(! c2->handshake_state->authenticated_ed25519);
|
|
|
|
done:
|
|
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);
|
|
memset(c1->identity_digest, 0, sizeof(c1->identity_digest));
|
|
memset(c2->identity_digest, 0, sizeof(c2->identity_digest));
|
|
connection_free_(TO_CONN(c1));
|
|
connection_free_(TO_CONN(c2));
|
|
tor_free(cell1);
|
|
tor_free(cell2);
|
|
certs_cell_free(cc1);
|
|
certs_cell_free(cc2);
|
|
if (chan1)
|
|
circuitmux_free(chan1->base_.cmux);
|
|
tor_free(chan1);
|
|
if (chan2)
|
|
circuitmux_free(chan2->base_.cmux);
|
|
tor_free(chan2);
|
|
crypto_pk_free(key1);
|
|
crypto_pk_free(key2);
|
|
}
|
|
|
|
typedef struct certs_data_s {
|
|
int is_ed;
|
|
int is_link_cert;
|
|
or_connection_t *c;
|
|
channel_tls_t *chan;
|
|
certs_cell_t *ccell;
|
|
var_cell_t *cell;
|
|
crypto_pk_t *key1, *key2;
|
|
} certs_data_t;
|
|
|
|
static int
|
|
recv_certs_cleanup(const struct testcase_t *test, void *obj)
|
|
{
|
|
(void)test;
|
|
certs_data_t *d = obj;
|
|
UNMOCK(tor_tls_cert_matches_key);
|
|
UNMOCK(connection_or_send_netinfo);
|
|
UNMOCK(connection_or_close_for_error);
|
|
UNMOCK(tor_tls_get_peer_cert);
|
|
|
|
if (d) {
|
|
tor_free(d->cell);
|
|
certs_cell_free(d->ccell);
|
|
connection_or_clear_identity(d->c);
|
|
connection_free_(TO_CONN(d->c));
|
|
circuitmux_free(d->chan->base_.cmux);
|
|
tor_free(d->chan);
|
|
crypto_pk_free(d->key1);
|
|
crypto_pk_free(d->key2);
|
|
tor_free(d);
|
|
}
|
|
routerkeys_free_all();
|
|
return 1;
|
|
}
|
|
|
|
static void *
|
|
recv_certs_setup(const struct testcase_t *test)
|
|
{
|
|
(void)test;
|
|
certs_data_t *d = tor_malloc_zero(sizeof(*d));
|
|
certs_cell_cert_t *ccc1 = NULL;
|
|
certs_cell_cert_t *ccc2 = NULL;
|
|
ssize_t n;
|
|
int is_ed = d->is_ed = !strcmpstart(test->setup_data, "Ed25519");
|
|
int is_rsa = !strcmpstart(test->setup_data, "RSA");
|
|
int is_link = d->is_link_cert = !strcmpend(test->setup_data, "-Link");
|
|
int is_auth = !strcmpend(test->setup_data, "-Auth");
|
|
tor_assert(is_ed != is_rsa);
|
|
tor_assert(is_link != is_auth);
|
|
|
|
d->c = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
d->chan = tor_malloc_zero(sizeof(*d->chan));
|
|
d->c->chan = d->chan;
|
|
d->c->base_.address = tor_strdup("HaveAnAddress");
|
|
tor_addr_from_ipv4h(&d->c->base_.addr, 0x801f0127);
|
|
d->c->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
|
|
d->chan->conn = d->c;
|
|
tt_int_op(connection_init_or_handshake_state(d->c, 1), ==, 0);
|
|
d->c->link_proto = 4;
|
|
|
|
d->key1 = pk_generate(2);
|
|
d->key2 = pk_generate(3);
|
|
|
|
tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
|
|
d->key1, d->key2, 86400), ==, 0);
|
|
if (is_ed) {
|
|
init_mock_ed_keys(d->key2);
|
|
} else {
|
|
routerkeys_free_all();
|
|
}
|
|
|
|
d->ccell = certs_cell_new();
|
|
ccc1 = certs_cell_cert_new();
|
|
certs_cell_add_certs(d->ccell, ccc1);
|
|
ccc2 = certs_cell_cert_new();
|
|
certs_cell_add_certs(d->ccell, ccc2);
|
|
d->ccell->n_certs = 2;
|
|
ccc1->cert_type = is_link ? 1 : 3;
|
|
ccc2->cert_type = 2;
|
|
|
|
const tor_x509_cert_t *a,*b;
|
|
const uint8_t *enca, *encb;
|
|
size_t lena, lenb;
|
|
tor_tls_get_my_certs(is_link ? 1 : 0, &a, &b);
|
|
tor_x509_cert_get_der(a, &enca, &lena);
|
|
tor_x509_cert_get_der(b, &encb, &lenb);
|
|
certs_cell_cert_setlen_body(ccc1, lena);
|
|
ccc1->cert_len = lena;
|
|
certs_cell_cert_setlen_body(ccc2, lenb);
|
|
ccc2->cert_len = lenb;
|
|
|
|
memcpy(certs_cell_cert_getarray_body(ccc1), enca, lena);
|
|
memcpy(certs_cell_cert_getarray_body(ccc2), encb, lenb);
|
|
|
|
if (is_ed) {
|
|
certs_cell_cert_t *ccc3 = NULL; /* Id->Sign */
|
|
certs_cell_cert_t *ccc4 = NULL; /* Sign->Link or Sign->Auth. */
|
|
certs_cell_cert_t *ccc5 = NULL; /* RSAId->Ed Id. */
|
|
const tor_cert_t *id_sign = get_master_signing_key_cert();
|
|
const tor_cert_t *secondary =
|
|
is_link ? get_current_link_cert_cert() : get_current_auth_key_cert();
|
|
const uint8_t *cc = NULL;
|
|
size_t cc_sz;
|
|
get_master_rsa_crosscert(&cc, &cc_sz);
|
|
|
|
ccc3 = certs_cell_cert_new();
|
|
ccc4 = certs_cell_cert_new();
|
|
ccc5 = certs_cell_cert_new();
|
|
certs_cell_add_certs(d->ccell, ccc3);
|
|
certs_cell_add_certs(d->ccell, ccc4);
|
|
certs_cell_add_certs(d->ccell, ccc5);
|
|
ccc3->cert_len = id_sign->encoded_len;
|
|
ccc4->cert_len = secondary->encoded_len;
|
|
ccc5->cert_len = cc_sz;
|
|
certs_cell_cert_setlen_body(ccc3, ccc3->cert_len);
|
|
certs_cell_cert_setlen_body(ccc4, ccc4->cert_len);
|
|
certs_cell_cert_setlen_body(ccc5, ccc5->cert_len);
|
|
memcpy(certs_cell_cert_getarray_body(ccc3), id_sign->encoded,
|
|
ccc3->cert_len);
|
|
memcpy(certs_cell_cert_getarray_body(ccc4), secondary->encoded,
|
|
ccc4->cert_len);
|
|
memcpy(certs_cell_cert_getarray_body(ccc5), cc, ccc5->cert_len);
|
|
ccc3->cert_type = 4;
|
|
ccc4->cert_type = is_link ? 5 : 6;
|
|
ccc5->cert_type = 7;
|
|
|
|
d->ccell->n_certs = 5;
|
|
}
|
|
|
|
d->cell = var_cell_new(4096);
|
|
d->cell->command = CELL_CERTS;
|
|
|
|
n = certs_cell_encode(d->cell->payload, 4096, d->ccell);
|
|
tt_int_op(n, >, 0);
|
|
d->cell->payload_len = n;
|
|
|
|
MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
|
|
MOCK(connection_or_send_netinfo, mock_send_netinfo);
|
|
MOCK(connection_or_close_for_error, mock_close_for_err);
|
|
MOCK(tor_tls_get_peer_cert, mock_get_peer_cert);
|
|
|
|
if (is_link) {
|
|
/* Say that this is the peer's certificate */
|
|
mock_peer_cert = tor_x509_cert_dup(a);
|
|
}
|
|
|
|
tt_int_op(0, ==, d->c->handshake_state->received_certs_cell);
|
|
tt_int_op(0, ==, mock_send_authenticate_called);
|
|
tt_int_op(0, ==, mock_send_netinfo_called);
|
|
|
|
return d;
|
|
done:
|
|
recv_certs_cleanup(test, d);
|
|
return NULL;
|
|
}
|
|
|
|
static struct testcase_setup_t setup_recv_certs = {
|
|
.setup_fn = recv_certs_setup,
|
|
.cleanup_fn = recv_certs_cleanup
|
|
};
|
|
|
|
static void
|
|
test_link_handshake_recv_certs_ok(void *arg)
|
|
{
|
|
certs_data_t *d = arg;
|
|
channel_tls_process_certs_cell(d->cell, d->chan);
|
|
tt_int_op(0, ==, mock_close_called);
|
|
tt_int_op(d->c->handshake_state->authenticated, ==, 1);
|
|
tt_int_op(d->c->handshake_state->authenticated_rsa, ==, 1);
|
|
tt_int_op(d->c->handshake_state->received_certs_cell, ==, 1);
|
|
tt_assert(d->c->handshake_state->certs->id_cert != NULL);
|
|
tt_assert(d->c->handshake_state->certs->auth_cert == NULL);
|
|
|
|
if (d->is_ed) {
|
|
tt_assert(d->c->handshake_state->certs->ed_id_sign != NULL);
|
|
tt_assert(d->c->handshake_state->certs->ed_sign_link != NULL);
|
|
tt_assert(d->c->handshake_state->certs->ed_sign_auth == NULL);
|
|
tt_assert(d->c->handshake_state->certs->ed_rsa_crosscert != NULL);
|
|
tt_int_op(d->c->handshake_state->authenticated_ed25519, ==, 1);
|
|
} else {
|
|
tt_assert(d->c->handshake_state->certs->ed_id_sign == NULL);
|
|
tt_assert(d->c->handshake_state->certs->ed_sign_link == NULL);
|
|
tt_assert(d->c->handshake_state->certs->ed_sign_auth == NULL);
|
|
tt_assert(d->c->handshake_state->certs->ed_rsa_crosscert == NULL);
|
|
tt_int_op(d->c->handshake_state->authenticated_ed25519, ==, 0);
|
|
}
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
static void
|
|
test_link_handshake_recv_certs_ok_server(void *arg)
|
|
{
|
|
certs_data_t *d = arg;
|
|
d->c->handshake_state->started_here = 0;
|
|
d->c->handshake_state->certs->started_here = 0;
|
|
channel_tls_process_certs_cell(d->cell, d->chan);
|
|
tt_int_op(0, ==, mock_close_called);
|
|
tt_int_op(d->c->handshake_state->authenticated, ==, 0);
|
|
tt_int_op(d->c->handshake_state->received_certs_cell, ==, 1);
|
|
tt_assert(d->c->handshake_state->certs->id_cert != NULL);
|
|
tt_assert(d->c->handshake_state->certs->link_cert == NULL);
|
|
if (d->is_ed) {
|
|
tt_assert(d->c->handshake_state->certs->ed_sign_auth != NULL);
|
|
tt_assert(d->c->handshake_state->certs->auth_cert == NULL);
|
|
} else {
|
|
tt_assert(d->c->handshake_state->certs->ed_sign_auth == NULL);
|
|
tt_assert(d->c->handshake_state->certs->auth_cert != NULL);
|
|
}
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
#define CERTS_FAIL(name, code) \
|
|
static void \
|
|
test_link_handshake_recv_certs_ ## name(void *arg) \
|
|
{ \
|
|
certs_data_t *d = arg; \
|
|
const char *require_failure_message = NULL; \
|
|
setup_capture_of_logs(LOG_INFO); \
|
|
{ code ; } \
|
|
channel_tls_process_certs_cell(d->cell, d->chan); \
|
|
tt_int_op(1, ==, mock_close_called); \
|
|
tt_int_op(0, ==, mock_send_authenticate_called); \
|
|
tt_int_op(0, ==, mock_send_netinfo_called); \
|
|
tt_int_op(0, ==, d->c->handshake_state->authenticated_rsa); \
|
|
tt_int_op(0, ==, d->c->handshake_state->authenticated_ed25519); \
|
|
if (require_failure_message) { \
|
|
expect_log_msg_containing(require_failure_message); \
|
|
} \
|
|
done: \
|
|
teardown_capture_of_logs(); \
|
|
}
|
|
|
|
CERTS_FAIL(badstate,
|
|
require_failure_message = "We're not doing a v3 handshake!";
|
|
d->c->base_.state = OR_CONN_STATE_CONNECTING;)
|
|
CERTS_FAIL(badproto,
|
|
require_failure_message = "not using link protocol >= 3";
|
|
d->c->link_proto = 2)
|
|
CERTS_FAIL(duplicate,
|
|
require_failure_message = "We already got one";
|
|
d->c->handshake_state->received_certs_cell = 1)
|
|
CERTS_FAIL(already_authenticated,
|
|
require_failure_message = "We're already authenticated!";
|
|
d->c->handshake_state->authenticated = 1)
|
|
CERTS_FAIL(empty,
|
|
require_failure_message = "It had no body";
|
|
d->cell->payload_len = 0)
|
|
CERTS_FAIL(bad_circid,
|
|
require_failure_message = "It had a nonzero circuit ID";
|
|
d->cell->circ_id = 1)
|
|
CERTS_FAIL(truncated_1,
|
|
require_failure_message = "It couldn't be parsed";
|
|
d->cell->payload[0] = 5)
|
|
CERTS_FAIL(truncated_2,
|
|
{
|
|
require_failure_message = "It couldn't be parsed";
|
|
d->cell->payload_len = 4;
|
|
memcpy(d->cell->payload, "\x01\x01\x00\x05", 4);
|
|
})
|
|
CERTS_FAIL(truncated_3,
|
|
{
|
|
require_failure_message = "It couldn't be parsed";
|
|
d->cell->payload_len = 7;
|
|
memcpy(d->cell->payload, "\x01\x01\x00\x05""abc", 7);
|
|
})
|
|
CERTS_FAIL(truncated_4, /* ed25519 */
|
|
{
|
|
require_failure_message = "It couldn't be parsed";
|
|
d->cell->payload_len -= 10;
|
|
})
|
|
CERTS_FAIL(truncated_5, /* ed25519 */
|
|
{
|
|
require_failure_message = "It couldn't be parsed";
|
|
d->cell->payload_len -= 100;
|
|
})
|
|
|
|
#define REENCODE() do { \
|
|
const char *msg = certs_cell_check(d->ccell); \
|
|
if (msg) puts(msg); \
|
|
ssize_t n = certs_cell_encode(d->cell->payload, 4096, d->ccell); \
|
|
tt_int_op(n, >, 0); \
|
|
d->cell->payload_len = n; \
|
|
} while (0)
|
|
|
|
CERTS_FAIL(truncated_6, /* ed25519 */
|
|
{
|
|
/* truncate the link certificate */
|
|
require_failure_message = "undecodable Ed certificate";
|
|
certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 3), 7);
|
|
certs_cell_get_certs(d->ccell, 3)->cert_len = 7;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(truncated_7, /* ed25519 */
|
|
{
|
|
/* truncate the crosscert */
|
|
require_failure_message = "Unparseable or overlong crosscert";
|
|
certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 4), 7);
|
|
certs_cell_get_certs(d->ccell, 4)->cert_len = 7;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(not_x509,
|
|
{
|
|
require_failure_message = "Received undecodable certificate";
|
|
certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 0), 3);
|
|
certs_cell_get_certs(d->ccell, 0)->cert_len = 3;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(both_link,
|
|
{
|
|
require_failure_message = "Duplicate x509 certificate";
|
|
certs_cell_get_certs(d->ccell, 0)->cert_type = 1;
|
|
certs_cell_get_certs(d->ccell, 1)->cert_type = 1;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(both_id_rsa,
|
|
{
|
|
require_failure_message = "Duplicate x509 certificate";
|
|
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
|
|
certs_cell_get_certs(d->ccell, 1)->cert_type = 2;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(both_auth,
|
|
{
|
|
require_failure_message = "Duplicate x509 certificate";
|
|
certs_cell_get_certs(d->ccell, 0)->cert_type = 3;
|
|
certs_cell_get_certs(d->ccell, 1)->cert_type = 3;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(duplicate_id, /* ed25519 */
|
|
{
|
|
require_failure_message = "Duplicate Ed25519 certificate";
|
|
certs_cell_get_certs(d->ccell, 2)->cert_type = 4;
|
|
certs_cell_get_certs(d->ccell, 3)->cert_type = 4;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(duplicate_link, /* ed25519 */
|
|
{
|
|
require_failure_message = "Duplicate Ed25519 certificate";
|
|
certs_cell_get_certs(d->ccell, 2)->cert_type = 5;
|
|
certs_cell_get_certs(d->ccell, 3)->cert_type = 5;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(duplicate_crosscert, /* ed25519 */
|
|
{
|
|
require_failure_message = "Duplicate RSA->Ed25519 crosscert";
|
|
certs_cell_get_certs(d->ccell, 2)->cert_type = 7;
|
|
certs_cell_get_certs(d->ccell, 3)->cert_type = 7;
|
|
REENCODE();
|
|
})
|
|
static void
|
|
test_link_handshake_recv_certs_missing_id(void *arg) /* ed25519 */
|
|
{
|
|
certs_data_t *d = arg;
|
|
tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
|
|
certs_cell_set_certs(d->ccell, 2, certs_cell_get_certs(d->ccell, 4));
|
|
certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
|
|
certs_cell_setlen_certs(d->ccell, 4);
|
|
d->ccell->n_certs = 4;
|
|
REENCODE();
|
|
|
|
/* This handshake succeeds, but since we have no ID cert, we will
|
|
* just do the RSA handshake. */
|
|
channel_tls_process_certs_cell(d->cell, d->chan);
|
|
tt_int_op(0, ==, mock_close_called);
|
|
tt_int_op(0, ==, d->c->handshake_state->authenticated_ed25519);
|
|
tt_int_op(1, ==, d->c->handshake_state->authenticated_rsa);
|
|
done:
|
|
;
|
|
}
|
|
CERTS_FAIL(missing_signing_key, /* ed25519 */
|
|
{
|
|
require_failure_message = "No Ed25519 signing key";
|
|
tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 2);
|
|
tt_int_op(cert->cert_type, ==, CERTTYPE_ED_ID_SIGN);
|
|
/* replace this with a valid master->signing cert, but with no
|
|
* signing key. */
|
|
const ed25519_keypair_t *mk = get_master_identity_keypair();
|
|
const ed25519_keypair_t *sk = get_master_signing_keypair();
|
|
tor_cert_t *bad_cert = tor_cert_create(mk, CERT_TYPE_ID_SIGNING,
|
|
&sk->pubkey, time(NULL), 86400,
|
|
0 /* don't include signer */);
|
|
certs_cell_cert_setlen_body(cert, bad_cert->encoded_len);
|
|
memcpy(certs_cell_cert_getarray_body(cert),
|
|
bad_cert->encoded, bad_cert->encoded_len);
|
|
cert->cert_len = bad_cert->encoded_len;
|
|
tor_cert_free(bad_cert);
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(missing_link, /* ed25519 */
|
|
{
|
|
require_failure_message = "No Ed25519 link key";
|
|
tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
|
|
certs_cell_set_certs(d->ccell, 3, certs_cell_get_certs(d->ccell, 4));
|
|
certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
|
|
certs_cell_setlen_certs(d->ccell, 4);
|
|
d->ccell->n_certs = 4;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(missing_auth, /* ed25519 */
|
|
{
|
|
d->c->handshake_state->started_here = 0;
|
|
d->c->handshake_state->certs->started_here = 0;
|
|
require_failure_message = "No Ed25519 link authentication key";
|
|
tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
|
|
certs_cell_set_certs(d->ccell, 3, certs_cell_get_certs(d->ccell, 4));
|
|
certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
|
|
certs_cell_setlen_certs(d->ccell, 4);
|
|
d->ccell->n_certs = 4;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(missing_crosscert, /* ed25519 */
|
|
{
|
|
require_failure_message = "Missing RSA->Ed25519 crosscert";
|
|
tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
|
|
certs_cell_setlen_certs(d->ccell, 4);
|
|
d->ccell->n_certs = 4;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(missing_rsa_id, /* ed25519 */
|
|
{
|
|
require_failure_message = "Missing legacy RSA ID cert";
|
|
tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
|
|
certs_cell_set_certs(d->ccell, 1, certs_cell_get_certs(d->ccell, 4));
|
|
certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
|
|
certs_cell_setlen_certs(d->ccell, 4);
|
|
d->ccell->n_certs = 4;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(link_mismatch, /* ed25519 */
|
|
{
|
|
require_failure_message = "Link certificate does not match "
|
|
"TLS certificate";
|
|
const tor_x509_cert_t *idc;
|
|
tor_tls_get_my_certs(1, NULL, &idc);
|
|
tor_x509_cert_free(mock_peer_cert);
|
|
/* Pretend that the peer cert was something else. */
|
|
mock_peer_cert = tor_x509_cert_dup(idc);
|
|
/* No reencode needed. */
|
|
})
|
|
CERTS_FAIL(bad_ed_sig, /* ed25519 */
|
|
{
|
|
require_failure_message = "At least one Ed25519 certificate was "
|
|
"badly signed";
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 3);
|
|
uint8_t *body = certs_cell_cert_getarray_body(cert);
|
|
ssize_t body_len = certs_cell_cert_getlen_body(cert);
|
|
/* Frob a byte in the signature */
|
|
body[body_len - 13] ^= 7;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(bad_crosscert, /*ed25519*/
|
|
{
|
|
require_failure_message = "Invalid RSA->Ed25519 crosscert";
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 4);
|
|
uint8_t *body = certs_cell_cert_getarray_body(cert);
|
|
ssize_t body_len = certs_cell_cert_getlen_body(cert);
|
|
/* Frob a byte in the signature */
|
|
body[body_len - 13] ^= 7;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(bad_rsa_id_cert, /*ed25519*/
|
|
{
|
|
require_failure_message = "legacy RSA ID certificate was not valid";
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 1);
|
|
uint8_t *body = certs_cell_cert_getarray_body(cert);
|
|
ssize_t body_len = certs_cell_cert_getlen_body(cert);
|
|
/* Frob a byte in the signature */
|
|
body[body_len - 13] ^= 7;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(expired_rsa_id, /* both */
|
|
{
|
|
require_failure_message = "Certificate already expired";
|
|
/* we're going to replace the identity cert with an expired one. */
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 1);
|
|
const tor_x509_cert_t *idc;
|
|
tor_tls_get_my_certs(1, NULL, &idc);
|
|
X509 *newc = X509_dup(idc->cert);
|
|
time_t new_end = time(NULL) - 86400 * 10;
|
|
X509_time_adj(X509_get_notAfter(newc), 0, &new_end);
|
|
EVP_PKEY *pk = crypto_pk_get_evp_pkey_(d->key2, 1);
|
|
tt_assert(X509_sign(newc, pk, EVP_sha1()));
|
|
int len = i2d_X509(newc, NULL);
|
|
certs_cell_cert_setlen_body(cert, len);
|
|
uint8_t *body = certs_cell_cert_getarray_body(cert);
|
|
int len2 = i2d_X509(newc, &body);
|
|
tt_int_op(len, ==, len2);
|
|
REENCODE();
|
|
X509_free(newc);
|
|
EVP_PKEY_free(pk);
|
|
})
|
|
CERTS_FAIL(expired_ed_id, /* ed25519 */
|
|
{
|
|
/* we're going to replace the Ed Id->sign cert with an expired one. */
|
|
require_failure_message = "At least one certificate expired";
|
|
/* We don't need to re-sign, since we check for expiration first. */
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 2);
|
|
uint8_t *body = certs_cell_cert_getarray_body(cert);
|
|
/* The expiration field is bytes [2..5]. It is in HOURS since the
|
|
* epoch. */
|
|
set_uint32(body+2, htonl(24)); /* Back to jan 2, 1970. */
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(expired_ed_link, /* ed25519 */
|
|
{
|
|
/* we're going to replace the Ed Sign->link cert with an expired one. */
|
|
require_failure_message = "At least one certificate expired";
|
|
/* We don't need to re-sign, since we check for expiration first. */
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 3);
|
|
uint8_t *body = certs_cell_cert_getarray_body(cert);
|
|
/* The expiration field is bytes [2..5]. It is in HOURS since the
|
|
* epoch. */
|
|
set_uint32(body+2, htonl(24)); /* Back to jan 2, 1970. */
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(expired_crosscert, /* ed25519 */
|
|
{
|
|
/* we're going to replace the Ed Sign->link cert with an expired one. */
|
|
require_failure_message = "Crosscert is expired";
|
|
/* We don't need to re-sign, since we check for expiration first. */
|
|
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 4);
|
|
uint8_t *body = certs_cell_cert_getarray_body(cert);
|
|
/* The expiration field is bytes [32..35]. once again, HOURS. */
|
|
set_uint32(body+32, htonl(24)); /* Back to jan 2, 1970. */
|
|
REENCODE();
|
|
})
|
|
|
|
CERTS_FAIL(wrong_labels_1,
|
|
{
|
|
require_failure_message = "The link certificate was not valid";
|
|
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
|
|
certs_cell_get_certs(d->ccell, 1)->cert_type = 1;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(wrong_labels_2,
|
|
{
|
|
const tor_x509_cert_t *a;
|
|
const tor_x509_cert_t *b;
|
|
const uint8_t *enca;
|
|
size_t lena;
|
|
require_failure_message = "The link certificate was not valid";
|
|
tor_tls_get_my_certs(1, &a, &b);
|
|
tor_x509_cert_get_der(a, &enca, &lena);
|
|
certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 1), lena);
|
|
memcpy(certs_cell_cert_getarray_body(certs_cell_get_certs(d->ccell, 1)),
|
|
enca, lena);
|
|
certs_cell_get_certs(d->ccell, 1)->cert_len = lena;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(wrong_labels_3,
|
|
{
|
|
require_failure_message =
|
|
"The certs we wanted (ID, Link) were missing";
|
|
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
|
|
certs_cell_get_certs(d->ccell, 1)->cert_type = 3;
|
|
REENCODE();
|
|
})
|
|
CERTS_FAIL(server_missing_certs,
|
|
{
|
|
require_failure_message =
|
|
"The certs we wanted (ID, Auth) were missing";
|
|
d->c->handshake_state->started_here = 0;
|
|
d->c->handshake_state->certs->started_here = 0;
|
|
|
|
})
|
|
CERTS_FAIL(server_wrong_labels_1,
|
|
{
|
|
require_failure_message =
|
|
"The authentication certificate was not valid";
|
|
d->c->handshake_state->started_here = 0;
|
|
d->c->handshake_state->certs->started_here = 0;
|
|
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
|
|
certs_cell_get_certs(d->ccell, 1)->cert_type = 3;
|
|
REENCODE();
|
|
})
|
|
|
|
static void
|
|
test_link_handshake_send_authchallenge(void *arg)
|
|
{
|
|
(void)arg;
|
|
|
|
or_connection_t *c1 = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
var_cell_t *cell1=NULL, *cell2=NULL;
|
|
|
|
MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell);
|
|
|
|
tt_int_op(connection_init_or_handshake_state(c1, 0), ==, 0);
|
|
c1->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
|
|
tt_assert(! mock_got_var_cell);
|
|
tt_int_op(0, ==, connection_or_send_auth_challenge_cell(c1));
|
|
cell1 = mock_got_var_cell;
|
|
tt_int_op(0, ==, connection_or_send_auth_challenge_cell(c1));
|
|
cell2 = mock_got_var_cell;
|
|
tt_int_op(38, ==, cell1->payload_len);
|
|
tt_int_op(38, ==, cell2->payload_len);
|
|
tt_int_op(0, ==, cell1->circ_id);
|
|
tt_int_op(0, ==, cell2->circ_id);
|
|
tt_int_op(CELL_AUTH_CHALLENGE, ==, cell1->command);
|
|
tt_int_op(CELL_AUTH_CHALLENGE, ==, cell2->command);
|
|
|
|
tt_mem_op("\x00\x02\x00\x01\x00\x03", ==, cell1->payload + 32, 6);
|
|
tt_mem_op("\x00\x02\x00\x01\x00\x03", ==, cell2->payload + 32, 6);
|
|
tt_mem_op(cell1->payload, !=, cell2->payload, 32);
|
|
|
|
done:
|
|
UNMOCK(connection_or_write_var_cell_to_buf);
|
|
connection_free_(TO_CONN(c1));
|
|
tor_free(cell1);
|
|
tor_free(cell2);
|
|
}
|
|
|
|
typedef struct authchallenge_data_s {
|
|
or_connection_t *c;
|
|
channel_tls_t *chan;
|
|
var_cell_t *cell;
|
|
} authchallenge_data_t;
|
|
|
|
static int
|
|
recv_authchallenge_cleanup(const struct testcase_t *test, void *obj)
|
|
{
|
|
(void)test;
|
|
authchallenge_data_t *d = obj;
|
|
|
|
UNMOCK(connection_or_send_netinfo);
|
|
UNMOCK(connection_or_close_for_error);
|
|
UNMOCK(connection_or_send_authenticate_cell);
|
|
|
|
if (d) {
|
|
tor_free(d->cell);
|
|
connection_free_(TO_CONN(d->c));
|
|
circuitmux_free(d->chan->base_.cmux);
|
|
tor_free(d->chan);
|
|
tor_free(d);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static void *
|
|
recv_authchallenge_setup(const struct testcase_t *test)
|
|
{
|
|
(void)test;
|
|
authchallenge_data_t *d = tor_malloc_zero(sizeof(*d));
|
|
d->c = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
d->chan = tor_malloc_zero(sizeof(*d->chan));
|
|
d->c->chan = d->chan;
|
|
d->c->base_.address = tor_strdup("HaveAnAddress");
|
|
d->c->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
|
|
d->chan->conn = d->c;
|
|
tt_int_op(connection_init_or_handshake_state(d->c, 1), ==, 0);
|
|
d->c->link_proto = 4;
|
|
d->c->handshake_state->received_certs_cell = 1;
|
|
d->cell = var_cell_new(128);
|
|
d->cell->payload_len = 38;
|
|
d->cell->payload[33] = 2; /* 2 methods */
|
|
d->cell->payload[35] = 7; /* This one isn't real */
|
|
d->cell->payload[37] = 1; /* This is the old RSA one. */
|
|
d->cell->command = CELL_AUTH_CHALLENGE;
|
|
|
|
get_options_mutable()->ORPort_set = 1;
|
|
|
|
MOCK(connection_or_close_for_error, mock_close_for_err);
|
|
MOCK(connection_or_send_netinfo, mock_send_netinfo);
|
|
MOCK(connection_or_send_authenticate_cell, mock_send_authenticate);
|
|
tt_int_op(0, ==, d->c->handshake_state->received_auth_challenge);
|
|
tt_int_op(0, ==, mock_send_authenticate_called);
|
|
tt_int_op(0, ==, mock_send_netinfo_called);
|
|
|
|
return d;
|
|
done:
|
|
recv_authchallenge_cleanup(test, d);
|
|
return NULL;
|
|
}
|
|
|
|
static struct testcase_setup_t setup_recv_authchallenge = {
|
|
.setup_fn = recv_authchallenge_setup,
|
|
.cleanup_fn = recv_authchallenge_cleanup
|
|
};
|
|
|
|
static void
|
|
test_link_handshake_recv_authchallenge_ok(void *arg)
|
|
{
|
|
authchallenge_data_t *d = arg;
|
|
|
|
channel_tls_process_auth_challenge_cell(d->cell, d->chan);
|
|
tt_int_op(0, ==, mock_close_called);
|
|
tt_int_op(1, ==, d->c->handshake_state->received_auth_challenge);
|
|
tt_int_op(1, ==, mock_send_authenticate_called);
|
|
tt_int_op(1, ==, mock_send_netinfo_called);
|
|
tt_int_op(1, ==, mock_send_authenticate_called_with_type); /* RSA */
|
|
done:
|
|
;
|
|
}
|
|
|
|
static void
|
|
test_link_handshake_recv_authchallenge_ok_ed25519(void *arg)
|
|
{
|
|
authchallenge_data_t *d = arg;
|
|
|
|
/* Add the ed25519 authentication mechanism here. */
|
|
d->cell->payload[33] = 3; /* 3 types are supported now. */
|
|
d->cell->payload[39] = 3;
|
|
d->cell->payload_len += 2;
|
|
channel_tls_process_auth_challenge_cell(d->cell, d->chan);
|
|
tt_int_op(0, ==, mock_close_called);
|
|
tt_int_op(1, ==, d->c->handshake_state->received_auth_challenge);
|
|
tt_int_op(1, ==, mock_send_authenticate_called);
|
|
tt_int_op(1, ==, mock_send_netinfo_called);
|
|
tt_int_op(3, ==, mock_send_authenticate_called_with_type); /* Ed25519 */
|
|
done:
|
|
;
|
|
}
|
|
|
|
static void
|
|
test_link_handshake_recv_authchallenge_ok_noserver(void *arg)
|
|
{
|
|
authchallenge_data_t *d = arg;
|
|
get_options_mutable()->ORPort_set = 0;
|
|
|
|
channel_tls_process_auth_challenge_cell(d->cell, d->chan);
|
|
tt_int_op(0, ==, mock_close_called);
|
|
tt_int_op(1, ==, d->c->handshake_state->received_auth_challenge);
|
|
tt_int_op(0, ==, mock_send_authenticate_called);
|
|
tt_int_op(0, ==, mock_send_netinfo_called);
|
|
done:
|
|
;
|
|
}
|
|
|
|
static void
|
|
test_link_handshake_recv_authchallenge_ok_unrecognized(void *arg)
|
|
{
|
|
authchallenge_data_t *d = arg;
|
|
d->cell->payload[37] = 99;
|
|
|
|
channel_tls_process_auth_challenge_cell(d->cell, d->chan);
|
|
tt_int_op(0, ==, mock_close_called);
|
|
tt_int_op(1, ==, d->c->handshake_state->received_auth_challenge);
|
|
tt_int_op(0, ==, mock_send_authenticate_called);
|
|
tt_int_op(1, ==, mock_send_netinfo_called);
|
|
done:
|
|
;
|
|
}
|
|
|
|
#define AUTHCHALLENGE_FAIL(name, code) \
|
|
static void \
|
|
test_link_handshake_recv_authchallenge_ ## name(void *arg) \
|
|
{ \
|
|
authchallenge_data_t *d = arg; \
|
|
const char *require_failure_message = NULL; \
|
|
setup_capture_of_logs(LOG_INFO); \
|
|
{ code ; } \
|
|
channel_tls_process_auth_challenge_cell(d->cell, d->chan); \
|
|
tt_int_op(1, ==, mock_close_called); \
|
|
tt_int_op(0, ==, mock_send_authenticate_called); \
|
|
tt_int_op(0, ==, mock_send_netinfo_called); \
|
|
if (require_failure_message) { \
|
|
expect_log_msg_containing(require_failure_message); \
|
|
} \
|
|
done: \
|
|
teardown_capture_of_logs(); \
|
|
}
|
|
|
|
AUTHCHALLENGE_FAIL(badstate,
|
|
require_failure_message = "We're not currently doing a "
|
|
"v3 handshake";
|
|
d->c->base_.state = OR_CONN_STATE_CONNECTING)
|
|
AUTHCHALLENGE_FAIL(badproto,
|
|
require_failure_message = "not using link protocol >= 3";
|
|
d->c->link_proto = 2)
|
|
AUTHCHALLENGE_FAIL(as_server,
|
|
require_failure_message = "We didn't originate this "
|
|
"connection";
|
|
d->c->handshake_state->started_here = 0;
|
|
d->c->handshake_state->certs->started_here = 0;)
|
|
AUTHCHALLENGE_FAIL(duplicate,
|
|
require_failure_message = "We already received one";
|
|
d->c->handshake_state->received_auth_challenge = 1)
|
|
AUTHCHALLENGE_FAIL(nocerts,
|
|
require_failure_message = "We haven't gotten a CERTS "
|
|
"cell yet";
|
|
d->c->handshake_state->received_certs_cell = 0)
|
|
AUTHCHALLENGE_FAIL(tooshort,
|
|
require_failure_message = "It was not well-formed";
|
|
d->cell->payload_len = 33)
|
|
AUTHCHALLENGE_FAIL(truncated,
|
|
require_failure_message = "It was not well-formed";
|
|
d->cell->payload_len = 34)
|
|
AUTHCHALLENGE_FAIL(nonzero_circid,
|
|
require_failure_message = "It had a nonzero circuit ID";
|
|
d->cell->circ_id = 1337)
|
|
|
|
static int
|
|
mock_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
|
|
{
|
|
(void)tls;
|
|
memcpy(secrets_out, "int getRandomNumber(){return 4;}", 32);
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
mock_set_circid_type(channel_t *chan,
|
|
crypto_pk_t *identity_rcvd,
|
|
int consider_identity)
|
|
{
|
|
(void) chan;
|
|
(void) identity_rcvd;
|
|
(void) consider_identity;
|
|
}
|
|
|
|
typedef struct authenticate_data_s {
|
|
int is_ed;
|
|
or_connection_t *c1, *c2;
|
|
channel_tls_t *chan2;
|
|
var_cell_t *cell;
|
|
crypto_pk_t *key1, *key2;
|
|
} authenticate_data_t;
|
|
|
|
static int
|
|
authenticate_data_cleanup(const struct testcase_t *test, void *arg)
|
|
{
|
|
(void) test;
|
|
UNMOCK(connection_or_write_var_cell_to_buf);
|
|
UNMOCK(tor_tls_get_peer_cert);
|
|
UNMOCK(tor_tls_get_tlssecrets);
|
|
UNMOCK(connection_or_close_for_error);
|
|
UNMOCK(channel_set_circid_type);
|
|
UNMOCK(tor_tls_export_key_material);
|
|
authenticate_data_t *d = arg;
|
|
if (d) {
|
|
tor_free(d->cell);
|
|
connection_or_clear_identity(d->c1);
|
|
connection_or_clear_identity(d->c2);
|
|
connection_free_(TO_CONN(d->c1));
|
|
connection_free_(TO_CONN(d->c2));
|
|
circuitmux_free(d->chan2->base_.cmux);
|
|
tor_free(d->chan2);
|
|
crypto_pk_free(d->key1);
|
|
crypto_pk_free(d->key2);
|
|
tor_free(d);
|
|
}
|
|
mock_peer_cert = NULL;
|
|
return 1;
|
|
}
|
|
|
|
static void *
|
|
authenticate_data_setup(const struct testcase_t *test)
|
|
{
|
|
authenticate_data_t *d = tor_malloc_zero(sizeof(*d));
|
|
int is_ed = d->is_ed = (test->setup_data == (void*)3);
|
|
|
|
scheduler_init();
|
|
|
|
MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell);
|
|
MOCK(tor_tls_get_peer_cert, mock_get_peer_cert);
|
|
MOCK(tor_tls_get_tlssecrets, mock_get_tlssecrets);
|
|
MOCK(connection_or_close_for_error, mock_close_for_err);
|
|
MOCK(channel_set_circid_type, mock_set_circid_type);
|
|
MOCK(tor_tls_export_key_material, mock_export_key_material);
|
|
d->c1 = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
d->c2 = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
tor_addr_from_ipv4h(&d->c1->base_.addr, 0x01020304);
|
|
tor_addr_from_ipv4h(&d->c2->base_.addr, 0x05060708);
|
|
|
|
d->key1 = pk_generate(2);
|
|
d->key2 = pk_generate(3);
|
|
tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
|
|
d->key1, d->key2, 86400), ==, 0);
|
|
|
|
init_mock_ed_keys(d->key2);
|
|
|
|
d->c1->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
|
|
d->c1->link_proto = 3;
|
|
tt_int_op(connection_init_or_handshake_state(d->c1, 1), ==, 0);
|
|
|
|
d->c2->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
|
|
d->c2->link_proto = 3;
|
|
tt_int_op(connection_init_or_handshake_state(d->c2, 0), ==, 0);
|
|
var_cell_t *cell = var_cell_new(16);
|
|
cell->command = CELL_CERTS;
|
|
or_handshake_state_record_var_cell(d->c1, d->c1->handshake_state, cell, 1);
|
|
or_handshake_state_record_var_cell(d->c2, d->c2->handshake_state, cell, 0);
|
|
memset(cell->payload, 0xf0, 16);
|
|
or_handshake_state_record_var_cell(d->c1, d->c1->handshake_state, cell, 0);
|
|
or_handshake_state_record_var_cell(d->c2, d->c2->handshake_state, cell, 1);
|
|
tor_free(cell);
|
|
|
|
d->chan2 = tor_malloc_zero(sizeof(*d->chan2));
|
|
channel_tls_common_init(d->chan2);
|
|
d->c2->chan = d->chan2;
|
|
d->chan2->conn = d->c2;
|
|
d->c2->base_.address = tor_strdup("C2");
|
|
d->c2->tls = tor_tls_new(-1, 1);
|
|
d->c2->handshake_state->received_certs_cell = 1;
|
|
|
|
const tor_x509_cert_t *id_cert=NULL, *link_cert=NULL, *auth_cert=NULL;
|
|
tt_assert(! tor_tls_get_my_certs(1, &link_cert, &id_cert));
|
|
|
|
const uint8_t *der;
|
|
size_t sz;
|
|
tor_x509_cert_get_der(id_cert, &der, &sz);
|
|
d->c1->handshake_state->certs->id_cert = tor_x509_cert_decode(der, sz);
|
|
d->c2->handshake_state->certs->id_cert = tor_x509_cert_decode(der, sz);
|
|
|
|
if (is_ed) {
|
|
d->c1->handshake_state->certs->ed_id_sign =
|
|
tor_cert_dup(get_master_signing_key_cert());
|
|
d->c2->handshake_state->certs->ed_id_sign =
|
|
tor_cert_dup(get_master_signing_key_cert());
|
|
d->c2->handshake_state->certs->ed_sign_auth =
|
|
tor_cert_dup(get_current_auth_key_cert());
|
|
} else {
|
|
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->certs->auth_cert = tor_x509_cert_decode(der, sz);
|
|
}
|
|
|
|
tor_x509_cert_get_der(link_cert, &der, &sz);
|
|
mock_peer_cert = tor_x509_cert_decode(der, sz);
|
|
tt_assert(mock_peer_cert);
|
|
|
|
/* Make an authenticate cell ... */
|
|
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;
|
|
|
|
return d;
|
|
done:
|
|
authenticate_data_cleanup(test, d);
|
|
return NULL;
|
|
}
|
|
|
|
static struct testcase_setup_t setup_authenticate = {
|
|
.setup_fn = authenticate_data_setup,
|
|
.cleanup_fn = authenticate_data_cleanup
|
|
};
|
|
|
|
static void
|
|
test_link_handshake_auth_cell(void *arg)
|
|
{
|
|
authenticate_data_t *d = arg;
|
|
auth1_t *auth1 = NULL;
|
|
crypto_pk_t *auth_pubkey = NULL;
|
|
|
|
/* Is the cell well-formed on the outer layer? */
|
|
tt_int_op(d->cell->command, ==, CELL_AUTHENTICATE);
|
|
tt_int_op(d->cell->payload[0], ==, 0);
|
|
if (d->is_ed)
|
|
tt_int_op(d->cell->payload[1], ==, 3);
|
|
else
|
|
tt_int_op(d->cell->payload[1], ==, 1);
|
|
tt_int_op(ntohs(get_uint16(d->cell->payload + 2)), ==,
|
|
d->cell->payload_len - 4);
|
|
|
|
/* Check it out for plausibility... */
|
|
auth_ctx_t ctx;
|
|
ctx.is_ed = d->is_ed;
|
|
tt_int_op(d->cell->payload_len-4, ==, auth1_parse(&auth1,
|
|
d->cell->payload+4,
|
|
d->cell->payload_len - 4, &ctx));
|
|
tt_assert(auth1);
|
|
|
|
if (d->is_ed) {
|
|
tt_mem_op(auth1->type, ==, "AUTH0003", 8);
|
|
} else {
|
|
tt_mem_op(auth1->type, ==, "AUTH0001", 8);
|
|
}
|
|
tt_mem_op(auth1->tlssecrets, ==, "int getRandomNumber(){return 4;}", 32);
|
|
|
|
/* Is the signature okay? */
|
|
const uint8_t *start = d->cell->payload+4, *end = auth1->end_of_signed;
|
|
if (d->is_ed) {
|
|
ed25519_signature_t sig;
|
|
tt_int_op(auth1_getlen_sig(auth1), ==, ED25519_SIG_LEN);
|
|
memcpy(&sig.sig, auth1_getarray_sig(auth1), ED25519_SIG_LEN);
|
|
tt_assert(!ed25519_checksig(&sig, start, end-start,
|
|
&get_current_auth_keypair()->pubkey));
|
|
} else {
|
|
uint8_t sig[128];
|
|
uint8_t digest[32];
|
|
tt_int_op(auth1_getlen_sig(auth1), >, 120);
|
|
auth_pubkey = tor_tls_cert_get_key(
|
|
d->c2->handshake_state->certs->auth_cert);
|
|
int n = crypto_pk_public_checksig(
|
|
auth_pubkey,
|
|
(char*)sig, sizeof(sig), (char*)auth1_getarray_sig(auth1),
|
|
auth1_getlen_sig(auth1));
|
|
tt_int_op(n, ==, 32);
|
|
crypto_digest256((char*)digest,
|
|
(const char*)start, end-start, DIGEST_SHA256);
|
|
tt_mem_op(sig, ==, digest, 32);
|
|
}
|
|
|
|
/* Then feed it to c2. */
|
|
tt_int_op(d->c2->handshake_state->authenticated, ==, 0);
|
|
channel_tls_process_authenticate_cell(d->cell, d->chan2);
|
|
tt_int_op(mock_close_called, ==, 0);
|
|
tt_int_op(d->c2->handshake_state->authenticated, ==, 1);
|
|
if (d->is_ed) {
|
|
tt_int_op(d->c2->handshake_state->authenticated_ed25519, ==, 1);
|
|
tt_int_op(d->c2->handshake_state->authenticated_rsa, ==, 1);
|
|
} else {
|
|
tt_int_op(d->c2->handshake_state->authenticated_ed25519, ==, 0);
|
|
tt_int_op(d->c2->handshake_state->authenticated_rsa, ==, 1);
|
|
}
|
|
|
|
done:
|
|
auth1_free(auth1);
|
|
crypto_pk_free(auth_pubkey);
|
|
}
|
|
|
|
#define AUTHENTICATE_FAIL(name, code) \
|
|
static void \
|
|
test_link_handshake_auth_ ## name(void *arg) \
|
|
{ \
|
|
authenticate_data_t *d = arg; \
|
|
const char *require_failure_message = NULL; \
|
|
setup_capture_of_logs(LOG_INFO); \
|
|
{ code ; } \
|
|
tt_int_op(d->c2->handshake_state->authenticated, ==, 0); \
|
|
channel_tls_process_authenticate_cell(d->cell, d->chan2); \
|
|
tt_int_op(mock_close_called, ==, 1); \
|
|
tt_int_op(d->c2->handshake_state->authenticated, ==, 0); \
|
|
if (require_failure_message) { \
|
|
expect_log_msg_containing(require_failure_message); \
|
|
} \
|
|
done: \
|
|
teardown_capture_of_logs(); \
|
|
}
|
|
|
|
AUTHENTICATE_FAIL(badstate,
|
|
require_failure_message = "We're not doing a v3 handshake";
|
|
d->c2->base_.state = OR_CONN_STATE_CONNECTING)
|
|
AUTHENTICATE_FAIL(badproto,
|
|
require_failure_message = "not using link protocol >= 3";
|
|
d->c2->link_proto = 2)
|
|
AUTHENTICATE_FAIL(atclient,
|
|
require_failure_message = "We originated this connection";
|
|
d->c2->handshake_state->started_here = 1;
|
|
d->c2->handshake_state->certs->started_here = 1;)
|
|
AUTHENTICATE_FAIL(duplicate,
|
|
require_failure_message = "We already got one";
|
|
d->c2->handshake_state->received_authenticate = 1)
|
|
static void
|
|
test_link_handshake_auth_already_authenticated(void *arg)
|
|
{
|
|
authenticate_data_t *d = arg;
|
|
setup_capture_of_logs(LOG_INFO);
|
|
d->c2->handshake_state->authenticated = 1;
|
|
channel_tls_process_authenticate_cell(d->cell, d->chan2);
|
|
tt_int_op(mock_close_called, ==, 1);
|
|
tt_int_op(d->c2->handshake_state->authenticated, ==, 1);
|
|
expect_log_msg_containing("The peer is already authenticated");
|
|
done:
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
AUTHENTICATE_FAIL(nocerts,
|
|
require_failure_message = "We never got a certs cell";
|
|
d->c2->handshake_state->received_certs_cell = 0)
|
|
AUTHENTICATE_FAIL(noidcert,
|
|
require_failure_message = "We never got an identity "
|
|
"certificate";
|
|
tor_x509_cert_free(d->c2->handshake_state->certs->id_cert);
|
|
d->c2->handshake_state->certs->id_cert = NULL)
|
|
AUTHENTICATE_FAIL(noauthcert,
|
|
require_failure_message = "We never got an RSA "
|
|
"authentication certificate";
|
|
tor_x509_cert_free(d->c2->handshake_state->certs->auth_cert);
|
|
d->c2->handshake_state->certs->auth_cert = NULL)
|
|
AUTHENTICATE_FAIL(tooshort,
|
|
require_failure_message = "Cell was way too short";
|
|
d->cell->payload_len = 3)
|
|
AUTHENTICATE_FAIL(badtype,
|
|
require_failure_message = "Authenticator type was not "
|
|
"recognized";
|
|
d->cell->payload[0] = 0xff)
|
|
AUTHENTICATE_FAIL(truncated_1,
|
|
require_failure_message = "Authenticator was truncated";
|
|
d->cell->payload[2]++)
|
|
AUTHENTICATE_FAIL(truncated_2,
|
|
require_failure_message = "Authenticator was truncated";
|
|
d->cell->payload[3]++)
|
|
AUTHENTICATE_FAIL(tooshort_1,
|
|
require_failure_message = "Authenticator was too short";
|
|
tt_int_op(d->cell->payload_len, >=, 260);
|
|
d->cell->payload[2] -= 1;
|
|
d->cell->payload_len -= 256;)
|
|
AUTHENTICATE_FAIL(badcontent,
|
|
require_failure_message = "Some field in the AUTHENTICATE "
|
|
"cell body was not as expected";
|
|
d->cell->payload[10] ^= 0xff)
|
|
AUTHENTICATE_FAIL(badsig_1,
|
|
if (d->is_ed)
|
|
require_failure_message = "Ed25519 signature wasn't valid";
|
|
else
|
|
require_failure_message = "RSA signature wasn't valid";
|
|
d->cell->payload[d->cell->payload_len - 5] ^= 0xff)
|
|
AUTHENTICATE_FAIL(missing_ed_id,
|
|
{
|
|
tor_cert_free(d->c2->handshake_state->certs->ed_id_sign);
|
|
d->c2->handshake_state->certs->ed_id_sign = NULL;
|
|
require_failure_message = "Ed authenticate without Ed ID "
|
|
"cert from peer";
|
|
})
|
|
AUTHENTICATE_FAIL(missing_ed_auth,
|
|
{
|
|
tor_cert_free(d->c2->handshake_state->certs->ed_sign_auth);
|
|
d->c2->handshake_state->certs->ed_sign_auth = NULL;
|
|
require_failure_message = "We never got an Ed25519 "
|
|
"authentication certificate";
|
|
})
|
|
|
|
#define TEST_RSA(name, flags) \
|
|
{ #name , test_link_handshake_ ## name, (flags), \
|
|
&passthrough_setup, (void*)"RSA" }
|
|
|
|
#define TEST_ED(name, flags) \
|
|
{ #name "_ed25519" , test_link_handshake_ ## name, (flags), \
|
|
&passthrough_setup, (void*)"Ed25519" }
|
|
|
|
#define TEST_RCV_AUTHCHALLENGE(name) \
|
|
{ "recv_authchallenge/" #name , \
|
|
test_link_handshake_recv_authchallenge_ ## name, TT_FORK, \
|
|
&setup_recv_authchallenge, NULL }
|
|
|
|
#define TEST_RCV_CERTS(name) \
|
|
{ "recv_certs/" #name , \
|
|
test_link_handshake_recv_certs_ ## name, TT_FORK, \
|
|
&setup_recv_certs, (void*)"RSA-Link" }
|
|
|
|
#define TEST_RCV_CERTS_RSA(name,type) \
|
|
{ "recv_certs/" #name , \
|
|
test_link_handshake_recv_certs_ ## name, TT_FORK, \
|
|
&setup_recv_certs, (void*)type }
|
|
|
|
#define TEST_RCV_CERTS_ED(name, type) \
|
|
{ "recv_certs/" #name "_ed25519", \
|
|
test_link_handshake_recv_certs_ ## name, TT_FORK, \
|
|
&setup_recv_certs, (void*)type }
|
|
|
|
#define TEST_AUTHENTICATE(name) \
|
|
{ "authenticate/" #name , test_link_handshake_auth_ ## name, TT_FORK, \
|
|
&setup_authenticate, NULL }
|
|
|
|
#define TEST_AUTHENTICATE_ED(name) \
|
|
{ "authenticate/" #name "_ed25519" , test_link_handshake_auth_ ## name, \
|
|
TT_FORK, &setup_authenticate, (void*)3 }
|
|
|
|
struct testcase_t link_handshake_tests[] = {
|
|
TEST_RSA(certs_ok, TT_FORK),
|
|
TEST_ED(certs_ok, TT_FORK),
|
|
|
|
TEST_RCV_CERTS(ok),
|
|
TEST_RCV_CERTS_ED(ok, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_RSA(ok_server, "RSA-Auth"),
|
|
TEST_RCV_CERTS_ED(ok_server, "Ed25519-Auth"),
|
|
TEST_RCV_CERTS(badstate),
|
|
TEST_RCV_CERTS(badproto),
|
|
TEST_RCV_CERTS(duplicate),
|
|
TEST_RCV_CERTS(already_authenticated),
|
|
TEST_RCV_CERTS(empty),
|
|
TEST_RCV_CERTS(bad_circid),
|
|
TEST_RCV_CERTS(truncated_1),
|
|
TEST_RCV_CERTS(truncated_2),
|
|
TEST_RCV_CERTS(truncated_3),
|
|
TEST_RCV_CERTS_ED(truncated_4, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(truncated_5, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(truncated_6, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(truncated_7, "Ed25519-Link"),
|
|
TEST_RCV_CERTS(not_x509),
|
|
TEST_RCV_CERTS(both_link),
|
|
TEST_RCV_CERTS(both_id_rsa),
|
|
TEST_RCV_CERTS(both_auth),
|
|
TEST_RCV_CERTS_ED(duplicate_id, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(duplicate_link, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(duplicate_crosscert, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(missing_crosscert, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(missing_id, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(missing_signing_key, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(missing_link, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(missing_auth, "Ed25519-Auth"),
|
|
TEST_RCV_CERTS_ED(missing_rsa_id, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(link_mismatch, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(bad_ed_sig, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(bad_rsa_id_cert, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(bad_crosscert, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_RSA(expired_rsa_id, "RSA-Link"),
|
|
TEST_RCV_CERTS_ED(expired_rsa_id, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(expired_ed_id, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(expired_ed_link, "Ed25519-Link"),
|
|
TEST_RCV_CERTS_ED(expired_crosscert, "Ed25519-Link"),
|
|
TEST_RCV_CERTS(wrong_labels_1),
|
|
TEST_RCV_CERTS(wrong_labels_2),
|
|
TEST_RCV_CERTS(wrong_labels_3),
|
|
TEST_RCV_CERTS(server_missing_certs),
|
|
TEST_RCV_CERTS(server_wrong_labels_1),
|
|
|
|
TEST_RSA(send_authchallenge, TT_FORK),
|
|
TEST_RCV_AUTHCHALLENGE(ok),
|
|
TEST_RCV_AUTHCHALLENGE(ok_ed25519),
|
|
TEST_RCV_AUTHCHALLENGE(ok_noserver),
|
|
TEST_RCV_AUTHCHALLENGE(ok_unrecognized),
|
|
TEST_RCV_AUTHCHALLENGE(badstate),
|
|
TEST_RCV_AUTHCHALLENGE(badproto),
|
|
TEST_RCV_AUTHCHALLENGE(as_server),
|
|
TEST_RCV_AUTHCHALLENGE(duplicate),
|
|
TEST_RCV_AUTHCHALLENGE(nocerts),
|
|
TEST_RCV_AUTHCHALLENGE(tooshort),
|
|
TEST_RCV_AUTHCHALLENGE(truncated),
|
|
TEST_RCV_AUTHCHALLENGE(nonzero_circid),
|
|
|
|
TEST_AUTHENTICATE(cell),
|
|
TEST_AUTHENTICATE_ED(cell),
|
|
TEST_AUTHENTICATE(badstate),
|
|
TEST_AUTHENTICATE(badproto),
|
|
TEST_AUTHENTICATE(atclient),
|
|
TEST_AUTHENTICATE(duplicate),
|
|
TEST_AUTHENTICATE(already_authenticated),
|
|
TEST_AUTHENTICATE(nocerts),
|
|
TEST_AUTHENTICATE(noidcert),
|
|
TEST_AUTHENTICATE(noauthcert),
|
|
TEST_AUTHENTICATE(tooshort),
|
|
TEST_AUTHENTICATE(badtype),
|
|
TEST_AUTHENTICATE(truncated_1),
|
|
TEST_AUTHENTICATE(truncated_2),
|
|
TEST_AUTHENTICATE(tooshort_1),
|
|
TEST_AUTHENTICATE(badcontent),
|
|
TEST_AUTHENTICATE(badsig_1),
|
|
TEST_AUTHENTICATE_ED(badsig_1),
|
|
TEST_AUTHENTICATE_ED(missing_ed_id),
|
|
TEST_AUTHENTICATE_ED(missing_ed_auth),
|
|
//TEST_AUTHENTICATE(),
|
|
|
|
END_OF_TESTCASES
|
|
};
|
|
|