Check for TLS_FALLBACK_SCSV
parent
e604c11e13
commit
8a1c4f8856
1
Makefile
1
Makefile
|
@ -69,6 +69,7 @@ $(RUBY_DIR)/: build/$(RUBY_NAME).tar.gz
|
|||
$(RUBY_OPENSSL_EXT_DIR)/Makefile: libs | $(RUBY_DIR)/
|
||||
patch -d $(RUBY_DIR)/ -p1 < tmp_key.patch
|
||||
patch -d $(RUBY_DIR)/ -p1 < set_ecdh_curves.patch
|
||||
patch -d $(RUBY_DIR)/ -p1 < fallback_scsv.patch
|
||||
cd $(RUBY_OPENSSL_EXT_DIR) && ruby extconf.rb
|
||||
|
||||
$(RUBY_OPENSSL_EXT_DIR)/openssl.so: libs $(RUBY_OPENSSL_EXT_DIR)/Makefile
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
|
||||
index 57519f2..c5b0c8b 100644
|
||||
--- a/ext/openssl/lib/openssl/ssl.rb
|
||||
+++ b/ext/openssl/lib/openssl/ssl.rb
|
||||
@@ -105,11 +105,12 @@ class SSLContext
|
||||
# SSLContext.new("SSLv23_client") => ctx
|
||||
#
|
||||
# You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
|
||||
- def initialize(version = nil)
|
||||
+ def initialize(version = nil, fallback_scsv = false)
|
||||
INIT_VARS.each { |v| instance_variable_set v, nil }
|
||||
self.options = self.options | OpenSSL::SSL::OP_ALL
|
||||
return unless version
|
||||
self.ssl_version = version
|
||||
+ self.enable_fallback_scsv if fallback_scsv
|
||||
end
|
||||
|
||||
##
|
||||
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
|
||||
index bcc624f..0c1780b 100644
|
||||
--- a/ext/openssl/ossl_ssl.c
|
||||
+++ b/ext/openssl/ossl_ssl.c
|
||||
@@ -978,6 +978,31 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
||||
return v;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * call-seq:
|
||||
+ * ctx.enable_fallback_scsv() => nil
|
||||
+ *
|
||||
+ * Activate TLS_FALLBACK_SCSV for this context.
|
||||
+ * See RFC 7507.
|
||||
+ */
|
||||
+static VALUE
|
||||
+ossl_sslctx_enable_fallback_scsv(VALUE self)
|
||||
+{
|
||||
+ SSL_CTX *ctx;
|
||||
+
|
||||
+ GetSSLCTX(self, ctx);
|
||||
+ if(!ctx){
|
||||
+ rb_warning("SSL_CTX is not initialized.");
|
||||
+ return Qnil;
|
||||
+ }
|
||||
+
|
||||
+ long modes = SSL_CTX_get_mode(ctx);
|
||||
+ modes |= SSL_MODE_SEND_FALLBACK_SCSV;
|
||||
+ SSL_CTX_set_mode(ctx, modes);
|
||||
+
|
||||
+ return Qnil;
|
||||
+}
|
||||
+
|
||||
#if !defined(OPENSSL_NO_EC)
|
||||
/*
|
||||
* call-seq:
|
||||
@@ -2330,6 +2355,7 @@ Init_ossl_ssl(void)
|
||||
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
||||
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
|
||||
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
|
||||
+ rb_define_method(cSSLContext, "enable_fallback_scsv", ossl_sslctx_enable_fallback_scsv, 0);
|
||||
|
||||
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
|
||||
|
|
@ -119,7 +119,14 @@ module CryptCheck
|
|||
]
|
||||
|
||||
def checks
|
||||
CHECKS
|
||||
checks = CHECKS
|
||||
unless @server.fallback_scsv? == nil
|
||||
checks += [
|
||||
[:no_fallback_scsv, Proc.new { |s| not s.fallback_scsv? }, :error],
|
||||
[:fallback_scsv, Proc.new { |s| s.fallback_scsv? }, :good]
|
||||
]
|
||||
end
|
||||
checks
|
||||
end
|
||||
|
||||
def calculate_states
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
require 'socket'
|
||||
require 'openssl'
|
||||
require 'httparty'
|
||||
require 'awesome_print'
|
||||
|
||||
module CryptCheck
|
||||
module Tls
|
||||
|
@ -41,6 +40,7 @@ module CryptCheck
|
|||
Logger.info { "Key : #{Tls.key_to_s self.key}" }
|
||||
fetch_prefered_ciphers
|
||||
check_supported_cipher
|
||||
check_fallback_scsv
|
||||
uniq_dh
|
||||
end
|
||||
|
||||
|
@ -174,6 +174,10 @@ module CryptCheck
|
|||
supported_ciphers.any? { |c| c.sweet32? }
|
||||
end
|
||||
|
||||
def fallback_scsv?
|
||||
@fallback_scsv
|
||||
end
|
||||
|
||||
private
|
||||
def name
|
||||
name = "#@ip:#@port"
|
||||
|
@ -229,6 +233,8 @@ module CryptCheck
|
|||
when /state=error: no ciphers available$/,
|
||||
/state=SSLv.* read server hello A: sslv.* alert handshake failure$/
|
||||
raise CipherNotAvailable, e
|
||||
when /state=SSLv.* read server hello A: tlsv.* alert inappropriate fallback$/
|
||||
raise InappropriateFallback, e
|
||||
end
|
||||
raise
|
||||
rescue ::SystemCallError => e
|
||||
|
@ -350,6 +356,34 @@ module CryptCheck
|
|||
end
|
||||
end
|
||||
|
||||
def check_fallback_scsv
|
||||
@fallback_scsv = false
|
||||
|
||||
methods = @supported_ciphers.keys
|
||||
if methods.size > 1
|
||||
# We will try to connect to the not better supported method
|
||||
method = methods[1]
|
||||
|
||||
begin
|
||||
ssl_client method, fallback: true
|
||||
rescue InappropriateFallback
|
||||
@fallback_scsv = true
|
||||
end
|
||||
else
|
||||
@fallback_scsv = nil
|
||||
end
|
||||
|
||||
text, color = case @fallback_scsv
|
||||
when true
|
||||
['Supported', :good]
|
||||
when false
|
||||
['Not supported', :error]
|
||||
when nil
|
||||
['Not applicable', :unknown]
|
||||
end
|
||||
Logger.info { "Fallback SCSV : #{text.colorize color}" }
|
||||
end
|
||||
|
||||
def verify_trust(chain, cert)
|
||||
store = ::OpenSSL::X509::Store.new
|
||||
store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
|
||||
|
|
Loading…
Reference in New Issue