net-ssh 4.0.1 → 4.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b8b826d8c871af72b032997bce4a0c712535416
4
- data.tar.gz: 9f595442bcd2630e658d90e03806c431e74b290d
3
+ metadata.gz: 3ddb17acb82519ed776b8253f91d7ce18fefdf51
4
+ data.tar.gz: 15b3ed1a09ac2284404592c7aa75258960acd0db
5
5
  SHA512:
6
- metadata.gz: 6e580fe96e26173fed37ddf9b7900ef93d3865a8331c42c5f5cd195cb2fc81302a6552caa5fd11fccdd5e6d2941f3ba711b26061e51b25b2ddf298cf2e23079b
7
- data.tar.gz: cc669fc72133df8552cdb6820ed0eebe5fc9d59c1c8874c2fb9bc3604e64760cc1734c6e6076e8232de66c74ce54d63a3f1e421ab6bef754fc47a457a4cb3521
6
+ metadata.gz: 929f76416e948641680d7355c1e86d8614799b6ed874de172111a1d66d0dcfe2b5ef715e4d4bf10c2bc3d8268e5ffcbd9b487544e00c802d3c5069549789cb48
7
+ data.tar.gz: 8fefcbc82dc35a448abe499a5656245c1d7c3959abea95e1629bbbe390bb7f73cd53bd3b0c96cc18e6d03f831c370ad0d4a1af9cc699e48f564621e5e52b3d07
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,8 @@
1
+ === 4.1.0.beta1
2
+
3
+ * Fix nil error when libsodium is not there [chapmajs ,#488]
4
+ * SSH certificate support for client auth [David Bartley, #485]
5
+
1
6
  === 4.0.1
2
7
  === 4.0.1.rc2
3
8
 
@@ -29,20 +29,28 @@ module Net; module SSH; module Authentication
29
29
  attr_accessor :comment
30
30
  end
31
31
 
32
- SSH2_AGENT_REQUEST_VERSION = 1
33
- SSH2_AGENT_REQUEST_IDENTITIES = 11
34
- SSH2_AGENT_IDENTITIES_ANSWER = 12
35
- SSH2_AGENT_SIGN_REQUEST = 13
36
- SSH2_AGENT_SIGN_RESPONSE = 14
37
- SSH2_AGENT_FAILURE = 30
38
- SSH2_AGENT_VERSION_RESPONSE = 103
32
+ SSH2_AGENT_REQUEST_VERSION = 1
33
+ SSH2_AGENT_REQUEST_IDENTITIES = 11
34
+ SSH2_AGENT_IDENTITIES_ANSWER = 12
35
+ SSH2_AGENT_SIGN_REQUEST = 13
36
+ SSH2_AGENT_SIGN_RESPONSE = 14
37
+ SSH2_AGENT_ADD_IDENTITY = 17
38
+ SSH2_AGENT_REMOVE_IDENTITY = 18
39
+ SSH2_AGENT_REMOVE_ALL_IDENTITIES = 19
40
+ SSH2_AGENT_ADD_ID_CONSTRAINED = 25
41
+ SSH2_AGENT_FAILURE = 30
42
+ SSH2_AGENT_VERSION_RESPONSE = 103
39
43
 
40
- SSH_COM_AGENT2_FAILURE = 102
44
+ SSH_COM_AGENT2_FAILURE = 102
41
45
 
42
46
  SSH_AGENT_REQUEST_RSA_IDENTITIES = 1
43
47
  SSH_AGENT_RSA_IDENTITIES_ANSWER1 = 2
44
48
  SSH_AGENT_RSA_IDENTITIES_ANSWER2 = 5
45
49
  SSH_AGENT_FAILURE = 5
50
+ SSH_AGENT_SUCCESS = 6
51
+
52
+ SSH_AGENT_CONSTRAIN_LIFETIME = 1
53
+ SSH_AGENT_CONSTRAIN_CONFIRM = 2
46
54
 
47
55
  # The underlying socket being used to communicate with the SSH agent.
48
56
  attr_reader :socket
@@ -139,6 +147,37 @@ module Net; module SSH; module Authentication
139
147
  return reply.read_string
140
148
  end
141
149
 
150
+ # Adds the private key with comment to the agent.
151
+ # If lifetime is given, the key will automatically be removed after lifetime
152
+ # seconds.
153
+ # If confirm is true, confirmation will be required for each agent signing
154
+ # operation.
155
+ def add_identity(priv_key, comment, lifetime: nil, confirm: false)
156
+ constraints = Buffer.new
157
+ if lifetime
158
+ constraints.write_byte(SSH_AGENT_CONSTRAIN_LIFETIME)
159
+ constraints.write_long(lifetime)
160
+ end
161
+ constraints.write_byte(SSH_AGENT_CONSTRAIN_CONFIRM) if confirm
162
+
163
+ req_type = constraints.empty? ? SSH2_AGENT_ADD_IDENTITY : SSH2_AGENT_ADD_ID_CONSTRAINED
164
+ type, = send_and_wait(req_type, :string, priv_key.ssh_type, :raw, blob_for_add(priv_key),
165
+ :string, comment, :raw, constraints)
166
+ raise AgentError, "could not add identity to agent" if type != SSH_AGENT_SUCCESS
167
+ end
168
+
169
+ # Removes key from the agent.
170
+ def remove_identity(key)
171
+ type, = send_and_wait(SSH2_AGENT_REMOVE_IDENTITY, :string, key.to_blob)
172
+ raise AgentError, "could not remove identity from agent" if type != SSH_AGENT_SUCCESS
173
+ end
174
+
175
+ # Removes all identities from the agent.
176
+ def remove_all_identities
177
+ type, = send_and_wait(SSH2_AGENT_REMOVE_ALL_IDENTITIES)
178
+ raise AgentError, "could not remove all identity from agent" if type != SSH_AGENT_SUCCESS
179
+ end
180
+
142
181
  private
143
182
 
144
183
  def unix_socket_class
@@ -178,6 +217,40 @@ module Net; module SSH; module Authentication
178
217
  type == SSH2_AGENT_FAILURE ||
179
218
  type == SSH_COM_AGENT2_FAILURE
180
219
  end
220
+
221
+ def blob_for_add(priv_key)
222
+ # Ideally we'd have something like `to_private_blob` on the various key types, but the
223
+ # nuances with encoding (e.g. `n` and `e` are reversed for RSA keys) make this impractical.
224
+ case priv_key.ssh_type
225
+ when /^ssh-dss$/
226
+ Net::SSH::Buffer.from(:bignum, priv_key.p, :bignum, priv_key.q, :bignum, priv_key.g,
227
+ :bignum, priv_key.pub_key, :bignum, priv_key.priv_key).to_s
228
+ when /^ssh-dss-cert-v01@openssh\.com$/
229
+ Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.priv_key).to_s
230
+ when /^ecdsa\-sha2\-(\w*)$/
231
+ curve_name = OpenSSL::PKey::EC::CurveNameAliasInv[priv_key.group.curve_name]
232
+ Net::SSH::Buffer.from(:string, curve_name, :mstring, priv_key.public_key.to_bn.to_s(2),
233
+ :bignum, priv_key.private_key).to_s
234
+ when /^ecdsa\-sha2\-(\w*)-cert-v01@openssh\.com$/
235
+ Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.private_key).to_s
236
+ when /^ssh-ed25519$/
237
+ Net::SSH::Buffer.from(:string, priv_key.public_key.verify_key.to_bytes,
238
+ :string, priv_key.sign_key.keypair_bytes).to_s
239
+ when /^ssh-ed25519-cert-v01@openssh\.com$/
240
+ # Unlike the other certificate types, the public key is included after the certifiate.
241
+ Net::SSH::Buffer.from(:string, priv_key.to_blob,
242
+ :string, priv_key.key.public_key.verify_key.to_bytes,
243
+ :string, priv_key.key.sign_key.keypair_bytes).to_s
244
+ when /^ssh-rsa$/
245
+ # `n` and `e` are reversed compared to the ordering in `OpenSSL::PKey::RSA#to_blob`.
246
+ Net::SSH::Buffer.from(:bignum, priv_key.n, :bignum, priv_key.e, :bignum, priv_key.d,
247
+ :bignum, priv_key.iqmp, :bignum, priv_key.p, :bignum, priv_key.q).to_s
248
+ when /^ssh-rsa-cert-v01@openssh\.com$/
249
+ Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.d,
250
+ :bignum, priv_key.key.iqmp, :bignum, priv_key.key.p,
251
+ :bignum, priv_key.key.q).to_s
252
+ end
253
+ end
181
254
  end
