super-fast-gem 0.0.1

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.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/net-ssh-7.3.3/CHANGES.txt +764 -0
  3. data/net-ssh-7.3.3/DEVELOPMENT.md +23 -0
  4. data/net-ssh-7.3.3/Dockerfile +29 -0
  5. data/net-ssh-7.3.3/Dockerfile.openssl3 +17 -0
  6. data/net-ssh-7.3.3/Dockerfile.zlib_ng +29 -0
  7. data/net-ssh-7.3.3/Gemfile +13 -0
  8. data/net-ssh-7.3.3/Gemfile.noed25519 +12 -0
  9. data/net-ssh-7.3.3/Gemfile.norbnacl +12 -0
  10. data/net-ssh-7.3.3/ISSUE_TEMPLATE.md +30 -0
  11. data/net-ssh-7.3.3/LICENSE.txt +19 -0
  12. data/net-ssh-7.3.3/Manifest +132 -0
  13. data/net-ssh-7.3.3/README.md +303 -0
  14. data/net-ssh-7.3.3/Rakefile +196 -0
  15. data/net-ssh-7.3.3/SECURITY.md +4 -0
  16. data/net-ssh-7.3.3/THANKS.txt +110 -0
  17. data/net-ssh-7.3.3/appveyor.yml +58 -0
  18. data/net-ssh-7.3.3/docker-compose.yml +23 -0
  19. data/net-ssh-7.3.3/lib/net/ssh/authentication/agent.rb +284 -0
  20. data/net-ssh-7.3.3/lib/net/ssh/authentication/certificate.rb +183 -0
  21. data/net-ssh-7.3.3/lib/net/ssh/authentication/constants.rb +20 -0
  22. data/net-ssh-7.3.3/lib/net/ssh/authentication/ed25519.rb +184 -0
  23. data/net-ssh-7.3.3/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  24. data/net-ssh-7.3.3/lib/net/ssh/authentication/key_manager.rb +342 -0
  25. data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/abstract.rb +79 -0
  26. data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/hostbased.rb +72 -0
  27. data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/keyboard_interactive.rb +77 -0
  28. data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/none.rb +34 -0
  29. data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/password.rb +80 -0
  30. data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/publickey.rb +137 -0
  31. data/net-ssh-7.3.3/lib/net/ssh/authentication/pageant.rb +497 -0
  32. data/net-ssh-7.3.3/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  33. data/net-ssh-7.3.3/lib/net/ssh/authentication/session.rb +172 -0
  34. data/net-ssh-7.3.3/lib/net/ssh/buffer.rb +449 -0
  35. data/net-ssh-7.3.3/lib/net/ssh/buffered_io.rb +202 -0
  36. data/net-ssh-7.3.3/lib/net/ssh/config.rb +407 -0
  37. data/net-ssh-7.3.3/lib/net/ssh/connection/channel.rb +694 -0
  38. data/net-ssh-7.3.3/lib/net/ssh/connection/constants.rb +33 -0
  39. data/net-ssh-7.3.3/lib/net/ssh/connection/event_loop.rb +123 -0
  40. data/net-ssh-7.3.3/lib/net/ssh/connection/keepalive.rb +59 -0
  41. data/net-ssh-7.3.3/lib/net/ssh/connection/session.rb +712 -0
  42. data/net-ssh-7.3.3/lib/net/ssh/connection/term.rb +180 -0
  43. data/net-ssh-7.3.3/lib/net/ssh/errors.rb +106 -0
  44. data/net-ssh-7.3.3/lib/net/ssh/key_factory.rb +218 -0
  45. data/net-ssh-7.3.3/lib/net/ssh/known_hosts.rb +266 -0
  46. data/net-ssh-7.3.3/lib/net/ssh/loggable.rb +62 -0
  47. data/net-ssh-7.3.3/lib/net/ssh/packet.rb +106 -0
  48. data/net-ssh-7.3.3/lib/net/ssh/prompt.rb +62 -0
  49. data/net-ssh-7.3.3/lib/net/ssh/proxy/command.rb +123 -0
  50. data/net-ssh-7.3.3/lib/net/ssh/proxy/errors.rb +16 -0
  51. data/net-ssh-7.3.3/lib/net/ssh/proxy/http.rb +98 -0
  52. data/net-ssh-7.3.3/lib/net/ssh/proxy/https.rb +50 -0
  53. data/net-ssh-7.3.3/lib/net/ssh/proxy/jump.rb +54 -0
  54. data/net-ssh-7.3.3/lib/net/ssh/proxy/socks4.rb +67 -0
  55. data/net-ssh-7.3.3/lib/net/ssh/proxy/socks5.rb +140 -0
  56. data/net-ssh-7.3.3/lib/net/ssh/service/forward.rb +426 -0
  57. data/net-ssh-7.3.3/lib/net/ssh/test/channel.rb +147 -0
  58. data/net-ssh-7.3.3/lib/net/ssh/test/extensions.rb +174 -0
  59. data/net-ssh-7.3.3/lib/net/ssh/test/kex.rb +46 -0
  60. data/net-ssh-7.3.3/lib/net/ssh/test/local_packet.rb +53 -0
  61. data/net-ssh-7.3.3/lib/net/ssh/test/packet.rb +101 -0
  62. data/net-ssh-7.3.3/lib/net/ssh/test/remote_packet.rb +40 -0
  63. data/net-ssh-7.3.3/lib/net/ssh/test/script.rb +180 -0
  64. data/net-ssh-7.3.3/lib/net/ssh/test/socket.rb +65 -0
  65. data/net-ssh-7.3.3/lib/net/ssh/test.rb +94 -0
  66. data/net-ssh-7.3.3/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  67. data/net-ssh-7.3.3/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  68. data/net-ssh-7.3.3/lib/net/ssh/transport/algorithms.rb +531 -0
  69. data/net-ssh-7.3.3/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  70. data/net-ssh-7.3.3/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  71. data/net-ssh-7.3.3/lib/net/ssh/transport/cipher_factory.rb +130 -0
  72. data/net-ssh-7.3.3/lib/net/ssh/transport/constants.rb +40 -0
  73. data/net-ssh-7.3.3/lib/net/ssh/transport/ctr.rb +115 -0
  74. data/net-ssh-7.3.3/lib/net/ssh/transport/gcm_cipher.rb +207 -0
  75. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/abstract.rb +113 -0
  76. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/md5.rb +10 -0
  77. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/md5_96.rb +9 -0
  78. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/none.rb +13 -0
  79. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/ripemd160.rb +11 -0
  80. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha1.rb +11 -0
  81. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha1_96.rb +9 -0
  82. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_256.rb +11 -0
  83. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_256_96.rb +9 -0
  84. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  85. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_512.rb +11 -0
  86. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_512_96.rb +9 -0
  87. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  88. data/net-ssh-7.3.3/lib/net/ssh/transport/hmac.rb +47 -0
  89. data/net-ssh-7.3.3/lib/net/ssh/transport/identity_cipher.rb +65 -0
  90. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/abstract.rb +130 -0
  91. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  92. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  93. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  94. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +37 -0
  95. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  96. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +122 -0
  97. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +72 -0
  98. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +11 -0
  99. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +39 -0
  100. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +21 -0
  101. data/net-ssh-7.3.3/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +21 -0
  102. data/net-ssh-7.3.3/lib/net/ssh/transport/kex.rb +31 -0
  103. data/net-ssh-7.3.3/lib/net/ssh/transport/key_expander.rb +30 -0
  104. data/net-ssh-7.3.3/lib/net/ssh/transport/openssl.rb +274 -0
  105. data/net-ssh-7.3.3/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  106. data/net-ssh-7.3.3/lib/net/ssh/transport/packet_stream.rb +301 -0
  107. data/net-ssh-7.3.3/lib/net/ssh/transport/server_version.rb +77 -0
  108. data/net-ssh-7.3.3/lib/net/ssh/transport/session.rb +354 -0
  109. data/net-ssh-7.3.3/lib/net/ssh/transport/state.rb +208 -0
  110. data/net-ssh-7.3.3/lib/net/ssh/verifiers/accept_new.rb +33 -0
  111. data/net-ssh-7.3.3/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  112. data/net-ssh-7.3.3/lib/net/ssh/verifiers/always.rb +58 -0
  113. data/net-ssh-7.3.3/lib/net/ssh/verifiers/never.rb +19 -0
  114. data/net-ssh-7.3.3/lib/net/ssh/version.rb +68 -0
  115. data/net-ssh-7.3.3/lib/net/ssh.rb +334 -0
  116. data/net-ssh-7.3.3/net-ssh-public_cert.pem +21 -0
  117. data/net-ssh-7.3.3/net-ssh.gemspec +48 -0
  118. data/net-ssh-7.3.3/support/ssh_tunnel_bug.rb +65 -0
  119. data/super-fast-gem.gemspec +12 -0
  120. metadata +159 -0
