net-ssh 7.3.3 → 8.0.0.beta3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- require 'rbnacl'
1
+ require 'openssl'
2
2
  require 'net/ssh/loggable'
3
3
 
4
4
  module Net
@@ -8,6 +8,15 @@ module Net
8
8
  class ChaCha20Poly1305Cipher
9
9
  include Net::SSH::Loggable
10
10
 
11
+ POLY1305_ALGORITHM = "POLY1305"
12
+ POLY1305_KEY_BYTES = 32
13
+ POLY1305_TAG_BYTES = 16
14
+ NAME = "chacha20-poly1305@openssh.com"
15
+ ZERO_BLOCK = "\x00".b * POLY1305_KEY_BYTES
16
+ ZERO_IV = "\x00".b * 16
17
+
18
+ class UnsupportedError < StandardError; end
19
+
11
20
  # Implicit HMAC, no need to do anything
12
21
  class ImplicitHMac
13
22
  def etm
@@ -24,7 +33,6 @@ module Net
24
33
  @chacha_hdr = OpenSSL::Cipher.new("chacha20")
25
34
  key_len = @chacha_hdr.key_len
26
35
  @chacha_main = OpenSSL::Cipher.new("chacha20")
27
- @poly = RbNaCl::OneTimeAuths::Poly1305
28
36
  if key.size < key_len * 2
29
37
  error { "chacha20_poly1305: keylength doesn't match" }
30
38
  raise "chacha20_poly1305: keylength doesn't match"
@@ -43,9 +51,9 @@ module Net
43
51
  end
44
52
 
45
53
  def update_cipher_mac(payload, sequence_number)
46
- iv_data = [0, 0, 0, sequence_number].pack("NNNN")
54
+ iv_data = packet_iv(sequence_number)
47
55
  @chacha_main.iv = iv_data
48
- poly_key = @chacha_main.update(([0] * 32).pack('C32'))
56
+ poly_key = @chacha_main.update(ZERO_BLOCK)
49
57
 
50
58
  packet_length = payload.size
51
59
  length_data = [packet_length].pack("N")
@@ -57,35 +65,36 @@ module Net
57
65
  unencrypted_data = payload
58
66
  packet += @chacha_main.update(unencrypted_data)
59
67
 
60
- packet += @poly.auth(poly_key, packet)
68
+ packet += self.class.poly1305_auth(poly_key, packet)
61
69
  return packet
62
70
  end
63
71
 
64
72
  def read_length(data, sequence_number)
65
- iv_data = [0, 0, 0, sequence_number].pack("NNNN")
73
+ iv_data = packet_iv(sequence_number)
66
74
  @chacha_hdr.iv = iv_data
67
75
  @chacha_hdr.update(data).unpack1("N")
68
76
  end
69
77
 
70
78
  def read_and_mac(data, mac, sequence_number)
71
- iv_data = [0, 0, 0, sequence_number].pack("NNNN")
79
+ iv_data = packet_iv(sequence_number)
72
80
  @chacha_main.iv = iv_data
73
- poly_key = @chacha_main.update(([0] * 32).pack('C32'))
81
+ poly_key = @chacha_main.update(ZERO_BLOCK)
74
82
 
75
83
  iv_data[0] = 1.chr
76
84
  @chacha_main.iv = iv_data
77
85
  unencrypted_data = @chacha_main.update(data[4..])
78
- begin
79
- ok = @poly.verify(poly_key, mac, data[0..])
80
- raise Net::SSH::Exception, "corrupted hmac detected #{name}" unless ok
81
- rescue RbNaCl::BadAuthenticatorError
82
- raise Net::SSH::Exception, "corrupted hmac detected #{name}"
83
- end
86
+
87
+ expected_mac = self.class.poly1305_auth(poly_key, data[0..])
88
+ valid_mac = mac.respond_to?(:bytesize) &&
89
+ mac.bytesize == POLY1305_TAG_BYTES &&
90
+ OpenSSL.fixed_length_secure_compare(expected_mac, mac)
91
+ raise Net::SSH::Exception, "corrupted hmac detected #{name}" unless valid_mac
92
+
84
93
  return unencrypted_data
85
94
  end
86
95
 
87
96
  def mac_length
