Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions lib/launcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,46 @@ def resolve_tls_ciphers
return nil if configured&.empty?
return configured unless configured.nil?

if File.exist?(CRYPTO_POLICIES_CONFIG)
logger.info "Crypto-policies detected, using PROFILE=SYSTEM for TLS ciphers."
'PROFILE=SYSTEM'
else
unless File.exist?(CRYPTO_POLICIES_CONFIG)
logger.debug "No crypto-policies detected, using HIGH cipher string as default."
'HIGH'
return 'HIGH'
end

if cipher_string_supported?('PROFILE=SYSTEM')
logger.info "Crypto-policies detected, using PROFILE=SYSTEM for TLS ciphers."
return 'PROFILE=SYSTEM'
end

cipher_string = crypto_policies_cipher_string
if cipher_string && cipher_string_supported?(cipher_string)
logger.info "Crypto-policies detected, but this OpenSSL build does not support the " \
"'PROFILE=SYSTEM' cipher-list alias. Using the CipherString resolved from " \
"#{CRYPTO_POLICIES_CONFIG} directly instead."
return cipher_string
end

logger.warn "Crypto-policies detected but could not be applied on this Ruby/OpenSSL build; " \
"falling back to the 'HIGH' cipher string."
'HIGH'
end

# Extracted so resolve_tls_ciphers can probe candidate cipher strings before
# committing to them, instead of only discovering they're unusable at startup.
def cipher_string_supported?(ciphers)
OpenSSL::SSL::SSLContext.new.ciphers = ciphers
true
rescue OpenSSL::SSL::SSLError
false
end

def crypto_policies_cipher_string
File.foreach(CRYPTO_POLICIES_CONFIG) do |line|
return Regexp.last_match(1).strip if line =~ /^CipherString\s*=\s*(.+)$/
end
nil
rescue SystemCallError => e
logger.warn "Unable to read #{CRYPTO_POLICIES_CONFIG}: #{e.message}"
nil
end

def validate_tls_ciphers!(ciphers)
Expand All @@ -135,12 +168,7 @@ def validate_tls_ciphers!(ciphers)
"The system crypto policy minimum TLS version may be overridden by this setting."
end

cipher_list = begin
OpenSSL::SSL::SSLContext.new.ciphers = ciphers
ciphers
rescue OpenSSL::SSL::SSLError
nil
end
cipher_list = cipher_string_supported?(ciphers) ? ciphers : nil

if OpenSSL::SSL::SSLContext.method_defined?(:ciphersuites=)
ciphersuites = begin
Expand Down
30 changes: 30 additions & 0 deletions test/launcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def test_resolve_tls_ciphers_raises_on_non_string
def test_resolve_tls_ciphers_autodetects_profile_system_when_crypto_policies_present
launcher = launcher_with({})
File.expects(:exist?).with(CRYPTO_POLICIES_CONFIG).returns(true)
launcher.stubs(:cipher_string_supported?).with('PROFILE=SYSTEM').returns(true)
launcher.logger.stubs(:info)
assert_equal 'PROFILE=SYSTEM', launcher.resolve_tls_ciphers
end
Expand All @@ -64,6 +65,35 @@ def test_resolve_tls_ciphers_defaults_to_high_when_no_crypto_policies
assert_equal 'HIGH', launcher.resolve_tls_ciphers
end

def test_resolve_tls_ciphers_falls_back_to_parsed_cipher_string_when_profile_system_unsupported
launcher = launcher_with({})
File.expects(:exist?).with(CRYPTO_POLICIES_CONFIG).returns(true)
launcher.stubs(:cipher_string_supported?).with('PROFILE=SYSTEM').returns(false)
launcher.stubs(:crypto_policies_cipher_string).returns('HIGH:!aNULL')
launcher.stubs(:cipher_string_supported?).with('HIGH:!aNULL').returns(true)
launcher.logger.stubs(:info)
assert_equal 'HIGH:!aNULL', launcher.resolve_tls_ciphers
end

def test_resolve_tls_ciphers_falls_back_to_high_when_crypto_policies_unparseable
launcher = launcher_with({})
File.expects(:exist?).with(CRYPTO_POLICIES_CONFIG).returns(true)
launcher.stubs(:cipher_string_supported?).with('PROFILE=SYSTEM').returns(false)
launcher.stubs(:crypto_policies_cipher_string).returns(nil)
launcher.logger.stubs(:warn)
assert_equal 'HIGH', launcher.resolve_tls_ciphers
end

def test_resolve_tls_ciphers_falls_back_to_high_when_parsed_cipher_string_also_unsupported
launcher = launcher_with({})
File.expects(:exist?).with(CRYPTO_POLICIES_CONFIG).returns(true)
launcher.stubs(:cipher_string_supported?).with('PROFILE=SYSTEM').returns(false)
launcher.stubs(:crypto_policies_cipher_string).returns('BOGUS')
launcher.stubs(:cipher_string_supported?).with('BOGUS').returns(false)
launcher.logger.stubs(:warn)
assert_equal 'HIGH', launcher.resolve_tls_ciphers
end

def test_validate_tls_ciphers_returns_nil_pair_for_nil
assert_equal [nil, nil], @launcher.validate_tls_ciphers!(nil)
end
Expand Down
Loading