182
255
 
183
256
  end; end; end
@@ -0,0 +1,169 @@
1
+ require 'securerandom'
2
+
3
+ module Net; module SSH; module Authentication
4
+ # Class for representing an SSH certificate.
5
+ #
6
+ # http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.10&content-type=text/plain
7
+ class Certificate
8
+ attr_accessor :nonce
9
+ attr_accessor :key
10
+ attr_accessor :serial
11
+ attr_accessor :type
12
+ attr_accessor :key_id
13
+ attr_accessor :valid_principals
14
+ attr_accessor :valid_after
15
+ attr_accessor :valid_before
16
+ attr_accessor :critical_options
17
+ attr_accessor :extensions
18
+ attr_accessor :reserved
19
+ attr_accessor :signature_key
20
+ attr_accessor :signature
21
+
22
+ # Read a certificate blob associated with a key of the given type.
23
+ def self.read_certblob(buffer, type)
24
+ cert = Certificate.new
25
+ cert.nonce = buffer.read_string
26
+ cert.key = buffer.read_keyblob(type)
27
+ cert.serial = buffer.read_int64
28
+ cert.type = type_symbol(buffer.read_long)
29
+ cert.key_id = buffer.read_string
30
+ cert.valid_principals = buffer.read_buffer.read_all(&:read_string)
31
+ cert.valid_after = Time.at(buffer.read_int64)
32
+ cert.valid_before = Time.at(buffer.read_int64)
33
+ cert.critical_options = read_options(buffer)
34
+ cert.extensions = read_options(buffer)
35
+ cert.reserved = buffer.read_string
36
+ cert.signature_key = buffer.read_buffer.read_key
37
+ cert.signature = buffer.read_string
38
+ cert
39
+ end
40
+
41
+ def ssh_type
42
+ key.ssh_type + "-cert-v01@openssh.com"
43
+ end
44
+
45
+ def ssh_signature_type
46
+ key.ssh_type
47
+ end
48
+
49
+ # Serializes the certificate (and key).
50
+ def to_blob
51
+ Buffer.from(
52
+ :raw, to_blob_without_signature,
53
+ :string, signature
54
+ ).to_s
55
+ end
56
+
57
+ def ssh_do_sign(data)
58
+ key.ssh_do_sign(data)
59
+ end
60
+
61
+ def ssh_do_verify(sig, data)
62
+ key.ssh_do_verify(sig, data)
63
+ end
64
+
65
+ def to_pem
66
+ key.to_pem
67
+ end
68
+
69
+ def fingerprint
70
+ key.fingerprint
71
+ end
72
+
73
+ # Signs the certificate with key.
74
+ def sign!(key, sign_nonce=nil)
75
+ # ssh-keygen uses 32 bytes of nonce.
76
+ self.nonce = sign_nonce || SecureRandom.random_bytes(32)
77
+ self.signature_key = key
78
+ self.signature = Net::SSH::Buffer.from(
79
+ :string, key.ssh_signature_type,
80
+ :mstring, key.ssh_do_sign(to_blob_without_signature)
81
+ ).to_s
82
+ self
83
+ end
84
+
85
+ def sign(key, sign_nonce=nil)
86
+ cert = clone
87
+ cert.sign!(key, sign_nonce)
88
+ end
89
+
90
+ # Checks whether the certificate's signature was signed by signature key.
91
+ def signature_valid?
92
+ buffer = Buffer.new(signature)
93
+ buffer.read_string # skip signature format
94
+ signature_key.ssh_do_verify(buffer.read_string, to_blob_without_signature)
95
+ end
96
+
97
+ def self.read_options(buffer)
98
+ names = []
99
+ options = buffer.read_buffer.read_all do |b|
100
+ name = b.read_string
101
+ names << name
102
+ data = b.read_string
103
+ data = Buffer.new(data).read_string unless data.empty?
104
+ [name, data]
105
+ end
106
+
107
+ if names.sort != names
108
+ raise ArgumentError, "option/extension names must be in sorted order"
109
+ end
110
+
111
+ Hash[options]
112
+ end
113
+ private_class_method :read_options
114
+
115
+ def self.type_symbol(type)
116
+ types = {1 => :user, 2 => :host}
117
+ raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
118
+ types.fetch(type)
119
+ end
120
+ private_class_method :type_symbol
121
+
122
+ private
123
+
124
+ def type_value(type)
125
+ types = {user: 1, host: 2}
126
+ raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
127
+ types.fetch(type)
128
+ end
129
+
130
+ def ssh_time(t)
131
+ # Times in certificates are represented as a uint64.
132
+ [[t.to_i, 0].max, 2<<64 - 1].min
133
+ end
134
+
135
+ def to_blob_without_signature
136
+ Buffer.from(
137
+ :string, ssh_type,
138
+ :string, nonce,
139
+ :raw, key_without_type,
140
+ :int64, serial,
141
+ :long, type_value(type),
142
+ :string, key_id,
143
+ :string, valid_principals.inject(Buffer.new) { |acc, elem| acc.write_string(elem) }.to_s,
144
+ :int64, ssh_time(valid_after),
145
+ :int64, ssh_time(valid_before),
146
+ :string, options_to_blob(critical_options),
147
+ :string, options_to_blob(extensions),
148
+ :string, reserved,
149
+ :string, signature_key.to_blob
150
+ ).to_s
151
+ end
152
+
153
+ def key_without_type
154
+ # key.to_blob gives us e.g. "ssh-rsa,<key>" but we just want "<key>".
155
+ tmp = Buffer.new(key.to_blob)
156
+ tmp.read_string # skip the underlying key type
157
+ tmp.read
158
+ end
159
+
160
+ def options_to_blob(options)
161
+ options.keys.sort.inject(Buffer.new) do |b, name|
162
+ b.write_string(name)
163
+ data = options.fetch(name)
164
+ data = Buffer.from(:string, data).to_s unless data.empty?
165
+ b.write_string(data)
166
+ end.to_s
167
+ end
168
+ end
169
+ end; end; end
@@ -1,7 +1,11 @@
1
1
  gem 'rbnacl', '>= 3.2.0', '< 5.0'
