Browse Source

Try using SSL_get_ciphers in place of session->ciphers

This should help openssl 1.1.  On pre-1.1, we double-check that these
two methods give us the same list, since the underlying code is awfully
hairy.
Nick Mathewson 9 years ago
parent
commit
67964cfa78
1 changed files with 29 additions and 5 deletions
  1. 29 5
      src/common/tortls.c

+ 29 - 5
src/common/tortls.c

@@ -1663,13 +1663,37 @@ tor_tls_classify_client_ciphers(const SSL *ssl,
 static int
 tor_tls_client_is_using_v2_ciphers(const SSL *ssl)
 {
-  SSL_SESSION *session;
-  if (!(session = SSL_get_session((SSL *)ssl))) {
-    log_info(LD_NET, "No session on TLS?");
-    return CIPHERS_ERR;
+  STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl);
+
+#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
+  {
+    SSL_SESSION *session;
+    STACK_OF(SSL_CIPHER) *c1;
+    int i;
+    if (!(session = SSL_get_session((SSL *)ssl))) {
+      log_info(LD_NET, "No session on TLS?");
+      return CIPHERS_ERR;
+    }
+    c1 = session->ciphers;
+
+    if (sk_SSL_CIPHER_num(c1) != sk_SSL_CIPHER_num(ciphers)) {
+      log_warn(LD_BUG, "Whoops. session->ciphers doesn't "
+               "match SSL_get_ciphers()");
+      return 0;
+    }
+    for (i = 0; i < sk_SSL_CIPHER_num(c1); ++i) {
+      SSL_CIPHER *a = sk_SSL_CIPHER_value(ciphers, i);
+      SSL_CIPHER *b = sk_SSL_CIPHER_value(c1, i);
+      if (a->id != b->id) {
+        log_warn(LD_BUG, "Cipher mismatch between session->ciphers and "
+                 "SSL_get_ciphers() at %d: %u vs %u", i,
+                 (unsigned)a, (unsigned)b);
+      }
+    }
   }
+#endif
 
-  return tor_tls_classify_client_ciphers(ssl, session->ciphers) >= CIPHERS_V2;
+  return tor_tls_classify_client_ciphers(ssl, ciphers) >= CIPHERS_V2;
 }
 
 /** Invoked when we're accepting a connection on <b>ssl</b>, and the connection