diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-10-03 19:57:41 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-10-03 19:57:41 -0400 |
commit | d315b8e8bc712f881fcc70624cb135a8e3855f63 (patch) | |
tree | cd6ba7cafb68055bfc730d0b7928956389c478a4 | |
parent | e1a25f0c3602e007872277ef9ab437cc97cfd47b (diff) | |
parent | d1fa0163e571913b8e4972c5c8a2d46798f46156 (diff) | |
download | tor-d315b8e8bc712f881fcc70624cb135a8e3855f63.tar.gz tor-d315b8e8bc712f881fcc70624cb135a8e3855f63.zip |
Merge remote-tracking branch 'public/bug13325_024' into maint-0.2.5
-rw-r--r-- | changes/bug13325 | 4 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/common/tortls.c | 48 |
3 files changed, 46 insertions, 10 deletions
diff --git a/changes/bug13325 b/changes/bug13325 new file mode 100644 index 0000000000..b1da4d0bd5 --- /dev/null +++ b/changes/bug13325 @@ -0,0 +1,4 @@ + o Compilation fixes: + - Build and run correctly on systems like OpenBSD-current that + have patched OpenSSL to remove get_cipher_by_char and/or its + implementations. Fixes issue 13325. diff --git a/configure.ac b/configure.ac index 676fad120e..9da79ac7b1 100644 --- a/configure.ac +++ b/configure.ac @@ -578,6 +578,10 @@ else fi AC_SUBST(TOR_OPENSSL_LIBS) +AC_CHECK_MEMBERS([struct ssl_method_st.get_cipher_by_char], , , +[#include <openssl/ssl.h> +]) + dnl ------------------------------------------------------ dnl Where do you live, zlib? And how do we call you? diff --git a/src/common/tortls.c b/src/common/tortls.c index 4fd9bba380..3ce42a63ac 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -1468,6 +1468,43 @@ static uint16_t v2_cipher_list[] = { /** Have we removed the unrecognized ciphers from v2_cipher_list yet? */ static int v2_cipher_list_pruned = 0; +/** Return 0 if <b>m</b> does not support the cipher with ID <b>cipher</b>; + * return 1 if it does support it, or if we have no way to tell. */ +static int +find_cipher_by_id(const SSL_METHOD *m, uint16_t cipher) +{ + const SSL_CIPHER *c; +#ifdef HAVE_STRUCT_SSL_METHOD_ST_GET_CIPHER_BY_CHAR + if (m && m->get_cipher_by_char) { + unsigned char cipherid[3]; + set_uint16(cipherid, htons(cipher)); + cipherid[2] = 0; /* If ssl23_get_cipher_by_char finds no cipher starting + * with a two-byte 'cipherid', it may look for a v2 + * cipher with the appropriate 3 bytes. */ + c = m->get_cipher_by_char(cipherid); + if (c) + tor_assert((c->id & 0xffff) == cipher); + return c != NULL; + } else +#endif + 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 + * quadratic search. + */ + int i; + for (i = 0; i < m->num_ciphers(); ++i) { + c = m->get_cipher(i); + if (c && (c->id & 0xffff) == cipher) { + return 1; + } + } + return 0; + } else { + return 1; /* No way to search */ + } +} + /** Remove from v2_cipher_list every cipher that we don't support, so that * comparing v2_cipher_list to a client's cipher list will give a sensible * result. */ @@ -1479,16 +1516,7 @@ prune_v2_cipher_list(void) inp = outp = v2_cipher_list; while (*inp) { - unsigned char cipherid[3]; - const SSL_CIPHER *cipher; - /* Is there no better way to do this? */ - set_uint16(cipherid, htons(*inp)); - cipherid[2] = 0; /* If ssl23_get_cipher_by_char finds no cipher starting - * with a two-byte 'cipherid', it may look for a v2 - * cipher with the appropriate 3 bytes. */ - cipher = m->get_cipher_by_char(cipherid); - if (cipher) { - tor_assert((cipher->id & 0xffff) == *inp); + if (find_cipher_by_id(m, *inp)) { *outp++ = *inp++; } else { inp++; |