From 3b9c502ff5c98856d4f8fdb7ed3c6ef34448bfb7 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Tue, 7 Feb 2017 09:19:18 +0100 Subject: [PATCH] crypto: add support for OpenSSL 1.1 In OpenSSL 1.1 BN and SSL are opaque structures. * BN_set0_pqg() has been implemented in 1.1 * SSL_is_server() has been implemented in 1.0.2 and 1.1 Reported-by: Vasiliy Glazov Closes: https://github.com/eiskaltdcpp/eiskaltdcpp/issues/356 Signed-off-by: Igor Gnatenko --- dcpp/CryptoManager.cpp | 15 +++++++++++---- dcpp/SSLSocket.cpp | 11 +++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/dcpp/CryptoManager.cpp b/dcpp/CryptoManager.cpp index 08893a75c..b672d92f4 100644 --- a/dcpp/CryptoManager.cpp +++ b/dcpp/CryptoManager.cpp @@ -27,12 +27,20 @@ #include "version.h" #include - +#include #include namespace dcpp { - +static const char ciphersuites[] = + "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:" + "ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:" + "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:" + "ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:" + "ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:" + "DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:" + "AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:AES128-SHA" + "!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"; CryptoManager::CryptoManager() : @@ -42,10 +50,10 @@ { SSL_library_init(); - clientContext.reset(SSL_CTX_new(TLSv1_client_method())); - clientVerContext.reset(SSL_CTX_new(TLSv1_client_method())); - serverContext.reset(SSL_CTX_new(TLSv1_server_method())); - serverVerContext.reset(SSL_CTX_new(TLSv1_server_method())); + clientContext.reset(SSL_CTX_new(SSLv23_client_method())); + clientVerContext.reset(SSL_CTX_new(SSLv23_client_method())); + serverContext.reset(SSL_CTX_new(SSLv23_server_method())); + serverVerContext.reset(SSL_CTX_new(SSLv23_server_method())); if(clientContext && clientVerContext && serverContext && serverVerContext) { dh.reset(DH_new()); @@ -101,10 +109,15 @@ }; if(dh) { - dh->p = BN_bin2bn(dh4096_p, sizeof(dh4096_p), 0); - dh->g = BN_bin2bn(dh4096_g, sizeof(dh4096_g), 0); - + BIGNUM *p = BN_bin2bn(dh4096_p, sizeof(dh4096_p), 0); + BIGNUM *g = BN_bin2bn(dh4096_g, sizeof(dh4096_g), 0); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + dh->p = p; + dh->g = g; if (!dh->p || !dh->g) { +#else + if (!DH_set0_pqg(dh, p, NULL, g)) { +#endif dh.reset(); } else { SSL_CTX_set_options(serverContext, SSL_OP_SINGLE_DH_USE); @@ -112,6 +125,28 @@ SSL_CTX_set_tmp_dh(serverContext, (DH*)dh); SSL_CTX_set_tmp_dh(serverVerContext, (DH*)dh); } + BN_free(p); + BN_free(g); + } + + SSL_CTX_set_options(clientContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); + SSL_CTX_set_cipher_list(clientContext, ciphersuites); + SSL_CTX_set_options(serverContext, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); + SSL_CTX_set_cipher_list(serverContext, ciphersuites); + SSL_CTX_set_options(clientVerContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); + SSL_CTX_set_cipher_list(clientVerContext, ciphersuites); + SSL_CTX_set_options(serverVerContext, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); + SSL_CTX_set_cipher_list(serverVerContext, ciphersuites); + + EC_KEY* tmp_ecdh; + /* NID_X9_62_prime256v1 is not secure, more secure is NID_secp384r1 or NID_secp521r1*/ + if((tmp_ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)) != NULL) { + SSL_CTX_set_options(serverContext, SSL_OP_SINGLE_ECDH_USE); + SSL_CTX_set_tmp_ecdh(serverContext, tmp_ecdh); + SSL_CTX_set_options(serverVerContext, SSL_OP_SINGLE_ECDH_USE); + SSL_CTX_set_tmp_ecdh(serverVerContext, tmp_ecdh); + + EC_KEY_free(tmp_ecdh); } SSL_CTX_set_verify(serverContext, SSL_VERIFY_NONE, 0); diff --git a/dcpp/SSLSocket.cpp b/dcpp/SSLSocket.cpp index 1e283eec8..d4dc12388 100644 --- a/dcpp/SSLSocket.cpp +++ b/dcpp/SSLSocket.cpp @@ -37,6 +37,13 @@ void SSLSocket::connect(const string& aIp, uint16_t aPort) { waitConnected(0); } +#if OPENSSL_VERSION_NUMBER < 0x10002000L +static inline int SSL_is_server(SSL *s) +{ + return s->server; +} +#endif + bool SSLSocket::waitConnected(uint32_t millis) { if(!ssl) { if(!Socket::waitConnected(millis)) { @@ -54,9 +61,9 @@ bool SSLSocket::waitConnected(uint32_t millis) { } while(true) { - int ret = ssl->server?SSL_accept(ssl):SSL_connect(ssl); + int ret = SSL_is_server(ssl)?SSL_accept(ssl):SSL_connect(ssl); if(ret == 1) { - dcdebug("Connected to SSL server using %s as %s\n", SSL_get_cipher(ssl), ssl->server?"server":"client"); + dcdebug("Connected to SSL server using %s as %s\n", SSL_get_cipher(ssl), SSL_is_server(ssl)?"server":"client"); return true; } if(!waitWant(ret, millis)) {