summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-02-03 14:46:33 -0500
committerNick Mathewson <nickm@torproject.org>2016-02-03 14:46:33 -0500
commita5f7a8b047e3e0e58604b054ef98b998be537523 (patch)
treef95d744e4ee2b233ecaf8e49564a69c8373e80a6
parent957cdb54699937818b539c75e413e88760ee34cd (diff)
parentfa52b6f075a8bb90a3f3a014ef7423940f8a20b7 (diff)
downloadtor-a5f7a8b047e3e0e58604b054ef98b998be537523.tar.gz
tor-a5f7a8b047e3e0e58604b054ef98b998be537523.zip
Merge branch 'openssl_compat'
-rw-r--r--changes/bug17921_bug179844
-rw-r--r--src/common/aes.c31
-rw-r--r--src/common/aes.h1
-rw-r--r--src/common/compat_openssl.h2
-rw-r--r--src/common/crypto.c4
-rw-r--r--src/common/tortls.c18
-rw-r--r--src/common/tortls.h7
-rw-r--r--src/test/test_crypto.c20
-rw-r--r--src/test/test_tortls.c33
9 files changed, 80 insertions, 40 deletions
diff --git a/changes/bug17921_bug17984 b/changes/bug17921_bug17984
new file mode 100644
index 0000000000..f254e295e0
--- /dev/null
+++ b/changes/bug17921_bug17984
@@ -0,0 +1,4 @@
+ o Minor features (compilation):
+ - Tor builds successfully with the unreleased OpenSSL 1.1 alpha
+ releases, and with the latest LibreSSL. Closes tickets 17921 and
+ 17984.
diff --git a/src/common/aes.c b/src/common/aes.c
index 7b6cc39b20..89c99c150a 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -81,47 +81,46 @@
#ifdef USE_EVP_AES_CTR
-struct aes_cnt_cipher {
- EVP_CIPHER_CTX evp;
-};
+/* We don't actually define the struct here. */
aes_cnt_cipher_t *
aes_new_cipher(const char *key, const char *iv)
{
- aes_cnt_cipher_t *cipher;
- cipher = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
- EVP_EncryptInit(&cipher->evp, EVP_aes_128_ctr(),
+ EVP_CIPHER_CTX *cipher = EVP_CIPHER_CTX_new();
+ EVP_EncryptInit(cipher, EVP_aes_128_ctr(),
(const unsigned char*)key, (const unsigned char *)iv);
- return cipher;
+ return (aes_cnt_cipher_t *) cipher;
}
void
-aes_cipher_free(aes_cnt_cipher_t *cipher)
+aes_cipher_free(aes_cnt_cipher_t *cipher_)
{
- if (!cipher)
+ if (!cipher_)
return;
- EVP_CIPHER_CTX_cleanup(&cipher->evp);
- memwipe(cipher, 0, sizeof(aes_cnt_cipher_t));
- tor_free(cipher);
+ EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
+ EVP_CIPHER_CTX_cleanup(cipher);
+ EVP_CIPHER_CTX_free(cipher);
}
void
-aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
+aes_crypt(aes_cnt_cipher_t *cipher_, const char *input, size_t len,
char *output)
{
int outl;
+ EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
tor_assert(len < INT_MAX);
- EVP_EncryptUpdate(&cipher->evp, (unsigned char*)output,
+ EVP_EncryptUpdate(cipher, (unsigned char*)output,
&outl, (const unsigned char *)input, (int)len);
}
void
-aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
+aes_crypt_inplace(aes_cnt_cipher_t *cipher_, char *data, size_t len)
{
int outl;
+ EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
tor_assert(len < INT_MAX);
- EVP_EncryptUpdate(&cipher->evp, (unsigned char*)data,
+ EVP_EncryptUpdate(cipher, (unsigned char*)data,
&outl, (unsigned char*)data, (int)len);
}
int
diff --git a/src/common/aes.h b/src/common/aes.h
index df2f3aa65d..5500db7d0c 100644
--- a/src/common/aes.h
+++ b/src/common/aes.h
@@ -13,7 +13,6 @@
* \brief Headers for aes.c
*/
-struct aes_cnt_cipher;
typedef struct aes_cnt_cipher aes_cnt_cipher_t;
aes_cnt_cipher_t* aes_new_cipher(const char *key, const char *iv);
diff --git a/src/common/compat_openssl.h b/src/common/compat_openssl.h
index 9c98181bdd..d5333a26d6 100644
--- a/src/common/compat_openssl.h
+++ b/src/common/compat_openssl.h
@@ -35,9 +35,11 @@
(((st) == SSL3_ST_SW_SRVR_HELLO_A) || \
((st) == SSL3_ST_SW_SRVR_HELLO_B))
#define OSSL_HANDSHAKE_STATE int
+#define CONST_IF_OPENSSL_1_1_API
#else
#define STATE_IS_SW_SERVER_HELLO(st) \
((st) == TLS_ST_SW_SRVR_HELLO)
+#define CONST_IF_OPENSSL_1_1_API const
#endif
#endif
diff --git a/src/common/crypto.c b/src/common/crypto.c
index a42c461b14..bc659b1935 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -373,8 +373,12 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
used by Tor and the set of algorithms available in the engine */
log_engine("RSA", ENGINE_get_default_RSA());
log_engine("DH", ENGINE_get_default_DH());
+#ifdef OPENSSL_1_1_API
+ log_engine("EC", ENGINE_get_default_EC());
+#else
log_engine("ECDH", ENGINE_get_default_ECDH());
log_engine("ECDSA", ENGINE_get_default_ECDSA());
+#endif
log_engine("RAND", ENGINE_get_default_RAND());
log_engine("RAND (which we will not use)", ENGINE_get_default_RAND());
log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 6e4cd3d480..827abc428d 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -911,7 +911,7 @@ tor_tls_cert_is_valid(int severity,
} else if (cert_key) {
int min_bits = 1024;
#ifdef EVP_PKEY_EC
- if (EVP_PKEY_type(cert_key->type) == EVP_PKEY_EC)
+ if (EVP_PKEY_base_id(cert_key) == EVP_PKEY_EC)
min_bits = 128;
#endif
if (EVP_PKEY_bits(cert_key) >= min_bits)
@@ -1338,7 +1338,7 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher)
return c != NULL;
}
# endif
-# if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
+# ifndef OPENSSL_1_1_API
if (m && m->get_cipher && m->num_ciphers) {
/* It would seem that some of the "let's-clean-up-openssl" forks have
* removed the get_cipher_by_char function. Okay, so now you get a
@@ -1414,7 +1414,7 @@ tor_tls_classify_client_ciphers(const SSL *ssl,
/* Now we need to see if there are any ciphers whose presence means we're
* dealing with an updated Tor. */
for (i = 0; i < sk_SSL_CIPHER_num(peer_ciphers); ++i) {
- SSL_CIPHER *cipher = sk_SSL_CIPHER_value(peer_ciphers, i);
+ const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(peer_ciphers, i);
const char *ciphername = SSL_CIPHER_get_name(cipher);
if (strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA) &&
strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA) &&
@@ -1431,7 +1431,7 @@ tor_tls_classify_client_ciphers(const SSL *ssl,
{
const uint16_t *v2_cipher = v2_cipher_list;
for (i = 0; i < sk_SSL_CIPHER_num(peer_ciphers); ++i) {
- SSL_CIPHER *cipher = sk_SSL_CIPHER_value(peer_ciphers, i);
+ const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(peer_ciphers, i);
uint16_t id = SSL_CIPHER_get_id(cipher) & 0xffff;
if (id == 0x00ff) /* extended renegotiation indicator. */
continue;
@@ -1453,7 +1453,7 @@ tor_tls_classify_client_ciphers(const SSL *ssl,
smartlist_t *elts = smartlist_new();
char *s;
for (i = 0; i < sk_SSL_CIPHER_num(peer_ciphers); ++i) {
- SSL_CIPHER *cipher = sk_SSL_CIPHER_value(peer_ciphers, i);
+ const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(peer_ciphers, i);
const char *ciphername = SSL_CIPHER_get_name(cipher);
smartlist_add(elts, (char*)ciphername);
}
@@ -1562,7 +1562,8 @@ tor_tls_server_info_callback(const SSL *ssl, int type, int val)
STATIC int
tor_tls_session_secret_cb(SSL *ssl, void *secret, int *secret_len,
STACK_OF(SSL_CIPHER) *peer_ciphers,
- SSL_CIPHER **cipher, void *arg)
+ CONST_IF_OPENSSL_1_1_API SSL_CIPHER **cipher,
+ void *arg)
{
(void) secret;
(void) secret_len;
@@ -1733,8 +1734,13 @@ tor_tls_block_renegotiation(tor_tls_t *tls)
void
tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls)
{
+#if defined(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) && \
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION != 0
long options = SSL_get_options(tls->ssl);
tor_assert(0 != (options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
+#else
+ (void) tls;
+#endif
}
/** Return whether this tls initiated the connect (client) or
diff --git a/src/common/tortls.h b/src/common/tortls.h
index 6a4ef9aebe..7239eb9fd7 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -143,9 +143,10 @@ STATIC size_t SSL_SESSION_get_master_key(SSL_SESSION *s, uint8_t *out,
STATIC void tor_tls_debug_state_callback(const SSL *ssl, int type, int val);
STATIC void tor_tls_server_info_callback(const SSL *ssl, int type, int val);
STATIC int tor_tls_session_secret_cb(SSL *ssl, void *secret,
- int *secret_len,
- STACK_OF(SSL_CIPHER) *peer_ciphers,
- SSL_CIPHER **cipher, void *arg);
+ int *secret_len,
+ STACK_OF(SSL_CIPHER) *peer_ciphers,
+ CONST_IF_OPENSSL_1_1_API SSL_CIPHER **cipher,
+ void *arg);
STATIC int find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m,
uint16_t cipher);
MOCK_DECL(STATIC X509*, tor_tls_create_certificate,(crypto_pk_t *rsa,
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index fb21f3ad09..671ae7d7b2 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -147,8 +147,14 @@ test_crypto_rng_engine(void *arg)
/* We should correct the method if it's a dummy. */
RAND_set_rand_method(&dummy_method);
+#ifdef LIBRESSL_VERSION_NUMBER
+ /* On libressl, you can't override the RNG. */
+ tt_assert(RAND_get_rand_method() == RAND_OpenSSL());
+ tt_int_op(0, ==, crypto_force_rand_ssleay());
+#else
tt_assert(RAND_get_rand_method() == &dummy_method);
tt_int_op(1, ==, crypto_force_rand_ssleay());
+#endif
tt_assert(RAND_get_rand_method() == RAND_OpenSSL());
/* Make sure we aren't calling dummy_method */
@@ -1108,6 +1114,11 @@ test_crypto_digests(void *arg)
crypto_pk_free(k);
}
+#ifndef OPENSSL_1_1_API
+#define EVP_ENCODE_CTX_new() tor_malloc_zero(sizeof(EVP_ENCODE_CTX))
+#define EVP_ENCODE_CTX_free(ctx) tor_free(ctx)
+#endif
+
/** Encode src into dest with OpenSSL's EVP Encode interface, returning the
* length of the encoded data in bytes.
*/
@@ -1115,12 +1126,13 @@ static int
base64_encode_evp(char *dest, char *src, size_t srclen)
{
const unsigned char *s = (unsigned char*)src;
- EVP_ENCODE_CTX ctx;
+ EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
int len, ret;
- EVP_EncodeInit(&ctx);
- EVP_EncodeUpdate(&ctx, (unsigned char *)dest, &len, s, (int)srclen);
- EVP_EncodeFinal(&ctx, (unsigned char *)(dest + len), &ret);
+ EVP_EncodeInit(ctx);
+ EVP_EncodeUpdate(ctx, (unsigned char *)dest, &len, s, (int)srclen);
+ EVP_EncodeFinal(ctx, (unsigned char *)(dest + len), &ret);
+ EVP_ENCODE_CTX_free(ctx);
return ret+ len;
}
diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c
index 98f5facc11..71b3863963 100644
--- a/src/test/test_tortls.c
+++ b/src/test/test_tortls.c
@@ -1347,11 +1347,10 @@ test_tortls_get_buffer_sizes(void *ignored)
tls->ssl->s3->wbuf.offset = 0;
tls->ssl->s3->wbuf.left = 43;
+ ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
- ret = tor_tls_get_buffer_sizes(NULL, NULL, NULL, NULL, NULL);
tt_int_op(ret, OP_EQ, -1);
#else
- ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
tt_int_op(ret, OP_EQ, 0);
tt_int_op(rbuf_c, OP_EQ, 0);
tt_int_op(wbuf_c, OP_EQ, 0);
@@ -1601,12 +1600,19 @@ test_tortls_block_renegotiation(void *ignored)
tls = tor_malloc_zero(sizeof(tor_tls_t));
tls->ssl = tor_malloc_zero(sizeof(SSL));
tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
- tls->ssl->s3->flags = 0x0010;
+#ifndef SUPPORT_UNSAFE_RENEGOTIATION_FLAG
+#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0
+#endif
- tor_tls_block_renegotiation(tls);
+ tls->ssl->s3->flags = SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
- tt_assert(!(SSL_get_options(tls->ssl) & 0x0010));
+ tor_tls_block_renegotiation(tls);
+#ifndef OPENSSL_1_1_API
+ tt_assert(!(tls->ssl->s3->flags &
+ SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
+#endif
+
done:
tor_free(tls->ssl->s3);
tor_free(tls->ssl);
@@ -1623,7 +1629,9 @@ test_tortls_unblock_renegotiation(void *ignored)
tls->ssl = tor_malloc_zero(sizeof(SSL));
tor_tls_unblock_renegotiation(tls);
- tt_assert(SSL_get_options(tls->ssl) & 0x00040000L);
+ tt_uint_op(SSL_get_options(tls->ssl) &
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, OP_EQ,
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
done:
tor_free(tls->ssl);
@@ -1907,6 +1915,7 @@ fixed_ssl_shutdown(SSL *s)
return fixed_ssl_shutdown_result;
}
+#ifndef LIBRESSL_VERSION_NUMBER
static int fixed_ssl_state_to_set;
static tor_tls_t *fixed_tls;
@@ -1924,6 +1933,7 @@ setting_version_and_state_ssl_shutdown(SSL *s)
s->version = SSL2_VERSION;
return fixed_ssl_shutdown_result;
}
+#endif
static int
dummy_handshake_func(SSL *s)
@@ -1957,6 +1967,7 @@ test_tortls_shutdown(void *ignored)
ret = tor_tls_shutdown(tls);
tt_int_op(ret, OP_EQ, -9);
+#ifndef LIBRESSL_VERSION_NUMBER
tls->ssl->handshake_func = dummy_handshake_func;
fixed_ssl_read_result_index = 0;
@@ -2018,6 +2029,7 @@ test_tortls_shutdown(void *ignored)
method->ssl_shutdown = setting_version_and_state_ssl_shutdown;
ret = tor_tls_shutdown(tls);
tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
+#endif
done:
teardown_capture_of_logs(previous_log);
@@ -2080,6 +2092,7 @@ test_tortls_read(void *ignored)
ret = tor_tls_read(tls, buf, 10);
tt_int_op(negotiated_callback_called, OP_EQ, 1);
+#ifndef LIBRESSL_VERSION_NUMBER
fixed_ssl_read_result_index = 0;
fixed_ssl_read_result[0] = 0;
tls->ssl->version = SSL2_VERSION;
@@ -2087,7 +2100,7 @@ test_tortls_read(void *ignored)
ret = tor_tls_read(tls, buf, 10);
tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
-
+#endif
// TODO: fill up
done:
@@ -2594,14 +2607,14 @@ test_tortls_create_certificate(void *ignored)
tt_assert(!ret);
fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = tor_malloc_zero(sizeof(EVP_PKEY));
+ fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
fixed_crypto_pk_get_evp_pkey_result[1] = NULL;
ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
tt_assert(!ret);
fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = tor_malloc_zero(sizeof(EVP_PKEY));
- fixed_crypto_pk_get_evp_pkey_result[1] = tor_malloc_zero(sizeof(EVP_PKEY));
+ fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
+ fixed_crypto_pk_get_evp_pkey_result[1] = EVP_PKEY_new();
ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
tt_assert(!ret);