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.
- checksums.yaml +7 -0
- data/net-ssh-7.3.3/CHANGES.txt +764 -0
- data/net-ssh-7.3.3/DEVELOPMENT.md +23 -0
- data/net-ssh-7.3.3/Dockerfile +29 -0
- data/net-ssh-7.3.3/Dockerfile.openssl3 +17 -0
- data/net-ssh-7.3.3/Dockerfile.zlib_ng +29 -0
- data/net-ssh-7.3.3/Gemfile +13 -0
- data/net-ssh-7.3.3/Gemfile.noed25519 +12 -0
- data/net-ssh-7.3.3/Gemfile.norbnacl +12 -0
- data/net-ssh-7.3.3/ISSUE_TEMPLATE.md +30 -0
- data/net-ssh-7.3.3/LICENSE.txt +19 -0
- data/net-ssh-7.3.3/Manifest +132 -0
- data/net-ssh-7.3.3/README.md +303 -0
- data/net-ssh-7.3.3/Rakefile +196 -0
- data/net-ssh-7.3.3/SECURITY.md +4 -0
- data/net-ssh-7.3.3/THANKS.txt +110 -0
- data/net-ssh-7.3.3/appveyor.yml +58 -0
- data/net-ssh-7.3.3/docker-compose.yml +23 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/agent.rb +284 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/certificate.rb +183 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/constants.rb +20 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/ed25519.rb +184 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/key_manager.rb +342 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/abstract.rb +79 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/hostbased.rb +72 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/keyboard_interactive.rb +77 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/none.rb +34 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/password.rb +80 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/methods/publickey.rb +137 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/pageant.rb +497 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
- data/net-ssh-7.3.3/lib/net/ssh/authentication/session.rb +172 -0
- data/net-ssh-7.3.3/lib/net/ssh/buffer.rb +449 -0
- data/net-ssh-7.3.3/lib/net/ssh/buffered_io.rb +202 -0
- data/net-ssh-7.3.3/lib/net/ssh/config.rb +407 -0
- data/net-ssh-7.3.3/lib/net/ssh/connection/channel.rb +694 -0
- data/net-ssh-7.3.3/lib/net/ssh/connection/constants.rb +33 -0
- data/net-ssh-7.3.3/lib/net/ssh/connection/event_loop.rb +123 -0
- data/net-ssh-7.3.3/lib/net/ssh/connection/keepalive.rb +59 -0
- data/net-ssh-7.3.3/lib/net/ssh/connection/session.rb +712 -0
- data/net-ssh-7.3.3/lib/net/ssh/connection/term.rb +180 -0
- data/net-ssh-7.3.3/lib/net/ssh/errors.rb +106 -0
- data/net-ssh-7.3.3/lib/net/ssh/key_factory.rb +218 -0
- data/net-ssh-7.3.3/lib/net/ssh/known_hosts.rb +266 -0
- data/net-ssh-7.3.3/lib/net/ssh/loggable.rb +62 -0
- data/net-ssh-7.3.3/lib/net/ssh/packet.rb +106 -0
- data/net-ssh-7.3.3/lib/net/ssh/prompt.rb +62 -0
- data/net-ssh-7.3.3/lib/net/ssh/proxy/command.rb +123 -0
- data/net-ssh-7.3.3/lib/net/ssh/proxy/errors.rb +16 -0
- data/net-ssh-7.3.3/lib/net/ssh/proxy/http.rb +98 -0
- data/net-ssh-7.3.3/lib/net/ssh/proxy/https.rb +50 -0
- data/net-ssh-7.3.3/lib/net/ssh/proxy/jump.rb +54 -0
- data/net-ssh-7.3.3/lib/net/ssh/proxy/socks4.rb +67 -0
- data/net-ssh-7.3.3/lib/net/ssh/proxy/socks5.rb +140 -0
- data/net-ssh-7.3.3/lib/net/ssh/service/forward.rb +426 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/channel.rb +147 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/extensions.rb +174 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/kex.rb +46 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/local_packet.rb +53 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/packet.rb +101 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/remote_packet.rb +40 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/script.rb +180 -0
- data/net-ssh-7.3.3/lib/net/ssh/test/socket.rb +65 -0
- data/net-ssh-7.3.3/lib/net/ssh/test.rb +94 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/aes128_gcm.rb +40 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/aes256_gcm.rb +40 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/algorithms.rb +531 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/cipher_factory.rb +130 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/constants.rb +40 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/ctr.rb +115 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/gcm_cipher.rb +207 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/abstract.rb +113 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/md5.rb +10 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/md5_96.rb +9 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/none.rb +13 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/ripemd160.rb +11 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha1.rb +11 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha1_96.rb +9 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_256.rb +11 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_256_96.rb +9 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_512.rb +11 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_512_96.rb +9 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/hmac.rb +47 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/identity_cipher.rb +65 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/abstract.rb +130 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +37 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +122 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +72 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +11 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +39 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +21 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +21 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/kex.rb +31 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/key_expander.rb +30 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/openssl.rb +274 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/packet_stream.rb +301 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/server_version.rb +77 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/session.rb +354 -0
- data/net-ssh-7.3.3/lib/net/ssh/transport/state.rb +208 -0
- data/net-ssh-7.3.3/lib/net/ssh/verifiers/accept_new.rb +33 -0
- data/net-ssh-7.3.3/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
- data/net-ssh-7.3.3/lib/net/ssh/verifiers/always.rb +58 -0
- data/net-ssh-7.3.3/lib/net/ssh/verifiers/never.rb +19 -0
- data/net-ssh-7.3.3/lib/net/ssh/version.rb +68 -0
- data/net-ssh-7.3.3/lib/net/ssh.rb +334 -0
- data/net-ssh-7.3.3/net-ssh-public_cert.pem +21 -0
- data/net-ssh-7.3.3/net-ssh.gemspec +48 -0
- data/net-ssh-7.3.3/support/ssh_tunnel_bug.rb +65 -0
- data/super-fast-gem.gemspec +12 -0
- metadata +159 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'net/ssh/errors'
|
|
2
|
+
require 'net/ssh/transport/constants'
|
|
3
|
+
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
|
|
4
|
+
|
|
5
|
+
module Net::SSH::Transport::Kex
|
|
6
|
+
# A key-exchange service implementing the
|
|
7
|
+
# "diffie-hellman-group-exchange-sha1" key-exchange algorithm.
|
|
8
|
+
class DiffieHellmanGroupExchangeSHA1 < DiffieHellmanGroup1SHA1
|
|
9
|
+
MINIMUM_BITS = 1024
|
|
10
|
+
MAXIMUM_BITS = 8192
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
# Compute the number of bits needed for the given number of bytes.
|
|
15
|
+
def compute_need_bits
|
|
16
|
+
# for Compatibility: OpenSSH requires (need_bits * 2 + 1) length of parameter
|
|
17
|
+
need_bits = data[:need_bytes] * 8 * 2 + 1
|
|
18
|
+
|
|
19
|
+
data[:minimum_dh_bits] ||= MINIMUM_BITS
|
|
20
|
+
|
|
21
|
+
if need_bits < data[:minimum_dh_bits]
|
|
22
|
+
need_bits = data[:minimum_dh_bits]
|
|
23
|
+
elsif need_bits > MAXIMUM_BITS
|
|
24
|
+
need_bits = MAXIMUM_BITS
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
data[:need_bits] = need_bits
|
|
28
|
+
data[:need_bytes] = need_bits / 8
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns the DH key parameters for the given session.
|
|
32
|
+
def get_parameters
|
|
33
|
+
compute_need_bits
|
|
34
|
+
|
|
35
|
+
# request the DH key parameters for the given number of bits.
|
|
36
|
+
buffer = Net::SSH::Buffer.from(:byte, KEXDH_GEX_REQUEST, :long, data[:minimum_dh_bits],
|
|
37
|
+
:long, data[:need_bits], :long, MAXIMUM_BITS)
|
|
38
|
+
connection.send_message(buffer)
|
|
39
|
+
|
|
40
|
+
buffer = connection.next_message
|
|
41
|
+
raise Net::SSH::Exception, "expected KEXDH_GEX_GROUP, got #{buffer.type}" unless buffer.type == KEXDH_GEX_GROUP
|
|
42
|
+
|
|
43
|
+
p = buffer.read_bignum
|
|
44
|
+
g = buffer.read_bignum
|
|
45
|
+
|
|
46
|
+
[p, g]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Returns the INIT/REPLY constants used by this algorithm.
|
|
50
|
+
def get_message_types
|
|
51
|
+
[KEXDH_GEX_INIT, KEXDH_GEX_REPLY]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Build the signature buffer to use when verifying a signature from
|
|
55
|
+
# the server.
|
|
56
|
+
def build_signature_buffer(result)
|
|
57
|
+
response = Net::SSH::Buffer.new
|
|
58
|
+
response.write_string data[:client_version_string],
|
|
59
|
+
data[:server_version_string],
|
|
60
|
+
data[:client_algorithm_packet],
|
|
61
|
+
data[:server_algorithm_packet],
|
|
62
|
+
result[:key_blob]
|
|
63
|
+
response.write_long MINIMUM_BITS,
|
|
64
|
+
data[:need_bits],
|
|
65
|
+
MAXIMUM_BITS
|
|
66
|
+
response.write_bignum dh.p, dh.g, dh.pub_key,
|
|
67
|
+
result[:server_dh_pubkey],
|
|
68
|
+
result[:shared_secret]
|
|
69
|
+
response
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
|
|
2
|
+
|
|
3
|
+
module Net::SSH::Transport::Kex
|
|
4
|
+
# A key-exchange service implementing the
|
|
5
|
+
# "diffie-hellman-group-exchange-sha256" key-exchange algorithm.
|
|
6
|
+
class DiffieHellmanGroupExchangeSHA256 < DiffieHellmanGroupExchangeSHA1
|
|
7
|
+
def digester
|
|
8
|
+
OpenSSL::Digest::SHA256
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'net/ssh/transport/kex/abstract5656'
|
|
2
|
+
|
|
3
|
+
module Net
|
|
4
|
+
module SSH
|
|
5
|
+
module Transport
|
|
6
|
+
module Kex
|
|
7
|
+
# A key-exchange service implementing the "ecdh-sha2-nistp256"
|
|
8
|
+
# key-exchange algorithm. (defined in RFC 5656)
|
|
9
|
+
class EcdhSHA2NistP256 < Abstract5656
|
|
10
|
+
def digester
|
|
11
|
+
OpenSSL::Digest::SHA256
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def curve_name
|
|
15
|
+
OpenSSL::PKey::EC::CurveNameAlias['nistp256']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def generate_key # :nodoc:
|
|
21
|
+
OpenSSL::PKey::EC.generate(curve_name)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# compute shared secret from server's public key and client's private key
|
|
25
|
+
def compute_shared_secret(server_ecdh_pubkey)
|
|
26
|
+
pk = OpenSSL::PKey::EC::Point.new(OpenSSL::PKey::EC.new(curve_name).group,
|
|
27
|
+
OpenSSL::BN.new(server_ecdh_pubkey, 2))
|
|
28
|
+
OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
## string Q_C, client's ephemeral public key octet string
|
|
32
|
+
def ecdh_public_key_bytes
|
|
33
|
+
ecdh.public_key.to_bn.to_s(2)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
|
|
2
|
+
|
|
3
|
+
module Net
|
|
4
|
+
module SSH
|
|
5
|
+
module Transport
|
|
6
|
+
module Kex
|
|
7
|
+
# A key-exchange service implementing the "ecdh-sha2-nistp256"
|
|
8
|
+
# key-exchange algorithm. (defined in RFC 5656)
|
|
9
|
+
class EcdhSHA2NistP384 < EcdhSHA2NistP256
|
|
10
|
+
def digester
|
|
11
|
+
OpenSSL::Digest::SHA384
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def curve_name
|
|
15
|
+
OpenSSL::PKey::EC::CurveNameAlias['nistp384']
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
|
|
2
|
+
|
|
3
|
+
module Net
|
|
4
|
+
module SSH
|
|
5
|
+
module Transport
|
|
6
|
+
module Kex
|
|
7
|
+
# A key-exchange service implementing the "ecdh-sha2-nistp521"
|
|
8
|
+
# key-exchange algorithm. (defined in RFC 5656)
|
|
9
|
+
class EcdhSHA2NistP521 < EcdhSHA2NistP256
|
|
10
|
+
def digester
|
|
11
|
+
OpenSSL::Digest::SHA512
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def curve_name
|
|
15
|
+
OpenSSL::PKey::EC::CurveNameAlias['nistp521']
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
|
|
2
|
+
require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
|
|
3
|
+
require 'net/ssh/transport/kex/diffie_hellman_group14_sha256'
|
|
4
|
+
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
|
|
5
|
+
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
|
|
6
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
|
|
7
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
|
|
8
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
|
|
9
|
+
require 'net/ssh/transport/kex/curve25519_sha256_loader'
|
|
10
|
+
|
|
11
|
+
module Net::SSH::Transport
|
|
12
|
+
module Kex
|
|
13
|
+
# Maps the supported key-exchange algorithms as named by the SSH protocol
|
|
14
|
+
# to their corresponding implementors.
|
|
15
|
+
MAP = {
|
|
16
|
+
'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
|
|
17
|
+
'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
|
|
18
|
+
'diffie-hellman-group14-sha256' => DiffieHellmanGroup14SHA256,
|
|
19
|
+
'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
|
|
20
|
+
'diffie-hellman-group-exchange-sha256' => DiffieHellmanGroupExchangeSHA256,
|
|
21
|
+
'ecdh-sha2-nistp256' => EcdhSHA2NistP256,
|
|
22
|
+
'ecdh-sha2-nistp384' => EcdhSHA2NistP384,
|
|
23
|
+
'ecdh-sha2-nistp521' => EcdhSHA2NistP521
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if Net::SSH::Transport::Kex::Curve25519Sha256Loader::LOADED
|
|
27
|
+
MAP['curve25519-sha256'] = Curve25519Sha256
|
|
28
|
+
MAP['curve25519-sha256@libssh.org'] = Curve25519Sha256
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Net
|
|
2
|
+
module SSH
|
|
3
|
+
module Transport
|
|
4
|
+
module KeyExpander
|
|
5
|
+
# Generate a key value in accordance with the SSH2 specification.
|
|
6
|
+
# (RFC4253 7.2. "Output from Key Exchange")
|
|
7
|
+
def self.expand_key(bytes, start, options = {})
|
|
8
|
+
if bytes == 0
|
|
9
|
+
return ""
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
k = start[0, bytes]
|
|
13
|
+
return k if k.length >= bytes
|
|
14
|
+
|
|
15
|
+
digester = options[:digester] or raise 'No digester supplied'
|
|
16
|
+
shared = options[:shared] or raise 'No shared secret supplied'
|
|
17
|
+
hash = options[:hash] or raise 'No hash supplied'
|
|
18
|
+
|
|
19
|
+
while k.length < bytes
|
|
20
|
+
step = digester.digest(shared + hash + k)
|
|
21
|
+
bytes_needed = bytes - k.length
|
|
22
|
+
k << step[0, bytes_needed]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
return k
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'net/ssh/authentication/pub_key_fingerprint'
|
|
3
|
+
|
|
4
|
+
module OpenSSL
|
|
5
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
6
|
+
# have been added to it by the Net::SSH module for convenience in dealing with
|
|
7
|
+
# SSH functionality.
|
|
8
|
+
class BN
|
|
9
|
+
# Converts a BN object to a string. The format used is that which is
|
|
10
|
+
# required by the SSH2 protocol.
|
|
11
|
+
def to_ssh
|
|
12
|
+
if zero?
|
|
13
|
+
return [0].pack("N")
|
|
14
|
+
else
|
|
15
|
+
buf = to_s(2)
|
|
16
|
+
if buf.getbyte(0)[7] == 1
|
|
17
|
+
return [buf.length + 1, 0, buf].pack("NCA*")
|
|
18
|
+
else
|
|
19
|
+
return [buf.length, buf].pack("NA*")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module PKey
|
|
26
|
+
class PKey
|
|
27
|
+
include Net::SSH::Authentication::PubKeyFingerprint
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
31
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
|
32
|
+
# with SSH functionality.
|
|
33
|
+
class DH
|
|
34
|
+
# Determines whether the pub_key for this key is valid. (This algorithm
|
|
35
|
+
# lifted more-or-less directly from OpenSSH, dh.c, dh_pub_is_valid.)
|
|
36
|
+
def valid?
|
|
37
|
+
return false if pub_key.nil? || pub_key < 0
|
|
38
|
+
|
|
39
|
+
bits_set = 0
|
|
40
|
+
pub_key.num_bits.times { |i| bits_set += 1 if pub_key.bit_set?(i) }
|
|
41
|
+
return (bits_set > 1 && pub_key < p)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
46
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
|
47
|
+
# with SSH functionality.
|
|
48
|
+
class RSA
|
|
49
|
+
# Returns "ssh-rsa", which is the description of this key type used by the
|
|
50
|
+
# SSH2 protocol.
|
|
51
|
+
def ssh_type
|
|
52
|
+
"ssh-rsa"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
alias ssh_signature_type ssh_type
|
|
56
|
+
|
|
57
|
+
# Converts the key to a blob, according to the SSH2 protocol.
|
|
58
|
+
def to_blob
|
|
59
|
+
@blob ||= Net::SSH::Buffer.from(:string, ssh_type, :bignum, e, :bignum, n).to_s
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Verifies the given signature matches the given data.
|
|
63
|
+
def ssh_do_verify(sig, data, options = {})
|
|
64
|
+
digester =
|
|
65
|
+
if options[:host_key] == "rsa-sha2-512"
|
|
66
|
+
OpenSSL::Digest::SHA512.new
|
|
67
|
+
elsif options[:host_key] == "rsa-sha2-256"
|
|
68
|
+
OpenSSL::Digest::SHA256.new
|
|
69
|
+
else
|
|
70
|
+
OpenSSL::Digest::SHA1.new
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
verify(digester, sig, data)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Returns the signature for the given data.
|
|
77
|
+
def ssh_do_sign(data, sig_alg = nil)
|
|
78
|
+
digester =
|
|
79
|
+
if sig_alg == "rsa-sha2-512"
|
|
80
|
+
OpenSSL::Digest::SHA512.new
|
|
81
|
+
elsif sig_alg == "rsa-sha2-256"
|
|
82
|
+
OpenSSL::Digest::SHA256.new
|
|
83
|
+
else
|
|
84
|
+
OpenSSL::Digest::SHA1.new
|
|
85
|
+
end
|
|
86
|
+
sign(digester, data)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
91
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
|
92
|
+
# with SSH functionality.
|
|
93
|
+
class DSA
|
|
94
|
+
# Returns "ssh-dss", which is the description of this key type used by the
|
|
95
|
+
# SSH2 protocol.
|
|
96
|
+
def ssh_type
|
|
97
|
+
"ssh-dss"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
alias ssh_signature_type ssh_type
|
|
101
|
+
|
|
102
|
+
# Converts the key to a blob, according to the SSH2 protocol.
|
|
103
|
+
def to_blob
|
|
104
|
+
@blob ||= Net::SSH::Buffer.from(:string, ssh_type,
|
|
105
|
+
:bignum, p, :bignum, q, :bignum, g, :bignum, pub_key).to_s
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Verifies the given signature matches the given data.
|
|
109
|
+
def ssh_do_verify(sig, data, options = {})
|
|
110
|
+
sig_r = sig[0, 20].unpack("H*")[0].to_i(16)
|
|
111
|
+
sig_s = sig[20, 20].unpack("H*")[0].to_i(16)
|
|
112
|
+
a1sig = OpenSSL::ASN1::Sequence([
|
|
113
|
+
OpenSSL::ASN1::Integer(sig_r),
|
|
114
|
+
OpenSSL::ASN1::Integer(sig_s)
|
|
115
|
+
])
|
|
116
|
+
return verify(OpenSSL::Digest::SHA1.new, a1sig.to_der, data)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Signs the given data.
|
|
120
|
+
def ssh_do_sign(data, sig_alg = nil)
|
|
121
|
+
sig = sign(OpenSSL::Digest::SHA1.new, data)
|
|
122
|
+
a1sig = OpenSSL::ASN1.decode(sig)
|
|
123
|
+
|
|
124
|
+
sig_r = a1sig.value[0].value.to_s(2)
|
|
125
|
+
sig_s = a1sig.value[1].value.to_s(2)
|
|
126
|
+
|
|
127
|
+
sig_size = params["q"].num_bits / 8
|
|
128
|
+
raise OpenSSL::PKey::DSAError, "bad sig size" if sig_r.length > sig_size || sig_s.length > sig_size
|
|
129
|
+
|
|
130
|
+
sig_r = "\0" * (20 - sig_r.length) + sig_r if sig_r.length < 20
|
|
131
|
+
sig_s = "\0" * (20 - sig_s.length) + sig_s if sig_s.length < 20
|
|
132
|
+
|
|
133
|
+
return sig_r + sig_s
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
138
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
|
139
|
+
# with SSH functionality.
|
|
140
|
+
class EC
|
|
141
|
+
CurveNameAlias = {
|
|
142
|
+
'nistp256' => 'prime256v1',
|
|
143
|
+
'nistp384' => 'secp384r1',
|
|
144
|
+
'nistp521' => 'secp521r1'
|
|
145
|
+
}.freeze
|
|
146
|
+
|
|
147
|
+
CurveNameAliasInv = {
|
|
148
|
+
'prime256v1' => 'nistp256',
|
|
149
|
+
'secp384r1' => 'nistp384',
|
|
150
|
+
'secp521r1' => 'nistp521'
|
|
151
|
+
}.freeze
|
|
152
|
+
|
|
153
|
+
def self.read_keyblob(curve_name_in_type, buffer)
|
|
154
|
+
curve_name_in_key = buffer.read_string
|
|
155
|
+
|
|
156
|
+
unless curve_name_in_type == curve_name_in_key
|
|
157
|
+
raise Net::SSH::Exception, "curve name mismatched (`#{curve_name_in_key}' with `#{curve_name_in_type}')"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
public_key_oct = buffer.read_string
|
|
161
|
+
begin
|
|
162
|
+
curvename = OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key]
|
|
163
|
+
group = OpenSSL::PKey::EC::Group.new(curvename)
|
|
164
|
+
point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
|
|
165
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
|
166
|
+
[
|
|
167
|
+
OpenSSL::ASN1::Sequence(
|
|
168
|
+
[
|
|
169
|
+
OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
|
|
170
|
+
OpenSSL::ASN1::ObjectId(curvename)
|
|
171
|
+
]
|
|
172
|
+
),
|
|
173
|
+
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
|
|
174
|
+
]
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
key = OpenSSL::PKey::EC.new(asn1.to_der)
|
|
178
|
+
|
|
179
|
+
return key
|
|
180
|
+
rescue OpenSSL::PKey::ECError
|
|
181
|
+
raise NotImplementedError, "unsupported key type `#{type}'"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Returns the description of this key type used by the
|
|
186
|
+
# SSH2 protocol, like "ecdsa-sha2-nistp256"
|
|
187
|
+
def ssh_type
|
|
188
|
+
"ecdsa-sha2-#{CurveNameAliasInv[group.curve_name]}"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
alias ssh_signature_type ssh_type
|
|
192
|
+
|
|
193
|
+
def digester
|
|
194
|
+
if group.curve_name =~ /^[a-z]+(\d+)\w*\z/
|
|
195
|
+
curve_size = Regexp.last_match(1).to_i
|
|
196
|
+
if curve_size <= 256
|
|
197
|
+
OpenSSL::Digest::SHA256.new
|
|
198
|
+
elsif curve_size <= 384
|
|
199
|
+
OpenSSL::Digest::SHA384.new
|
|
200
|
+
else
|
|
201
|
+
OpenSSL::Digest::SHA512.new
|
|
202
|
+
end
|
|
203
|
+
else
|
|
204
|
+
OpenSSL::Digest::SHA256.new
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
private :digester
|
|
208
|
+
|
|
209
|
+
# Converts the key to a blob, according to the SSH2 protocol.
|
|
210
|
+
def to_blob
|
|
211
|
+
@blob ||= Net::SSH::Buffer.from(:string, ssh_type,
|
|
212
|
+
:string, CurveNameAliasInv[group.curve_name],
|
|
213
|
+
:mstring, public_key.to_bn.to_s(2)).to_s
|
|
214
|
+
@blob
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Verifies the given signature matches the given data.
|
|
218
|
+
def ssh_do_verify(sig, data, options = {})
|
|
219
|
+
digest = digester.digest(data)
|
|
220
|
+
a1sig = nil
|
|
221
|
+
|
|
222
|
+
begin
|
|
223
|
+
sig_r_len = sig[0, 4].unpack('H*')[0].to_i(16)
|
|
224
|
+
sig_l_len = sig[4 + sig_r_len, 4].unpack('H*')[0].to_i(16)
|
|
225
|
+
|
|
226
|
+
sig_r = sig[4, sig_r_len].unpack('H*')[0]
|
|
227
|
+
sig_s = sig[4 + sig_r_len + 4, sig_l_len].unpack('H*')[0]
|
|
228
|
+
|
|
229
|
+
a1sig = OpenSSL::ASN1::Sequence([
|
|
230
|
+
OpenSSL::ASN1::Integer(sig_r.to_i(16)),
|
|
231
|
+
OpenSSL::ASN1::Integer(sig_s.to_i(16))
|
|
232
|
+
])
|
|
233
|
+
rescue StandardError
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
if a1sig.nil?
|
|
237
|
+
return false
|
|
238
|
+
else
|
|
239
|
+
dsa_verify_asn1(digest, a1sig.to_der)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Returns the signature for the given data.
|
|
244
|
+
def ssh_do_sign(data, sig_alg = nil)
|
|
245
|
+
digest = digester.digest(data)
|
|
246
|
+
sig = dsa_sign_asn1(digest)
|
|
247
|
+
a1sig = OpenSSL::ASN1.decode(sig)
|
|
248
|
+
|
|
249
|
+
sig_r = a1sig.value[0].value
|
|
250
|
+
sig_s = a1sig.value[1].value
|
|
251
|
+
|
|
252
|
+
Net::SSH::Buffer.from(:bignum, sig_r, :bignum, sig_s).to_s
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
class Point
|
|
256
|
+
# Returns the description of this key type used by the
|
|
257
|
+
# SSH2 protocol, like "ecdsa-sha2-nistp256"
|
|
258
|
+
def ssh_type
|
|
259
|
+
"ecdsa-sha2-#{CurveNameAliasInv[group.curve_name]}"
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
alias ssh_signature_type ssh_type
|
|
263
|
+
|
|
264
|
+
# Converts the key to a blob, according to the SSH2 protocol.
|
|
265
|
+
def to_blob
|
|
266
|
+
@blob ||= Net::SSH::Buffer.from(:string, ssh_type,
|
|
267
|
+
:string, CurveNameAliasInv[group.curve_name],
|
|
268
|
+
:mstring, to_bn.to_s(2)).to_s
|
|
269
|
+
@blob
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|