Commit d52f4060 authored by Nick Mathewson's avatar Nick Mathewson 🥔
Browse files

Merge branch 'maint-0.2.9' into maint-0.3.2

parents c798957b 85a87923
Loading
Loading
Loading
Loading

changes/bug27226

0 → 100644
+5 −0
Original line number Diff line number Diff line
  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.
+6 −4
Original line number Diff line number Diff line
@@ -896,18 +896,20 @@ tor_tls_cert_get_key(tor_x509_cert_t *cert)
MOCK_IMPL(int,
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;
  int result;

  if (!peercert)
    return 0;
  link_key = X509_get_pubkey(peercert);
  cert_key = X509_get_pubkey(cert->cert);

  result = link_key && cert_key && EVP_PKEY_cmp(cert_key, link_key) == 1;

  X509_free(peercert);
  tor_x509_cert_free(peer);
  if (link_key)
    EVP_PKEY_free(link_key);
  if (cert_key)
+60 −59
Original line number Diff line number Diff line
@@ -547,13 +547,6 @@ test_tortls_x509_cert_get_id_digests(void *ignored)
}

#ifndef OPENSSL_OPAQUE
static int
fixed_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
  (void) a; (void) b;
  return 1;
}

static void
fake_x509_free(X509 *cert)
{
@@ -570,70 +563,78 @@ fake_x509_free(X509 *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
test_tortls_cert_matches_key(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));
  cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
  one = tor_malloc_zero(sizeof(X509));
  one->references = 1;
  two = tor_malloc_zero(sizeof(X509));
  two->references = 1;
  X509 *cert1 = NULL, *cert2 = NULL, *cert3 = NULL, *cert4 = NULL;
  tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
  crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;

  res = tor_tls_cert_matches_key(tls, cert);
  tt_int_op(res, OP_EQ, 0);
  k1 = pk_generate(1);
  k2 = pk_generate(2);
  k3 = pk_generate(3);

  tls->ssl = tor_malloc_zero(sizeof(SSL));
  tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
  tls->ssl->session->peer = one;
  res = tor_tls_cert_matches_key(tls, cert);
  tt_int_op(res, OP_EQ, 0);

  cert->cert = two;
  res = tor_tls_cert_matches_key(tls, cert);
  tt_int_op(res, OP_EQ, 0);

  one->cert_info = tor_malloc_zero(sizeof(X509_CINF));
  one->cert_info->key = tor_malloc_zero(sizeof(X509_PUBKEY));
  one->cert_info->key->pkey = tor_malloc_zero(sizeof(EVP_PKEY));
  one->cert_info->key->pkey->references = 1;
  one->cert_info->key->pkey->ameth = meth;
  one->cert_info->key->pkey->type = 1;

  two->cert_info = tor_malloc_zero(sizeof(X509_CINF));
  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);
  tt_int_op(res, OP_EQ, 0);

  one->cert_info->key->pkey->type = 1;
  two->cert_info->key->pkey->type = 1;
  res = tor_tls_cert_matches_key(tls, cert);
  tt_int_op(res, OP_EQ, 1);
  cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
  cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
  cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
  cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);

  tt_assert(cert1 && cert2 && cert3 && cert4);

  c1 = tor_x509_cert_new(cert1); cert1 = NULL;
  c2 = tor_x509_cert_new(cert2); cert2 = NULL;
  c3 = tor_x509_cert_new(cert3); cert3 = NULL;
  c4 = tor_x509_cert_new(cert4); cert4 = NULL;

  tt_assert(c1 && c2 && c3 && c4);

  MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);

  fixed_x509_cert = NULL;
  /* If the peer has no certificate, it shouldn't match anything. */
  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));
  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:
  EVP_PKEY_asn1_free(meth);
  tor_free(tls->ssl->session);
  tor_free(tls->ssl);
  tor_free(tls);
  tor_free(cert);
  fake_x509_free(one);
  fake_x509_free(two);
  tor_x509_cert_free(c1);
  tor_x509_cert_free(c2);
  tor_x509_cert_free(c3);
  tor_x509_cert_free(c4);
  if (cert1) X509_free(cert1);
  if (cert2) X509_free(cert2);
  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
test_tortls_cert_get_key(void *ignored)
{