diff options
-rw-r--r-- | cpp/src/IceSSL/OpenSSLEngine.cpp | 64 | ||||
-rw-r--r-- | cpp/src/IceSSL/OpenSSLEngine.h | 2 | ||||
-rw-r--r-- | cpp/src/IceSSL/SChannelEngine.cpp | 25 | ||||
-rw-r--r-- | cpp/src/IceSSL/SecureTransportEngine.cpp | 31 | ||||
-rw-r--r-- | cpp/test/IceSSL/configuration/AllTests.cpp | 27 | ||||
-rw-r--r-- | java-compat/src/Ice/src/main/java/IceSSL/SSLEngine.java | 4 | ||||
-rw-r--r-- | java/src/IceSSL/src/main/java/com/zeroc/IceSSL/SSLEngine.java | 4 |
7 files changed, 143 insertions, 14 deletions
diff --git a/cpp/src/IceSSL/OpenSSLEngine.cpp b/cpp/src/IceSSL/OpenSSLEngine.cpp index 133d98ee465..e008094afb6 100644 --- a/cpp/src/IceSSL/OpenSSLEngine.cpp +++ b/cpp/src/IceSSL/OpenSSLEngine.cpp @@ -399,9 +399,21 @@ OpenSSL::SSLEngine::initialize() // TLS1.1 and TLS1.2 to avoid security issues with SSLv3 // vector<string> defaultProtocols; +#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1_METHOD) defaultProtocols.push_back("tls1_0"); +#endif + +#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1_METHOD) defaultProtocols.push_back("tls1_1"); +#endif + +#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2_METHOD) defaultProtocols.push_back("tls1_2"); +#endif + +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3_METHOD) + defaultProtocols.push_back("tls1_3"); +#endif const int protocols = parseProtocols(properties->getPropertyAsListWithDefault(propPrefix + "Protocols", defaultProtocols)); @@ -541,8 +553,9 @@ OpenSSL::SSLEngine::initialize() vector<string> files; if(!IceUtilInternal::splitString(certFile, IceUtilInternal::pathsep, files) || files.size() > 2) { - PluginInitializationException ex(__FILE__, __LINE__, - "IceSSL: invalid value for " + propPrefix + "CertFile:\n" + certFile); + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid value for " + propPrefix + "CertFile:\n" + + certFile); } numCerts = files.size(); for(vector<string>::iterator p = files.begin(); p != files.end(); ++p) @@ -551,8 +564,8 @@ OpenSSL::SSLEngine::initialize() string resolved; if(!checkPath(file, defaultDir, false, resolved)) { - PluginInitializationException ex(__FILE__, __LINE__, - "IceSSL: certificate file not found:\n" + file); + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: certificate file not found:\n" + file); } file = resolved; @@ -963,19 +976,48 @@ OpenSSL::SSLEngine::parseProtocols(const StringSeq& protocols) const string prot = IceUtilInternal::toUpper(*p); if(prot == "SSL3" || prot == "SSLV3") { +#if defined(OPENSSL_NO_SSL3_METHOD) || !defined(SSL3_VERSION) + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: OpenSSL was build without SSLv3 support"); +#else v |= SSLv3; +#endif } else if(prot == "TLS" || prot == "TLS1" || prot == "TLSV1" || prot == "TLS1_0" || prot == "TLSV1_0") { +#if defined(OPENSSL_NO_TLS1_METHOD) || !defined(TLS1_VERSION) + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: OpenSSL was build without TLS 1.0 support"); +#else v |= TLSv1_0; +#endif } else if(prot == "TLS1_1" || prot == "TLSV1_1") { +#if defined(OPENSSL_NO_TLS1_1_METHOD) || !defined(TLS1_1_VERSION) + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: OpenSSL was build without TLS 1.1 support"); +#else v |= TLSv1_1; +#endif } else if(prot == "TLS1_2" || prot == "TLSV1_2") { +#if defined(OPENSSL_NO_TLS1_2_METHOD) || !defined(TLS1_2_VERSION) + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: OpenSSL was build without TLS 1.2 support"); +#else v |= TLSv1_2; +#endif + } + else if(prot == "TLS1_3" || prot == "TLSV1_3") + { +#if defined(OPENSSL_NO_TLS1_3_METHOD) || !defined(TLS1_3_VERSION) + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: OpenSSL was build without TLS 1.3 support"); +#else + v |= TLSv1_3; +#endif } else { @@ -1014,14 +1056,21 @@ void OpenSSL::SSLEngine::setOptions(int protocols) { long opts = SSL_OP_NO_SSLv2; // SSLv2 is not supported. + +#ifdef SSL_OP_NO_SSLv3 if(!(protocols & SSLv3)) { opts |= SSL_OP_NO_SSLv3; } +#endif + +#ifdef SSL_OP_NO_TLSv1 if(!(protocols & TLSv1_0)) { opts |= SSL_OP_NO_TLSv1; } +#endif + #ifdef SSL_OP_NO_TLSv1_1 if(!(protocols & TLSv1_1)) { @@ -1042,5 +1091,12 @@ OpenSSL::SSLEngine::setOptions(int protocols) opts |= SSL_OP_NO_TLSv1_2; } #endif + +#ifdef SSL_OP_NO_TLSv1_3 + if(!(protocols & TLSv1_3)) + { + opts |= SSL_OP_NO_TLSv1_3; + } +#endif SSL_CTX_set_options(_ctx, opts); } diff --git a/cpp/src/IceSSL/OpenSSLEngine.h b/cpp/src/IceSSL/OpenSSLEngine.h index 681648dd2ba..2fad7263ca9 100644 --- a/cpp/src/IceSSL/OpenSSLEngine.h +++ b/cpp/src/IceSSL/OpenSSLEngine.h @@ -45,7 +45,7 @@ private: void cleanup(); SSL_METHOD* getMethod(int); void setOptions(int); - enum Protocols { SSLv3 = 0x01, TLSv1_0 = 0x02, TLSv1_1 = 0x04, TLSv1_2 = 0x08 }; + enum Protocols { SSLv3 = 1, TLSv1_0 = 2, TLSv1_1 = 4, TLSv1_2 = 8, TLSv1_3 = 16 }; int parseProtocols(const Ice::StringSeq&) const; SSL_CTX* _ctx; diff --git a/cpp/src/IceSSL/SChannelEngine.cpp b/cpp/src/IceSSL/SChannelEngine.cpp index 19a50c49631..1dbbf390fd2 100644 --- a/cpp/src/IceSSL/SChannelEngine.cpp +++ b/cpp/src/IceSSL/SChannelEngine.cpp @@ -22,6 +22,15 @@ #include <wincrypt.h> // +// SP_PROT_TLS1_3 is new in v10.0.15021 SDK +// +#ifndef SP_PROT_TLS1_3 +# define SP_PROT_TLS1_3_SERVER 0x00001000 +# define SP_PROT_TLS1_3_CLIENT 0x00002000 +# define SP_PROT_TLS1_3 (SP_PROT_TLS1_3_SERVER | SP_PROT_TLS1_3_CLIENT) +#endif + +// // CALG_ECDH_EPHEM algorithm constant is not defined in older version of the SDK headers // // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx @@ -417,23 +426,23 @@ parseProtocols(const StringSeq& protocols) if(prot == "SSL3" || prot == "SSLV3") { - v |= SP_PROT_SSL3_SERVER; - v |= SP_PROT_SSL3_CLIENT; + v |= SP_PROT_SSL3; } else if(prot == "TLS" || prot == "TLS1" || prot == "TLSV1" || prot == "TLS1_0" || prot == "TLSV1_0") { - v |= SP_PROT_TLS1_SERVER; - v |= SP_PROT_TLS1_CLIENT; + v |= SP_PROT_TLS1; } else if(prot == "TLS1_1" || prot == "TLSV1_1") { - v |= SP_PROT_TLS1_1_SERVER; - v |= SP_PROT_TLS1_1_CLIENT; + v |= SP_PROT_TLS1_1; } else if(prot == "TLS1_2" || prot == "TLSV1_2") { - v |= SP_PROT_TLS1_2_SERVER; - v |= SP_PROT_TLS1_2_CLIENT; + v |= SP_PROT_TLS1_2; + } + else if (prot == "TLS1_3" || prot == "TLSV1_2") + { + v |= SP_PROT_TLS1_3; } else { diff --git a/cpp/src/IceSSL/SecureTransportEngine.cpp b/cpp/src/IceSSL/SecureTransportEngine.cpp index 80f28129bf7..a3304676bfe 100644 --- a/cpp/src/IceSSL/SecureTransportEngine.cpp +++ b/cpp/src/IceSSL/SecureTransportEngine.cpp @@ -129,7 +129,7 @@ CiphersHelper::initialize() _ciphers["RSA_EXPORT_WITH_RC4_40_MD5"] = SSL_RSA_EXPORT_WITH_RC4_40_MD5; _ciphers["RSA_WITH_RC4_128_MD5"] = SSL_RSA_WITH_RC4_128_MD5; _ciphers["RSA_WITH_RC4_128_SHA"] = SSL_RSA_WITH_RC4_128_SHA; - _ciphers["RSA_EXPORT_WITH_RC2_CBC_40_MD5"] = SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5; + _ciphers["RSA_EXPORT_WITH_RC2_CBC_40_MD5"] = SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5; _ciphers["RSA_WITH_IDEA_CBC_SHA"] = SSL_RSA_WITH_IDEA_CBC_SHA; _ciphers["RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_RSA_EXPORT_WITH_DES40_CBC_SHA; _ciphers["RSA_WITH_DES_CBC_SHA"] = SSL_RSA_WITH_DES_CBC_SHA; @@ -341,6 +341,16 @@ CiphersHelper::initialize() _ciphers["RSA_WITH_DES_CBC_MD5"] = SSL_RSA_WITH_DES_CBC_MD5; _ciphers["RSA_WITH_3DES_EDE_CBC_MD5"] = SSL_RSA_WITH_3DES_EDE_CBC_MD5; _ciphers["NO_SUCH_CIPHERSUITE"] = SSL_NO_SUCH_CIPHERSUITE; + + // + // TLS 1.3 standard cipher suites + // + _ciphers["TLS_AES_128_GCM_SHA256"] = TLS_AES_128_GCM_SHA256; + _ciphers["TLS_AES_256_GCM_SHA384"] = TLS_AES_256_GCM_SHA384; + _ciphers["TLS_CHACHA20_POLY1305_SHA256"] = TLS_CHACHA20_POLY1305_SHA256; + _ciphers["TLS_AES_128_CCM_SHA256"] = TLS_AES_128_CCM_SHA256; + _ciphers["TLS_AES_128_CCM_8_SHA256"] = TLS_AES_128_CCM_8_SHA256; + } } @@ -741,6 +751,21 @@ CiphersHelper::cipherName(SSLCipherSuite cipher) return "RSA_WITH_DES_CBC_MD5"; case SSL_RSA_WITH_3DES_EDE_CBC_MD5: return "RSA_WITH_3DES_EDE_CBC_MD5"; + + // + //TLS 1.3 standard cipher suites + // + case TLS_AES_128_GCM_SHA256: + return "TLS_AES_128_GCM_SHA256"; + case TLS_AES_256_GCM_SHA384: + return "TLS_AES_256_GCM_SHA384"; + case TLS_CHACHA20_POLY1305_SHA256: + return "TLS_CHACHA20_POLY1305_SHA256"; + case TLS_AES_128_CCM_SHA256: + return "TLS_AES_128_CCM_SHA256"; + case TLS_AES_128_CCM_8_SHA256: + return "TLS_AES_128_CCM_8_SHA256"; + default: return ""; } @@ -772,6 +797,10 @@ parseProtocol(const string& p) { return kTLSProtocol12; } + else if(prot == "TLS1_3" || prot == "TLSV1_3") + { + return kTLSProtocol13; + } else { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unrecognized protocol `" + p + "'"); diff --git a/cpp/test/IceSSL/configuration/AllTests.cpp b/cpp/test/IceSSL/configuration/AllTests.cpp index 349fa08425b..d0ee7e2c9de 100644 --- a/cpp/test/IceSSL/configuration/AllTests.cpp +++ b/cpp/test/IceSSL/configuration/AllTests.cpp @@ -2121,6 +2121,10 @@ allTests(Test::TestHelper* helper, const string& /*testDir*/, bool p12) } // + // Skip the test if OpenSSL was build without SSL3 support + // +#if !defined(OPENSSL_NO_SSL3_METHOD) + // // This should fail because the client only accept SSLv3 and the server // use the default protocol set that disables SSLv3 // @@ -2157,6 +2161,7 @@ allTests(Test::TestHelper* helper, const string& /*testDir*/, bool p12) fact->destroyServer(server); comm->destroy(); } +#endif // // SSLv3 is now disabled by default with some SSL implementations. @@ -2601,6 +2606,13 @@ allTests(Test::TestHelper* helper, const string& /*testDir*/, bool p12) #ifndef ICE_OS_UWP cout << "testing ciphers... " << flush; { + + // + // With OpenSSL 1.1.1 the initialization will success because TLS 1.3 + // ciphersuites are still enabled. They are not affected by IceSSL.Ciphers + // properties + // +# if !(defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010100fL) InitializationData initData; initData.properties = createClientProps(defaultProps, p12, "c_rsa_ca1", "cacert1"); initData.properties->setProperty("IceSSL.Ciphers", "UNKNOWN"); @@ -2612,6 +2624,7 @@ allTests(Test::TestHelper* helper, const string& /*testDir*/, bool p12) catch(const Ice::PluginInitializationException&) { } +# endif } # ifndef ICE_USE_SCHANNEL { @@ -2623,6 +2636,13 @@ allTests(Test::TestHelper* helper, const string& /*testDir*/, bool p12) initData.properties = createClientProps(defaultProps, p12); # ifdef ICE_USE_OPENSSL initData.properties->setProperty("IceSSL.Ciphers", anonCiphers); +# if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010100fL + // + // With OpenSSL 1.1 disable tls1.3 so that client and server negotiate + // an anon cipher + // + initData.properties->setProperty("IceSSL.Protocols", "tls1_2,tls1_1"); +# endif # else initData.properties->setProperty("IceSSL.Ciphers", "(DH_anon*)"); # endif @@ -2929,6 +2949,13 @@ allTests(Test::TestHelper* helper, const string& /*testDir*/, bool p12) // initData.properties = createClientProps(defaultProps, p12); initData.properties->setProperty("IceSSL.Ciphers", "ADH"); +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010100fL + // + // With OpenSSL 1.1 disable tls1.3 so that client and server negotiate + // an anon cipher + // + initData.properties->setProperty("IceSSL.Protocols", "tls1_2,tls1_1"); +#endif comm = initialize(initData); fact = ICE_CHECKED_CAST(Test::ServerFactoryPrx, comm->stringToProxy(factoryRef)); test(fact); diff --git a/java-compat/src/Ice/src/main/java/IceSSL/SSLEngine.java b/java-compat/src/Ice/src/main/java/IceSSL/SSLEngine.java index 4d8d7f41740..3bc4bcacd42 100644 --- a/java-compat/src/Ice/src/main/java/IceSSL/SSLEngine.java +++ b/java-compat/src/Ice/src/main/java/IceSSL/SSLEngine.java @@ -67,6 +67,10 @@ class SSLEngine { l.add("TLSv1.2"); } + else if(s.equals("TLS1_3") || s.equals("TLSV1_3")) + { + l.add("TLSv1.3"); + } else { Ice.PluginInitializationException e = new Ice.PluginInitializationException(); diff --git a/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/SSLEngine.java b/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/SSLEngine.java index e8d5370de13..f01bc920b7f 100644 --- a/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/SSLEngine.java +++ b/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/SSLEngine.java @@ -68,6 +68,10 @@ class SSLEngine { l.add("TLSv1.2"); } + else if(s.equals("TLS1_3") || s.equals("TLSV1_3")) + { + l.add("TLSv1.3"); + } else { PluginInitializationException e = new PluginInitializationException(); |