[tor-commits] [tor/master] Run correctly on OpenBSD systems without SSL_METHOD.get_cipher_by_char

nickm at torproject.org nickm at torproject.org
Fri Oct 3 23:58:28 UTC 2014


commit d1fa0163e571913b8e4972c5c8a2d46798f46156
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Oct 3 12:15:09 2014 -0400

    Run correctly on OpenBSD systems without SSL_METHOD.get_cipher_by_char
    
    Also, make sure we will compile correctly on systems where they
    finally rip it out.
    
    Fixes issue #13325.  Caused by this openbsd commit:
    
       ​http://marc.info/?l=openbsd-cvs&m=140768179627976&w=2
    
    Reported by Fredzupy.
---
 changes/bug13325    |    4 ++++
 configure.ac        |    4 ++++
 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 0000000..b1da4d0
--- /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 3456013..3548474 100644
--- a/configure.ac
+++ b/configure.ac
@@ -524,6 +524,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 c13b12f..9d45eb0 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -1478,6 +1478,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. */
@@ -1489,16 +1526,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++;





More information about the tor-commits mailing list