88
- 16
97
+ POLY1305_TAG_BYTES
89
98
  end
90
99
 
91
100
  def block_size
@@ -93,7 +102,7 @@ module Net
93
102
  end
94
103
 
95
104
  def name
96
- "chacha20-poly1305@openssh.com"
105
+ NAME
97
106
  end
98
107
 
99
108
  def implicit_mac?
@@ -111,6 +120,70 @@ module Net
111
120
  def self.key_length
112
121
  64
113
122
  end
123
+
124
+ def self.iv_len
125
+ 0
126
+ end
127
+
128
+ def self.auth_length
129
+ POLY1305_TAG_BYTES
130
+ end
131
+
132
+ def self.decrypt_private_key(ciphertext, auth_tag, key, _initialization_vector)
133
+ raise ArgumentError, "chacha20_poly1305: keylength doesn't match" unless
134
+ key.respond_to?(:bytesize) && key.bytesize == key_length
135
+
136
+ ciphertext = binary_string(ciphertext)
137
+ chacha = OpenSSL::Cipher.new("chacha20")
138
+ chacha.decrypt
139
+ chacha.key = binary_string(key[0...POLY1305_KEY_BYTES])
140
+
141
+ iv_data = ZERO_IV.dup
142
+ chacha.iv = iv_data
143
+ poly_key = chacha.update(ZERO_BLOCK)
144
+
145
+ valid_mac = OpenSSL.fixed_length_secure_compare(poly1305_auth(poly_key, ciphertext), auth_tag)
146
+ raise Net::SSH::Exception, "corrupted hmac detected #{NAME}" unless valid_mac
147
+
148
+ iv_data.setbyte(0, 1)
149
+ chacha.iv = iv_data
150
+ chacha.update(ciphertext)
151
+ end
152
+
153
+ def self.ensure_supported!
154
+ raise UnsupportedError, "OpenSSL::PKey raw private key APIs are unavailable" unless OpenSSL::PKey.respond_to?(:new_raw_private_key)
155
+
156
+ OpenSSL::Cipher.new("chacha20")
157
+
158
+ tag = poly1305_auth("\x00" * POLY1305_KEY_BYTES, "")
159
+ raise UnsupportedError, "OpenSSL Poly1305 authentication failed" unless tag.bytesize == POLY1305_TAG_BYTES
160
+ rescue OpenSSL::Cipher::CipherError, OpenSSL::PKey::PKeyError => e
161
+ raise UnsupportedError, e.message
162
+ end
163
+
164
+ def self.poly1305_auth(poly_key, data)
165
+ validate_poly1305_key!(poly_key)
166
+ OpenSSL::PKey.new_raw_private_key(POLY1305_ALGORITHM, binary_string(poly_key)).sign(nil, binary_string(data))
167
+ end
168
+
169
+ def self.validate_poly1305_key!(poly_key)
170
+ raise ArgumentError, "invalid Poly1305 key" unless poly_key.respond_to?(:bytesize) && poly_key.bytesize == POLY1305_KEY_BYTES
171
+ end
172
+
173
+ def self.binary_string(string)
174
+ string.dup.force_encoding('BINARY')
175
+ end
176
+ private_class_method :binary_string
177
+
178
+ def packet_iv(sequence_number)
179
+ iv_data = ZERO_IV.dup
180
+ iv_data.setbyte(12, (sequence_number >> 24) & 0xff)
181
+ iv_data.setbyte(13, (sequence_number >> 16) & 0xff)
182
+ iv_data.setbyte(14, (sequence_number >> 8) & 0xff)
183
+ iv_data.setbyte(15, sequence_number & 0xff)
184
+ iv_data
185
+ end
186
+ private :packet_iv
114
187
  end
115
188
  end
116
189
  end
@@ -1,15 +1,34 @@
1
1
  module Net
2
2
  module SSH
3
3
  module Transport
4
- # Loads chacha20 poly1305 support which requires optinal dependency rbnacl
4
+ # Loads chacha20-poly1305 support backed by Ruby OpenSSL APIs.
5
5
  module ChaCha20Poly1305CipherLoader
6
6
  begin
7
7
  require 'net/ssh/transport/chacha20_poly1305_cipher'