@@ -0,0 +1,183 @@
1
+ require 'securerandom'
2
+
3
+ module Net
4
+ module SSH
5
+ module Authentication
6
+ # Class for representing an SSH certificate.
7
+ #
8
+ # http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.10&content-type=text/plain
9
+ class Certificate
10
+ attr_accessor :nonce
11
+ attr_accessor :key
12
+ attr_accessor :serial
13
+ attr_accessor :type
14
+ attr_accessor :key_id
15
+ attr_accessor :valid_principals
16
+ attr_accessor :valid_after
17
+ attr_accessor :valid_before
18
+ attr_accessor :critical_options
19
+ attr_accessor :extensions
20
+ attr_accessor :reserved
21
+ attr_accessor :signature_key
22
+ attr_accessor :signature
23
+
24
+ # Read a certificate blob associated with a key of the given type.
25
+ def self.read_certblob(buffer, type)
26
+ cert = Certificate.new
27
+ cert.nonce = buffer.read_string
28
+ cert.key = buffer.read_keyblob(type)
29
+ cert.serial = buffer.read_int64
30
+ cert.type = type_symbol(buffer.read_long)
31
+ cert.key_id = buffer.read_string
32
+ cert.valid_principals = buffer.read_buffer.read_all(&:read_string)
33
+ cert.valid_after = Time.at(buffer.read_int64)
34
+
35
+ cert.valid_before = if RUBY_PLATFORM == "java"
36
+ # 0x20c49ba5e353f7 = 0x7fffffffffffffff/1000, the largest value possible for JRuby
37
+ # JRuby Time.at multiplies the arg by 1000, and then stores it in a signed long.
38
+ # 0x20c49ba2d52500 = 292278993-01-01 00:00:00 +0000
39
+ # JRuby 9.1 does not accept the year 292278994 because of edge cases (https://github.com/JodaOrg/joda-time/issues/190)
40
+ Time.at([0x20c49ba2d52500, buffer.read_int64].min)
41
+ else
42
+ Time.at(buffer.read_int64)
43
+ end
44
+
45
+ cert.critical_options = read_options(buffer)
46
+ cert.extensions = read_options(buffer)
47
+ cert.reserved = buffer.read_string
48
+ cert.signature_key = buffer.read_buffer.read_key
49
+ cert.signature = buffer.read_string
50
+ cert
51
+ end
52
+
53
+ def ssh_type
54
+ key.ssh_type + "-cert-v01@openssh.com"
55
+ end
56
+
57
+ def ssh_signature_type
58
+ key.ssh_type
59
+ end
60
+
61
+ # Serializes the certificate (and key).
62
+ def to_blob
63
+ Buffer.from(
64
+ :raw, to_blob_without_signature,
65
+ :string, signature
66
+ ).to_s
67
+ end
68
+
69
+ def ssh_do_sign(data, sig_alg = nil)
70
+ key.ssh_do_sign(data, sig_alg)
71
+ end
72
+
73
+ def ssh_do_verify(sig, data, options = {})
74
+ key.ssh_do_verify(sig, data, options)
75
+ end
76
+
77
+ def to_pem
78
+ key.to_pem
79
+ end
80
+
81
+ def fingerprint
82
+ key.fingerprint
83
+ end
84
+
85
+ # Signs the certificate with key.
86
+ def sign!(key, sign_nonce = nil)
87
+ # ssh-keygen uses 32 bytes of nonce.
88
+ self.nonce = sign_nonce || SecureRandom.random_bytes(32)
89
+ self.signature_key = key
90
+ self.signature = Net::SSH::Buffer.from(
91
+ :string, key.ssh_signature_type,
92
+ :mstring, key.ssh_do_sign(to_blob_without_signature)
93
+ ).to_s
94
+ self
95
+ end
96
+
97
+ def sign(key, sign_nonce = nil)
98
+ cert = clone
99
+ cert.sign!(key, sign_nonce)
100
+ end
101
+
102
+ # Checks whether the certificate's signature was signed by signature key.
103
+ def signature_valid?
104
+ buffer = Buffer.new(signature)
105
+ sig_format = buffer.read_string
106
+ signature_key.ssh_do_verify(buffer.read_string, to_blob_without_signature, host_key: sig_format)
107
+ end
108
+
109
+ def self.read_options(buffer)
110
+ names = []
111
+ options = buffer.read_buffer.read_all do |b|
112
+ name = b.read_string
113
+ names << name
114
+ data = b.read_string
115
+ data = Buffer.new(data).read_string unless data.empty?
116
+ [name, data]
117
+ end
118
+
119
+ raise ArgumentError, "option/extension names must be in sorted order" if names.sort != names
120
+
121
+ Hash[options]
122
+ end
123
+ private_class_method :read_options
124
+
125
+ def self.type_symbol(type)
126
+ types = { 1 => :user, 2 => :host }
127
+ raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
128
+
129
+ types.fetch(type)
130
+ end
131
+ private_class_method :type_symbol
132
+
133
+ private
134
+
135
+ def type_value(type)
136
+ types = { user: 1, host: 2 }
137
+ raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
138
+
139
+ types.fetch(type)
140
+ end
141
+
142
+ def ssh_time(t)
143
+ # Times in certificates are represented as a uint64.
144
+ [[t.to_i, 0].max, 2 << 64 - 1].min
145
+ end
146
+
147
+ def to_blob_without_signature
148
+ Buffer.from(
149
+ :string, ssh_type,
150
+ :string, nonce,
151
+ :raw, key_without_type,
152
+ :int64, serial,
153
+ :long, type_value(type),
154
+ :string, key_id,
155
+ :string, valid_principals.inject(Buffer.new) { |acc, elem| acc.write_string(elem) }.to_s,
156
+ :int64, ssh_time(valid_after),
157
+ :int64, ssh_time(valid_before),
158
+ :string, options_to_blob(critical_options),
159
+ :string, options_to_blob(extensions),
160
+ :string, reserved,
161
+ :string, signature_key.to_blob
162
+ ).to_s
163
+ end
164
+
165
+ def key_without_type
166
+ # key.to_blob gives us e.g. "ssh-rsa,<key>" but we just want "<key>".
167
+ tmp = Buffer.new(key.to_blob)
168
+ tmp.read_string # skip the underlying key type
169
+ tmp.read
170
+ end
171
+
172
+ def options_to_blob(options)
173
+ options.keys.sort.inject(Buffer.new) do |b, name|
174
+ b.write_string(name)
175
+ data = options.fetch(name)
176
+ data = Buffer.from(:string, data).to_s unless data.empty?
177
+ b.write_string(data)
178
+ end.to_s
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,20 @@
1
+ module Net
2
+ module SSH
3
+ module Authentication
4
+ # Describes the constants used by the Net::SSH::Authentication components
5
+ # of the Net::SSH library. Individual authentication method implemenations
6
+ # may define yet more constants that are specific to their implementation.
7
+ module Constants
8
+ USERAUTH_REQUEST = 50
9
+ USERAUTH_FAILURE = 51
10
+ USERAUTH_SUCCESS = 52
11
+ USERAUTH_BANNER = 53
12
+
13
+ USERAUTH_PASSWD_CHANGEREQ = 60
14
+ USERAUTH_PK_OK = 60
15
+
16
+ USERAUTH_METHOD_RANGE = 60..79
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,184 @@
1
+ gem 'ed25519', '~> 1.2'
2
+ gem 'bcrypt_pbkdf', '~> 1.0' unless RUBY_PLATFORM == "java"
3
+
4
+ require 'ed25519'
5
+
6
+ require 'net/ssh/transport/cipher_factory'
7
+ require 'net/ssh/authentication/pub_key_fingerprint'
8
+ require 'bcrypt_pbkdf' unless RUBY_PLATFORM == "java"
9
+
10
+ module Net
11
+ module SSH
12
+ module Authentication
13
+ module ED25519
14
+ class SigningKeyFromFile < SimpleDelegator
15
+ def initialize(pk, sk)
16
+ key = ::Ed25519::SigningKey.from_keypair(sk)
17
+ raise ArgumentError, "pk does not match sk" unless pk == key.verify_key.to_bytes
18
+
19
+ super(key)
20
+ end
21
+ end
22
+
23
+ class OpenSSHPrivateKeyLoader
24
+ CipherFactory = Net::SSH::Transport::CipherFactory
25
+
26
+ MBEGIN = "-----BEGIN OPENSSH PRIVATE KEY-----\n"
27
+ MEND = "-----END OPENSSH PRIVATE KEY-----"
28
+ MAGIC = "openssh-key-v1"
29
+
30
+ class DecryptError < ArgumentError
31
+ def initialize(message, encrypted_key: false)
32
+ super(message)
33
+ @encrypted_key = encrypted_key
34
+ end
35
+
36
+ def encrypted_key?
37
+ return @encrypted_key
38
+ end
39
+ end
40
+
41
+ def self.read(datafull, password)
42
+ datafull = datafull.strip
43
+ raise ArgumentError.new("Expected #{MBEGIN} at start of private key") unless datafull.start_with?(MBEGIN)
44
+ raise ArgumentError.new("Expected #{MEND} at end of private key") unless datafull.end_with?(MEND)
45
+
46
+ datab64 = datafull[MBEGIN.size...-MEND.size]
47
+ data = datab64.unpack1("m")
48
+ raise ArgumentError.new("Expected #{MAGIC} at start of decoded private key") unless data.start_with?(MAGIC)
49
+
50
+ buffer = Net::SSH::Buffer.new(data[MAGIC.size + 1..-1])
51
+
52
+ ciphername = buffer.read_string
53
+ raise ArgumentError.new("#{ciphername} in private key is not supported") unless
54
+ CipherFactory.supported?(ciphername)
55
+
56
+ kdfname = buffer.read_string
57
+ raise ArgumentError.new("Expected #{kdfname} to be or none or bcrypt") unless %w[none bcrypt].include?(kdfname)
58
+
59
+ kdfopts = Net::SSH::Buffer.new(buffer.read_string)
60
+ num_keys = buffer.read_long
61
+ raise ArgumentError.new("Only 1 key is supported in ssh keys #{num_keys} was in private key") unless num_keys == 1
62
+
63
+ _pubkey = buffer.read_string
64
+
65
+ len = buffer.read_long
66
+
67
+ keylen, blocksize, ivlen = CipherFactory.get_lengths(ciphername, iv_len: true)
68
+ raise ArgumentError.new("Private key len:#{len} is not a multiple of #{blocksize}") if
69
+ ((len < blocksize) || ((blocksize > 0) && (len % blocksize) != 0))
70
+
71
+ if kdfname == 'bcrypt'
72
+ salt = kdfopts.read_string
73
+ rounds = kdfopts.read_long
74
+
75
+ raise "BCryptPbkdf is not implemented for jruby" if RUBY_PLATFORM == "java"
76
+
77
+ key = BCryptPbkdf::key(password, salt, keylen + ivlen, rounds)
78
+ raise DecryptError.new("BCyryptPbkdf failed", encrypted_key: true) unless key
79
+ else
80
+ key = '\x00' * (keylen + ivlen)
81
+ end
82
+
83
+ cipher = CipherFactory.get(ciphername, key: key[0...keylen], iv: key[keylen...keylen + ivlen], decrypt: true)
84
+
85
+ decoded = cipher.update(buffer.remainder_as_buffer.to_s)
86
+ decoded << cipher.final
87
+
88
+ decoded = Net::SSH::Buffer.new(decoded)
89
+ check1 = decoded.read_long
90
+ check2 = decoded.read_long
91
+
92
+ raise DecryptError.new("Decrypt failed on private key", encrypted_key: kdfname == 'bcrypt') if (check1 != check2)
93
+
94
+ type_name = decoded.read_string
95
+ case type_name
96
+ when "ssh-ed25519"
97
+ PrivKey.new(decoded)
98
+ else
99
+ decoded.read_private_keyblob(type_name)
100
+ end
101
+ end
102
+ end
103
+
104
+ class PubKey
105
+ include Net::SSH::Authentication::PubKeyFingerprint
106
+
107
+ attr_reader :verify_key
108
+
109
+ def initialize(data)
110
+ @verify_key = ::Ed25519::VerifyKey.new(data)
111
+ end
112
+
113
+ def self.read_keyblob(buffer)
114
+ PubKey.new(buffer.read_string)
115
+ end
116
+
117
+ def to_blob
118
+ Net::SSH::Buffer.from(:mstring, "ssh-ed25519".dup, :string, @verify_key.to_bytes).to_s
119
+ end
120
+
121
+ def ssh_type
122
+ "ssh-ed25519"
123
+ end
124
+
125
+ def ssh_signature_type
126
+ ssh_type
127
+ end
128
+
129
+ def ssh_do_verify(sig, data, options = {})
130
+ @verify_key.verify(sig, data)
131
+ end
132
+
133
+ def to_pem
134
+ # TODO this is not pem
135
+ ssh_type + [@verify_key.to_bytes].pack("m")
136
+ end
137
+ end
138
+
139
+ class PrivKey
140
+ CipherFactory = Net::SSH::Transport::CipherFactory
141
+
142
+ MBEGIN = "-----BEGIN OPENSSH PRIVATE KEY-----\n"
143
+ MEND = "-----END OPENSSH PRIVATE KEY-----\n"
144
+ MAGIC = "openssh-key-v1"
145
+
146
+ attr_reader :sign_key
147
+
148
+ def initialize(buffer)
149
+ pk = buffer.read_string
150
+ sk = buffer.read_string
151
+ _comment = buffer.read_string
152
+
153
+ @pk = pk
154
+ @sign_key = SigningKeyFromFile.new(pk, sk)
155
+ end
156
+
157
+ def to_blob
158
+ public_key.to_blob
159
+ end
160
+
161
+ def ssh_type
162
+ "ssh-ed25519"
163
+ end
164
+
165
+ def ssh_signature_type
166
+ ssh_type
167
+ end
168
+
169
+ def public_key
170
+ PubKey.new(@pk)
171
+ end
172
+
173
+ def ssh_do_sign(data, sig_alg = nil)
174
+ @sign_key.sign(data)
175
+ end
176
+
177
+ def self.read(data, password)
178
+ OpenSSHPrivateKeyLoader.read(data, password)
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,31 @@
1
+ module Net
2
+ module SSH
3
+ module Authentication
4
+ # Loads ED25519 support which requires optinal dependecies like
5
+ # ed25519, bcrypt_pbkdf
6
+ module ED25519Loader
7
+ begin
8
+ require 'net/ssh/authentication/ed25519'
9
+ LOADED = true
10
+ ERROR = nil
11
+ rescue LoadError => e
12
+ ERROR = e
13
+ LOADED = false
14
+ end
15
+
16
+ def self.raiseUnlessLoaded(message)
17
+ description = ERROR.is_a?(LoadError) ? dependenciesRequiredForED25519 : +''
18
+ description << "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
19
+ raise NotImplementedError, "#{message}\n#{description}" unless LOADED
20
+ end
21
+
22
+ def self.dependenciesRequiredForED25519
23
+ result = +"net-ssh requires the following gems for ed25519 support:\n"
24
+ result << " * ed25519 (>= 1.2, < 2.0)\n"
25
+ result << " * bcrypt_pbkdf (>= 1.0, < 2.0)\n" unless RUBY_PLATFORM == "java"
26
+ result << "See https://github.com/net-ssh/net-ssh/issues/565 for more information\n"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end