loqs commented on PR #3738:
URL: https://github.com/apache/thrift/pull/3738#issuecomment-5389282276

   Will you be doing the other conversions required for OpenSLL 4.0?:
   - Replace deprecated SSLv23_method/SSLv3_method/TLSv*_method with 
TLS_method()
   - Use SSL_CTX_set_min/max_proto_version instead of per-version method 
functions
   - Guard ERR_remove_state() with OPENSSL_VERSION_NUMBER < 0x10100000L
   - Use const-correct X509 APIs
   
   ```patch
   diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c 
b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
   index d6c7bb2ba..3344408d8 100644
   --- a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
   +++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
   @@ -285,7 +285,9 @@ thrift_ssl_socket_close (ThriftTransport *transport, 
GError **error)
          SSL_shutdown(ssl_socket->ssl);
          SSL_free(ssl_socket->ssl);
          ssl_socket->ssl = NULL;
   +#if OPENSSL_VERSION_NUMBER < 0x10100000L
          ERR_remove_state(0);
   +#endif
      }
      return thrift_socket_close(transport, error);
    }
   @@ -710,7 +712,9 @@ void thrift_ssl_socket_finalize_openssl(void)
      ERR_free_strings();
      EVP_cleanup();
      CRYPTO_cleanup_all_ex_data();
   +#if OPENSSL_VERSION_NUMBER < 0x10100000L
      ERR_remove_state(0);
   +#endif
    }
    
    
   @@ -831,6 +835,29 @@ SSL_CTX*
    thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, 
GError **error)
    {
      SSL_CTX* context = NULL;
   +
   +#if OPENSSL_VERSION_NUMBER >= 0x10100000L
   +  /* OpenSSL 1.1.0 and later: TLS_method() handles negotiation across all
   +     versions; the protocol range is gated dynamically below. */
   +  switch(ssl_protocol){
   +    case SSLTLS:
   +    case TLSv1_0:
   +    case TLSv1_1:
   +    case TLSv1_2:
   +#ifndef OPENSSL_NO_SSL3
   +    case SSLv3:
   +#endif
   +      context = SSL_CTX_new(TLS_method());
   +      break;
   +    default:
   +      g_set_error (error, THRIFT_TRANSPORT_ERROR,
   +               THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
   +               "The SSL protocol is unknown for %d", ssl_protocol);
   +      return NULL;
   +      break;
   +  }
   +#else
   +  /* OpenSSL < 1.1.0: select the protocol via the per-version method. */
      switch(ssl_protocol){
        case SSLTLS:
          context = SSL_CTX_new(SSLv23_method());
   @@ -856,6 +883,7 @@ 
thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GErro
          return NULL;
          break;
      }
   +#endif
    
      if (context == NULL) {
          thrift_ssl_socket_get_error((const guchar*)"No cipher overlay", 
THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE, error);
   @@ -870,5 +898,55 @@ 
thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GErro
          SSL_CTX_set_options(context, SSL_OP_NO_SSLv3);   /* THRIFT-3164 */
      }
    
   +#if OPENSSL_VERSION_NUMBER >= 0x10100000L
   +  /* Pin the protocol range for the explicit SSL/TLS variants. */
   +  switch(ssl_protocol){
   +#ifndef OPENSSL_NO_SSL3
   +    case SSLv3:
   +      if (!SSL_CTX_set_min_proto_version(context, SSL3_VERSION)
   +          || !SSL_CTX_set_max_proto_version(context, SSL3_VERSION)) {
   +        SSL_CTX_free(context);
   +        g_set_error (error, THRIFT_TRANSPORT_ERROR,
   +                     THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
   +                     "Failed to set SSLv3 protocol version");
   +        return NULL;
   +      }
   +      break;
   +#endif
   +    case TLSv1_0:
   +      if (!SSL_CTX_set_min_proto_version(context, TLS1_VERSION)
   +          || !SSL_CTX_set_max_proto_version(context, TLS1_VERSION)) {
   +        SSL_CTX_free(context);
   +        g_set_error (error, THRIFT_TRANSPORT_ERROR,
   +                     THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
   +                     "Failed to set TLSv1.0 protocol version");
   +        return NULL;
   +      }
   +      break;
   +    case TLSv1_1:
   +      if (!SSL_CTX_set_min_proto_version(context, TLS1_1_VERSION)
   +          || !SSL_CTX_set_max_proto_version(context, TLS1_1_VERSION)) {
   +        SSL_CTX_free(context);
   +        g_set_error (error, THRIFT_TRANSPORT_ERROR,
   +                     THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
   +                     "Failed to set TLSv1.1 protocol version");
   +        return NULL;
   +      }
   +      break;
   +    case TLSv1_2:
   +      if (!SSL_CTX_set_min_proto_version(context, TLS1_2_VERSION)
   +          || !SSL_CTX_set_max_proto_version(context, TLS1_2_VERSION)) {
   +        SSL_CTX_free(context);
   +        g_set_error (error, THRIFT_TRANSPORT_ERROR,
   +                     THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
   +                     "Failed to set TLSv1.2 protocol version");
   +        return NULL;
   +      }
   +      break;
   +    default:
   +      break;
   +  }
   +#endif
   +
      return context;
    }
   diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.cpp 
b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
   index bb8dfd13f..7dec08b08 100644
   --- a/lib/cpp/src/thrift/transport/TSSLSocket.cpp
   +++ b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
   @@ -180,6 +180,52 @@ static char uppercase(char c);
    
    // SSLContext implementation
    SSLContext::SSLContext(const SSLProtocol& protocol) {
   +#if OPENSSL_VERSION_NUMBER >= 0x10100000L
   +  if (protocol == SSLTLS) {
   +    ctx_ = SSL_CTX_new(TLS_method());
   +  } else if (protocol == TLSv1_0) {
   +    ctx_ = SSL_CTX_new(TLS_method());
   +    if (ctx_ != nullptr
   +        && (!SSL_CTX_set_min_proto_version(ctx_, TLS1_VERSION)
   +            || !SSL_CTX_set_max_proto_version(ctx_, TLS1_VERSION))) {
   +      SSL_CTX_free(ctx_);
   +      ctx_ = nullptr;
   +      throw TSSLException("SSL_CTX_new: Failed to set TLSv1.0 protocol 
version");
   +    }
   +  } else if (protocol == TLSv1_1) {
   +    ctx_ = SSL_CTX_new(TLS_method());
   +    if (ctx_ != nullptr
   +        && (!SSL_CTX_set_min_proto_version(ctx_, TLS1_1_VERSION)
   +            || !SSL_CTX_set_max_proto_version(ctx_, TLS1_1_VERSION))) {
   +      SSL_CTX_free(ctx_);
   +      ctx_ = nullptr;
   +      throw TSSLException("SSL_CTX_new: Failed to set TLSv1.1 protocol 
version");
   +    }
   +  } else if (protocol == TLSv1_2) {
   +    ctx_ = SSL_CTX_new(TLS_method());
   +    if (ctx_ != nullptr
   +        && (!SSL_CTX_set_min_proto_version(ctx_, TLS1_2_VERSION)
   +            || !SSL_CTX_set_max_proto_version(ctx_, TLS1_2_VERSION))) {
   +      SSL_CTX_free(ctx_);
   +      ctx_ = nullptr;
   +      throw TSSLException("SSL_CTX_new: Failed to set TLSv1.2 protocol 
version");
   +    }
   +#if !defined(OPENSSL_NO_SSL3) && OPENSSL_VERSION_NUMBER < 0x40000000L
   +  } else if (protocol == SSLv3) {
   +    ctx_ = SSL_CTX_new(TLS_method());
   +    if (ctx_ != nullptr
   +        && (!SSL_CTX_set_min_proto_version(ctx_, SSL3_VERSION)
   +            || !SSL_CTX_set_max_proto_version(ctx_, SSL3_VERSION))) {
   +      SSL_CTX_free(ctx_);
   +      ctx_ = nullptr;
   +      throw TSSLException("SSL_CTX_new: Failed to set SSLv3 protocol 
version");
   +    }
   +#endif
   +  } else {
   +    /// UNKNOWN PROTOCOL!
   +    throw TSSLException("SSL_CTX_new: Unknown protocol");
   +  }
   +#else
      if (protocol == SSLTLS) {
        ctx_ = SSL_CTX_new(SSLv23_method());
    #ifndef OPENSSL_NO_SSL3
   @@ -196,6 +242,7 @@ SSLContext::SSLContext(const SSLProtocol& protocol) {
        /// UNKNOWN PROTOCOL!
        throw TSSLException("SSL_CTX_new: Unknown protocol");
      }
   +#endif
    
      if (ctx_ == nullptr) {
        string errors;
   @@ -770,7 +817,7 @@ void TSSLSocket::authorize() {
          if (name == nullptr) {
            continue;
          }
   -      char* data = (char*)ASN1_STRING_data(name->d.ia5);
   +      const char* data = (const char*)ASN1_STRING_get0_data(name->d.ia5);
          int length = ASN1_STRING_length(name->d.ia5);
          switch (name->type) {
          case GEN_DNS:
   @@ -796,9 +843,9 @@ void TSSLSocket::authorize() {
      }
    
      // extract commonName
   -  X509_NAME* name = X509_get_subject_name(cert);
   +  const X509_NAME* name = X509_get_subject_name(cert);
      if (name != nullptr) {
   -    X509_NAME_ENTRY* entry;
   +    const X509_NAME_ENTRY* entry;
        unsigned char* utf8;
        int last = -1;
        while (decision == AccessManager::SKIP) {
   @@ -808,7 +855,7 @@ void TSSLSocket::authorize() {
          entry = X509_NAME_get_entry(name, last);
          if (entry == nullptr)
            continue;
   -      ASN1_STRING* common = X509_NAME_ENTRY_get_data(entry);
   +      const ASN1_STRING* common = X509_NAME_ENTRY_get_data(entry);
          int size = ASN1_STRING_to_UTF8(&utf8, common);
          if (host.empty()) {
            host = (server() ? getPeerHost() : getHost());
   diff --git a/lib/cpp/test/SecurityFromBufferTest.cpp 
b/lib/cpp/test/SecurityFromBufferTest.cpp
   index 08f76b3f2..3df15106e 100644
   --- a/lib/cpp/test/SecurityFromBufferTest.cpp
   +++ b/lib/cpp/test/SecurityFromBufferTest.cpp
   @@ -229,7 +229,7 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix) {
              continue;
            }
    
   -#ifdef OPENSSL_NO_SSL3
   +#if defined(OPENSSL_NO_SSL3) || OPENSSL_VERSION_NUMBER >= 0x40000000L
            if (si == 2 || ci == 2) {
              // Skip all SSLv3 cases - protocol not supported
              continue;
   diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp
   index 86640bd68..b133ef0f8 100644
   --- a/lib/cpp/test/SecurityTest.cpp
   +++ b/lib/cpp/test/SecurityTest.cpp
   @@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix)
                        continue;
                    }
    
   -#ifdef OPENSSL_NO_SSL3
   +#if defined(OPENSSL_NO_SSL3) || OPENSSL_VERSION_NUMBER >= 0x40000000L
                    if (si == 2 || ci == 2)
                    {
                        // Skip all SSLv3 cases - protocol not supported
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to