|  | @@ -1518,10 +1518,23 @@ 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)
 | 
	
		
			
				|  |  | +find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    const SSL_CIPHER *c;
 | 
	
		
			
				|  |  | -#ifdef HAVE_STRUCT_SSL_METHOD_ST_GET_CIPHER_BY_CHAR
 | 
	
		
			
				|  |  | +#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,2)
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    unsigned char cipherid[3];
 | 
	
		
			
				|  |  | +    tor_assert(ssl);
 | 
	
		
			
				|  |  | +    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 = SSL_CIPHER_find((SSL*)ssl, cipherid);
 | 
	
		
			
				|  |  | +    if (c)
 | 
	
		
			
				|  |  | +      tor_assert((c->id & 0xffff) == cipher);
 | 
	
		
			
				|  |  | +    return c != NULL;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +#elif defined(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));
 | 
	
	
		
			
				|  | @@ -1534,6 +1547,7 @@ find_cipher_by_id(const SSL_METHOD *m, uint16_t cipher)
 | 
	
		
			
				|  |  |      return c != NULL;
 | 
	
		
			
				|  |  |    } else
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | +#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
 | 
	
		
			
				|  |  |    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
 | 
	
	
		
			
				|  | @@ -1547,23 +1561,24 @@ find_cipher_by_id(const SSL_METHOD *m, uint16_t cipher)
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      return 0;
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    return 1; /* No way to search */
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +  (void) ssl;
 | 
	
		
			
				|  |  | +  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. */
 | 
	
		
			
				|  |  |  static void
 | 
	
		
			
				|  |  | -prune_v2_cipher_list(void)
 | 
	
		
			
				|  |  | +prune_v2_cipher_list(const SSL *ssl)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    uint16_t *inp, *outp;
 | 
	
		
			
				|  |  |    const SSL_METHOD *m = SSLv23_method();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    inp = outp = v2_cipher_list;
 | 
	
		
			
				|  |  |    while (*inp) {
 | 
	
		
			
				|  |  | -    if (find_cipher_by_id(m, *inp)) {
 | 
	
		
			
				|  |  | +    if (find_cipher_by_id(ssl, m, *inp)) {
 | 
	
		
			
				|  |  |        *outp++ = *inp++;
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  |        inp++;
 | 
	
	
		
			
				|  | @@ -1585,7 +1600,7 @@ tor_tls_classify_client_ciphers(const SSL *ssl,
 | 
	
		
			
				|  |  |    int i, res;
 | 
	
		
			
				|  |  |    tor_tls_t *tor_tls;
 | 
	
		
			
				|  |  |    if (PREDICT_UNLIKELY(!v2_cipher_list_pruned))
 | 
	
		
			
				|  |  | -    prune_v2_cipher_list();
 | 
	
		
			
				|  |  | +    prune_v2_cipher_list(ssl);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    tor_tls = tor_tls_get_by_ssl(ssl);
 | 
	
		
			
				|  |  |    if (tor_tls && tor_tls->client_cipher_list_type)
 |