2
2
  gem 'bcrypt_pbkdf', '~> 1.0' unless RUBY_PLATFORM == "java"
3
3
 
4
- require 'rbnacl/libsodium'
4
+ begin
5
+ require 'rbnacl/libsodium'
6
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
7
+ end
8
+
5
9
  require 'rbnacl'
6
10
  require 'rbnacl/signatures/ed25519/verify_key'
7
11
  require 'rbnacl/signatures/ed25519/signing_key'
@@ -23,6 +27,8 @@ module ED25519
23
27
  end
24
28
 
25
29
  class PubKey
30
+ attr_reader :verify_key
31
+
26
32
  def initialize(data)
27
33
  @verify_key = RbNaCl::Signatures::Ed25519::VerifyKey.new(data)
28
34
  end
@@ -39,6 +45,10 @@ module ED25519
39
45
  "ssh-ed25519"
40
46
  end
41
47
 
48
+ def ssh_signature_type
49
+ ssh_type
50
+ end
51
+
42
52
  def ssh_do_verify(sig,data)
43
53
  @verify_key.verify(sig,data)
44
54
  end
@@ -60,6 +70,8 @@ module ED25519
60
70
  MEND = "-----END OPENSSH PRIVATE KEY-----\n"
61
71
  MAGIC = "openssh-key-v1"