8
+ Net::SSH::Transport::ChaCha20Poly1305Cipher.ensure_supported!
8
9
  LOADED = true
9
10
  ERROR = nil
10
11
  rescue LoadError => e
11
12
  ERROR = e
12
13
  LOADED = false
14
+ rescue StandardError => e
15
+ if defined?(Net::SSH::Transport::ChaCha20Poly1305Cipher::UnsupportedError) &&
16
+ e.is_a?(Net::SSH::Transport::ChaCha20Poly1305Cipher::UnsupportedError)
17
+ ERROR = e
18
+ LOADED = false
19
+ else
20
+ raise
21
+ end
22
+ end
23
+
24
+ def self.raiseUnlessLoaded(message)
25
+ description = LOADED ? '' : chacha20_poly1305_support_required
26
+ description += "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
27
+ raise NotImplementedError, "#{message}\n#{description}" unless LOADED
28
+ end
29
+
30
+ def self.chacha20_poly1305_support_required
31
+ "net-ssh requires openssl >= 3.2.0 and a crypto backend with ChaCha20 and Poly1305 enabled for chacha20-poly1305@openssh.com support.\n"
13
32
  end
14
33
  end
15
34
  end
@@ -100,7 +100,11 @@ module Net
100
100
  # if :iv_len option is supplied the third return value will be ivlen
101
101
  def self.get_lengths(name, options = {})
102
102
  klass = SSH_TO_CLASS[name]
103
- return [klass.key_length, klass.block_size] unless klass.nil?
103
+ unless klass.nil?
104
+ result = [klass.key_length, klass.block_size]
105
+ result << klass.iv_len if options[:iv_len]
106
+ return result
107
+ end
104
108
 
105
109
  ossl_name = SSH_TO_OSSL[name]
106
110
  if ossl_name.nil? || ossl_name == "none"
@@ -124,6 +128,24 @@ module Net
124
128
  end
125
129
  result
126
130
  end
131
+
132
+ def self.auth_length(name)
133
+ klass = SSH_TO_CLASS[name]
134
+ return klass.auth_length if klass.respond_to?(:auth_length)
135
+
136
+ 0
137
+ end
138
+
139
+ def self.decrypt_private_key(name, ciphertext, auth_tag, key, initialization_vector)
140
+ klass = SSH_TO_CLASS[name]
141
+ raise Net::SSH::Exception, "#{name} does not support private key decryption" unless
142
+ klass.respond_to?(:decrypt_private_key)
143
+
144
+ raise Net::SSH::Exception, "incorrect auth_tag length" unless
145
+ auth_tag.respond_to?(:bytesize) && auth_tag.bytesize == klass.auth_length
146
+
147
+ klass.decrypt_private_key(ciphertext, auth_tag, key, initialization_vector)
148
+ end
127
149
  end
128
150
  end
129
151
  end
@@ -5,7 +5,11 @@ module Net
5
5
  module Transport
6
6
  ## Extension module for aes(128|256)gcm ciphers
7
7
  module GCMCipher
8
- # rubocop:disable Metrics/AbcSize
8
+ BLOCK_SIZE = 16
9
+ IV_BYTES = 12
10
+ AUTH_TAG_BYTES = 16
11
+
12
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
9
13
  def self.extended(orig)
10
14
  # rubocop:disable Metrics/BlockLength
11
15
  orig.class_eval do
@@ -100,15 +104,32 @@ module Net
100
104
  end
101
105
 
102
106
  def mac_length
103
- 16
107
+ GCMCipher::AUTH_TAG_BYTES
104
108
  end
105
109
 
106
110
  def block_size
107
- 16
111
+ GCMCipher::BLOCK_SIZE
108
112
  end
109
113
 
110
114
  def self.block_size
111
- 16
115
+ GCMCipher::BLOCK_SIZE
116
+ end
117
+
118
+ def self.iv_len
119
+ GCMCipher::IV_BYTES
120
+ end
121
+
122
+ def self.auth_length
123
+ GCMCipher::AUTH_TAG_BYTES
124
+ end
125
+
126
+ def self.decrypt_private_key(ciphertext, auth_tag, key, initialization_vector)
127
+ cipher = new(encrypt: false, key: key)
128
+
129
+ cipher.nonce = initialization_vector
130
+ cipher.cipher.auth_tag = auth_tag.to_s
131
+ cipher.cipher.auth_data = ''
132
+ cipher.cipher.update(ciphertext.to_s) << cipher.cipher.final
112
133
  end
