From 82c6c5f1499d19403360557ef522840031b52118 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Tue, 19 Jan 2016 15:19:14 +0100 Subject: [PATCH] added support for ECDH, new Context ctor --- NetSSL_OpenSSL/include/Poco/Net/Context.h | 64 +++- NetSSL_OpenSSL/include/Poco/Net/SSLManager.h | 8 + NetSSL_OpenSSL/src/Context.cpp | 340 +++++++++++++------ NetSSL_OpenSSL/src/SSLManager.cpp | 31 +- 4 files changed, 318 insertions(+), 125 deletions(-) diff --git a/NetSSL_OpenSSL/include/Poco/Net/Context.h b/NetSSL_OpenSSL/include/Poco/Net/Context.h index 805885381..4d57b3f6e 100644 --- a/NetSSL_OpenSSL/include/Poco/Net/Context.h +++ b/NetSSL_OpenSSL/include/Poco/Net/Context.h @@ -104,6 +104,58 @@ public: PROTO_TLSV1_1 = 0x08, PROTO_TLSV1_2 = 0x10 }; + + struct Params + { + Params(); + /// Initializes the struct with default values. + + std::string privateKeyFile; + /// Path to the private key file used for encryption. + /// Can be empty if no private key file is used. + + std::string certificateFile; + /// Path to the certificate file (in PEM format). + /// If the private key and the certificate are stored in the same file, this + /// can be empty if privateKeyFile is given. + + std::string caLocation; + /// Path to the file or directory containing the CA/root certificates. + /// Can be empty if the OpenSSL builtin CA certificates + /// are used (see loadDefaultCAs). + + VerificationMode verificationMode; + /// Specifies whether and how peer certificates are validated. + /// Defaults to VERIFY_RELAXED. + + int verificationDepth; + /// Sets the upper limit for verification chain sizes. Verification + /// will fail if a certificate chain larger than this is encountered. + /// Defaults to 9. + + bool loadDefaultCAs; + /// Specifies whether the builtin CA certificates from OpenSSL are used. + /// Defaults to false. + + std::string cipherList; + /// Specifies the supported ciphers in OpenSSL notation. + /// Defaults to "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH". + + std::string dhParamsFile; + /// Specifies a file containing Diffie-Hellman parameters. + /// If empty, the default parameters are used. + + std::string ecdhCurve; + /// Specifies the name of the curve to use for ECDH, based + /// on the curve names specified in RFC 4492. + /// Defaults to "prime256v1". + }; + + Context(Usage usage, const Params& params); + /// Creates a Context using the given parameters. + /// + /// * usage specifies whether the context is used by a client or server. + /// * params specifies the context parameters. Context( Usage usage, @@ -281,9 +333,19 @@ public: /// The protocols to be disabled are specified by OR-ing /// values from the Protocols enumeration, e.g.: /// - /// context.disableProtocols(PROTO_SSLV2 | PROTO_SSLV3) + /// context.disableProtocols(PROTO_SSLV2 | PROTO_SSLV3); private: + void init(const Params& params); + /// Initializes the Context with the given parameters. + + void initDH(const std::string& dhFile); + /// Initializes the Context with Diffie-Hellman parameters. + + void initECDH(const std::string& curve); + /// Initializes the Context with Elliptic-Curve Diffie-Hellman key + /// exchange curve parameters. + void createSSLContext(); /// Create a SSL_CTX object according to Context configuration. diff --git a/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h b/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h index 058c73bac..df9f27716 100644 --- a/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h +++ b/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h @@ -95,6 +95,8 @@ class NetSSL_API SSLManager /// true|false /// true|false /// sslv2,sslv3,tlsv1,tlsv1_1,tlsv1_2 + /// dh.pem + /// prime256v1 /// /// false /// @@ -140,6 +142,10 @@ class NetSSL_API SSLManager /// - requireTLSv1_2 (boolean): Require a TLSv1.2 connection. /// - disableProtocols (string): A comma-separated list of protocols that should be /// disabled. Valid protocol names are sslv2, sslv3, tlsv1, tlsv1_1, tlsv1_2. + /// - dhParamsFile (string): Specifies a file containing Diffie-Hellman parameters. + /// If not specified or empty, the default parameters are used. + /// - ecdhCurve (string): Specifies the name of the curve to use for ECDH, based + /// on the curve names specified in RFC 4492. Defaults to "prime256v1". /// - fips: Enable or disable OpenSSL FIPS mode. Only supported if the OpenSSL version /// that this library is built against supports FIPS mode. { @@ -324,6 +330,8 @@ private: static const std::string CFG_REQUIRE_TLSV1_1; static const std::string CFG_REQUIRE_TLSV1_2; static const std::string CFG_DISABLE_PROTOCOLS; + static const std::string CFG_DH_PARAMS_FILE; + static const std::string CFG_ECDH_CURVE; #ifdef OPENSSL_FIPS static const std::string CFG_FIPS_MODE; diff --git a/NetSSL_OpenSSL/src/Context.cpp b/NetSSL_OpenSSL/src/Context.cpp index 7a79cf0d0..f8b606e8b 100644 --- a/NetSSL_OpenSSL/src/Context.cpp +++ b/NetSSL_OpenSSL/src/Context.cpp @@ -32,6 +32,25 @@ namespace Poco { namespace Net { +Context::Params::Params(): + verificationMode(VERIFY_RELAXED), + verificationDepth(9), + loadDefaultCAs(false), + cipherList("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") +{ +} + + +Context::Context(Usage usage, const Params& params): + _usage(usage), + _mode(params.verificationMode), + _pSSLContext(0), + _extendedCertificateVerification(true) +{ + init(params); +} + + Context::Context( Usage usage, const std::string& privateKeyFile, @@ -46,72 +65,15 @@ Context::Context( _pSSLContext(0), _extendedCertificateVerification(true) { - Poco::Crypto::OpenSSLInitializer::initialize(); - - createSSLContext(); - - try - { - int errCode = 0; - if (!caLocation.empty()) - { - Poco::File aFile(caLocation); - if (aFile.isDirectory()) - errCode = SSL_CTX_load_verify_locations(_pSSLContext, 0, Poco::Path::transcode(caLocation).c_str()); - else - errCode = SSL_CTX_load_verify_locations(_pSSLContext, Poco::Path::transcode(caLocation).c_str(), 0); - if (errCode != 1) - { - std::string msg = Utility::getLastError(); - throw SSLContextException(std::string("Cannot load CA file/directory at ") + caLocation, msg); - } - } - - if (loadDefaultCAs) - { - errCode = SSL_CTX_set_default_verify_paths(_pSSLContext); - if (errCode != 1) - { - std::string msg = Utility::getLastError(); - throw SSLContextException("Cannot load default CA certificates", msg); - } - } - - if (!privateKeyFile.empty()) - { - errCode = SSL_CTX_use_PrivateKey_file(_pSSLContext, Poco::Path::transcode(privateKeyFile).c_str(), SSL_FILETYPE_PEM); - if (errCode != 1) - { - std::string msg = Utility::getLastError(); - throw SSLContextException(std::string("Error loading private key from file ") + privateKeyFile, msg); - } - } - - if (!certificateFile.empty()) - { - errCode = SSL_CTX_use_certificate_chain_file(_pSSLContext, Poco::Path::transcode(certificateFile).c_str()); - if (errCode != 1) - { - std::string errMsg = Utility::getLastError(); - throw SSLContextException(std::string("Error loading certificate from file ") + certificateFile, errMsg); - } - } - - if (isForServerUse()) - SSL_CTX_set_verify(_pSSLContext, verificationMode, &SSLManager::verifyServerCallback); - else - SSL_CTX_set_verify(_pSSLContext, verificationMode, &SSLManager::verifyClientCallback); - - SSL_CTX_set_cipher_list(_pSSLContext, cipherList.c_str()); - SSL_CTX_set_verify_depth(_pSSLContext, verificationDepth); - SSL_CTX_set_mode(_pSSLContext, SSL_MODE_AUTO_RETRY); - SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_OFF); - } - catch (...) - { - SSL_CTX_free(_pSSLContext); - throw; - } + Params params; + params.privateKeyFile = privateKeyFile; + params.certificateFile = certificateFile; + params.caLocation = caLocation; + params.verificationMode = verificationMode; + params.verificationDepth = verificationDepth; + params.loadDefaultCAs = loadDefaultCAs; + params.cipherList = cipherList; + init(params); } @@ -127,52 +89,13 @@ Context::Context( _pSSLContext(0), _extendedCertificateVerification(true) { - Poco::Crypto::OpenSSLInitializer::initialize(); - - createSSLContext(); - - try - { - int errCode = 0; - if (!caLocation.empty()) - { - Poco::File aFile(caLocation); - if (aFile.isDirectory()) - errCode = SSL_CTX_load_verify_locations(_pSSLContext, 0, Poco::Path::transcode(caLocation).c_str()); - else - errCode = SSL_CTX_load_verify_locations(_pSSLContext, Poco::Path::transcode(caLocation).c_str(), 0); - if (errCode != 1) - { - std::string msg = Utility::getLastError(); - throw SSLContextException(std::string("Cannot load CA file/directory at ") + caLocation, msg); - } - } - - if (loadDefaultCAs) - { - errCode = SSL_CTX_set_default_verify_paths(_pSSLContext); - if (errCode != 1) - { - std::string msg = Utility::getLastError(); - throw SSLContextException("Cannot load default CA certificates", msg); - } - } - - if (isForServerUse()) - SSL_CTX_set_verify(_pSSLContext, verificationMode, &SSLManager::verifyServerCallback); - else - SSL_CTX_set_verify(_pSSLContext, verificationMode, &SSLManager::verifyClientCallback); - - SSL_CTX_set_cipher_list(_pSSLContext, cipherList.c_str()); - SSL_CTX_set_verify_depth(_pSSLContext, verificationDepth); - SSL_CTX_set_mode(_pSSLContext, SSL_MODE_AUTO_RETRY); - SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_OFF); - } - catch (...) - { - SSL_CTX_free(_pSSLContext); - throw; - } + Params params; + params.caLocation = caLocation; + params.verificationMode = verificationMode; + params.verificationDepth = verificationDepth; + params.loadDefaultCAs = loadDefaultCAs; + params.cipherList = cipherList; + init(params); } @@ -190,6 +113,80 @@ Context::~Context() } +void Context::init(const Params& params) +{ + Poco::Crypto::OpenSSLInitializer::initialize(); + + createSSLContext(); + + try + { + int errCode = 0; + if (!params.caLocation.empty()) + { + Poco::File aFile(params.caLocation); + if (aFile.isDirectory()) + errCode = SSL_CTX_load_verify_locations(_pSSLContext, 0, Poco::Path::transcode(params.caLocation).c_str()); + else + errCode = SSL_CTX_load_verify_locations(_pSSLContext, Poco::Path::transcode(params.caLocation).c_str(), 0); + if (errCode != 1) + { + std::string msg = Utility::getLastError(); + throw SSLContextException(std::string("Cannot load CA file/directory at ") + params.caLocation, msg); + } + } + + if (params.loadDefaultCAs) + { + errCode = SSL_CTX_set_default_verify_paths(_pSSLContext); + if (errCode != 1) + { + std::string msg = Utility::getLastError(); + throw SSLContextException("Cannot load default CA certificates", msg); + } + } + + if (!params.privateKeyFile.empty()) + { + errCode = SSL_CTX_use_PrivateKey_file(_pSSLContext, Poco::Path::transcode(params.privateKeyFile).c_str(), SSL_FILETYPE_PEM); + if (errCode != 1) + { + std::string msg = Utility::getLastError(); + throw SSLContextException(std::string("Error loading private key from file ") + params.privateKeyFile, msg); + } + } + + if (!params.certificateFile.empty()) + { + errCode = SSL_CTX_use_certificate_chain_file(_pSSLContext, Poco::Path::transcode(params.certificateFile).c_str()); + if (errCode != 1) + { + std::string errMsg = Utility::getLastError(); + throw SSLContextException(std::string("Error loading certificate from file ") + params.certificateFile, errMsg); + } + } + + if (isForServerUse()) + SSL_CTX_set_verify(_pSSLContext, params.verificationMode, &SSLManager::verifyServerCallback); + else + SSL_CTX_set_verify(_pSSLContext, params.verificationMode, &SSLManager::verifyClientCallback); + + SSL_CTX_set_cipher_list(_pSSLContext, params.cipherList.c_str()); + SSL_CTX_set_verify_depth(_pSSLContext, params.verificationDepth); + SSL_CTX_set_mode(_pSSLContext, SSL_MODE_AUTO_RETRY); + SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_OFF); + + initDH(params.dhParamsFile); + initECDH(params.ecdhCurve); + } + catch (...) + { + SSL_CTX_free(_pSSLContext); + throw; + } +} + + void Context::useCertificate(const Poco::Crypto::X509Certificate& certificate) { int errCode = SSL_CTX_use_certificate(_pSSLContext, const_cast(certificate.certificate())); @@ -412,4 +409,123 @@ void Context::createSSLContext() } +void Context::initDH(const std::string& dhParamsFile) +{ +#ifndef OPENSSL_NO_DH + // 1024-bit MODP Group with 160-bit prime order subgroup (RFC5114) + // -----BEGIN DH PARAMETERS----- + // MIIBDAKBgQCxC4+WoIDgHd6S3l6uXVTsUsmfvPsGo8aaap3KUtI7YWBz4oZ1oj0Y + // mDjvHi7mUsAT7LSuqQYRIySXXDzUm4O/rMvdfZDEvXCYSI6cIZpzck7/1vrlZEc4 + // +qMaT/VbzMChUa9fDci0vUW/N982XBpl5oz9p21NpwjfH7K8LkpDcQKBgQCk0cvV + // w/00EmdlpELvuZkF+BBN0lisUH/WQGz/FCZtMSZv6h5cQVZLd35pD1UE8hMWAhe0 + // sBuIal6RVH+eJ0n01/vX07mpLuGQnQ0iY/gKdqaiTAh6CR9THb8KAWm2oorWYqTR + // jnOvoy13nVkY0IvIhY9Nzvl8KiSFXm7rIrOy5QICAKA= + // -----END DH PARAMETERS----- + // + + static const unsigned char dh1024_p[] = + { + 0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E, + 0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6, + 0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86, + 0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0, + 0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C, + 0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70, + 0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA, + 0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0, + 0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF, + 0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08, + 0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71, + }; + + static const unsigned char dh1024_g[] = + { + 0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42, + 0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F, + 0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E, + 0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13, + 0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F, + 0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1, + 0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08, + 0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A, + 0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59, + 0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24, + 0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5, + }; + + DH* dh = 0; + if (!dhParamsFile.empty()) + { + BIO* bio = BIO_new_file(dhParamsFile.c_str(), "r"); + if (!bio) + { + std::string msg = Utility::getLastError(); + throw SSLContextException(std::string("Error opening Diffie-Hellman parameters file ") + dhParamsFile, msg); + } + dh = PEM_read_bio_DHparams(bio, 0, 0, 0); + BIO_free(bio); + if (!dh) + { + std::string msg = Utility::getLastError(); + throw SSLContextException(std::string("Error reading Diffie-Hellman parameters from file ") + dhParamsFile, msg); + } + } + else + { + dh = DH_new(); + if (!dh) + { + std::string msg = Utility::getLastError(); + throw SSLContextException("Error creating Diffie-Hellman parameters", msg); + } + dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0); + dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0); + dh->length = 160; + if ((!dh->p) || (!dh->g)) + { + DH_free(dh); + throw SSLContextException("Error creating Diffie-Hellman parameters"); + } + } + SSL_CTX_set_tmp_dh(_pSSLContext, dh); + SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_DH_USE); + DH_free(dh); +#else + if (!dhParamsFile.empty()) + throw SSLContextException("OpenSSL does not support DH"); +#endif +} + + +void Context::initECDH(const std::string& curve) +{ +#if OPENSSL_VERSION_NUMBER >= 0x0090800fL +#ifndef OPENSSL_NO_ECDH + int nid = 0; + if (!curve.empty()) + { + nid = OBJ_sn2nid(curve.c_str()); + } + else + { + nid = OBJ_sn2nid("prime256v1"); + } + if (nid == 0) + { + throw SSLContextException("Unknown ECDH curve name", curve); + } + + EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid); + if (!ecdh) + { + throw SSLContextException("Cannot create ECDH curve"); + } + SSL_CTX_set_tmp_ecdh(_pSSLContext, ecdh); + SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_ECDH_USE); + EC_KEY_free(ecdh); +#endif +#endif +} + + } } // namespace Poco::Net diff --git a/NetSSL_OpenSSL/src/SSLManager.cpp b/NetSSL_OpenSSL/src/SSLManager.cpp index f58e5ae18..5bd52cddb 100644 --- a/NetSSL_OpenSSL/src/SSLManager.cpp +++ b/NetSSL_OpenSSL/src/SSLManager.cpp @@ -59,6 +59,8 @@ const std::string SSLManager::CFG_REQUIRE_TLSV1("requireTLSv1"); const std::string SSLManager::CFG_REQUIRE_TLSV1_1("requireTLSv1_1"); const std::string SSLManager::CFG_REQUIRE_TLSV1_2("requireTLSv1_2"); const std::string SSLManager::CFG_DISABLE_PROTOCOLS("disableProtocols"); +const std::string SSLManager::CFG_DH_PARAMS_FILE("dhParamsFile"); +const std::string SSLManager::CFG_ECDH_CURVE("ecdhCurve"); #ifdef OPENSSL_FIPS const std::string SSLManager::CFG_FIPS_MODE("openSSL.fips"); const bool SSLManager::VAL_FIPS_MODE(false); @@ -251,30 +253,35 @@ void SSLManager::initDefaultContext(bool server) std::string prefix = server ? CFG_SERVER_PREFIX : CFG_CLIENT_PREFIX; + Context::Params params; // mandatory options - std::string privKeyFile = config.getString(prefix + CFG_PRIV_KEY_FILE, ""); - std::string certFile = config.getString(prefix + CFG_CERTIFICATE_FILE, privKeyFile); - std::string caLocation = config.getString(prefix + CFG_CA_LOCATION, ""); + params.privateKeyFile = config.getString(prefix + CFG_PRIV_KEY_FILE, ""); + params.certificateFile = config.getString(prefix + CFG_CERTIFICATE_FILE, params.privateKeyFile); + params.caLocation = config.getString(prefix + CFG_CA_LOCATION, ""); - if (server && certFile.empty() && privKeyFile.empty()) + if (server && params.certificateFile.empty() && params.privateKeyFile.empty()) throw SSLException("Configuration error: no certificate file has been specified"); // optional options for which we have defaults defined - Context::VerificationMode verMode = VAL_VER_MODE; + params.verificationMode = VAL_VER_MODE; if (config.hasProperty(prefix + CFG_VER_MODE)) { // either: none, relaxed, strict, once std::string mode = config.getString(prefix + CFG_VER_MODE); - verMode = Utility::convertVerificationMode(mode); + params.verificationMode = Utility::convertVerificationMode(mode); } - int verDepth = config.getInt(prefix + CFG_VER_DEPTH, VAL_VER_DEPTH); - bool loadDefCA = config.getBool(prefix + CFG_ENABLE_DEFAULT_CA, VAL_ENABLE_DEFAULT_CA); - std::string cipherList = config.getString(prefix + CFG_CIPHER_LIST, VAL_CIPHER_LIST); - cipherList = config.getString(prefix + CFG_CYPHER_LIST, cipherList); // for backwards compatibility + params.verificationDepth = config.getInt(prefix + CFG_VER_DEPTH, VAL_VER_DEPTH); + params.loadDefaultCAs = config.getBool(prefix + CFG_ENABLE_DEFAULT_CA, VAL_ENABLE_DEFAULT_CA); + params.cipherList = config.getString(prefix + CFG_CIPHER_LIST, VAL_CIPHER_LIST); + params.cipherList = config.getString(prefix + CFG_CYPHER_LIST, params.cipherList); // for backwards compatibility bool requireTLSv1 = config.getBool(prefix + CFG_REQUIRE_TLSV1, false); bool requireTLSv1_1 = config.getBool(prefix + CFG_REQUIRE_TLSV1_1, false); bool requireTLSv1_2 = config.getBool(prefix + CFG_REQUIRE_TLSV1_2, false); + + params.dhParamsFile = config.getString(prefix + CFG_DH_PARAMS_FILE, ""); + params.ecdhCurve = config.getString(prefix + CFG_ECDH_CURVE, ""); + Context::Usage usage; if (server) @@ -287,7 +294,7 @@ void SSLManager::initDefaultContext(bool server) usage = Context::TLSV1_SERVER_USE; else usage = Context::SERVER_USE; - _ptrDefaultServerContext = new Context(usage, privKeyFile, certFile, caLocation, verMode, verDepth, loadDefCA, cipherList); + _ptrDefaultServerContext = new Context(usage, params); } else { @@ -299,7 +306,7 @@ void SSLManager::initDefaultContext(bool server) usage = Context::TLSV1_CLIENT_USE; else usage = Context::CLIENT_USE; - _ptrDefaultClientContext = new Context(usage, privKeyFile, certFile, caLocation, verMode, verDepth, loadDefCA, cipherList); + _ptrDefaultClientContext = new Context(usage, params); } std::string disabledProtocolsList = config.getString(prefix + CFG_DISABLE_PROTOCOLS, "");