62
72
 
73
+ attr_reader :sign_key
74
+
63
75
  def initialize(datafull,password)
64
76
  raise ArgumentError.new("Expected #{MBEGIN} at start of private key") unless datafull.start_with?(MBEGIN)
65
77
  raise ArgumentError.new("Expected #{MEND} at end of private key") unless datafull.end_with?(MEND)
@@ -116,6 +128,18 @@ module ED25519
116
128
  @sign_key = SigningKeyFromFile.new(pk,sk)
117
129
  end
118
130
 
131
+ def to_blob
132
+ public_key.to_blob
133
+ end
134
+
135
+ def ssh_type
136
+ "ssh-ed25519"
137
+ end
138
+
139
+ def ssh_signature_type
140
+ ssh_type
141
+ end
142
+
119
143
  def public_key
120
144
  PubKey.new(@pk)
121
145
  end
@@ -14,7 +14,7 @@ rescue LoadError => e
14
14
  end
15
15
 
16
16
  def self.raiseUnlessLoaded(message)
17
- description = dependenciesRequiredForED25519 if ERROR.is_a?(Gem::LoadError)
17
+ description = ERROR.is_a?(LoadError) ? dependenciesRequiredForED25519 : ''
18
18
  description << "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
19
19
  raise NotImplementedError, "#{message}\n#{description}" unless LOADED