113
134
 
114
135
  #
@@ -117,7 +138,7 @@ module Net
117
138
  # N_MAX maximum nonce (IV) length 12 octets
118
139
  #
119
140
  def iv_len
120
- 12
141
+ GCMCipher::IV_BYTES
121
142
  end
122
143
 
123
144
  #
@@ -201,7 +222,7 @@ module Net
201
222
  end
202
223
  # rubocop:enable Metrics/BlockLength
203
224
  end
204
- # rubocop:enable Metrics/AbcSize
225
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
205
226
  end
206
227
  end
207
228
  end
@@ -1,7 +1,4 @@
1
- gem 'x25519' # raise if the gem x25519 is not installed
2
-
3
- require 'x25519'
4
-
1
+ require 'openssl'
5
2
  require 'net/ssh/transport/constants'
6
3
  require 'net/ssh/transport/kex/abstract5656'
7
4
 
@@ -12,25 +9,60 @@ module Net
12
9
  # A key-exchange service implementing the "curve25519-sha256@libssh.org"
13
10
  # key-exchange algorithm. (defined in https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-06)
14
11
  class Curve25519Sha256 < Abstract5656
12
+ ALGORITHM = "X25519"
13
+ KEY_BYTES = 32
14
+
15
+ class UnsupportedError < StandardError; end
16
+
17
+ def self.ensure_supported!
18
+ unless OpenSSL::PKey.respond_to?(:generate_key) && OpenSSL::PKey.respond_to?(:new_raw_public_key)
19
+ raise UnsupportedError, "OpenSSL::PKey raw public key APIs are unavailable"
20
+ end
21
+
22
+ key = generate_x25519_key
23
+ public_key = new_raw_public_key(key.raw_public_key)
24
+ validate_key_bytes!(key.derive(public_key), "shared secret", KEY_BYTES)
25
+ rescue OpenSSL::PKey::PKeyError => e
26
+ raise UnsupportedError, e.message
27
+ end
28
+
29
+ def self.generate_x25519_key
30
+ OpenSSL::PKey.generate_key(ALGORITHM)
31
+ end
32
+
33
+ def self.new_raw_public_key(key)
34
+ validate_key_bytes!(key, "public key", KEY_BYTES)
35
+ OpenSSL::PKey.new_raw_public_key(ALGORITHM, binary_string(key))
36
+ end
37
+
38
+ def self.validate_key_bytes!(key, label, expected_bytes)
39
+ raise ArgumentError, "invalid X25519 #{label}" unless key.respond_to?(:bytesize) && key.bytesize == expected_bytes
40
+ end
41
+
42
+ def self.binary_string(string)
43
+ string.dup.force_encoding('BINARY')
44
+ end
45
+ private_class_method :binary_string
46
+
15
47
  def digester
16
48
  OpenSSL::Digest::SHA256
17
49
  end
18
50
 
19
51
  private
20
52
 
21
- def generate_key # :nodoc:
22
- ::X25519::Scalar.generate
53
+ def generate_key
54
+ self.class.generate_x25519_key
23
55
  end
24
56
 
25
57
  ## string Q_C, client's ephemeral public key octet string
26
58
  def ecdh_public_key_bytes
27
- ecdh.public_key.to_bytes
59
+ ecdh.raw_public_key
28
60
  end
29
61
 
30
62
  # compute shared secret from server's public key and client's private key
31
63
  def compute_shared_secret(server_ecdh_pubkey)
32
- pk = ::X25519::MontgomeryU.new(server_ecdh_pubkey)
33
- OpenSSL::BN.new(ecdh.diffie_hellman(pk).to_bytes, 2)
64
+ pk = self.class.new_raw_public_key(server_ecdh_pubkey)
65
+ OpenSSL::BN.new(ecdh.derive(pk), 2)
34
66
  end
35
67
  end
36
68
  end
@@ -2,26 +2,34 @@ module Net
2
2
  module SSH
