summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Fazekas <mfazekas@szemafor.com>2016-07-16 10:33:09 +0200
committerMiklos Fazekas <mfazekas@szemafor.com>2016-07-19 22:08:17 +0200
commit87cdb30ac0e8d00238e2a175352873a09fc04718 (patch)
treec8f1bfd696a1bb459687b52b0a1e157b6bac6163
parent1739e0378f20b81c71dac9401b090c67f6962972 (diff)
downloadnet-ssh-87cdb30ac0e8d00238e2a175352873a09fc04718.tar.gz
Raise better errors if ED25519 support is not available
-rw-r--r--lib/net/ssh/authentication/ed25519.rb8
-rw-r--r--lib/net/ssh/authentication/ed25519_loader.rb21
-rw-r--r--lib/net/ssh/buffer.rb6
-rw-r--r--lib/net/ssh/key_factory.rb13
-rw-r--r--test/authentication/test_ed25519.rb8
5 files changed, 41 insertions, 15 deletions
diff --git a/lib/net/ssh/authentication/ed25519.rb b/lib/net/ssh/authentication/ed25519.rb
index 7dce81c..021c2ad 100644
--- a/lib/net/ssh/authentication/ed25519.rb
+++ b/lib/net/ssh/authentication/ed25519.rb
@@ -1,5 +1,5 @@
-gem 'rbnacl-libsodium', '~> 1.0.10'
-gem 'rbnacl', '~> 3.4.0'
+gem 'rbnacl-libsodium', '>= 1.0.10'
+gem 'rbnacl', '>= 3.2.0', '< 4.0'
gem 'bcrypt_pbkdf', '~> 1.0.0.alpha1' unless RUBY_PLATFORM == "java"
require 'rbnacl/libsodium'
@@ -14,6 +14,7 @@ require 'base64'
require 'net/ssh/transport/cipher_factory'
require 'bcrypt_pbkdf' unless RUBY_PLATFORM == "java"
+module Net; module SSH; module Authentication
module ED25519
class SigningKeyFromFile < RbNaCl::Signatures::Ed25519::SigningKey
def initialize(pk,sk)
@@ -132,4 +133,5 @@ module ED25519
ED25519::PubKey.read_keyblob(buffer)
end
end
-end \ No newline at end of file
+end
+end; end; end \ No newline at end of file
diff --git a/lib/net/ssh/authentication/ed25519_loader.rb b/lib/net/ssh/authentication/ed25519_loader.rb
new file mode 100644
index 0000000..5699d28
--- /dev/null
+++ b/lib/net/ssh/authentication/ed25519_loader.rb
@@ -0,0 +1,21 @@
+module Net; module SSH; module Authentication
+
+# Loads ED25519 support which requires optinal dependecies like
+# rbnacl-libsodium, rbnacl, bcrypt_pbkdf
+module ED25519Loader
+
+begin
+ require 'net/ssh/authentication/ed25519'
+ LOADED = true
+ ERROR = nil
+rescue LoadError => e
+ ERROR = e
+ LOADED = false
+end
+
+def self.raiseUnlessLoaded(message)
+ raise NotImplementedError, "#{message} -- see #{ED25519_LOAD_ERROR}" unless LOADED
+end
+
+end
+end; end; end \ No newline at end of file
diff --git a/lib/net/ssh/buffer.rb b/lib/net/ssh/buffer.rb
index ef8b59c..e1ee886 100644
--- a/lib/net/ssh/buffer.rb
+++ b/lib/net/ssh/buffer.rb
@@ -1,6 +1,8 @@
require 'net/ssh/ruby_compat'
require 'net/ssh/transport/openssl'
+require 'net/ssh/authentication/ed25519_loader'
+
module Net; module SSH
# Net::SSH::Buffer is a flexible class for building and parsing binary
@@ -256,8 +258,8 @@ module Net; module SSH
key.n = read_bignum
when /^ssh-ed25519$/
- key = ED25519::PubKey.read_keyblob(self)
-
+ Net::SSH::Authentication::ED25519Loader.raiseUnlessLoaded("unsupported key type `#{type}'")
+ key = Net::SSH::Authentication::ED25519::PubKey.read_keyblob(self)
when /^ecdsa\-sha2\-(\w*)$/
unless defined?(OpenSSL::PKey::EC)
raise NotImplementedError, "unsupported key type `#{type}'"
diff --git a/lib/net/ssh/key_factory.rb b/lib/net/ssh/key_factory.rb
index 60f1dc8..d101aec 100644
--- a/lib/net/ssh/key_factory.rb
+++ b/lib/net/ssh/key_factory.rb
@@ -1,10 +1,7 @@
require 'net/ssh/transport/openssl'
require 'net/ssh/prompt'
-begin
- require 'net/ssh/authentication/ed25519'
-rescue LoadError => e # rubocop:disable Lint/HandleExceptions
-end
+require 'net/ssh/authentication/ed25519_loader'
module Net; module SSH
@@ -26,7 +23,7 @@ module Net; module SSH
}
if defined?(OpenSSL::PKey::EC)
MAP["ecdsa"] = OpenSSL::PKey::EC
- MAP["ed25519"] = ED25519::PrivKey if defined? ED25519
+ MAP["ed25519"] = Net::SSH::Authentication::ED25519::PrivKey if defined? Net::SSH::Authentication::ED25519
end
class <<self
@@ -112,7 +109,11 @@ module Net; module SSH
# appropriately.
def classify_key(data, filename)
if data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/)
- return ->(key_data, passphrase) { ED25519::PrivKey.read(key_data, passphrase) }, ArgumentError
+ if defined?(Net::SSH::Authentication::ED25519)
+ return ->(key_data, passphrase) { Net::SSH::Authentication::ED25519::PrivKey.read(key_data, passphrase) }, ArgumentError
+ else
+ raise OpenSSL::PKey::PKeyError, "OpenSSH keys only supported if ED25519 is available - #{ED25519_LOAD_ERROR}"
+ end
elsif OpenSSL::PKey.respond_to?(:read)
return ->(key_data, passphrase) { OpenSSL::PKey.read(key_data, passphrase) }, ArgumentError
elsif data.match(/-----BEGIN DSA PRIVATE KEY-----/)
diff --git a/test/authentication/test_ed25519.rb b/test/authentication/test_ed25519.rb
index 28d5ebd..ba4ad1c 100644
--- a/test/authentication/test_ed25519.rb
+++ b/test/authentication/test_ed25519.rb
@@ -13,8 +13,8 @@ module Authentication
pub_data = pub.read_string
priv = private_key_no_pwd
- pub_key = ED25519::PubKey.new(pub_data)
- priv_key = ED25519::PrivKey.new(priv,nil)
+ pub_key = Net::SSH::Authentication::ED25519::PubKey.new(pub_data)
+ priv_key = Net::SSH::Authentication::ED25519::PrivKey.new(priv,nil)
shared_secret = "Hello"
signed = priv_key.ssh_do_sign(shared_secret)
@@ -32,8 +32,8 @@ module Authentication
pub_data = pub.read_string
priv = private_key_pwd
- pub_key = ED25519::PubKey.new(pub_data)
- priv_key = ED25519::PrivKey.new(priv,'pwd')
+ pub_key = Net::SSH::Authentication::ED25519::PubKey.new(pub_data)
+ priv_key = Net::SSH::Authentication::ED25519::PrivKey.new(priv,'pwd')
shared_secret = "Hello"
signed = priv_key.ssh_do_sign(shared_secret)