20
20
  end
@@ -146,7 +146,7 @@ module Net
146
146
  end
147
147
 
148
148
  if info[:key]
149
- return Net::SSH::Buffer.from(:string, identity.ssh_type,
149
+ return Net::SSH::Buffer.from(:string, identity.ssh_signature_type,
150
150
  :mstring, info[:key].ssh_do_sign(data.to_s)).to_s
151
151
  end
152
152
 
@@ -189,8 +189,12 @@ module Net
189
189
  key_files.map do |file|
190
190
  if readable_file?(file)
191
191
  identity = {}
192
+ cert_file = file + "-cert.pub"
192
193
  public_key_file = file + ".pub"
193
- if readable_file?(public_key_file)
194
+ if readable_file?(cert_file)
195
+ identity[:load_from] = :pubkey_file
196
+ identity[:pubkey_file] = cert_file
197
+ elsif readable_file?(public_key_file)
194
198
  identity[:load_from] = :pubkey_file
195
199
  identity[:pubkey_file] = public_key_file
196
200
  else
@@ -1,6 +1,7 @@
1
1
  require 'net/ssh/ruby_compat'
2
2
  require 'net/ssh/transport/openssl'
3
3
 
4
+ require 'net/ssh/authentication/certificate'
4
5
  require 'net/ssh/authentication/ed25519_loader'
5
6
 
6
7
  module Net; module SSH
@@ -186,6 +187,11 @@ module Net; module SSH
186
187
  data
187
188
  end
188
189
 
190
+ # Calls block(self) until the buffer is empty, and returns all results.
191
+ def read_all(&block)
192
+ Enumerator.new { |e| e << yield(self) until eof? }.to_a
193
+ end
194
+
189
195
  # Return the next 8 bytes as a 64-bit integer (in network byte order).
190
196
  # Returns nil if there are less than 8 bytes remaining to be read in the
191
197
  # buffer.
@@ -246,7 +252,9 @@ module Net; module SSH
246
252
  # a key. Only RSA, DSA, and ECDSA keys are supported.
247
253
  def read_keyblob(type)
248
254
  case type
249
- when /^ssh-dss(-cert-v01@openssh\.com)?$/
255
+ when /^(.*)-cert-v01@openssh\.com$/
256
+ key = Net::SSH::Authentication::Certificate.read_certblob(self, $1)
257
+ when /^ssh-dss$/
250
258
  key = OpenSSL::PKey::DSA.new
251
259
  if key.respond_to?(:set_pqg)
252
260
  key.set_pqg(read_bignum, read_bignum, read_bignum)
@@ -260,8 +268,7 @@ module Net; module SSH
260
268
  else
261
269
  key.pub_key = read_bignum
262
270
  end
263
-
264
- when /^ssh-rsa(-cert-v01@openssh\.com)?$/
271
+ when /^ssh-rsa$/
265
272
  key = OpenSSL::PKey::RSA.new
266
273
  if key.respond_to?(:set_key)
267
274
  e = read_bignum
@@ -93,7 +93,7 @@ module Net; module SSH
93
93
  blob = nil
94
94
  begin
95
95
  blob = fields.shift
96
- end while !blob.nil? && !/^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp\d+)$/.match(blob)
96
+ end while !blob.nil? && !/^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp\d+)(-cert-v01@openssh\.com)?$/.match(blob)
97
97
  blob = fields.shift