3
3
  module Transport
4
4
  module Kex
5
- # Loads Curve25519Sha256 support which requires optinal dependencies
5
+ # Loads Curve25519Sha256 support backed by Ruby OpenSSL X25519 APIs.
6
6
  module Curve25519Sha256Loader
7
7
  begin
8
8
  require 'net/ssh/transport/kex/curve25519_sha256'
9
+ Net::SSH::Transport::Kex::Curve25519Sha256.ensure_supported!
9
10
  LOADED = true
10
11
  ERROR = nil
11
12
  rescue LoadError => e
12
13
  ERROR = e
13
14
  LOADED = false
15
+ rescue StandardError => e
16
+ if defined?(Net::SSH::Transport::Kex::Curve25519Sha256::UnsupportedError) &&
17
+ e.is_a?(Net::SSH::Transport::Kex::Curve25519Sha256::UnsupportedError)
18
+ ERROR = e
19
+ LOADED = false
20
+ else
21
+ raise
22
+ end
14
23
  end
15
24
 
16
25
  def self.raiseUnlessLoaded(message)
17
- description = ERROR.is_a?(LoadError) ? dependenciesRequiredForX25519 : ''
18
- description << "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
26
+ description = LOADED ? '' : x25519SupportRequired
27
+ description += "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
19
28
  raise NotImplementedError, "#{message}\n#{description}" unless LOADED
20
29
  end
21
30
 
22
- def self.dependenciesRequiredForX25519
23
- result = "net-ssh requires the following gems for x25519 support:\n"
24
- result << " * x25519\n"
31
+ def self.x25519SupportRequired
32
+ "net-ssh requires openssl >= 3.2.0 and a crypto backend with X25519 enabled for curve25519-sha256 support.\n"
25
33
  end
26
34
  end
27
35
  end
@@ -19,10 +19,8 @@ module Net
19
19
  # We've never seen this host before, so raise an exception.
20
20
  process_cache_miss(host_keys, arguments, HostKeyUnknown, "is unknown") if host_keys.empty?
21
21
 
22
- # If we found any matches, check to see that the key type and
23
- # blob also match.
24
-
25
- found = host_keys.any? do |key|
22
+ # Find the known-hosts entry whose key matches the presented certificate.
23
+ found_key = host_keys.find do |key|
26
24
  if key.respond_to?(:matches_key?)
27
25
  key.matches_key?(arguments[:key])
28
26
  else
@@ -30,11 +28,17 @@ module Net
30
28
  end
31
29
  end
32
30
 
33
- # If a match was found, return true. Otherwise, raise an exception
34
- # indicating that the key was not recognized.
35
- process_cache_miss(host_keys, arguments, HostKeyMismatch, "does not match") unless found
31
+ # No matching entry found key is not recognized.
32
+ process_cache_miss(host_keys, arguments, HostKeyMismatch, "does not match") unless found_key
33
+
34
+ # For @cert-authority entries, enforce the certificate constraints
35
+ # OpenSSH checks in sshkey_cert_check_authority. A certificate signed by
36
+ # the trusted CA but failing any of these is rejected with
37
+ # HostKeyMismatch (not HostKeyUnknown) so AcceptNew does not swallow the
38
+ # failure and remember the rejected certificate.
39
+ verify_certificate!(found_key, host_keys, arguments)
36
40
 
37
- found
41
+ true
38
42
  end
39
43
 
40
44
  def verify_signature(&block)
@@ -43,6 +47,37 @@ module Net
43
47
 
44
48
  private
45
49
 
