Module: Gem::PqTlsPolicy

Defined in:
lib/rubygems_pq_tls_policy.rb,
lib/rubygems_pq_tls_policy/error.rb,
lib/rubygems_pq_tls_policy/patch.rb,
lib/rubygems_pq_tls_policy/config.rb,
lib/rubygems_pq_tls_policy/version.rb,
lib/rubygems_pq_tls_policy/diagnostic.rb

Defined Under Namespace

Modules: Diagnostic, Patch Classes: Config, Error, InvalidConfiguration, UnsupportedRuntime, Violation

Constant Summary collapse

VERSION =
"1.0.1"

Class Method Summary collapse

Class Method Details

.configObject



53
54
55
# File 'lib/rubygems_pq_tls_policy/config.rb', line 53

def self.config
  Config.new
end

.install!Object



26
27
28
29
30
31
32
33
# File 'lib/rubygems_pq_tls_policy.rb', line 26

def install!
  return true if installed?

  validate_runtime!
  OpenSSL::SSL::SSLSocket.prepend(Patch)
  @installed = true
  true
end

.install_if_enabledObject



12
13
14
15
16
17
18
# File 'lib/rubygems_pq_tls_policy.rb', line 12

def install_if_enabled
  config = self.config
  return false unless config.enabled?

  config.validate!
  install!
end

.install_if_enabled_for_plugin!Object



20
21
22
23
24
# File 'lib/rubygems_pq_tls_policy.rb', line 20

def install_if_enabled_for_plugin!
  install_if_enabled
rescue Error => e
  abort "RubyGems PQ TLS policy failed to load: #{e.message} (#{e.class})"
end

.installed?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/rubygems_pq_tls_policy.rb', line 35

def installed?
  @installed == true
end

.openssl_runtime_version_at_least?(major, minor, patch) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rubygems_pq_tls_policy.rb', line 73

def openssl_runtime_version_at_least?(major, minor, patch)
  version = if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION)
    OpenSSL::OPENSSL_LIBRARY_VERSION
  elsif defined?(OpenSSL::OPENSSL_VERSION)
    OpenSSL::OPENSSL_VERSION
  end

  match = version.to_s.match(/\AOpenSSL\s+(\d+)\.(\d+)\.(\d+)/)
  return false unless match

  ([match[1].to_i, match[2].to_i, match[3].to_i] <=> [major, minor, patch]) >= 0
end

.validate_runtime!Object

Raises:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rubygems_pq_tls_policy.rb', line 43

def validate_runtime!
  begin
    require "openssl"
  rescue LoadError => e
    raise UnsupportedRuntime, "OpenSSL is unavailable: #{e.message}"
  end

  requirements = []
  socket = defined?(OpenSSL::SSL::SSLSocket) ? OpenSSL::SSL::SSLSocket : nil

  requirements << "OpenSSL::SSL::SSLSocket is unavailable" unless socket
  unless socket&.method_defined?(:post_connection_check)
    requirements << "OpenSSL::SSL::SSLSocket#post_connection_check is unavailable"
  end
  unless socket&.method_defined?(:group)
    requirements << "OpenSSL::SSL::SSLSocket#group is unavailable"
  end

  unless openssl_runtime_version_at_least?(3, 5, 0)
    requirements << "OpenSSL runtime must be 3.5.0 or newer for the default PQ TLS group"
  end

  return true if requirements.empty?

  raise UnsupportedRuntime,
    "RubyGems PQ TLS policy cannot be enabled on this Ruby/OpenSSL runtime. " \
    "#{requirements.join('; ')}. " \
    "Use Ruby linked against OpenSSL 3.5 or newer, such as ruby:4.0.5-trixie."
end

.warn_unavailable(message) ⇒ Object



39
40
41
# File 'lib/rubygems_pq_tls_policy.rb', line 39

def warn_unavailable(message)
  warn "[rubygems:tls] #{message}" if config.trace?
end