From 67964cfa787461bc56380fe46439fd5c9863bb4f Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 14 May 2015 08:42:08 -0400 Subject: [PATCH] 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. --- src/common/tortls.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/common/tortls.c b/src/common/tortls.c index 08966b6419..75d390f909 100644 --- a/src/common/tortls.c +++ b/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); - return tor_tls_classify_client_ciphers(ssl, session->ciphers) >= CIPHERS_V2; +#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, ciphers) >= CIPHERS_V2; } /** Invoked when we're accepting a connection on ssl, and the connection