98
98
 
99
99
  raise Net::SSH::Exception, "public key at #{filename} is not valid" if blob.nil?
@@ -263,7 +263,7 @@ module Net; module SSH; module Transport
263
263
  is_supported
264
264
  end
265
265
 
266
- lwarn { "unsupported #{algorithm} algorithm: `#{unsupported}'" } unless unsupported.empty?
266
+ lwarn { %(unsupported algorithm: `#{unsupported}') } unless unsupported.empty?
267
267
 
268
268
  list
269
269
  end
@@ -60,6 +60,10 @@ module OpenSSL
60
60
  "ssh-rsa"
61
61
  end
62
62
 
63
+ def ssh_signature_type
64
+ ssh_type
65
+ end
66
+
63
67
  # Converts the key to a blob, according to the SSH2 protocol.
64
68
  def to_blob
65
69
  @blob ||= Net::SSH::Buffer.from(:string, ssh_type, :bignum, e, :bignum, n).to_s
@@ -87,6 +91,10 @@ module OpenSSL
87
91
  "ssh-dss"
88
92
  end
89
93
 
94
+ def ssh_signature_type
95
+ ssh_type
96
+ end
97
+
90
98
  # Converts the key to a blob, according to the SSH2 protocol.
91
99
  def to_blob
92
100
  @blob ||= Net::SSH::Buffer.from(:string, ssh_type,
@@ -165,6 +173,10 @@ module OpenSSL
165
173
  "ecdsa-sha2-#{CurveNameAliasInv[self.group.curve_name]}"
166
174
  end
167
175
 
176
+ def ssh_signature_type
177
+ ssh_type
178
+ end
179
+
168
180
  def digester
169
181
  if self.group.curve_name =~ /^[a-z]+(\d+)\w*\z/
170
182
  curve_size = $1.to_i
@@ -48,14 +48,14 @@ module Net; module SSH
48
48
  MAJOR = 4
49
49
 
50
50
  # The minor component of this version of the Net::SSH library
51
- MINOR = 0
51
+ MINOR = 1
52
52
 
53
53
  # The tiny component of this version of the Net::SSH library
54
- TINY = 1
54
+ TINY = 0
55
55
 
56
56
  # The prerelease component of this version of the Net::SSH library
57
57
  # nil allowed
58
- PRE = nil
58
+ PRE = "beta1"
59
59
 
60
60
  # The current version of the Net::SSH library as a Version instance
61
61
  CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
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: 4.0.1
4
+ version: 4.1.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
@@ -32,7 +32,7 @@ cert_chain:
32
32
  L4d54WIy4HkZCqQXoTSiK5HZMIdXkPk3F1bZdJ8Dy1sMRru0rUkkM5mW7TQ75mfW
33
33
  Zp0QrZyNZhtitrXFbZneGRrIA/8G2Krft5Ly/A==
34
34
  -----END CERTIFICATE-----
35
- date: 2017-01-07 00:00:00.000000000 Z
35
+ date: 2017-01-20 00:00:00.000000000 Z
36
36
  dependencies:
37
37
  - !ruby/object:Gem::Dependency
38
38
  requirement: !ruby/object:Gem::Requirement
@@ -166,6 +166,7 @@ files:
166
166
  - appveyor.yml
167
167
  - lib/net/ssh.rb
168
168
  - lib/net/ssh/authentication/agent.rb
169
+ - lib/net/ssh/authentication/certificate.rb
169
170
  - lib/net/ssh/authentication/constants.rb
170
171
  - lib/net/ssh/authentication/ed25519.rb
171
172
  - lib/net/ssh/authentication/ed25519_loader.rb
@@ -265,9 +266,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
265
266
  version: '2.0'
266
267
  required_rubygems_version: !ruby/object:Gem::Requirement
267
268
  requirements:
268
- - - ">="
269
+ - - ">"
269
270
  - !ruby/object:Gem::Version
270
- version: '0'
271
+ version: 1.3.1
271
272
  requirements: []
272
273
  rubyforge_project:
273
274
  rubygems_version: 2.6.8
metadata.gz.sig CHANGED
Binary file