50
+ # Enforces the @cert-authority certificate constraints for entries that
51
+ # implement them (Net::SSH::HostKeyEntries::CertAuthority). Non-certificate
52
+ # entries do not respond to these predicates and are left untouched.
53
+ def verify_certificate!(entry, host_keys, arguments)
54
+ cert = arguments[:key]
55
+
56
+ if entry.respond_to?(:matches_validity?) && !entry.matches_validity?(cert)
57
+ reason = if cert.valid_before && cert.valid_before < Time.now
58
+ "Certificate has expired"
59
+ else
60
+ "Certificate is not yet valid"
61
+ end
62
+ process_cache_miss(host_keys, arguments, HostKeyMismatch, reason)
63
+ end
64
+
65
+ if entry.respond_to?(:matches_principal?) && !entry.matches_principal?(cert, host_keys.hostname)
66
+ process_cache_miss(host_keys, arguments, HostKeyMismatch,
67
+ "Certificate invalid: name is not a listed principal")
68
+ end
69
+
70
+ if entry.respond_to?(:matches_type?) && !entry.matches_type?(cert)
71
+ process_cache_miss(host_keys, arguments, HostKeyMismatch,
72
+ "Certificate invalid: not a host certificate")
73
+ end
74
+
75
+ return unless entry.respond_to?(:critical_options_supported?) && !entry.critical_options_supported?(cert)
76
+
77
+ process_cache_miss(host_keys, arguments, HostKeyMismatch,
78
+ "Certificate invalid: unsupported critical option")
79
+ end
80
+
46
81
  def process_cache_miss(host_keys, args, exc_class, message)
47
82
  exception = exc_class.new("fingerprint #{args[:fingerprint]} " +
48
83
  "#{message} for #{host_keys.host.inspect}")
@@ -46,17 +46,17 @@ module Net
46
46
  end
47
47
 
48
48
  # The major component of this version of the Net::SSH library
49
- MAJOR = 7
49
+ MAJOR = 8
50
50
 
51
51
  # The minor component of this version of the Net::SSH library
52
- MINOR = 3
52
+ MINOR = 0
53
53
 
54
54
  # The tiny component of this version of the Net::SSH library
55
- TINY = 3
55
+ TINY = 0
56
56
 
57
57
  # The prerelease component of this version of the Net::SSH library
58
58
  # nil allowed
59
- PRE = nil
59
+ PRE = "beta3"
60
60
 
61
61
  # The current version of the Net::SSH library as a Version instance
62
62
  CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
data/net-ssh.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.description = %q{Net::SSH: a pure-Ruby implementation of the SSH2 client protocol. It allows you to write programs that invoke and interact with processes on remote servers, via SSH2.}
16
16
  spec.homepage = "https://github.com/net-ssh/net-ssh"
17
17
  spec.license = "MIT"
18
- spec.required_ruby_version = Gem::Requirement.new(">= 2.6")
18
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7")
19
19
  spec.metadata = {
20
20
  "changelog_uri" => "https://github.com/net-ssh/net-ssh/blob/master/CHANGES.txt"
21
21
  }
@@ -30,13 +30,9 @@ Gem::Specification.new do |spec|
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
32
 
33
- unless ENV['NET_SSH_NO_ED25519']
34
- spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0") unless RUBY_PLATFORM == "java"
35
- spec.add_development_dependency("ed25519", "~> 1.2")
36
- spec.add_development_dependency('x25519') unless RUBY_PLATFORM == 'java'
37
- end
33
+ spec.add_dependency("openssl", ">= 3.2.0")
38
34
 
39
- spec.add_development_dependency('rbnacl', '~> 7.1') unless ENV['NET_SSH_NO_RBNACL']
35
+ spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0") unless RUBY_PLATFORM == "java"
40
36
 
41
37
  spec.add_development_dependency "base64"
42
38
  spec.add_development_dependency "bundler", ">= 1.17"
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.3
4
+ version: 8.0.0.beta3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
@@ -32,64 +32,36 @@ cert_chain:
32
32
  ufHf4AX2UIkJbh7zCPkiNCqIr7MSWLNFG/9lOlHYsEJM8XujT1ofPobYx6YSFx/C
33
33
  7HBrI7UX7awt6UvBZebhcHzyMHxg/B5PVQllPA==
34
34
  -----END CERTIFICATE-----
35
- date: 2026-06-27 00:00:00.000000000 Z
35
+ date: 2026-08-09 00:00:00.000000000 Z
36
36
  dependencies:
37
37
  - !ruby/object:Gem::Dependency
