Merge branch 'maint-0.3.3' into maint-0.3.4

This commit is contained in:
Nick Mathewson 2018-08-21 19:20:31 -04:00
commit f68aab83ba
3 changed files with 67 additions and 60 deletions

5
changes/bug27226 Normal file
View File

@ -0,0 +1,5 @@
o Minor bugfixes (testing, openssl compatibility):
- Our "tortls/cert_matches_key" unit test no longer relies on OpenSSL
internals. Previously, it relied on unsupported OpenSSL behavior in
a way that caused it to crash with OpenSSL 1.0.2p. Fixes bug 27226;
bugfix on 0.2.5.1-alpha.

View File

@ -917,18 +917,20 @@ tor_tls_cert_get_key(tor_x509_cert_t *cert)
MOCK_IMPL(int, MOCK_IMPL(int,
tor_tls_cert_matches_key,(const tor_tls_t *tls, const tor_x509_cert_t *cert)) tor_tls_cert_matches_key,(const tor_tls_t *tls, const tor_x509_cert_t *cert))
{ {
X509 *peercert = SSL_get_peer_certificate(tls->ssl); tor_x509_cert_t *peer = tor_tls_get_peer_cert((tor_tls_t *)tls);
if (!peer)
return 0;
X509 *peercert = peer->cert;
EVP_PKEY *link_key = NULL, *cert_key = NULL; EVP_PKEY *link_key = NULL, *cert_key = NULL;
int result; int result;
if (!peercert)
return 0;
link_key = X509_get_pubkey(peercert); link_key = X509_get_pubkey(peercert);
cert_key = X509_get_pubkey(cert->cert); cert_key = X509_get_pubkey(cert->cert);
result = link_key && cert_key && EVP_PKEY_cmp(cert_key, link_key) == 1; result = link_key && cert_key && EVP_PKEY_cmp(cert_key, link_key) == 1;
X509_free(peercert); tor_x509_cert_free(peer);
if (link_key) if (link_key)
EVP_PKEY_free(link_key); EVP_PKEY_free(link_key);
if (cert_key) if (cert_key)

View File

@ -553,13 +553,6 @@ test_tortls_x509_cert_get_id_digests(void *ignored)
} }
#ifndef OPENSSL_OPAQUE #ifndef OPENSSL_OPAQUE
static int
fixed_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
(void) a; (void) b;
return 1;
}
/* /*
* Use only for the matching fake_x509_free() call * Use only for the matching fake_x509_free() call
*/ */
@ -585,70 +578,78 @@ fake_x509_free(X509 *cert)
tor_free(cert); tor_free(cert);
} }
} }
#endif
static tor_x509_cert_t *fixed_x509_cert = NULL;
static tor_x509_cert_t *
get_peer_cert_mock_return_fixed(tor_tls_t *tls)
{
(void)tls;
if (fixed_x509_cert)
return tor_x509_cert_dup(fixed_x509_cert);
else
return NULL;
}
static void static void
test_tortls_cert_matches_key(void *ignored) test_tortls_cert_matches_key(void *ignored)
{ {
(void)ignored; (void)ignored;
int res;
tor_tls_t *tls;
tor_x509_cert_t *cert;
X509 *one = NULL, *two = NULL;
EVP_PKEY_ASN1_METHOD *meth = EVP_PKEY_asn1_new(999, 0, NULL, NULL);
EVP_PKEY_asn1_set_public(meth, NULL, NULL, fixed_pub_cmp, NULL, NULL, NULL);
tls = tor_malloc_zero(sizeof(tor_tls_t)); X509 *cert1 = NULL, *cert2 = NULL, *cert3 = NULL, *cert4 = NULL;
cert = tor_malloc_zero(sizeof(tor_x509_cert_t)); tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
one = fake_x509_malloc(); crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;
one->references = 1;
two = fake_x509_malloc();
two->references = 1;
res = tor_tls_cert_matches_key(tls, cert); k1 = pk_generate(1);
tt_int_op(res, OP_EQ, 0); k2 = pk_generate(2);
k3 = pk_generate(3);
tls->ssl = tor_malloc_zero(sizeof(SSL)); cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION)); cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
tls->ssl->session->peer = one; cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
res = tor_tls_cert_matches_key(tls, cert); cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);
tt_int_op(res, OP_EQ, 0);
cert->cert = two; tt_assert(cert1 && cert2 && cert3 && cert4);
res = tor_tls_cert_matches_key(tls, cert);
tt_int_op(res, OP_EQ, 0);
one->cert_info = tor_malloc_zero(sizeof(X509_CINF)); c1 = tor_x509_cert_new(cert1); cert1 = NULL;
one->cert_info->key = tor_malloc_zero(sizeof(X509_PUBKEY)); c2 = tor_x509_cert_new(cert2); cert2 = NULL;
one->cert_info->key->pkey = tor_malloc_zero(sizeof(EVP_PKEY)); c3 = tor_x509_cert_new(cert3); cert3 = NULL;
one->cert_info->key->pkey->references = 1; c4 = tor_x509_cert_new(cert4); cert4 = NULL;
one->cert_info->key->pkey->ameth = meth;
one->cert_info->key->pkey->type = 1;
two->cert_info = tor_malloc_zero(sizeof(X509_CINF)); tt_assert(c1 && c2 && c3 && c4);
two->cert_info->key = tor_malloc_zero(sizeof(X509_PUBKEY));
two->cert_info->key->pkey = tor_malloc_zero(sizeof(EVP_PKEY));
two->cert_info->key->pkey->references = 1;
two->cert_info->key->pkey->ameth = meth;
two->cert_info->key->pkey->type = 2;
res = tor_tls_cert_matches_key(tls, cert); MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);
tt_int_op(res, OP_EQ, 0);
one->cert_info->key->pkey->type = 1; fixed_x509_cert = NULL;
two->cert_info->key->pkey->type = 1; /* If the peer has no certificate, it shouldn't match anything. */
res = tor_tls_cert_matches_key(tls, cert); tt_assert(! tor_tls_cert_matches_key(NULL, c1));
tt_int_op(res, OP_EQ, 1); tt_assert(! tor_tls_cert_matches_key(NULL, c2));
tt_assert(! tor_tls_cert_matches_key(NULL, c3));
tt_assert(! tor_tls_cert_matches_key(NULL, c4));
fixed_x509_cert = c1;
/* If the peer has a certificate, it should match every cert with the same
* subject key. */
tt_assert(tor_tls_cert_matches_key(NULL, c1));
tt_assert(tor_tls_cert_matches_key(NULL, c2));
tt_assert(! tor_tls_cert_matches_key(NULL, c3));
tt_assert(! tor_tls_cert_matches_key(NULL, c4));
done: done:
EVP_PKEY_asn1_free(meth); tor_x509_cert_free(c1);
tor_free(tls->ssl->session); tor_x509_cert_free(c2);
tor_free(tls->ssl); tor_x509_cert_free(c3);
tor_free(tls); tor_x509_cert_free(c4);
tor_free(cert); if (cert1) X509_free(cert1);
fake_x509_free(one); if (cert2) X509_free(cert2);
fake_x509_free(two); if (cert3) X509_free(cert3);
if (cert4) X509_free(cert4);
crypto_pk_free(k1);
crypto_pk_free(k2);
crypto_pk_free(k3);
UNMOCK(tor_tls_get_peer_cert);
} }
#ifndef OPENSSL_OPAQUE
static void static void
test_tortls_cert_get_key(void *ignored) test_tortls_cert_get_key(void *ignored)
{ {
@ -2795,7 +2796,7 @@ struct testcase_t tortls_tests[] = {
LOCAL_TEST_CASE(always_accept_verify_cb, 0), LOCAL_TEST_CASE(always_accept_verify_cb, 0),
INTRUSIVE_TEST_CASE(x509_cert_free, 0), INTRUSIVE_TEST_CASE(x509_cert_free, 0),
LOCAL_TEST_CASE(x509_cert_get_id_digests, 0), LOCAL_TEST_CASE(x509_cert_get_id_digests, 0),
INTRUSIVE_TEST_CASE(cert_matches_key, 0), LOCAL_TEST_CASE(cert_matches_key, 0),
INTRUSIVE_TEST_CASE(cert_get_key, 0), INTRUSIVE_TEST_CASE(cert_get_key, 0),
LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK), LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK),
LOCAL_TEST_CASE(get_my_certs, TT_FORK), LOCAL_TEST_CASE(get_my_certs, TT_FORK),
@ -2839,4 +2840,3 @@ struct testcase_t tortls_tests[] = {
LOCAL_TEST_CASE(context_init_one, 0), LOCAL_TEST_CASE(context_init_one, 0),
END_OF_TESTCASES END_OF_TESTCASES
}; };