diff --git a/lib/ssh_data/certificate.rb b/lib/ssh_data/certificate.rb index 3925297..ee12b10 100644 --- a/lib/ssh_data/certificate.rb +++ b/lib/ssh_data/certificate.rb @@ -148,11 +148,12 @@ def rfc4253 # Sign this certificate with a private key. # # private_key - An SSHData::PrivateKey::Base subclass instance. + # algo: - Optionally specify the signature algorithm to use. # # Returns nothing. - def sign(private_key) + def sign(private_key, algo: nil) @ca_key = private_key.public_key - @signature = private_key.sign(signed_data) + @signature = private_key.sign(signed_data, algo: algo) end # Verify the certificate's signature. diff --git a/lib/ssh_data/private_key/base.rb b/lib/ssh_data/private_key/base.rb index 79bbbba..7829d30 100644 --- a/lib/ssh_data/private_key/base.rb +++ b/lib/ssh_data/private_key/base.rb @@ -18,19 +18,21 @@ def self.generate(**kwargs) # Make an SSH signature. # # signed_data - The String message over which to calculated the signature. + # algo: - Optionally specify the signature algorithm to use. # # Returns a binary String signature. - def sign(signed_data) + def sign(signed_data, algo: nil) raise "implement me" end # Issue a certificate using this private key. # - # kwargs - See SSHData::Certificate.new. + # signature_algo: - Optionally specify the signature algorithm to use. + # kwargs - See SSHData::Certificate.new. # # Returns a SSHData::Certificate instance. - def issue_certificate(**kwargs) - Certificate.new(**kwargs).tap { |c| c.sign(self) } + def issue_certificate(signature_algo: nil, **kwargs) + Certificate.new(**kwargs).tap { |c| c.sign(self, algo: signature_algo) } end end end diff --git a/lib/ssh_data/private_key/dsa.rb b/lib/ssh_data/private_key/dsa.rb index e9c3fd0..81233e6 100644 --- a/lib/ssh_data/private_key/dsa.rb +++ b/lib/ssh_data/private_key/dsa.rb @@ -50,7 +50,9 @@ def initialize(algo:, p:, q:, g:, x:, y:, comment:) # signed_data - The String message over which to calculated the signature. # # Returns a binary String signature. - def sign(signed_data) + def sign(signed_data, algo: nil) + algo ||= self.algo + raise AlgorithmError unless algo == self.algo openssl_sig = openssl.sign(OpenSSL::Digest::SHA1.new, signed_data) raw_sig = PublicKey::DSA.ssh_signature(openssl_sig) Encoding.encode_signature(algo, raw_sig) diff --git a/lib/ssh_data/private_key/ecdsa.rb b/lib/ssh_data/private_key/ecdsa.rb index 5a24c3f..8740c1d 100644 --- a/lib/ssh_data/private_key/ecdsa.rb +++ b/lib/ssh_data/private_key/ecdsa.rb @@ -68,7 +68,9 @@ def initialize(algo:, curve:, public_key:, private_key:, comment:) # signed_data - The String message over which to calculated the signature. # # Returns a binary String signature. - def sign(signed_data) + def sign(signed_data, algo: nil) + algo ||= self.algo + raise AlgorithmError unless algo == self.algo openssl_sig = openssl.sign(public_key.digest.new, signed_data) raw_sig = PublicKey::ECDSA.ssh_signature(openssl_sig) Encoding.encode_signature(algo, raw_sig) diff --git a/lib/ssh_data/private_key/ed25519.rb b/lib/ssh_data/private_key/ed25519.rb index 374a4fd..395a4b0 100644 --- a/lib/ssh_data/private_key/ed25519.rb +++ b/lib/ssh_data/private_key/ed25519.rb @@ -55,7 +55,9 @@ def initialize(algo:, pk:, sk:, comment:) # signed_data - The String message over which to calculated the signature. # # Returns a binary String signature. - def sign(signed_data) + def sign(signed_data, algo: nil) + algo ||= self.algo + raise AlgorithmError unless algo == self.algo raw_sig = ed25519_key.sign(signed_data) Encoding.encode_signature(algo, raw_sig) end diff --git a/lib/ssh_data/private_key/rsa.rb b/lib/ssh_data/private_key/rsa.rb index 3f7a3b4..d539cee 100644 --- a/lib/ssh_data/private_key/rsa.rb +++ b/lib/ssh_data/private_key/rsa.rb @@ -61,8 +61,11 @@ def initialize(algo:, n:, e:, d:, iqmp:, p:, q:, comment:) # signed_data - The String message over which to calculated the signature. # # Returns a binary String signature. - def sign(signed_data) - raw_sig = openssl.sign(OpenSSL::Digest::SHA1.new, signed_data) + def sign(signed_data, algo: nil) + algo ||= self.algo + digest = PublicKey::RSA::ALGO_DIGESTS[algo] + raise AlgorithmError if digest.nil? + raw_sig = openssl.sign(digest.new, signed_data) Encoding.encode_signature(algo, raw_sig) end diff --git a/lib/ssh_data/public_key.rb b/lib/ssh_data/public_key.rb index 56f89cf..477e960 100644 --- a/lib/ssh_data/public_key.rb +++ b/lib/ssh_data/public_key.rb @@ -8,6 +8,11 @@ module PublicKey ALGO_ECDSA521 = "ecdsa-sha2-nistp521" ALGO_ED25519 = "ssh-ed25519" + # RSA SHA2 *signature* algorithms used with ALGO_RSA keys. + # https://tools.ietf.org/html/draft-rsa-dsa-sha2-256-02 + ALGO_RSA_SHA2_256 = "rsa-sha2-256" + ALGO_RSA_SHA2_512 = "rsa-sha2-512" + ALGOS = [ ALGO_RSA, ALGO_DSA, ALGO_ECDSA256, ALGO_ECDSA384, ALGO_ECDSA521, ALGO_ED25519 diff --git a/lib/ssh_data/public_key/rsa.rb b/lib/ssh_data/public_key/rsa.rb index b6f5fe9..96e11ab 100644 --- a/lib/ssh_data/public_key/rsa.rb +++ b/lib/ssh_data/public_key/rsa.rb @@ -3,6 +3,12 @@ module PublicKey class RSA < Base attr_reader :e, :n, :openssl + ALGO_DIGESTS = { + ALGO_RSA => OpenSSL::Digest::SHA1, + ALGO_RSA_SHA2_256 => OpenSSL::Digest::SHA256, + ALGO_RSA_SHA2_512 => OpenSSL::Digest::SHA512 + } + def initialize(algo:, e:, n:) unless algo == ALGO_RSA raise DecodeError, "bad algorithm: #{algo.inspect}" @@ -25,11 +31,13 @@ def initialize(algo:, e:, n:) # Returns boolean. def verify(signed_data, signature) sig_algo, raw_sig, _ = Encoding.decode_signature(signature) - if sig_algo != ALGO_RSA + digest = ALGO_DIGESTS[sig_algo] + + if digest.nil? raise DecodeError, "bad signature algorithm: #{sig_algo.inspect}" end - openssl.verify(OpenSSL::Digest::SHA1.new, raw_sig, signed_data) + openssl.verify(digest.new, raw_sig, signed_data) end # RFC4253 binary encoding of the public key. diff --git a/spec/certificate_spec.rb b/spec/certificate_spec.rb index 7aa2202..9453972 100644 --- a/spec/certificate_spec.rb +++ b/spec/certificate_spec.rb @@ -66,6 +66,22 @@ SSHData::PublicKey::RSA # ca key type ] + test_cases << [ + :rsa_cert_sha2_256_sig, # name + "rsa_leaf_for_rsa_ca_sha2_256-cert.pub", # fixture + SSHData::Certificate::ALGO_RSA, # algo + SSHData::PublicKey::RSA, # public key type + SSHData::PublicKey::RSA # ca key type + ] + + test_cases << [ + :rsa_cert_sha2_512_sig, # name + "rsa_leaf_for_rsa_ca_sha2_512-cert.pub", # fixture + SSHData::Certificate::ALGO_RSA, # algo + SSHData::PublicKey::RSA, # public key type + SSHData::PublicKey::RSA # ca key type + ] + test_cases << [ :dsa_cert, # name "dsa_leaf_for_rsa_ca-cert.pub", # fixture @@ -155,6 +171,22 @@ expect(subject.verify).to eq(true) end + it "can be signed with an RSA key using ALGO_RSA_SHA2_256" do + expect { + subject.sign(rsa_ca, algo: SSHData::PublicKey::ALGO_RSA_SHA2_256) + }.to change {subject.signature} + + expect(subject.verify).to eq(true) + end + + it "can be signed with an RSA key using ALGO_RSA_SHA2_512" do + expect { + subject.sign(rsa_ca, algo: SSHData::PublicKey::ALGO_RSA_SHA2_512) + }.to change {subject.signature} + + expect(subject.verify).to eq(true) + end + it "can be signed with an DSA key" do expect { subject.sign(dsa_ca) }.to change {subject.signature} expect(subject.verify).to eq(true) diff --git a/spec/fixtures/gen.sh b/spec/fixtures/gen.sh index a2b4d20..f5d33e6 100755 --- a/spec/fixtures/gen.sh +++ b/spec/fixtures/gen.sh @@ -10,6 +10,12 @@ ssh-keygen -ted25519 -N "" -f ./ed25519_ca ssh-keygen -trsa -N "" -f ./rsa_leaf_for_rsa_ca ssh-keygen -s rsa_ca -z 123 -n p1,p2 -O clear -I my-ident -O critical:foo=bar -O extension:baz=qwer -O permit-X11-forwarding rsa_leaf_for_rsa_ca.pub +ssh-keygen -trsa -N "" -f ./rsa_leaf_for_rsa_ca_sha2_256 +ssh-keygen -trsa-sha2-256 -s rsa_ca -z 123 -n p1,p2 -O clear -I my-ident -O critical:foo=bar -O extension:baz=qwer -O permit-X11-forwarding rsa_leaf_for_rsa_ca_sha2_256.pub + +ssh-keygen -trsa -N "" -f ./rsa_leaf_for_rsa_ca_sha2_512 +ssh-keygen -trsa-sha2-512 -s rsa_ca -z 123 -n p1,p2 -O clear -I my-ident -O critical:foo=bar -O extension:baz=qwer -O permit-X11-forwarding rsa_leaf_for_rsa_ca_sha2_512.pub + ssh-keygen -trsa -N "" -f ./rsa_leaf_for_dsa_ca ssh-keygen -s dsa_ca -z 123 -n p1,p2 -O clear -I my-ident -O critical:foo=bar -O extension:baz=qwer -O permit-X11-forwarding rsa_leaf_for_dsa_ca.pub diff --git a/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256 b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256 new file mode 100644 index 0000000..8432941 --- /dev/null +++ b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256 @@ -0,0 +1,28 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn +NhAAAAAwEAAQAAAQEAoOYrE6L+gal76n6oC5sydFkqX6aaB8Iv6gcqoZmrqM8j+Fzimxbc +xi8vcAci/R/yxwFu43FO/trjF+inaUWk7uniB748pJFNd5ELBeJtU1CHMjO6i3jYQQ7NRB +N19gTcFHO+n1BmvI66/BLbSOJ/h/DLObDjbLE6YaC83oD7lHYn/OTrl5XhSnYqsLZfdma1 +EgEbcs18ILBCjBHrtWyAquS8GjAXX1elobkipOV4d/+ba/xJ04LxBBz3rhX8raalNArQsm +x0v53kjE+fv1RlQFnAnDykG480536ZYxwLJzxzYUO1TgQel6tyhC63tmm5egowRdtTER0+ +tkwVLNTxkwAAA+AR0V0oEdFdKAAAAAdzc2gtcnNhAAABAQCg5isTov6BqXvqfqgLmzJ0WS +pfppoHwi/qByqhmauozyP4XOKbFtzGLy9wByL9H/LHAW7jcU7+2uMX6KdpRaTu6eIHvjyk +kU13kQsF4m1TUIcyM7qLeNhBDs1EE3X2BNwUc76fUGa8jrr8EttI4n+H8Ms5sONssTphoL +zegPuUdif85OuXleFKdiqwtl92ZrUSARtyzXwgsEKMEeu1bICq5LwaMBdfV6WhuSKk5Xh3 +/5tr/EnTgvEEHPeuFfytpqU0CtCybHS/neSMT5+/VGVAWcCcPKQbjzTnfpljHAsnPHNhQ7 +VOBB6Xq3KELre2abl6CjBF21MRHT62TBUs1PGTAAAAAwEAAQAAAQBBa7TCJDjlUZs/ykXb +ijvmkMao452nX+6JcmaEFG52kdqnRmUg+BfGQTNBkrVIRHA7ODr1IYIkH63Mb9158UZRmi +k8Sr5vj2D3J7NarikTgh+mauADi5wqP7F4Z41D/c/aRQGR12gebM5cZfJhXS7LgD2xdFnU +PO9m+KsysTEZuJgYX+pbPghTL48XdMPowJUsu5FmKmz25KVr88CJWNUzpYqXYvmgsSALf1 +fDRF0ggejPpnUHB/GL1+bz04FETocC2303yVNSgrIZID7KZoNW6PM+2BrtCt6bTMXYq+DF +kvFu3WgFxFO09WzUmEJKXxtpQfEzTLqA8Mt+jMAl095hAAAAgBBrMWdYEoNpG+h1BjdvMm +8iHI2Q3dwYnINKuWJ8GDhNCOXZ5mq99160iEB7Jh2SP2IgFz3V7rFEDbohA8YPvSkBhWZT +LRQD9fGtV0uhwPrAd64ddh6ibq6G6DooTGUFKuGLbh+EFVVoGFTOsZNTXYImYJPvAXw13u +BViGaUauu6AAAAgQDL/CgLsy+/qwInCI/Y/MFjl0UavfDrasgzgbm9vNM6ElDT6DaNkxH4 +LuEvEI6+kLKP1AfOgFUkh/mV1N6NJ5y46nT1JPW8QyLBCYl/c17zF73tpKImvUscr/TAIo +I4prMmx5bfH21JIWDQsUr2q2jSKsDz6JJazXOxjEEgn5WZowAAAIEAye1tbTOHXcyvOFeJ +75dHZm3wskRnGSNCEIOfZGdkyXf+NQYVivQ4hyiMWc/rsxCD105y2Mmdhgw9fJP5ULmfBZ +unZkHNgBqVquow3wx9z7fMrLRDmIkgCuZfyZQ0UbSF432zayhLDuZslekq6jQKiqLiL5DA +OXOZSsQvpcwCp1EAAAAmbWFzdGFoeWV0aUBCZW5qYW1pbnMtTWFjQm9vay1Qcm8ubG9jYW +wBAgMEBQ== +-----END OPENSSH PRIVATE KEY----- diff --git a/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256-cert.pub b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256-cert.pub new file mode 100644 index 0000000..083c4f1 --- /dev/null +++ b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256-cert.pub @@ -0,0 +1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgD6UPGJ65bMZSZcwYFa21ImYDt95dT4AEXhg/V543f/sAAAADAQABAAABAQCg5isTov6BqXvqfqgLmzJ0WSpfppoHwi/qByqhmauozyP4XOKbFtzGLy9wByL9H/LHAW7jcU7+2uMX6KdpRaTu6eIHvjykkU13kQsF4m1TUIcyM7qLeNhBDs1EE3X2BNwUc76fUGa8jrr8EttI4n+H8Ms5sONssTphoLzegPuUdif85OuXleFKdiqwtl92ZrUSARtyzXwgsEKMEeu1bICq5LwaMBdfV6WhuSKk5Xh3/5tr/EnTgvEEHPeuFfytpqU0CtCybHS/neSMT5+/VGVAWcCcPKQbjzTnfpljHAsnPHNhQ7VOBB6Xq3KELre2abl6CjBF21MRHT62TBUs1PGTAAAAAAAAAHsAAAABAAAACG15LWlkZW50AAAADAAAAAJwMQAAAAJwMgAAAAAAAAAA//////////8AAAASAAAAA2ZvbwAAAAcAAAADYmFyAAAAMAAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAA2JhegAAAAgAAAAEcXdlcgAAAAAAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQDPB20SS4Ry0ahVJGIf5aYRU81PwtUiDLj2ChUnMfYtCYemucIRjkfTUquHzePbecUaWx/NHX0GHRv7c4NO+TYx/UPDC6e2ZmRhDRy/pc5qtyRu7fqBSsrhBAvAdv13F5LzMlRv+oZXIEBeNM8Zd3NIgapztMdxkBF+LsNksbisg9ixTJcOb3iSZVzQP4vmQH1wviO0/WFYj+rS3TroT6gPxUuafzThcXFtxLWAXAM+f9bLP9cJHW3AAGfohylRKTcVsxS7x7YljrK0EwfAh4KvjTAnk5gpbdLHaPweRrN62eYfIRZxCubdedDVuZ3PVlUmQWAhntHUkInB+mlkP/HvAAABFAAAAAxyc2Etc2hhMi0yNTYAAAEAixSGL6nIAe7Qo/Kd1jAtVf7SkF0lotoy8xQjKE/1urWhMohFEQc7Yfdt4PYiKflnrSN//vqZyGN2t+5iwvPV4OQJXoHZFbNU/sJAgqHcYtrUIXGiU+7IZePDy/9V0Snl/wAupIMyxApX0YTAmWTdNrNdlPS/SGTZgE2yFgG00xHTqfPZtnOzSz/34URlqzqVk/T1mBYv7ibJDB5V+ODyR/f/iMP3gvHcwwRQ3xF9qBYYdlB8P0GlElgkH4A2JJ/xy1bOjvzkuaPOcMus6JxL/jrEnnbkEowrTa4xgRJCk5j3KxUiQuYaxbrtu4Haav4MQ6wC0RIs1So9nqoq+iuTEg== mastahyeti@Benjamins-MacBook-Pro.local diff --git a/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256.pub b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256.pub new file mode 100644 index 0000000..6713b46 --- /dev/null +++ b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_256.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCg5isTov6BqXvqfqgLmzJ0WSpfppoHwi/qByqhmauozyP4XOKbFtzGLy9wByL9H/LHAW7jcU7+2uMX6KdpRaTu6eIHvjykkU13kQsF4m1TUIcyM7qLeNhBDs1EE3X2BNwUc76fUGa8jrr8EttI4n+H8Ms5sONssTphoLzegPuUdif85OuXleFKdiqwtl92ZrUSARtyzXwgsEKMEeu1bICq5LwaMBdfV6WhuSKk5Xh3/5tr/EnTgvEEHPeuFfytpqU0CtCybHS/neSMT5+/VGVAWcCcPKQbjzTnfpljHAsnPHNhQ7VOBB6Xq3KELre2abl6CjBF21MRHT62TBUs1PGT mastahyeti@Benjamins-MacBook-Pro.local diff --git a/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512 b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512 new file mode 100644 index 0000000..5d39524 --- /dev/null +++ b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512 @@ -0,0 +1,28 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn +NhAAAAAwEAAQAAAQEA1n6Umdz5V50Dqo0lZkrj55wOD4ga/09Tv6AvnVcUwa1eI9ZUuqQg +NOWEKP26NMgvk2zmf7ouQ5qlJe6PJXp3PkdXovMg7sh0rx173s9iOuV/IPfKOJDhycRdPX +Klkm0SuU69da7D6kY978Z02bvsmNh8UKbsZIfjX0dSo1pFCZkcKh7ytlTIzgnIKt3oXArw +HWJFCiQu/O1FS1hcvfOSPeFYsrJIbYxWVGTuE8gQWCgtNx9VRmPGZ6P0Jalto1RtAkb9xH +PWZ9yJ80rcdrtXn3+gfckqfrrhPIBpc9lBZhuCFKPuZuVnSxXxe8sCDIe95bWgrKuVMCUl +mAK27X0bqwAAA+C06Dl2tOg5dgAAAAdzc2gtcnNhAAABAQDWfpSZ3PlXnQOqjSVmSuPnnA +4PiBr/T1O/oC+dVxTBrV4j1lS6pCA05YQo/bo0yC+TbOZ/ui5DmqUl7o8lenc+R1ei8yDu +yHSvHXvez2I65X8g98o4kOHJxF09cqWSbRK5Tr11rsPqRj3vxnTZu+yY2HxQpuxkh+NfR1 +KjWkUJmRwqHvK2VMjOCcgq3ehcCvAdYkUKJC787UVLWFy985I94ViyskhtjFZUZO4TyBBY +KC03H1VGY8Zno/QlqW2jVG0CRv3Ec9Zn3InzStx2u1eff6B9ySp+uuE8gGlz2UFmG4IUo+ +5m5WdLFfF7ywIMh73ltaCsq5UwJSWYArbtfRurAAAAAwEAAQAAAQEAlP26FSKEZJJhYI/I +ocR1iIVC0xEUx7F/mAUZ7e32Mg5N7RDNLBQjdvrSkXKlbFJ9kac8eQ6HYlhCTRXngv4NZE +pEGqFNh+/f9V/CkmN1dTnC09CrPB2PaQqoRa2kSxDOx79lJSCvX8VI8ovk0PWThBwkRhWc +8LvfeWheg6+Jcv8MfTDeQMvEejJrifYeIgUnhsa8cUY1aVgQI/BLLwJatBILsmeYHPpJUc +X28ctZ04IJPySGmS70xgOKqttcESjwaCWWq8Zbwv8jLYvBzRWjyyKVV5W4D7SE23yNfXE0 +KZFLcieB7PDefI/8f9o9UXj1Qgn9tUDfEVUH3X22Ob99KQAAAIBNg8crl4+1Tx/i29c23w +JwOjtTWSEF4c4F3oPl93aCBydNrkLoVxtEELFoCntmzFDlz0b0qoYJjLELZVYOhFzY1yK4 ++zBzEDDIYtyXmg462c4rlBmMzsX5AT2bOAbqMkz2IzHBUO56Of4R/Cv3H/3wGSCTdKtLme +rYKMGlZU7R7QAAAIEA+X98OD+rBGo2S6fOgr+JKCpJm57xAZ41hQcoqK/exlaY+i6C4fGx +jxhItyKJyEFtZMffTIsoyqN/C/N0jXt2GPTt11h7cuXoML8hOO+xnugACnn42g8+0uBs01 +25sZJEAELgvHAzbAUdHke+yjJVEPTjG6num1vJkZwXR0J5u68AAACBANwVkhpLxypZst8S +zK3HAJsASDOvN+5N+r8/nKoIPEC3+p0r05wyUa43Iy2aX/xNHwYVlv9y1Hd76exwjIHsyD +DgYHv0IIVUx/6jeaX/Qs6DzgUz0NsmE889uskEzfYDk9EL+j/EU5DP1IZXf/u0ZSAx6z9m +uKe8b0az20O3sLLFAAAAJm1hc3RhaHlldGlAQmVuamFtaW5zLU1hY0Jvb2stUHJvLmxvY2 +FsAQIDBA== +-----END OPENSSH PRIVATE KEY----- diff --git a/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512-cert.pub b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512-cert.pub new file mode 100644 index 0000000..d2325b2 --- /dev/null +++ b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512-cert.pub @@ -0,0 +1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgaEtgZ62R/ngTrlVxslotA3cnRoxl37uMWr+VNdlPEBIAAAADAQABAAABAQDWfpSZ3PlXnQOqjSVmSuPnnA4PiBr/T1O/oC+dVxTBrV4j1lS6pCA05YQo/bo0yC+TbOZ/ui5DmqUl7o8lenc+R1ei8yDuyHSvHXvez2I65X8g98o4kOHJxF09cqWSbRK5Tr11rsPqRj3vxnTZu+yY2HxQpuxkh+NfR1KjWkUJmRwqHvK2VMjOCcgq3ehcCvAdYkUKJC787UVLWFy985I94ViyskhtjFZUZO4TyBBYKC03H1VGY8Zno/QlqW2jVG0CRv3Ec9Zn3InzStx2u1eff6B9ySp+uuE8gGlz2UFmG4IUo+5m5WdLFfF7ywIMh73ltaCsq5UwJSWYArbtfRurAAAAAAAAAHsAAAABAAAACG15LWlkZW50AAAADAAAAAJwMQAAAAJwMgAAAAAAAAAA//////////8AAAASAAAAA2ZvbwAAAAcAAAADYmFyAAAAMAAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAA2JhegAAAAgAAAAEcXdlcgAAAAAAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQDPB20SS4Ry0ahVJGIf5aYRU81PwtUiDLj2ChUnMfYtCYemucIRjkfTUquHzePbecUaWx/NHX0GHRv7c4NO+TYx/UPDC6e2ZmRhDRy/pc5qtyRu7fqBSsrhBAvAdv13F5LzMlRv+oZXIEBeNM8Zd3NIgapztMdxkBF+LsNksbisg9ixTJcOb3iSZVzQP4vmQH1wviO0/WFYj+rS3TroT6gPxUuafzThcXFtxLWAXAM+f9bLP9cJHW3AAGfohylRKTcVsxS7x7YljrK0EwfAh4KvjTAnk5gpbdLHaPweRrN62eYfIRZxCubdedDVuZ3PVlUmQWAhntHUkInB+mlkP/HvAAABFAAAAAxyc2Etc2hhMi01MTIAAAEAEBiCMP+uDhsrErHm//3GZC50M9dOP0rTC/BdSjndEYe58kROkSRqNA3FNYMe+710ch91lNBQ5IksX7zR1MkeCmzupcrdnP42wdv6ILG4/9kWZQcGIiGLeUVmeEl6QtjnW6r012igAkgDGP6Z+SDs74o7KV+GxiPxWgidn3ak09g2LkHmARD3yRS230+uft0vwOm6Z6sPA+bwGV4VDN6p///UOb+sg2CnNNbx3fFRaw6M6R1HIpbsNNmkyk5rVJAlKmKOJ3tBz3ZL2bN/ThWTlPeDz2IUlJdUCzwO+JkcFL9oVeHZvxgupdTrsZDkOkA5qC9DB3xwMKIlKaNff/nCJg== mastahyeti@Benjamins-MacBook-Pro.local diff --git a/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512.pub b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512.pub new file mode 100644 index 0000000..0c97b81 --- /dev/null +++ b/spec/fixtures/rsa_leaf_for_rsa_ca_sha2_512.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWfpSZ3PlXnQOqjSVmSuPnnA4PiBr/T1O/oC+dVxTBrV4j1lS6pCA05YQo/bo0yC+TbOZ/ui5DmqUl7o8lenc+R1ei8yDuyHSvHXvez2I65X8g98o4kOHJxF09cqWSbRK5Tr11rsPqRj3vxnTZu+yY2HxQpuxkh+NfR1KjWkUJmRwqHvK2VMjOCcgq3ehcCvAdYkUKJC787UVLWFy985I94ViyskhtjFZUZO4TyBBYKC03H1VGY8Zno/QlqW2jVG0CRv3Ec9Zn3InzStx2u1eff6B9ySp+uuE8gGlz2UFmG4IUo+5m5WdLFfF7ywIMh73ltaCsq5UwJSWYArbtfRur mastahyeti@Benjamins-MacBook-Pro.local diff --git a/spec/private_key/dsa_spec.rb b/spec/private_key/dsa_spec.rb index 2de4673..bf0a106 100644 --- a/spec/private_key/dsa_spec.rb +++ b/spec/private_key/dsa_spec.rb @@ -5,6 +5,7 @@ let(:public_key) { private_key.public_key } let(:params) { private_key.params } let(:message) { "hello, world!" } + let(:cert_key) { SSHData::PrivateKey::DSA.generate.public_key } let(:openssh_key) { SSHData::PrivateKey.parse(fixture("dsa_leaf_for_rsa_ca")) } @@ -20,6 +21,31 @@ expect(subject.public_key.verify(message, subject.sign(message))).to eq(true) end + it "can sign messages" do + expect(subject.public_key.verify(message, subject.sign(message))).to eq(true) + end + + it "can sign messages with ALGO_DSA" do + sig = subject.sign(message, algo: SSHData::PublicKey::ALGO_DSA) + expect(subject.public_key.verify(message, sig)).to eq(true) + end + + it "raises when trying to sign with bad algo" do + expect { + subject.sign(message, algo: SSHData::PublicKey::ALGO_RSA) + }.to raise_error(SSHData::AlgorithmError) + end + + it "raises when trying to sign with bad algo" do + expect { + subject.issue_certificate( + public_key: cert_key, + key_id: "some ident", + signature_algo: SSHData::PublicKey::ALGO_RSA + ) + }.to raise_error(SSHData::AlgorithmError) + end + it "has an algo" do expect(subject.algo).to eq(SSHData::PublicKey::ALGO_DSA) end diff --git a/spec/private_key/ecdsa_spec.rb b/spec/private_key/ecdsa_spec.rb index 05c8d62..badda57 100644 --- a/spec/private_key/ecdsa_spec.rb +++ b/spec/private_key/ecdsa_spec.rb @@ -2,6 +2,7 @@ describe SSHData::PrivateKey::ECDSA do let(:openssh_key) { SSHData::PrivateKey.parse(fixture("ecdsa_leaf_for_rsa_ca")) } + let(:cert_key) { SSHData::PrivateKey::DSA.generate.public_key } it "can raises AlgorithmError for unknown curves" do expect { @@ -37,6 +38,27 @@ expect(subject.public_key.verify(message, subject.sign(message))).to eq(true) end + it "can sign messages with ALGO_ECDSA" do + sig = subject.sign(message, algo: algo) + expect(subject.public_key.verify(message, sig)).to eq(true) + end + + it "raises when trying to sign with bad algo" do + expect { + subject.sign(message, algo: SSHData::PublicKey::ALGO_RSA) + }.to raise_error(SSHData::AlgorithmError) + end + + it "raises when trying to sign with bad algo" do + expect { + subject.issue_certificate( + public_key: cert_key, + key_id: "some ident", + signature_algo: SSHData::PublicKey::ALGO_RSA + ) + }.to raise_error(SSHData::AlgorithmError) + end + it "has an algo" do expect(subject.algo).to eq(algo) end diff --git a/spec/private_key/ed25519_spec.rb b/spec/private_key/ed25519_spec.rb index a411115..70cca1a 100644 --- a/spec/private_key/ed25519_spec.rb +++ b/spec/private_key/ed25519_spec.rb @@ -5,6 +5,7 @@ let(:verify_key) { signing_key.verify_key } let(:comment) { "asdf" } let(:message) { "hello, world!" } + let(:cert_key) { SSHData::PrivateKey::DSA.generate.public_key } let(:openssh_key) { SSHData::PrivateKey.parse(fixture("ed25519_leaf_for_rsa_ca")) } @@ -27,6 +28,27 @@ expect(subject.public_key.verify(message, subject.sign(message))).to eq(true) end + it "can sign messages with ALGO_ED25519" do + sig = subject.sign(message, algo: SSHData::PublicKey::ALGO_ED25519) + expect(subject.public_key.verify(message, sig)).to eq(true) + end + + it "raises when trying to sign with bad algo" do + expect { + subject.sign(message, algo: SSHData::PublicKey::ALGO_RSA) + }.to raise_error(SSHData::AlgorithmError) + end + + it "raises when trying to sign with bad algo" do + expect { + subject.issue_certificate( + public_key: cert_key, + key_id: "some ident", + signature_algo: SSHData::PublicKey::ALGO_RSA + ) + }.to raise_error(SSHData::AlgorithmError) + end + it "has an algo" do expect(subject.algo).to eq(SSHData::PublicKey::ALGO_ED25519) end diff --git a/spec/private_key/rsa_spec.rb b/spec/private_key/rsa_spec.rb index 1352758..cb8f277 100644 --- a/spec/private_key/rsa_spec.rb +++ b/spec/private_key/rsa_spec.rb @@ -5,6 +5,7 @@ let(:public_key) { private_key.public_key } let(:params) { private_key.params } let(:message) { "hello, world!" } + let(:cert_key) { SSHData::PrivateKey::DSA.generate.public_key } let(:openssh_key) { SSHData::PrivateKey.parse(fixture("rsa_leaf_for_rsa_ca")) } @@ -28,8 +29,48 @@ }.not_to raise_error end - it "can sign messages" do - expect(subject.public_key.verify(message, subject.sign(message))).to eq(true) + [ + nil, + SSHData::PublicKey::ALGO_RSA, + SSHData::PublicKey::ALGO_RSA_SHA2_256, + SSHData::PublicKey::ALGO_RSA_SHA2_512 + ].each do |signature_algo| + it "can sign messages with #{signature_algo}" do + sig = subject.sign(message, algo: signature_algo) + expect(subject.public_key.verify(message, sig)).to eq(true) + + algo, _ = SSHData::Encoding.decode_signature(sig) + expect(algo).to eq(signature_algo || SSHData::PublicKey::ALGO_RSA) + end + + it "can issue a certificate with a #{signature_algo} signature" do + cert = subject.issue_certificate( + public_key: cert_key, + key_id: "some ident", + signature_algo: signature_algo + ) + + algo, _ = SSHData::Encoding.decode_signature(cert.signature) + + expect(algo).to eq(signature_algo || SSHData::PublicKey::ALGO_RSA) + expect(cert.verify).to be(true) + end + end + + it "raises when trying to sign with bad algo" do + expect { + subject.issue_certificate( + public_key: cert_key, + key_id: "some ident", + signature_algo: SSHData::PublicKey::ALGO_DSA + ) + }.to raise_error(SSHData::AlgorithmError) + end + + it "raises when trying to issue a certificate with bad signature algo" do + expect { + subject.sign(message, algo: SSHData::PublicKey::ALGO_DSA) + }.to raise_error(SSHData::AlgorithmError) end it "has an algo" do