38
- name: bcrypt_pbkdf
39
- requirement: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - "~>"
42
- - !ruby/object:Gem::Version
43
- version: '1.0'
44
- type: :development
45
- prerelease: false
46
- version_requirements: !ruby/object:Gem::Requirement
47
- requirements:
48
- - - "~>"
49
- - !ruby/object:Gem::Version
50
- version: '1.0'
51
- - !ruby/object:Gem::Dependency
52
- name: ed25519
53
- requirement: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - "~>"
56
- - !ruby/object:Gem::Version
57
- version: '1.2'
58
- type: :development
59
- prerelease: false
60
- version_requirements: !ruby/object:Gem::Requirement
61
- requirements:
62
- - - "~>"
63
- - !ruby/object:Gem::Version
64
- version: '1.2'
65
- - !ruby/object:Gem::Dependency
66
- name: x25519
38
+ name: openssl
67
39
  requirement: !ruby/object:Gem::Requirement
68
40
  requirements:
69
41
  - - ">="
70
42
  - !ruby/object:Gem::Version
71
- version: '0'
72
- type: :development
43
+ version: 3.2.0
44
+ type: :runtime
73
45
  prerelease: false
74
46
  version_requirements: !ruby/object:Gem::Requirement
75
47
  requirements:
76
48
  - - ">="
77
49
  - !ruby/object:Gem::Version
78
- version: '0'
50
+ version: 3.2.0
79
51
  - !ruby/object:Gem::Dependency
80
- name: rbnacl
52
+ name: bcrypt_pbkdf
81
53
  requirement: !ruby/object:Gem::Requirement
82
54
  requirements:
83
55
  - - "~>"
84
56
  - !ruby/object:Gem::Version
85
- version: '7.1'
57
+ version: '1.0'
86
58
  type: :development
87
59
  prerelease: false
88
60
  version_requirements: !ruby/object:Gem::Requirement
89
61
  requirements:
90
62
  - - "~>"
91
63
  - !ruby/object:Gem::Version
92
- version: '7.1'
64
+ version: '1.0'
93
65
  - !ruby/object:Gem::Dependency
94
66
  name: base64
95
67
  requirement: !ruby/object:Gem::Requirement
@@ -214,8 +186,6 @@ files:
214
186
  - Dockerfile.openssl3
215
187
  - Dockerfile.zlib_ng
216
188
  - Gemfile
217
- - Gemfile.noed25519
218
- - Gemfile.norbnacl
219
189
  - ISSUE_TEMPLATE.md
220
190
  - LICENSE.txt
221
191
  - Manifest
@@ -338,12 +308,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
338
308
  requirements:
339
309
  - - ">="
340
310
  - !ruby/object:Gem::Version
341
- version: '2.6'
311
+ version: '2.7'
342
312
  required_rubygems_version: !ruby/object:Gem::Requirement
343
313
  requirements:
344
- - - ">="
314
+ - - ">"
345
315
  - !ruby/object:Gem::Version
346
- version: '0'
316
+ version: 1.3.1
347
317
  requirements: []
348
318
  rubygems_version: 3.3.3
349
319
  signing_key:
metadata.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- 6l���o�GBާ|����3p���Ks�Lc��!!�vt|�Eq�"��Y�_��j�͆�GRT�b��0�Y����S
2
- curO40HS켮��p�+s#�����S��2T4�;T���Z}����7��`�jO���֯�0H�Ӑ���TM�@�,(�?���@)^s2���A�!�>� �|k3k)4��>�����l���Ew���g
1
+ �E��w ,#g�!g���c�D��gH�͗
2
+ �`��_aGX�b��z\ ��%魠���|�%�v?Mh��"��U4Q���W��mr��"H��[�7hHh���[�ڂf��ꄫ���~]��U4�ͽ^T�^86�3L������� �g�^�ŕ"+d3̼����\�LK������(�}j-�m�,�"����&3\�V��B#�t|�:4�a� ��˹֯��
data/Gemfile.noed25519 DELETED
@@ -1,12 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- ENV['NET_SSH_NO_ED25519'] = 'true'
4
- # Specify your gem's dependencies in mygem.gemspec
5
- gemspec
6
-
7
- if ENV["CI"] && !Gem.win_platform?
8
- gem 'simplecov', require: false, group: :test
9
- gem 'codecov', require: false, group: :test
10
- end
11
-
12
- gem 'webrick', group: %i[development test] if RUBY_VERSION.split(".")[0].to_i >= 3