File 0001-OpenSSL-1.1.1-updates-add-no_tlsv1_1.patch of Package rubygem-puma.16022

From 05c20179de45b0105f27ebbb5f2aa15410aae7c6 Mon Sep 17 00:00:00 2001
From: dmaiocchi <dmaiocchi@suse.com>
Date: Fri, 31 Jul 2020 18:08:46 +0200
Subject: [PATCH] OpenSSL 1.1.1 updates, add #no_tlsv1_1

# Conflicts:
#	ext/puma_http11/mini_ssl.c
---
 ext/puma_http11/mini_ssl.c | 84 +++++++++++++++++++++++++++++++++++---
 lib/puma/minissl.rb        | 13 ++++--
 2 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/ext/puma_http11/mini_ssl.c b/ext/puma_http11/mini_ssl.c
index b2549cf1..6312c60b 100644
--- a/ext/puma_http11/mini_ssl.c
+++ b/ext/puma_http11/mini_ssl.c
@@ -142,7 +142,7 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
   VALUE obj;
   SSL_CTX* ctx;
   SSL* ssl;
-  int ssl_options;
+  int min, ssl_options;
 
   ms_conn* conn = engine_alloc(self, &obj);
 
@@ -168,8 +168,14 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
   ID sym_no_tlsv1 = rb_intern("no_tlsv1");
   VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
 
+  ID sym_no_tlsv1_1 = rb_intern("no_tlsv1_1");
+  VALUE no_tlsv1_1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1_1, 0);
 
+#ifdef HAVE_TLS_SERVER_METHOD
+  ctx = SSL_CTX_new(TLS_server_method());
+#else
   ctx = SSL_CTX_new(SSLv23_server_method());
+#endif
   conn->ctx = ctx;
 
   SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
@@ -180,12 +186,36 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
     SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
   }
 
-  ssl_options  = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
+  ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
+
+#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
+  if (RTEST(no_tlsv1_1)) {
+    min = TLS1_2_VERSION;
+  }
+  else if (RTEST(no_tlsv1)) {
+    min = TLS1_1_VERSION;
+  }
+  else {
+    min = TLS1_VERSION;
+  }
+  
+  SSL_CTX_set_min_proto_version(ctx, min);
+
+  SSL_CTX_set_options(ctx, ssl_options);
+
+#else
+  /* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */
+  ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE;
 
-  if(RTEST(no_tlsv1)) {
+  if (RTEST(no_tlsv1)) {
     ssl_options |= SSL_OP_NO_TLSv1;
   }
+  if(RTEST(no_tlsv1_1)) {
+    ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
+  }
   SSL_CTX_set_options(ctx, ssl_options);
+#endif
+
   SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
 
   if (!NIL_P(ssl_cipher_filter)) {
@@ -199,12 +229,18 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
   DH *dh = get_dh1024();
   SSL_CTX_set_tmp_dh(ctx, dh);
 
-#ifndef OPENSSL_NO_ECDH
-  EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+  // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
+  // longer needed.
+  EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
   if (ecdh) {
     SSL_CTX_set_tmp_ecdh(ctx, ecdh);
     EC_KEY_free(ecdh);
   }
+#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+  // Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
+  // negotiation.
+  SSL_CTX_set_ecdh_auto(ctx, 1);
 #endif
 
   ssl = SSL_new(ctx);
@@ -226,8 +262,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
 VALUE engine_init_client(VALUE klass) {
   VALUE obj;
   ms_conn* conn = engine_alloc(klass, &obj);
-
+#ifdef HAVE_DTLS_METHOD
+  conn->ctx = SSL_CTX_new(DTLS_method());
+#else
   conn->ctx = SSL_CTX_new(DTLSv1_method());
+#endif
   conn->ssl = SSL_new(conn->ctx);
   SSL_set_app_data(conn->ssl, NULL);
   SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
@@ -443,6 +482,39 @@ void Init_mini_ssl(VALUE puma) {
   mod = rb_define_module_under(puma, "MiniSSL");
   eng = rb_define_class_under(mod, "Engine", rb_cObject);
 
+  // OpenSSL Build / Runtime/Load versions
+
+  /* Version of OpenSSL that Puma was compiled with */
+  rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
+
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
+  /* Version of OpenSSL that Puma loaded with */
+  rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
+#else
+  rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
+#endif
+ 
+#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD) 
+  /* True if SSL3 is not available */ 
+  rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue); 
+#else 
+  rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse); 
+#endif 
+
+#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD) 
+  /* True if TLS1 is not available */ 
+  rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue); 
+#else 
+  rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse); 
+#endif 
+
+#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD) 
+  /* True if TLS1_1 is not available */ 
+  rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue); 
+#else 
+  rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse); 
+#endif 
+
   rb_define_singleton_method(mod, "check", noop, 0);
 
   eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
diff --git a/lib/puma/minissl.rb b/lib/puma/minissl.rb
index aebfa888..d48c5c13 100644
--- a/lib/puma/minissl.rb
+++ b/lib/puma/minissl.rb
@@ -175,10 +175,11 @@ module Puma
 
     class Context
       attr_accessor :verify_mode
-      attr_reader :no_tlsv1
+      attr_reader :no_tlsv1, :no_tlsv1_1
 
       def initialize
-        @no_tlsv1 = false
+        @no_tlsv1   = false
+        @no_tlsv1_1 = false
       end
 
       if defined?(JRUBY_VERSION)
@@ -216,18 +217,24 @@ module Puma
           @ca = ca
         end
 
-
         def check
           raise "Key not configured" unless @key
           raise "Cert not configured" unless @cert
         end
       end
 
+      # disables TLSv1
       def no_tlsv1=(tlsv1)
         raise ArgumentError, "Invalid value of no_tlsv1" unless ['true', 'false', true, false].include?(tlsv1)
         @no_tlsv1 = tlsv1
       end
 
+      # disables TLSv1 and TLSv1.1.  Overrides `#no_tlsv1=`
+      def no_tlsv1_1=(tlsv1_1)
+        raise ArgumentError, "Invalid value of no_tlsv1" unless ['true', 'false', true, false].include?(tlsv1_1)
+        @no_tlsv1_1 = tlsv1_1
+      end
+
     end
 
     VERIFY_NONE = 0
-- 
2.26.2

openSUSE Build Service is sponsored by